11import type { Channel , Message } from '#models' ;
22import { parseNick } from '#utils' ;
33import { defineStore } from 'pinia' ;
4- import { computed , reactive , ref , watch } from 'vue' ;
4+ import { computed , reactive , readonly , ref , watch } from 'vue' ;
55import useIrcStore from './irc' ;
66import { useWindowFocus } from '@vueuse/core' ;
77import useNotificationsStore from './notifications' ;
@@ -27,7 +27,7 @@ const useChannelStore = defineStore('channel', () => {
2727 name : channelName ,
2828 banStatus : 'normal' ,
2929 messages : [ ] ,
30- usersTyping : [ ] ,
30+ usersTyping : new Set ( ) ,
3131 notificationsEnabled : true ,
3232 hasMention : false ,
3333 hasNotification : false ,
@@ -37,7 +37,6 @@ const useChannelStore = defineStore('channel', () => {
3737 }
3838
3939 const activeTarget = ref ( '#general' ) ;
40- const activeChannel = computed ( ( ) => getChannel ( activeTarget . value ) ) ;
4140
4241 function changeActiveChannel ( channel : string ) {
4342 activeTarget . value = channel ;
@@ -47,7 +46,6 @@ const useChannelStore = defineStore('channel', () => {
4746 return ;
4847 }
4948 const newChannel = irc . client . channel ( channel ) ;
50- newChannel . join ( ) ;
5149 newChannel . updateUsers ( ) ;
5250 getChannel ( channel ) ;
5351 }
@@ -106,70 +104,66 @@ const useChannelStore = defineStore('channel', () => {
106104 return ;
107105 }
108106
109- client . on ( 'message' , ( { message, nick, type, target, tags } ) => {
110- const username = parseNick ( nick ) ;
111- const isPrivateMessage =
112- type === 'privmsg' &&
113- ! target . startsWith ( '#' ) &&
114- irc . currentUser . username === parseNick ( target ) ;
115- const channel = isPrivateMessage ? getChannel ( username ) : getChannel ( target ) ;
116-
117- // TODO: Read from 'raw' events to get replayed messages
118- // TODO: Use `typing` client tag if `message-tags` capability is available
119- // Handling typing status updates
120- if ( type === 'action' && message === 'is typing...' ) {
121- if ( ! channel . usersTyping . includes ( username ) ) {
122- channel . usersTyping . push ( username ) ;
123- }
124- return ;
125- } else if ( type === 'action' && message === 'is not typing...' ) {
126- channel . usersTyping = channel . usersTyping . filter ( ( u ) => u !== username ) ;
127- return ;
128- }
129-
130- const highlightedMessage = highlightKeywords ( message ) ;
131- const newMessage : Message = {
132- // TODO: Read from server time, if available
133- time : new Date ( ) ,
134- starred : false ,
135- message : highlightedMessage ,
136- target,
137- nick,
138- type : 'message' ,
139- tags : tags ?? { } ,
140- } ;
141- // TODO: Cap messages per channel (50)
142- log . debug ( newMessage ) ;
143- channel . messages . push ( newMessage ) ;
144-
145- // If the user has allows for notifications on channel or keywords
146- // Display/send notifications if user is in another channel or has browser blurred
147- // Otherwise mark channel as read if user is actively viewing the channel
148- const isOtherChannel = channel . name !== activeTarget . value ;
149- if ( ! isFocusedWindow || isOtherChannel ) {
150- if ( channel . notificationsEnabled ) {
151- addMessageNotification ( channel . name , newMessage ) ;
152-
153- if (
154- message . toLocaleLowerCase ( ) . includes ( irc . currentUser . username . toLocaleLowerCase ( ) )
107+ client
108+ . on ( 'action' , ( event ) => {
109+ log . debug ( 'Action' , event ) ;
110+ // TODO: Use typing client-tag
111+ // See https://ircv3.net/specs/client-tags/typing
112+ } )
113+ . on ( 'notice' , ( event ) => {
114+ log . debug ( 'Notice' , event ) ;
115+ } )
116+ . on ( 'privmsg' , ( event ) => {
117+ log . debug ( 'PRIVMSG' , event ) ;
118+ const { message, nick, target, tags } = event ;
119+ const username = parseNick ( nick ) ;
120+ const isPrivateMessage =
121+ ! target . startsWith ( '#' ) && irc . currentUser . username === parseNick ( target ) ;
122+ const channel = isPrivateMessage ? getChannel ( username ) : getChannel ( target ) ;
123+
124+ const highlightedMessage = highlightKeywords ( message ) ;
125+ const newMessage : Message = {
126+ // TODO: Read from server time, if available
127+ time : new Date ( ) ,
128+ starred : false ,
129+ message : highlightedMessage ,
130+ target,
131+ nick,
132+ type : 'message' ,
133+ tags : tags ?? { } ,
134+ } ;
135+ // TODO: Cap messages per channel (50)
136+ log . debug ( newMessage ) ;
137+ channel . messages . push ( newMessage ) ;
138+
139+ // If the user has allows for notifications on channel or keywords
140+ // Display/send notifications if user is in another channel or has browser blurred
141+ // Otherwise mark channel as read if user is actively viewing the channel
142+ const isOtherChannel = channel . name !== activeTarget . value ;
143+ if ( ! isFocusedWindow || isOtherChannel ) {
144+ if ( channel . notificationsEnabled ) {
145+ addMessageNotification ( channel . name , newMessage ) ;
146+
147+ if (
148+ message . toLocaleLowerCase ( ) . includes ( irc . currentUser . username . toLocaleLowerCase ( ) )
149+ ) {
150+ channel . hasMention = true ;
151+ }
152+ } else if (
153+ notifications . notificationKeywords . some ( ( keyword ) => message . includes ( keyword ) )
155154 ) {
156- channel . hasMention = true ;
155+ addMessageNotification ( channel . name , newMessage ) ;
157156 }
158- } else if (
159- notifications . notificationKeywords . some ( ( keyword ) => message . includes ( keyword ) )
160- ) {
161- addMessageNotification ( channel . name , newMessage ) ;
157+ } else {
158+ markAsRead ( channel . name ) ;
162159 }
163- } else {
164- markAsRead ( channel . name ) ;
165- }
166- } ) ;
160+ } ) ;
167161 } ,
168162 ) ;
169163
170164 return {
171165 channelList,
172- activeChannel,
166+ activeChannel : computed ( ( ) => readonly ( getChannel ( activeTarget . value ) ) ) ,
173167 changeActiveChannel,
174168 joinChannel,
175169 leaveChannel,
0 commit comments