1+ import { AUTO_JOIN_CHANNELS } from '#constants' ;
12import type { Channel , Message , MessageType } from '#models' ;
23import { parseNick , sortedInsert } from '#utils' ;
3- import { useWindowFocus } from '@vueuse/core' ;
4+ import { useLocalStorage , useWindowFocus } from '@vueuse/core' ;
45import log from 'loglevel' ;
56import { defineStore } from 'pinia' ;
67import { computed , reactive , readonly , ref , watch } from 'vue' ;
@@ -17,6 +18,7 @@ const useChannelStore = defineStore('channel', () => {
1718 const isFocusedWindow = useWindowFocus ( ) ;
1819 const channelMap = reactive ( new Map < string , Channel > ( ) ) ;
1920 const channelList = computed ( ( ) => Array . from ( channelMap . keys ( ) ) ) ;
21+ const joinedChannels = useLocalStorage < Set < string > > ( 'chat_joinedChannels' , AUTO_JOIN_CHANNELS ) ;
2022
2123 /**
2224 * Gets channel from list.
@@ -53,12 +55,21 @@ const useChannelStore = defineStore('channel', () => {
5355 } ) ;
5456 const currentMessages = computed ( ( ) => currentChannel . value ?. messages ?? [ ] ) ;
5557
56- function joinChannel ( channel : string ) {
58+ function requestChatHistory ( channelOrUsername : string ) {
59+ if ( ! irc . client || ! channelOrUsername . startsWith ( '#' ) ) {
60+ // Skip requests for user channels
61+ return ;
62+ }
63+ irc . client . raw ( `CHATHISTORY LATEST ${ channelOrUsername } * ${ MAX_MESSAGES_PER_CHANNEL } ` ) ;
64+ }
65+
66+ function joinChannel ( channel : string , options : Partial < { force : boolean } > = { force : false } ) {
5767 if ( ! irc . client ) {
5868 return ;
5969 }
6070
6171 if (
72+ ! options . force &&
6273 channelList . value . some (
6374 ( c ) => channel . localeCompare ( c , undefined , { sensitivity : 'accent' } ) === 0 ,
6475 )
@@ -68,15 +79,32 @@ const useChannelStore = defineStore('channel', () => {
6879 return ;
6980 }
7081
82+ joinedChannels . value . add ( channel ) ;
7183 const isIRCChannel = channel . startsWith ( '#' ) ;
7284 createOrGetChannel ( channel ) ;
7385 if ( isIRCChannel ) {
7486 const newChannel = irc . client . channel ( channel ) ;
7587 newChannel . updateUsers ( ) ;
88+ requestChatHistory ( channel ) ;
7689 }
7790 goToChannel ( channel ) ;
7891 }
7992
93+ /**
94+ * Re-JOIN channels on application start or on client reconnection
95+ */
96+ function rejoinChannels ( ) {
97+ if ( joinedChannels . value . size === 0 ) {
98+ return ;
99+ }
100+
101+ const channels = Array . from ( joinedChannels . value ) ;
102+ for ( const channel of channels ) {
103+ joinChannel ( channel , { force : true } ) ;
104+ }
105+ goToChannel ( channels [ 0 ] ) ;
106+ }
107+
80108 function leaveChannel ( channel : string ) {
81109 if ( ! irc . client ) {
82110 return ;
@@ -100,6 +128,7 @@ const useChannelStore = defineStore('channel', () => {
100128 }
101129 }
102130
131+ joinedChannels . value . delete ( channel ) ;
103132 channelMap . delete ( channel ) ;
104133 if ( isIRCChannel ) {
105134 irc . client . part ( channel ) ;
@@ -261,18 +290,16 @@ const useChannelStore = defineStore('channel', () => {
261290 const isMe = username === irc . currentUser . username ;
262291 if ( isMe ) {
263292 // Check if incoming message from self is the one sent recently
264- const pendingIndex = channel . messages . findLastIndex (
293+ const pendingMessage = channel . messages . findLast (
265294 ( m ) =>
266295 m . status === 'pending' &&
267296 ( m . pendingId === event . tags . label || m . message === event . message ) ,
268297 ) ;
269298
270- if ( pendingIndex !== - 1 ) {
299+ if ( pendingMessage ) {
271300 // Mark incoming message as successful sent if it was pending
272- newMessage . status = 'sent' ;
273- newMessage . pendingId = channel . messages [ pendingIndex ] . pendingId ;
274- // Remove pending version so that incoming message is inserted correctly
275- channel . messages . splice ( pendingIndex , 1 ) ;
301+ Object . assign ( pendingMessage , newMessage , { status : 'sent' } ) ;
302+ return ;
276303 }
277304 }
278305
@@ -308,7 +335,13 @@ const useChannelStore = defineStore('channel', () => {
308335 } else {
309336 markAsRead ( channel . name ) ;
310337 }
338+ } )
339+ . on ( 'connected' , ( ) => {
340+ // After successful client reconnection
341+ rejoinChannels ( ) ;
311342 } ) ;
343+
344+ rejoinChannels ( ) ;
312345 } ,
313346 ) ;
314347
0 commit comments