const defaultState = { settingsModalState: 'hidden', settingsModalLoaded: false, settingsModalTargetTab: null, settings: { currentSaveStateNotice: null, noticeClearTimeout: null, notificationPermission: null }, browserSupport: { cssFilter: window.CSS && window.CSS.supports && ( window.CSS.supports('filter', 'drop-shadow(0 0)') || window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)') ) }, mobileLayout: false, globalNotices: [], layoutHeight: 0, lastTimeline: null } const interfaceMod = { state: defaultState, mutations: { settingsSaved (state, { success, error }) { if (success) { if (state.noticeClearTimeout) { clearTimeout(state.noticeClearTimeout) } state.settings.currentSaveStateNotice = { error: false, data: success } state.settings.noticeClearTimeout = setTimeout(() => delete state.settings.currentSaveStateNotice, 2000) } else { state.settings.currentSaveStateNotice = { error: true, errorData: error } } }, setNotificationPermission (state, permission) { state.notificationPermission = permission }, setMobileLayout (state, value) { state.mobileLayout = value }, closeSettingsModal (state) { state.settingsModalState = 'hidden' }, togglePeekSettingsModal (state) { switch (state.settingsModalState) { case 'minimized': state.settingsModalState = 'visible' return case 'visible': state.settingsModalState = 'minimized' return default: throw new Error('Illegal minimization state of settings modal') } }, openSettingsModal (state) { state.settingsModalState = 'visible' if (!state.settingsModalLoaded) { state.settingsModalLoaded = true } }, setSettingsModalTargetTab (state, value) { state.settingsModalTargetTab = value }, pushGlobalNotice (state, notice) { state.globalNotices.push(notice) }, removeGlobalNotice (state, notice) { state.globalNotices = state.globalNotices.filter(n => n !== notice) }, setLayoutHeight (state, value) { state.layoutHeight = value }, setLastTimeline (state, value) { state.lastTimeline = value } }, actions: { setPageTitle ({ rootState }, option = '') { document.title = `${option} ${rootState.instance.name}` }, settingsSaved ({ commit, dispatch }, { success, error }) { commit('settingsSaved', { success, error }) }, setNotificationPermission ({ commit }, permission) { commit('setNotificationPermission', permission) }, setMobileLayout ({ commit }, value) { commit('setMobileLayout', value) }, closeSettingsModal ({ commit }) { commit('closeSettingsModal') }, openSettingsModal ({ commit }) { commit('openSettingsModal') }, togglePeekSettingsModal ({ commit }) { commit('togglePeekSettingsModal') }, clearSettingsModalTargetTab ({ commit }) { commit('setSettingsModalTargetTab', null) }, openSettingsModalTab ({ commit }, value) { commit('setSettingsModalTargetTab', value) commit('openSettingsModal') }, pushGlobalNotice ( { commit, dispatch, state }, { messageKey, messageArgs = {}, level = 'error', timeout = 0 }) { const notice = { messageKey, messageArgs, level } commit('pushGlobalNotice', notice) // Adding a new element to array wraps it in a Proxy, which breaks the comparison // TODO: Generate UUID or something instead or relying on !== operator? const newNotice = state.globalNotices[state.globalNotices.length - 1] if (timeout) { setTimeout(() => dispatch('removeGlobalNotice', newNotice), timeout) } return newNotice }, removeGlobalNotice ({ commit }, notice) { commit('removeGlobalNotice', notice) }, setLayoutHeight ({ commit }, value) { commit('setLayoutHeight', value) }, setLastTimeline ({ commit }, value) { commit('setLastTimeline', value) } } } export default interfaceMod