import { Long } from 'bson' ; import { Channel , ChannelStore , LoginData } from '../../channel' ; import { TalkSession } from '../client' ; import { EventContext , TypedEmitter } from '../../event' ; import { InformedOpenLink , OpenChannel , OpenChannelData , OpenChannelManageSession , OpenLink , OpenLinkChannelTemplate , OpenLinkComponent , OpenLinkCreateTemplate , OpenLinkKickedUser , OpenLinkKickedUserInfo , OpenLinkProfiles , OpenLinkProfileTemplate , OpenLinkService , OpenLinkSession , OpenLinkUpdateTemplate , } from '../../openlink' ; import { AsyncCommandResult , DefaultRes , KnownDataStatusCode } from '../../request' ; import { ChannelListUpdater , TalkChannelListHandler , updateChatList } from '../channel' ; import { OpenChannelListEvents } from '../event' ; import { Managed } from '../managed' ; import { TalkOpenChannel } from './talk-open-channel' ; import { TalkOpenChannelListHandler } from './talk-open-channel-handler' ; import { TalkOpenChannelManageSession } from './talk-open-channel-session' ; import { OpenLinkUpdater } from './talk-open-link-handler' ; import { OpenChannelUserInfo } from '../../user' ; import { ClientDataLoader } from '../../loader' ; import { TalkClientLinkStore } from './client-link-store' ; export type TalkOpenChannelListEvents = OpenChannelListEvents < TalkOpenChannel , OpenChannelUserInfo > ; /**
 * Manage open profile, channel.
 */ export class TalkOpenChannelList extends TypedEmitter < TalkOpenChannelListEvents > implements Managed < TalkOpenChannelListEvents > , OpenChannelManageSession , ChannelStore < TalkOpenChannel > , OpenLinkSession , ChannelListUpdater < TalkOpenChannel > , OpenLinkUpdater { private _handler : TalkChannelListHandler < TalkOpenChannel > ; private _openHandler : TalkOpenChannelListHandler < TalkOpenChannel , OpenChannelUserInfo > ; private _linkStore : TalkClientLinkStore ; private _manageSession : TalkOpenChannelManageSession ; private _map : Map < string , TalkOpenChannel > ; constructor ( private _session , private _loader , list , clientLinkList ) { super ( ) ; this . _manageSession = new TalkOpenChannelManageSession ( _session ) ; this . _handler = new TalkChannelListHandler ( this , this , this ) ; this . _openHandler = new TalkOpenChannelListHandler ( this , this , this ) ; this . _linkStore = new TalkClientLinkStore ( _session , clientLinkList ) ; this . _map = new Map ( ) ; if ( list . length > 0 ) { list . forEach ( ( channel ) => this . _map . set ( channel . channelId . toString ( ) , channel ) ) ; } } get linkService ( ) : OpenLinkService { return this . _linkStore ; } param { InformedOpenLink } link deprecated addClientLink ( link ) { this . _linkStore . addClientLink ( link ) ; } param { Long } linkId return { boolean } deprecated deleteClientLink ( linkId ) { return this . _linkStore . deleteClientLink ( linkId ) ; } removeChannel ( channel ) { return this . _map . delete ( channel . channelId . toString ( ) ) ; } async addChannel ( channel ) { return this . addOpenChannel ( { ... channel , linkId : Long . ZERO } ) ; } get ( channelId ) { return this . _map . get ( channelId . toString ( ) ) ; } deprecated param { Long } linkId return { TalkOpenChannel | undefined } getChannelByLinkId ( linkId ) { for ( const channel of this . all ( ) ) { if ( channel . linkId . eq ( linkId ) ) return channel ; } } param { Long } linkId return { TalkOpenChannel [ ] } getLinkChannelList ( linkId ) { const list = [ ] ; for ( const channel of this . all ( ) ) { if ( channel . linkId . eq ( linkId ) ) list . push ( channel ) ; } return list ; } get size ( ) : number { return this . _map . size ; } all ( ) { return this . _map . values ( ) ; } return { IterableIterator < InformedOpenLink > } deprecated allClientLink ( ) { return this . _linkStore . allClientLink ( ) ; } param { Long } linkId return { InformedOpenLink | undefined } deprecated getClientLink ( linkId ) { return this . _linkStore . getClientLink ( linkId ) ; } deprecated get clientLinkCount ( ) : number { return this . _linkStore . clientLinkCount ; } async addOpenChannel ( channel , lastUpdate ? ) { const last = this . get ( channel . channelId ) ; if ( last ) return { success : true , status : KnownDataStatusCode . SUCCESS , result : last } ; const infoStoreRes = await this . _loader . loadOpenChannelStore ( channel , lastUpdate ) ; const chatStoreRes = await this . _loader . loadChatListStore ( channel ) ; const talkChannel = new TalkOpenChannel ( channel , this . _session , infoStoreRes . value , chatStoreRes . value ) ; this . _map . set ( channel . channelId . toString ( ) , talkChannel ) ; if ( infoStoreRes . shouldUpdate ) { const res = await talkChannel . updateAll ( ) ; if ( ! res . success ) return res ; } if ( chatStoreRes . shouldUpdate ) { await updateChatList ( talkChannel ) ; } return { success : true , status : KnownDataStatusCode . SUCCESS , result : talkChannel } ; } async leaveKicked ( channel ) { const res = await this . _manageSession . leaveKicked ( channel ) ; if ( res . success ) { this . _map . delete ( channel . channelId . toString ( ) ) ; } return res ; } async leaveChannel ( channel ) { const res = await this . _manageSession . leaveChannel ( channel ) ; if ( res . success ) { this . _map . delete ( channel . channelId . toString ( ) ) ; } return res ; } getLatestLinkList ( ) { return this . _linkStore . getLatestLinkList ( ) ; } getOpenLink ( ... components ) { return this . _linkStore . getOpenLink ( ... components ) ; } getJoinInfo ( linkURL , referer ? ) { return this . _linkStore . getJoinInfo ( linkURL , referer ) ; } getKickList ( link ) { return this . _linkStore . getKickList ( link ) ; } removeKicked ( link , kickedUser ) { return this . _linkStore . removeKicked ( link , kickedUser ) ; } async deleteLink ( link ) { const res = await this . _linkStore . deleteLink ( link ) ; if ( res . success ) { this . _linkStore . deleteClientLink ( link . linkId ) ; for ( const channel of this . getLinkChannelList ( link . linkId ) ) { this . removeChannel ( channel ) ; } } return res ; } react ( link , flag ) { return this . _linkStore . react ( link , flag ) ; } getReaction ( link ) { return this . _linkStore . getReaction ( link ) ; } async createOpenChannel ( template , profile ) { const res = await this . _linkStore . createOpenChannel ( template , profile ) ; if ( ! res . success ) return res ; return this . addOpenChannel ( res . result ) ; } createOpenDirectProfile ( template , profile ) { return this . _linkStore . createOpenDirectProfile ( template , profile ) ; } createOpenProfile ( template ) { return this . _linkStore . createOpenProfile ( template ) ; } updateOpenLink ( link , settings ) { return this . _linkStore . updateOpenLink ( link , settings ) ; } async pushReceived ( method , data , parentCtx ) { const ctx = new EventContext < TalkOpenChannelListEvents > ( this , parentCtx ) ; await Promise . all ( Array . from ( this . _map . values ( ) ) . map ( ( channel ) => channel . pushReceived ( method , data , ctx ) ) ) ; await this . _handler . pushReceived ( method , data , parentCtx ) ; await this . _openHandler . pushReceived ( method , data , parentCtx ) ; await this . _linkStore . pushReceived ( method , data , parentCtx ) ; } async joinChannel ( link , profile , passcode ? ) { const res = await this . _manageSession . joinChannel ( link , profile , passcode ) ; if ( ! res . success ) return res ; return this . addOpenChannel ( res . result ) ; } param { TalkOpenChannelList } talkChannelList param { LoginData < OpenChannelData > [ ] } channelList static async initialize ( talkChannelList , channelList = [ ] ) { talkChannelList . _map . clear ( ) ; await Promise . all ( channelList . map ( ( data ) => talkChannelList . addOpenChannel ( data . channel , data . lastUpdate ) ) ) ; await talkChannelList . _linkStore . getLatestLinkList ( ) ; return talkChannelList ; } }