import { createStore } from 'vuex' import VuexPersistence from 'vuex-persist' export const STORE_KEY_USER = `convene_${ window.location.hostname }_user` export const STORE_KEY_SETTINGS = `convene_${ window.location.hostname }_settings` // A Vuex plugin to persist the user object to either session or local storage, based on flag in the store state. // const persistUserPlugin = store => { var user; if (store.state.useLocalStorage) { user = JSON.parse(window.localStorage.getItem(STORE_KEY_USER)); } else { user = JSON.parse(window.sessionStorage.getItem(STORE_KEY_USER)); } const initialState = user ? { status: { loggedIn: true }, user } : { status: { loggedIn: false }, user: null }; store.state.auth = initialState; store.subscribe((mutation, state) => { if (mutation.type == 'setUser' || mutation.type == 'setUseLocalStorage') { if (state.useLocalStorage) { window.localStorage.setItem(STORE_KEY_USER, JSON.stringify(state.auth.user)); window.sessionStorage.removeItem(STORE_KEY_USER); } else { window.sessionStorage.setItem(STORE_KEY_USER, JSON.stringify(state.auth.user)); window.localStorage.removeItem(STORE_KEY_USER); } } }) } const vuexPersistLocalStorage = new VuexPersistence({ key: STORE_KEY_SETTINGS, storage: localStorage, reducer: state => { if (state.useLocalStorage) { return { language: state.language, currentRoomId: state.currentRoomId, hasShownMissedItemsHint: state.hasShownMissedItemsHint, globalNotification: state.globalNotification, uaAccepted: state.uaAccepted, }; } else { return {}; } } }) const vuexPersistSessionStorage = new VuexPersistence({ key: STORE_KEY_SETTINGS, storage: sessionStorage, reducer: state => { if (!state.useLocalStorage) { return { language: state.language, currentRoomId: state.currentRoomId, hasShownMissedItemsHint: state.hasShownMissedItemsHint, uaAccepted: state.uaAccepted, }; } else { return {}; } } }) const defaultUseSessionStorage = (sessionStorage.getItem(STORE_KEY_USER) != null); const store = createStore({ state: { language: null, currentRoomId: null, auth: null, tempuser: null, useLocalStorage: !defaultUseSessionStorage, globalNotification: false, uaAccepted: false }, mutations: { loginSuccess(state, user) { state.auth.status.loggedIn = true; state.auth.user = user; }, loginFailure(state) { state.auth.status.loggedIn = false; state.auth.user = null; }, logout(state) { state.auth.status.loggedIn = false; state.auth.user = null; }, setLanguage(state, locale) { state.language = locale; }, setCurrentRoomId(state, roomId) { state.currentRoomId = roomId; }, setUser(state, user) { state.auth.user = user; // Don't stringify, our persistUserPlugin handles that! }, setTempUser(state, user) { state.tempuser = JSON.stringify(user); }, setUseLocalStorage(state, useLocalStorage) { state.useLocalStorage = useLocalStorage; }, setHasShownMissedItemsHint(state, flag) { state.hasShownMissedItemsHint = flag; }, setGlobalNotification(state, flag) { state.globalNotification = flag; }, acceptUA(state, accepted) { state.uaAccepted = accepted; } }, actions: { login({ commit }, { user, registrationFlowHandler }) { return this.$matrix.login(user, registrationFlowHandler).then( user => { commit('loginSuccess', user); return Promise.resolve(user); }, error => { commit('loginFailure'); return Promise.reject(error); } ); }, createUser({ commit }, { user, registrationFlowHandler }) { return this.$matrix.login(user, registrationFlowHandler, true).then( user => { commit('loginSuccess', user); return Promise.resolve(user); }, error => { commit('loginFailure'); return Promise.reject(error); } ); }, logout({ commit }) { this.$matrix.logout(); commit('logout'); }, migrate({ state }, migrationData) { if (migrationData && migrationData.type) { let storage = migrationData.type == "session" ? sessionStorage : localStorage; if (migrationData.settings) { try { const settings = JSON.parse(migrationData.settings); storage.setItem(STORE_KEY_SETTINGS, migrationData.settings); state.useLocalStorage = migrationData.type != "session"; } catch (error) { console.error("Failed to migrate settings", error); } } if (migrationData.user) { const user = JSON.parse(migrationData.user); state.auth.user = user; return this.$matrix.migrate(user).then( (user) => { return Promise.resolve(user); }, (error) => { return Promise.reject(error); } ); } } return Promise.reject("Migration error"); } }, getters: { storage: state => { if (state.useLocalStorage) { return window.localStorage; } else { return window.sessionStorage; } } }, plugins: [vuexPersistLocalStorage.plugin, vuexPersistSessionStorage.plugin, persistUserPlugin] }); export default store;