@@ -14,6 +14,7 @@ import { directMessageManager } from './managers/direct_message.mjs';
1414import { parseModServerMessage } from './messages/message_types.mjs' ;
1515import { faviconManager } from './managers/favicon_manager.mjs' ;
1616import { tabListManager } from './managers/tab_list_manager.mjs' ;
17+ import { notificationManager } from './managers/notification_manager.mjs' ;
1718
1819/**
1920 * Import all types we might need
@@ -162,6 +163,19 @@ loadMoreButtonElement.addEventListener('click', () => {
162163 }
163164} ) ;
164165
166+ async function enableNotificationsOnClick ( ) {
167+ if ( await notificationManager . enableNotifications ( ) ) {
168+ console . log ( 'Notifications enabled' ) ;
169+ } else {
170+ console . log ( 'Notifications not enabled' ) ;
171+ }
172+
173+ document . body . removeEventListener ( 'click' , enableNotificationsOnClick ) ;
174+ }
175+ if ( ! notificationManager . isEnabled ( ) ) {
176+ document . body . addEventListener ( 'click' , enableNotificationsOnClick ) ;
177+ }
178+
165179/**
166180 * ======================
167181 * Chat related functions
@@ -210,79 +224,76 @@ function handleChatMessage(message) {
210224 faviconManager . handleNewMessage ( message . payload . isPing ) ;
211225 }
212226
213- requestAnimationFrame ( ( ) => {
214- const messageElement = document . createElement ( 'article' ) ;
215- messageElement . classList . add ( 'message' ) ;
227+ const messageElement = document . createElement ( 'article' ) ;
228+ messageElement . classList . add ( 'message' ) ;
216229
217- if ( message . payload . isPing ) {
218- messageElement . classList . add ( 'ping' ) ;
219- }
220-
221- // Create timestamp outside of try block. That way errors can be timestamped as well for the moment they did happen.
222- const { timeString, fullDateTime } = formatTimestamp ( message . timestamp ) ;
223- const timeElement = document . createElement ( 'time' ) ;
224- timeElement . dateTime = new Date ( message . timestamp ) . toISOString ( ) ;
225- timeElement . textContent = timeString ;
226- timeElement . title = fullDateTime ;
227- timeElement . className = 'message-time' ;
228- messageElement . appendChild ( timeElement ) ;
230+ if ( message . payload . isPing ) {
231+ messageElement . classList . add ( 'ping' ) ;
232+ }
229233
230- try {
231- // Format the chat message - this uses the Component format from message_parsing
232- assertIsComponent ( message . payload . component ) ;
233- const chatContent = formatChatMessage (
234- message . payload . component ,
235- message . payload . translations ,
236- ) ;
237- messageElement . appendChild ( chatContent ) ;
238- } catch ( e ) {
239- console . error ( message ) ;
240- if ( e instanceof ComponentError ) {
241- console . error ( 'Invalid component:' , e . toString ( ) ) ;
242- messageElement . appendChild (
243- formatChatMessage (
244- {
245- text : 'Invalid message received from server' ,
246- color : 'red' ,
247- } ,
248- { } ,
249- ) ,
250- ) ;
251- } else {
252- console . error ( 'Error parsing message:' , e ) ;
253- messageElement . appendChild (
254- formatChatMessage (
255- {
256- text : 'Error parsing message' ,
257- color : 'red' ,
258- } ,
259- { } ,
260- ) ,
261- ) ;
262- }
234+ // Create timestamp outside of try block. That way errors can be timestamped as well for the moment they did happen.
235+ const { timeString, fullDateTime } = formatTimestamp ( message . timestamp ) ;
236+ const timeElement = document . createElement ( 'time' ) ;
237+ timeElement . dateTime = new Date ( message . timestamp ) . toISOString ( ) ;
238+ timeElement . textContent = timeString ;
239+ timeElement . title = fullDateTime ;
240+ timeElement . className = 'message-time' ;
241+ messageElement . appendChild ( timeElement ) ;
242+
243+ try {
244+ // Format the chat message - this uses the Component format from message_parsing
245+ assertIsComponent ( message . payload . component ) ;
246+ const chatContent = formatChatMessage (
247+ message . payload . component ,
248+ message . payload . translations ,
249+ ) ;
250+
251+ if ( message . payload . notify && chatContent . textContent ) {
252+ notificationManager . sendNotification ( chatContent . textContent ) ;
263253 }
264254
265- // Storing raw scroll value. To be used to fix the scroll position down the line.
266- const scrolledFromTop = messagesElement . scrollTop ;
267-
268- if ( message . payload . history ) {
269- // Insert the message after the load-more button
270- loadMoreContainerElement . before ( messageElement ) ;
255+ messageElement . appendChild ( chatContent ) ;
256+ } catch ( e ) {
257+ console . error ( message ) ;
258+ if ( e instanceof ComponentError ) {
259+ console . error ( 'Invalid component:' , e . toString ( ) ) ;
260+ messageElement . appendChild (
261+ formatChatMessage ( {
262+ text : 'Invalid message received from server' ,
263+ color : 'red' ,
264+ } ) ,
265+ ) ;
271266 } else {
272- // For new messages, insert at the start
273- messagesElement . insertBefore (
274- messageElement ,
275- messagesElement . firstChild ,
267+ console . error ( 'Error parsing message:' , e ) ;
268+ messageElement . appendChild (
269+ formatChatMessage ( {
270+ text : 'Error parsing message' ,
271+ color : 'red' ,
272+ } ) ,
276273 ) ;
277274 }
275+ }
278276
279- // If it is due to the flex column reverse or something else, once the user has scrolled it doesn't "lock" at the bottom.
280- // Let's fix that, if the user was near the bottom when a message was inserted we put them back there.
281- // Note: the values appear negative due to the flex column shenanigans.
282- if ( scrolledFromTop <= 1 && scrolledFromTop >= - 35 ) {
283- messagesElement . scrollTop = 0 ;
284- }
285- } ) ;
277+ // Storing raw scroll value. To be used to fix the scroll position down the line.
278+ const scrolledFromTop = messagesElement . scrollTop ;
279+
280+ if ( message . payload . history ) {
281+ // Insert the message after the load-more button
282+ loadMoreContainerElement . before ( messageElement ) ;
283+ } else {
284+ // For new messages, insert at the start
285+ messagesElement . insertBefore (
286+ messageElement ,
287+ messagesElement . firstChild ,
288+ ) ;
289+ }
290+
291+ // If it is due to the flex column reverse or something else, once the user has scrolled it doesn't "lock" at the bottom.
292+ // Let's fix that, if the user was near the bottom when a message was inserted we put them back there.
293+ // Note: the values appear negative due to the flex column shenanigans.
294+ if ( scrolledFromTop <= 1 && scrolledFromTop >= - 35 ) {
295+ messagesElement . scrollTop = 0 ;
296+ }
286297}
287298
288299function clearMessageHistory ( ) {
0 commit comments