import * as mobx from 'mobx' ; import { action , decorate , IObservableArray , observable } from 'mobx' ; import { useStaticRendering } from 'mobx-react' ; import { io } from 'socket.io-client' ; import { addTeamApiMethod , getTeamInvitationsApiMethod } from '../api/team-leader' ; import { getTeamListApiMethod , getTeamMembersApiMethod } from '../api/team-member' ; import { User } from './user' ; import { Team } from './team' ; useStaticRendering ( typeof window === 'undefined' ) ; mobx . configure ( { enforceActions : 'observed' } ) ; class Store { public isServer : boolean ; public currentUser ? : User = null ; public currentUrl = '' ; public currentTeam ? : Team ; public teams : IObservableArray < Team > = observable ( [ ] ) ; public socket : SocketIOClient . Socket ; constructor ( { initialState = { } , isServer , socket = null , } ) { this . isServer = ! ! isServer ; this . setCurrentUser ( initialState . user ) ; this . currentUrl = initialState . currentUrl || '' ; if ( initialState . teamSlug || ( initialState . user && initialState . user . defaultTeamSlug ) ) { this . setCurrentTeam ( initialState . teamSlug || initialState . user . defaultTeamSlug , initialState . teams ) ; } this . socket = socket ; if ( socket ) { socket . on ( 'disconnect' , ( ) => { console . log ( 'socket: ## disconnected' ) ; } ) ; socket . on ( 'reconnect' , ( attemptNumber ) => { console . log ( 'socket: $$ reconnected' , attemptNumber ) ; } ) ; } } public changeCurrentUrl ( url ) { this . currentUrl = url ; } public async setCurrentUser ( user ) { if ( user ) { this . currentUser = new User ( { store : this , ... user } ) ; } else { this . currentUser = null ; } } public async addTeam ( { name , avatarUrl } ) { const data = await addTeamApiMethod ( { name , avatarUrl } ) ; const team = new Team ( { store : this , ... data } ) ; return team ; } public async setCurrentTeam ( slug , initialTeams ) { if ( this . currentTeam ) { if ( this . currentTeam . slug === slug ) { return ; } } let found = false ; const teams = initialTeams || ( await getTeamListApiMethod ( ) ) . teams ; for ( const team of teams ) { if ( team . slug === slug ) { found = true ; this . currentTeam = new Team ( { ... team , store : this } ) ; const users = team . initialMembers || ( await getTeamMembersApiMethod ( this . currentTeam . _id ) ) . users ; const invitations = team . initialInvitations || ( await getTeamInvitationsApiMethod ( this . currentTeam . _id ) ) . invitations ; this . currentTeam . setInitialMembersAndInvitations ( users , invitations ) ; break ; } } if ( ! found ) { this . currentTeam = null ; } } public addTeamToLocalCache ( data ) { const teamObj = new Team ( { user : this . currentUser , store : this , ... data } ) ; this . teams . unshift ( teamObj ) ; return teamObj ; } public editTeamFromLocalCache ( data ) { const team = this . teams . find ( ( item ) => item . _id === data . _id ) ; if ( team ) { if ( data . memberIds && data . memberIds . includes ( this . currentUser . _id ) ) { team . changeLocalCache ( data ) ; } else { this . removeTeamFromLocalCache ( data . _id ) ; } } else if ( data . memberIds && data . memberIds . includes ( this . currentUser . _id ) ) { this . addTeamToLocalCache ( data ) ; } } public removeTeamFromLocalCache ( teamId ) { const team = this . teams . find ( ( t ) => t . _id === teamId ) ; this . teams . remove ( team ) ; } } decorate ( Store , { currentUser : observable , currentUrl : observable , currentTeam : observable , changeCurrentUrl : action , setCurrentUser : action , setCurrentTeam : action , } ) ; let store = null ; function initializeStore ( initialState = { } ) { const isServer = typeof window === 'undefined' ; const socket = isServer ? null : io ( process . env . URL_API , { reconnection : true , autoConnect : true , transports : [ 'polling' , 'websocket' ] , withCredentials : true , } ) ; const _store = store !== null && store !== undefined ? store : new Store ( { initialState , isServer , socket } ) ; if ( typeof window === 'undefined' ) { return _store ; } if ( ! store ) { store = _store ; } return _store ; } function getStore ( ) { return store ; } export { Store , initializeStore , getStore } ;