@@ -3,7 +3,7 @@ import { toID } from '../utils/generic';
3
3
import newMessage , { Message } from './message' ;
4
4
import { Room } from './room/room' ;
5
5
import { User } from './user' ;
6
- import { clientNotification , RoomNotification } from './notifications' ;
6
+ import { clientNotification , notificationsEngine , RoomNotification as RoomNotifications } from './notifications' ;
7
7
import { Protocol } from '@pkmn/protocol' ;
8
8
import { assert , assertNever } from '@/lib/utils' ;
9
9
import { BattleRoom } from './room/battleRoom' ;
@@ -24,8 +24,10 @@ interface UseClientStoreType {
24
24
// messages: Message[]; // only messages from the current room
25
25
messages : Record < Room [ 'ID' ] , Message [ ] > ; // messages from all rooms
26
26
newMessage : ( room : Room , message : Message ) => void ;
27
- notifications : RoomNotification [ ] ;
28
- // setNotifications: (notifications: RoomNotification[]) => void;
27
+ notifications : Record < Room [ 'ID' ] , RoomNotifications > ;
28
+ clearNotifications : ( roomID : Room [ 'ID' ] ) => void ;
29
+ addUnread : ( room : Room ) => void ;
30
+ addMention : ( room : Room ) => void ;
29
31
avatar : string ;
30
32
theme : 'light' | 'dark' ;
31
33
user : string | undefined
@@ -42,6 +44,10 @@ export const useClientStore = create<UseClientStoreType>((set) => ({
42
44
messages : { } ,
43
45
newMessage : ( room : Room , message : Message ) => {
44
46
set ( ( state ) => {
47
+ if ( room !== state . currentRoom ) {
48
+ state . addUnread ( room ) ;
49
+ }
50
+
45
51
if ( ! state . messages [ room . ID ] ) {
46
52
return {
47
53
messages : { ...state . messages , [ room . ID ] : [ message ] } ,
@@ -52,10 +58,48 @@ export const useClientStore = create<UseClientStoreType>((set) => ({
52
58
} ;
53
59
} ) ;
54
60
} ,
55
- notifications : [ ] ,
61
+ notifications : { } ,
62
+ addUnread : ( room : Room ) => {
63
+ set ( ( state ) => {
64
+ if ( ! state . notifications [ room . ID ] ) {
65
+ return {
66
+ notifications : { ...state . notifications , [ room . ID ] : { unread : 1 , mentions : 0 } } ,
67
+ } ;
68
+ }
69
+ return {
70
+ notifications : { ...state . notifications , [ room . ID ] : { unread : state . notifications [ room . ID ] . unread + 1 , mentions : state . notifications [ room . ID ] . mentions } } ,
71
+ } ;
72
+ } ) ;
73
+ } ,
74
+ addMention : ( room : Room ) => {
75
+ set ( ( state ) => {
76
+ if ( ! state . notifications [ room . ID ] ) {
77
+ return {
78
+ notifications : { ...state . notifications , [ room . ID ] : { unread : 0 , mentions : 1 } } ,
79
+ } ;
80
+ }
81
+ return {
82
+ notifications : { ...state . notifications , [ room . ID ] : { unread : state . notifications [ room . ID ] . unread , mentions : state . notifications [ room . ID ] . mentions + 1 } } ,
83
+ } ;
84
+ } ) ;
85
+ } ,
86
+ clearNotifications : ( roomID : string ) => {
87
+ set ( ( state ) => {
88
+ if ( ! state . notifications [ roomID ] ) {
89
+ return {
90
+ notifications : { ...state . notifications , [ roomID ] : { unread : 0 , mentions : 0 } } ,
91
+ } ;
92
+ }
93
+ return {
94
+ notifications : { ...state . notifications , [ roomID ] : { unread : 0 , mentions : 0 } } ,
95
+ } ;
96
+ } ) ;
97
+ } ,
98
+
56
99
avatar : 'lucas' ,
57
100
theme : localStorage . getItem ( 'theme' ) as 'light' | 'dark' ?? 'dark' ,
58
101
user : undefined ,
102
+
59
103
} ) ) ;
60
104
61
105
@@ -108,7 +152,7 @@ export class Client {
108
152
constructor ( options ?: ClientConstructor ) {
109
153
// if running test suite, don't do anything
110
154
if ( import . meta. env . VITEST ) {
111
- console . log ( 'Running tests, skipping client initialization' ) ;
155
+ console . debug ( 'Running tests, skipping client initialization' ) ;
112
156
return ;
113
157
}
114
158
try {
@@ -211,8 +255,9 @@ export class Client {
211
255
selectRoom ( roomid : string ) {
212
256
this . __selectedRoom = roomid ;
213
257
this . room ( roomid ) ?. select ( ) ;
214
- this . settings . changeRooms ( this . rooms ) ;
258
+ // this.settings.changeRooms(this.rooms);
215
259
useClientStore . setState ( { currentRoom : this . room ( roomid ) } ) ;
260
+ useClientStore . getState ( ) . clearNotifications ( roomid ) ;
216
261
}
217
262
218
263
async queryUser ( user : string , callback : ( json : any ) => void ) {
@@ -330,16 +375,29 @@ export class Client {
330
375
return highlight ;
331
376
}
332
377
378
+ private shouldNotify ( room : Room , message : Message ) {
379
+ if ( this . selectedRoom == room . ID && document . hasFocus ( ) ) return false ;
380
+ if ( room . checkMessageStaleness ( message ) ) return false ;
381
+ if ( message . hld || room . type === 'pm' ) return true ;
382
+ return false ;
383
+ }
384
+
333
385
private forceHighlightMsg ( roomid : string , message : Message ) {
334
386
return this . highlightMsg ( roomid , message , true ) ;
335
387
}
336
388
337
- getNotifications ( ) : RoomNotification [ ] {
338
- return Array . from ( this . rooms ) . map ( ( [ _ , room ] ) => ( {
339
- room : room . ID ,
340
- mentions : room . mentions ,
341
- unread : room . unread ,
342
- } ) ) ;
389
+ getNotifications ( ) : Map < string , RoomNotifications > {
390
+ return new Map (
391
+ [ ...this . rooms ] . map ( ( [ roomID , room ] ) => [ roomID , { unread : room . unread , mentions : room . mentions } ] ) ,
392
+ ) ;
393
+ }
394
+
395
+ clearNotifications ( roomID : string ) {
396
+ const room = this . room ( roomID ) ;
397
+ if ( room ) {
398
+ room . clearNotifications ( ) ;
399
+ useClientStore . getState ( ) . clearNotifications ( roomID ) ;
400
+ }
343
401
}
344
402
345
403
openSettings ( ) {
@@ -509,7 +567,9 @@ export class Client {
509
567
private _addRoom ( room : Room ) {
510
568
this . rooms . set ( room . ID , room ) ;
511
569
useClientStore . setState ( { rooms : new Map ( this . rooms ) } ) ;
512
- this . selectRoom ( room . ID ) ;
570
+ if ( ! this . settings . rooms . find ( ( r ) => r . ID === room . ID ) ?. open ) {
571
+ this . selectRoom ( room . ID ) ;
572
+ }
513
573
if ( room . type !== 'permanent' && ! this . settings . rooms . find ( ( r ) => r . ID === room . ID ) ) {
514
574
this . settings . addRoom ( room ) ;
515
575
}
@@ -544,6 +604,7 @@ export class Client {
544
604
message : Message ,
545
605
) {
546
606
const room = this . room ( roomID ) ;
607
+ this . highlightMsg ( roomID , message ) ;
547
608
if ( ! room ) {
548
609
console . warn ( 'addMessageToRoom: room (' + roomID + ') is unknown. Message:' , message ) ;
549
610
return ;
@@ -552,24 +613,21 @@ export class Client {
552
613
selected : this . selectedRoom === roomID ,
553
614
selfSent : toID ( this . settings . username ) === toID ( message . user ) ,
554
615
} ;
555
- let shouldNotify = false ;
556
616
if ( message . name ) {
557
617
room . addUHTML ( message , settings ) ;
558
618
} else {
559
- shouldNotify = room . addMessage ( message , settings ) ;
619
+ room . addMessage ( message , settings ) ;
560
620
}
561
621
useClientStore . getState ( ) . newMessage ( room , message ) ;
562
- if ( shouldNotify ) {
563
- this . events . dispatchEvent (
564
- new CustomEvent ( 'notification' , {
565
- detail : {
566
- user : message . user ,
567
- message : message . content ,
568
- room : roomID ,
569
- roomType : room . type ,
570
- } as clientNotification ,
571
- } ) ,
572
- ) ;
622
+
623
+ if ( this . shouldNotify ( room , message ) ) {
624
+ notificationsEngine . sendNotification ( {
625
+ user : message . user ?? '' ,
626
+ message : message . content ,
627
+ room : roomID ,
628
+ roomType : room . type ,
629
+ } ) ;
630
+ useClientStore . getState ( ) . addMention ( room ) ;
573
631
}
574
632
}
575
633
0 commit comments