diff --git a/assets/styles/style.scss b/assets/styles/style.scss
index 00d0ca85..3dc28bd6 100644
--- a/assets/styles/style.scss
+++ b/assets/styles/style.scss
@@ -110,6 +110,7 @@
color: orange;
}
+livechat-error,
.peertube-plugin-livechat-error {
color: red;
}
@@ -202,6 +203,7 @@ table.peertube-plugin-livechat-prosody-list-rooms td {
}
}
+livechat-spinner,
.livechat-spinner {
display: flex;
flex-direction: row;
@@ -246,3 +248,9 @@ table.peertube-plugin-livechat-prosody-list-rooms td {
max-width: 30vw;
}
}
+
+livechat-error {
+ display: block;
+ padding: 50px;
+ text-align: center;
+}
diff --git a/client/@types/global.d.ts b/client/@types/global.d.ts
index 11b999ac..468ce51f 100644
--- a/client/@types/global.d.ts
+++ b/client/@types/global.d.ts
@@ -107,3 +107,5 @@ declare const LOC_ACTION_IMPORT_EMOJIS_INFO: string
declare const LOC_ACTION_ADD_ENTRY: string
declare const LOC_ACTION_REMOVE_ENTRY: string
declare const LOC_ACTION_REMOVE_ENTRY_CONFIRM: string
+
+declare const LOC_LOADING_ERROR: string
diff --git a/client/common/configuration/elements/channel-configuration.ts b/client/common/configuration/elements/channel-configuration.ts
index 38723019..619d33a0 100644
--- a/client/common/configuration/elements/channel-configuration.ts
+++ b/client/common/configuration/elements/channel-configuration.ts
@@ -230,6 +230,8 @@ export class ChannelConfigurationElement extends LivechatElement {
}
return this._asyncTaskRender.render({
+ pending: () => html``,
+ error: () => html``,
complete: () => html`
diff --git a/client/common/configuration/elements/channel-emojis.ts b/client/common/configuration/elements/channel-emojis.ts
index 2b3a921b..425c3b01 100644
--- a/client/common/configuration/elements/channel-emojis.ts
+++ b/client/common/configuration/elements/channel-emojis.ts
@@ -71,7 +71,8 @@ export class ChannelEmojisElement extends LivechatElement {
}
}
return this._asyncTaskRender.render({
- pending: () => {},
+ pending: () => html`
`,
+ error: () => html`
`,
complete: () => html`
- `,
- error: (err: any) => {
- this.registerClientOptions?.peertubeHelpers.notifier.error(err.toString())
- }
+ `
})
}
diff --git a/client/common/configuration/elements/channel-home.ts b/client/common/configuration/elements/channel-home.ts
index 1e34f0b6..99459e79 100644
--- a/client/common/configuration/elements/channel-home.ts
+++ b/client/common/configuration/elements/channel-home.ts
@@ -47,6 +47,8 @@ export class ChannelHomeElement extends LivechatElement {
protected override render = (): unknown => {
return this._asyncTaskRender.render({
+ pending: () => html`
`,
+ error: () => html`
`,
complete: () => html`
@@ -62,7 +64,7 @@ export class ChannelHomeElement extends LivechatElement {
${channel.avatar
? html``
- : html``
+ : html``
}
diff --git a/client/common/lib/elements/error.ts b/client/common/lib/elements/error.ts
new file mode 100644
index 00000000..3fcc7037
--- /dev/null
+++ b/client/common/lib/elements/error.ts
@@ -0,0 +1,19 @@
+// SPDX-FileCopyrightText: 2024 John Livingston
+//
+// SPDX-License-Identifier: AGPL-3.0-only
+
+import type { DirectiveResult } from 'lit/directive'
+import { html, TemplateResult } from 'lit'
+import { customElement, property } from 'lit/decorators.js'
+import { LivechatElement } from './livechat'
+import { ptTr } from '../directives/translation'
+
+@customElement('livechat-error')
+export class ErrorElement extends LivechatElement {
+ @property({ attribute: false })
+ public msg: string | DirectiveResult = ptTr(LOC_LOADING_ERROR)
+
+ protected override render = (): TemplateResult => {
+ return html`${this.msg}`
+ }
+}
diff --git a/client/common/lib/elements/index.js b/client/common/lib/elements/index.js
index 56ea7912..f0b920d3 100644
--- a/client/common/lib/elements/index.js
+++ b/client/common/lib/elements/index.js
@@ -9,3 +9,5 @@ import './dynamic-table-form'
import './configuration-row'
import './tags-input'
import './image-file-input'
+import './spinner'
+import './error'
diff --git a/client/common/lib/elements/spinner.ts b/client/common/lib/elements/spinner.ts
new file mode 100644
index 00000000..3d93479b
--- /dev/null
+++ b/client/common/lib/elements/spinner.ts
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2024 John Livingston
+//
+// SPDX-License-Identifier: AGPL-3.0-only
+
+import { html, TemplateResult } from 'lit'
+import { customElement } from 'lit/decorators.js'
+import { LivechatElement } from './livechat'
+
+@customElement('livechat-spinner')
+export class SpinnerElement extends LivechatElement {
+ protected override render = (): TemplateResult => {
+ return html`
` // CSS does the trick.
+ }
+}
diff --git a/languages/en.yml b/languages/en.yml
index 11981df6..4d6964ba 100644
--- a/languages/en.yml
+++ b/languages/en.yml
@@ -515,3 +515,5 @@ action_import_emojis_info: If imported data are okay, don't forgot to save the f
action_add_entry: Add an entry
action_remove_entry: Remove this entry
action_remove_entry_confirm: Are you sure you want to remove this entry?
+
+loading_error: An error occured while loading data.