Skip to content

Commit 3ad1f1f

Browse files
implement toast notifications in AppComponent; update AppListener and ConnectionListener interfaces for error handling
1 parent 0999c3c commit 3ad1f1f

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

src/app.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export class App implements AppListener {
1414
return App.instance;
1515
}
1616

17+
toast(info: string): void { for (const listener of this.app_listeners) { listener.toast(info); } }
18+
1719
get_selected_component(): Component<any, HTMLElement> | null { return this.selected_comp; }
1820

1921
selected_component(component: Component<any, HTMLElement> | null): void {
@@ -34,6 +36,8 @@ export class App implements AppListener {
3436

3537
export interface AppListener {
3638

39+
toast(info: string): void;
40+
3741
selected_component(component: Component<any, HTMLElement> | null): void;
3842
}
3943

@@ -140,9 +144,44 @@ export class AppComponent extends Component<App, HTMLDivElement> implements AppL
140144
this.main.classList.add('d-flex', 'flex-column', 'flex-grow-1');
141145
fragment.appendChild(this.main);
142146

147+
// Add the toast container..
148+
const toast_container = document.createElement('div');
149+
toast_container.classList.add('toast-container');
150+
fragment.appendChild(toast_container);
151+
143152
this.element.appendChild(fragment);
144153
}
145154

155+
toast(info: string): void {
156+
const toast_container = this.element.querySelector('.toast-container') as HTMLDivElement;
157+
const toast = document.createElement('div');
158+
toast.classList.add('toast');
159+
toast.setAttribute('role', 'alert');
160+
toast.setAttribute('aria-live', 'assertive');
161+
toast.setAttribute('aria-atomic', 'true');
162+
toast.setAttribute('data-bs-autohide', 'true');
163+
toast.setAttribute('data-bs-delay', '5000');
164+
const toast_header = document.createElement('div');
165+
toast_header.classList.add('toast-header');
166+
const toast_title = document.createElement('strong');
167+
toast_title.classList.add('me-auto');
168+
toast_title.innerText = 'Info';
169+
toast_header.appendChild(toast_title);
170+
const toast_button = document.createElement('button');
171+
toast_button.classList.add('btn-close');
172+
toast_button.setAttribute('type', 'button');
173+
toast_button.setAttribute('data-bs-dismiss', 'toast');
174+
toast_button.setAttribute('aria-label', 'Close');
175+
toast_header.appendChild(toast_button);
176+
toast.appendChild(toast_header);
177+
const toast_body = document.createElement('div');
178+
toast_body.classList.add('toast-body');
179+
toast_body.innerText = info;
180+
toast.appendChild(toast_body);
181+
toast_container.appendChild(toast);
182+
setTimeout(() => toast.remove(), 5000);
183+
}
184+
146185
selected_component(component: Component<any, HTMLElement> | null): void {
147186
if (component)
148187
this.main.appendChild(component.element);
@@ -151,7 +190,7 @@ export class AppComponent extends Component<App, HTMLDivElement> implements AppL
151190
connected(info: any): void { }
152191
received_message(message: any): void { }
153192
disconnected(): void { }
154-
error(error: any): void { }
193+
connection_error(error: any): void { }
155194

156195
populate_navbar(container: HTMLDivElement): void { }
157196

src/utils/connection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class Connection {
4545

4646
this.socket.onerror = (error) => {
4747
console.error('Connection error: ', error);
48-
for (const listener of this.connection_listeners) { listener.error(error); }
48+
for (const listener of this.connection_listeners) { listener.connection_error(error); }
4949
};
5050
}
5151
}
@@ -58,5 +58,5 @@ export interface ConnectionListener {
5858

5959
disconnected(): void;
6060

61-
error(error: any): void;
61+
connection_error(error: any): void;
6262
}

0 commit comments

Comments
 (0)