import EventEmitter from 'events'; import appDispatcher from '../dispatcher'; import cons from './cons'; function getSettings() { const settings = localStorage.getItem('settings'); if (settings === null) return null; return JSON.parse(settings); } function setSettings(key, value) { let settings = getSettings(); if (settings === null) settings = {}; settings[key] = value; localStorage.setItem('settings', JSON.stringify(settings)); } class Settings extends EventEmitter { constructor() { super(); this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme']; this.themeIndex = this.getThemeIndex(); this.useSystemTheme = this.getUseSystemTheme(); this.isMarkdown = this.getIsMarkdown(); this.isPeopleDrawer = this.getIsPeopleDrawer(); this.hideMembershipEvents = this.getHideMembershipEvents(); this.hideNickAvatarEvents = this.getHideNickAvatarEvents(); this._showNotifications = this.getShowNotifications(); this.isTouchScreenDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); } getThemeIndex() { if (typeof this.themeIndex === 'number') return this.themeIndex; const settings = getSettings(); if (settings === null) return 0; if (typeof settings.themeIndex === 'undefined') return 0; // eslint-disable-next-line radix return parseInt(settings.themeIndex); } getThemeName() { return this.themes[this.themeIndex]; } setTheme(themeIndex) { const appBody = document.getElementById('appBody'); appBody.classList.remove('system-theme'); this.themes.forEach((themeName) => { if (themeName === '') return; appBody.classList.remove(themeName); }); // If use system theme is enabled // we will override current theme choice with system theme if (this.useSystemTheme) { appBody.classList.add('system-theme'); } else if (this.themes[themeIndex] !== '') { appBody.classList.add(this.themes[themeIndex]); } setSettings('themeIndex', themeIndex); this.themeIndex = themeIndex; } getUseSystemTheme() { if (typeof this.useSystemTheme === 'boolean') return this.useSystemTheme; const settings = getSettings(); if (settings === null) return false; if (typeof settings.useSystemTheme === 'undefined') return false; return settings.useSystemTheme; } getIsMarkdown() { if (typeof this.isMarkdown === 'boolean') return this.isMarkdown; const settings = getSettings(); if (settings === null) return true; if (typeof settings.isMarkdown === 'undefined') return true; return settings.isMarkdown; } getHideMembershipEvents() { if (typeof this.hideMembershipEvents === 'boolean') return this.hideMembershipEvents; const settings = getSettings(); if (settings === null) return false; if (typeof settings.hideMembershipEvents === 'undefined') return false; return settings.hideMembershipEvents; } getHideNickAvatarEvents() { if (typeof this.hideNickAvatarEvents === 'boolean') return this.hideNickAvatarEvents; const settings = getSettings(); if (settings === null) return false; if (typeof settings.hideNickAvatarEvents === 'undefined') return false; return settings.hideNickAvatarEvents; } getIsPeopleDrawer() { if (typeof this.isPeopleDrawer === 'boolean') return this.isPeopleDrawer; const settings = getSettings(); if (settings === null) return true; if (typeof settings.isPeopleDrawer === 'undefined') return true; return settings.isPeopleDrawer; } get showNotifications() { if (window.Notification?.permission !== 'granted') return false; return this._showNotifications; } getShowNotifications() { if (typeof this._showNotifications === 'boolean') return this._showNotifications; const settings = getSettings(); if (settings === null) return true; if (typeof settings.showNotifications === 'undefined') return true; return settings.showNotifications; } setter(action) { const actions = { [cons.actions.settings.TOGGLE_SYSTEM_THEME]: () => { this.useSystemTheme = !this.useSystemTheme; setSettings('useSystemTheme', this.useSystemTheme); this.setTheme(this.themeIndex); this.emit(cons.events.settings.SYSTEM_THEME_TOGGLED, this.useSystemTheme); }, [cons.actions.settings.TOGGLE_MARKDOWN]: () => { this.isMarkdown = !this.isMarkdown; setSettings('isMarkdown', this.isMarkdown); this.emit(cons.events.settings.MARKDOWN_TOGGLED, this.isMarkdown); }, [cons.actions.settings.TOGGLE_PEOPLE_DRAWER]: () => { this.isPeopleDrawer = !this.isPeopleDrawer; setSettings('isPeopleDrawer', this.isPeopleDrawer); this.emit(cons.events.settings.PEOPLE_DRAWER_TOGGLED, this.isPeopleDrawer); }, [cons.actions.settings.TOGGLE_MEMBERSHIP_EVENT]: () => { this.hideMembershipEvents = !this.hideMembershipEvents; setSettings('hideMembershipEvents', this.hideMembershipEvents); this.emit(cons.events.settings.MEMBERSHIP_EVENTS_TOGGLED, this.hideMembershipEvents); }, [cons.actions.settings.TOGGLE_NICKAVATAR_EVENT]: () => { this.hideNickAvatarEvents = !this.hideNickAvatarEvents; setSettings('hideNickAvatarEvents', this.hideNickAvatarEvents); this.emit(cons.events.settings.NICKAVATAR_EVENTS_TOGGLED, this.hideNickAvatarEvents); }, [cons.actions.settings.TOGGLE_NOTIFICATIONS]: async () => { if (window.Notification?.permission !== 'granted') { this._showNotifications = false; } else { this._showNotifications = !this._showNotifications; } setSettings('showNotifications', this._showNotifications); this.emit(cons.events.settings.NOTIFICATIONS_TOGGLED, this._showNotifications); }, }; actions[action.type]?.(); } } const settings = new Settings(); appDispatcher.register(settings.setter.bind(settings)); export default settings;