diff --git a/src/domain/ErrorViewModel.ts b/src/domain/ErrorViewModel.ts new file mode 100644 index 00000000..9045af80 --- /dev/null +++ b/src/domain/ErrorViewModel.ts @@ -0,0 +1,44 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { ViewModel, Options as BaseOptions } from "./ViewModel"; +import {submitLogsFromSessionToDefaultServer} from "./rageshake"; +import type { Session } from "../matrix/Session"; + +type Options = { + error: Error + session: Session, + onClose: () => void +} & BaseOptions; + +export class ErrorViewModel extends ViewModel { + get message(): string { + return this.getOption("error")?.message; + } + + close() { + this.getOption("onClose")(); + } + + async submitLogs(): Promise { + try { + await submitLogsFromSessionToDefaultServer(this.getOption("session"), this.platform); + return true; + } catch (err) { + return false; + } + } +} \ No newline at end of file diff --git a/src/platform/web/ui/css/themes/element/error.css b/src/platform/web/ui/css/themes/element/error.css new file mode 100644 index 00000000..f4e4fb6f --- /dev/null +++ b/src/platform/web/ui/css/themes/element/error.css @@ -0,0 +1,50 @@ +.ErrorView_block { + background: var(--error-color); + color: var(--fixed-white); + margin: 16px; +} + +.ErrorView_inline { + color: var(--error-color); + margin: 4px; +} + +.ErrorView { + font-weight: bold; + margin: 16px; + border-radius: 8px; + padding: 12px; + display: flex; + gap: 4px; +} + +.ErrorView_message { + flex-basis: 0; + flex-grow: 1; + margin: 0px; + word-break: break-all; + word-break: break-word; +} + +.ErrorView_submit { + align-self: end; +} + +.ErrorView_close { + align-self: start; + width: 16px; + height: 16px; + border: none; + background: none; + background-repeat: no-repeat; + background-size: contain; + cursor: pointer; +} + +.ErrorView_block .ErrorView_close { + background-image: url('icons/clear.svg?primary=fixed-white'); +} + +.ErrorView_inline .ErrorView_close { + background-image: url('icons/clear.svg?primary=text-color'); +} \ No newline at end of file diff --git a/src/platform/web/ui/css/themes/element/theme.css b/src/platform/web/ui/css/themes/element/theme.css index 6403bb60..84a27f13 100644 --- a/src/platform/web/ui/css/themes/element/theme.css +++ b/src/platform/web/ui/css/themes/element/theme.css @@ -19,6 +19,7 @@ limitations under the License. @import url('inter.css'); @import url('timeline.css'); @import url('call.css'); +@import url('error.css'); :root { font-size: 10px; diff --git a/src/platform/web/ui/general/ErrorView.ts b/src/platform/web/ui/general/ErrorView.ts new file mode 100644 index 00000000..f44361c3 --- /dev/null +++ b/src/platform/web/ui/general/ErrorView.ts @@ -0,0 +1,56 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {TemplateView, Builder} from "./TemplateView"; +import { disableTargetCallback } from "./utils"; + +import type { ViewNode } from "./types"; +import type {ErrorViewModel} from "../../../../domain/ErrorViewModel"; + + +export class ErrorView extends TemplateView { + constructor(vm: ErrorViewModel, private readonly options: {inline: boolean} = {inline: false}) { + super(vm); + } + override render(t: Builder, vm: ErrorViewModel): ViewNode { + const submitLogsButton = t.button({ + className: "ErrorView_submit", + onClick: disableTargetCallback(async () => { + if (await vm.submitLogs()) { + alert("Logs submitted!"); + } else { + alert("Could not submit logs"); + } + }) + }, "Submit logs"); + const closeButton = t.button({ + className: "ErrorView_close", + onClick: () => vm.close(), + title: "Dismiss error" + }); + return t.div({ + className: { + "ErrorView": true, + "ErrorView_inline": this.options.inline, + "ErrorView_block": !this.options.inline + }}, [ + t.p({className: "ErrorView_message"}, vm.message), + submitLogsButton, + closeButton + ]); + } +} +