diff --git a/react/features/base/lib-jitsi-meet/actionTypes.js b/react/features/base/lib-jitsi-meet/actionTypes.js index 25f9a44f5..dbb12d4e3 100644 --- a/react/features/base/lib-jitsi-meet/actionTypes.js +++ b/react/features/base/lib-jitsi-meet/actionTypes.js @@ -1,3 +1,13 @@ +/** + * The type of Redux action which signals that {@link JitsiMeetJS.init()} was + * invoked and completed successfully. + * + * { + * type: LIB_LOAD_STORAGE_DONE + * } + */ +export const LIB_LOAD_STORAGE_DONE = Symbol('LIB_LOAD_STORAGE_DONE'); + /** * The type of Redux action which signals that {@link JitsiMeetJS} was disposed. * diff --git a/react/features/base/lib-jitsi-meet/middleware.js b/react/features/base/lib-jitsi-meet/middleware.js index f6f0b5b08..1ff312dc8 100644 --- a/react/features/base/lib-jitsi-meet/middleware.js +++ b/react/features/base/lib-jitsi-meet/middleware.js @@ -6,7 +6,10 @@ import { PARTICIPANT_LEFT } from '../participants'; import { MiddlewareRegistry } from '../redux'; import { disposeLib, initLib, setWebRTCReady } from './actions'; -import { LIB_DID_INIT, LIB_INIT_ERROR } from './actionTypes'; +import { + LIB_DID_INIT, LIB_INIT_ERROR, + LIB_LOAD_STORAGE_DONE +} from './actionTypes'; import { WEBRTC_NOT_READY, WEBRTC_NOT_SUPPORTED } from './constants'; /** @@ -23,6 +26,15 @@ MiddlewareRegistry.register(store => next => action => { switch (action.type) { case LIB_DID_INIT: store.dispatch(setWebRTCReady(true)); + if (window.localStorage.setLoadingCompleteCb) { + window.localStorage.setLoadingCompleteCb(() => { + store.dispatch({ + type: LIB_LOAD_STORAGE_DONE + }); + }); + } else { + console.error('No window.localStorage.setLoadingCompleteCb'); + } break; case LIB_INIT_ERROR: diff --git a/react/features/base/lib-jitsi-meet/native/Storage.js b/react/features/base/lib-jitsi-meet/native/Storage.js index 3843057a4..ed65822b3 100644 --- a/react/features/base/lib-jitsi-meet/native/Storage.js +++ b/react/features/base/lib-jitsi-meet/native/Storage.js @@ -33,6 +33,7 @@ export default class Storage { if (typeof this._keyPrefix !== 'undefined') { // Load all previously persisted data items from React Native's // AsyncStorage. + console.info('LOAD STORAGE START'); AsyncStorage.getAllKeys().then((...getAllKeysCallbackArgs) => { // XXX The keys argument of getAllKeys' callback may or may not // be preceded by an error argument. @@ -61,11 +62,25 @@ export default class Storage { this[key] = value; } } + + console.info('LOAD STORAGE DONE'); + this.loadingComplete = true; + if (typeof this._loadingCompleteCallback === 'function') { + console.info('LOAD STORAGE DONE - CALLING CALLBACK'); + this._loadingCompleteCallback(); + } }); }); } } + setLoadingCompleteCb(callback) { + this._loadingCompleteCallback = callback; + if (this.loadingComplete) { + callback(); + } + } + /** * Removes all keys from this storage. * diff --git a/react/features/recent/actionTypes.js b/react/features/recent/actionTypes.js index 56dbcacf5..1b6be332b 100644 --- a/react/features/recent/actionTypes.js +++ b/react/features/recent/actionTypes.js @@ -6,3 +6,13 @@ * } */ export const ADD_RECENT_URL = Symbol('ADD_RECENT_URL'); + + +/** + * + * { + * type: LOADED_RECENT_URLS, + * entries: [] + * } + */ +export const LOADED_RECENT_URLS = Symbol('LOADED_RECENT_URLS'); diff --git a/react/features/recent/middleware.js b/react/features/recent/middleware.js index 075935fec..a24200529 100644 --- a/react/features/recent/middleware.js +++ b/react/features/recent/middleware.js @@ -3,8 +3,9 @@ import { MiddlewareRegistry } from '../base/redux'; import { getInviteURL } from '../base/connection'; import { CONFERENCE_WILL_JOIN } from '../base/conference'; +import { LIB_LOAD_STORAGE_DONE } from '../base/lib-jitsi-meet'; -import { ADD_RECENT_URL } from './actionTypes'; +import {ADD_RECENT_URL, LOADED_RECENT_URLS} from './actionTypes'; /** * Middleware that captures conference actions and sets the correct audio mode @@ -18,6 +19,26 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { const result = next(action); switch (action.type) { + case LIB_LOAD_STORAGE_DONE: { + let entries = []; + const recentURLs = window.localStorage.getItem('recentURLs'); + + if (recentURLs) { + console.info('FOUND STORED URLs', recentURLs); + try { + entries = JSON.parse(recentURLs); + } catch (error) { + console.error('Failed to parse recent URLS', error); + } + } else { + console.info('NO STORED URLs found'); + } + dispatch({ + type: LOADED_RECENT_URLS, + entries + }); + break; + } case CONFERENCE_WILL_JOIN: { dispatch({ type: ADD_RECENT_URL, diff --git a/react/features/recent/reducer.js b/react/features/recent/reducer.js index 1c61ab2ea..0c668d8fd 100644 --- a/react/features/recent/reducer.js +++ b/react/features/recent/reducer.js @@ -1,5 +1,5 @@ -import { ReducerRegistry } from '../base/redux'; -import { ADD_RECENT_URL } from './actionTypes'; +import { ReducerRegistry, set } from '../base/redux'; +import { ADD_RECENT_URL, LOADED_RECENT_URLS } from './actionTypes'; const MAX_LENGTH = 25; @@ -12,6 +12,14 @@ const INITIAL_STATE = { */ ReducerRegistry.register('features/recent', (state = INITIAL_STATE, action) => { switch (action.type) { + case LOADED_RECENT_URLS: { + // FIXME if that happens too late it may overwrite any recent URLs + const newState = set(state, 'entries', action.entries); + + console.info('RECENT STATE ON LOAD: ', newState); + + return newState; + } case ADD_RECENT_URL: { return _addRecentUrl(state, action); } @@ -56,5 +64,7 @@ function _addRecentUrl(state, action) { console.info('RECENT URLs', state); + window.localStorage.setItem('recentURLs', JSON.stringify(state.entries)); + return state; }