focalboard/webapp/src/userSettings.ts
Scott Bishel 22aae37dd1
User updates (#3244)
* retrieve additional user fields

* implement config setting

* cleanup

* fix tests

* remove unused constant

* fix more tests

* add tests, cleanup

* lint fixes

* revert bad lint fixes

* more merge fixes

* update to use personal setting

* add user settings

* update package-lock.json

* lint fixes

* npm audit fix

* update tests

* Revert "lint fixes"

This reverts commit 6a50d335ca.

* Revert "update package-lock.json"

This reverts commit 1117e557e4.

* Revert "npm audit fix"

This reverts commit 77ea931c77.

* Revert "Revert "lint fixes""

This reverts commit 3ebd81b9fa.

* restore to original

* fix for empty prefs

* fix bad merge

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2022-07-08 08:43:43 -06:00

215 lines
6.5 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {notifySettingsChanged} from './nativeApp'
import {Utils} from './utils'
// eslint-disable-next-line no-shadow
export enum UserSettingKey {
Language = 'language',
Theme = 'theme',
LastTeamId = 'lastTeamId',
LastBoardId = 'lastBoardId',
LastViewId = 'lastViewId',
EmojiMartSkin = 'emoji-mart.skin',
EmojiMartLast = 'emoji-mart.last',
EmojiMartFrequently = 'emoji-mart.frequently',
RandomIcons = 'randomIcons',
MobileWarningClosed = 'mobileWarningClosed',
WelcomePageViewed = 'welcomePageViewed',
HideCloudMessage = 'hideCloudMessage',
NameFormat = 'nameFormat'
}
export class UserSettings {
static get(key: UserSettingKey): string | null {
return localStorage.getItem(key)
}
static set(key: UserSettingKey, value: string | null): void {
if (!Object.values(UserSettingKey).includes(key)) {
return
}
if (value === null) {
localStorage.removeItem(key)
} else {
localStorage.setItem(key, value)
}
notifySettingsChanged(key)
}
static get language(): string | null {
return UserSettings.get(UserSettingKey.Language)
}
static set language(newValue: string | null) {
UserSettings.set(UserSettingKey.Language, newValue)
}
static get theme(): string | null {
return UserSettings.get(UserSettingKey.Theme)
}
static set theme(newValue: string | null) {
UserSettings.set(UserSettingKey.Theme, newValue)
}
static get lastTeamId(): string | null {
return UserSettings.get(UserSettingKey.LastTeamId)
}
static set lastTeamId(newValue: string | null) {
UserSettings.set(UserSettingKey.LastTeamId, newValue)
}
// maps last board ID for each team
// maps teamID -> board ID
static get lastBoardId(): {[key: string]: string} {
let rawData = UserSettings.get(UserSettingKey.LastBoardId) || '{}'
if (rawData[0] !== '{') {
rawData = '{}'
}
let mapping: {[key: string]: string}
try {
mapping = JSON.parse(rawData)
} catch {
// revert to empty data if JSON conversion fails.
// This will happen when users run the new code for the first time
mapping = {}
}
return mapping
}
static setLastTeamID(teamID: string | null): void {
UserSettings.set(UserSettingKey.LastTeamId, teamID)
}
static setLastBoardID(teamID: string, boardID: string | null): void {
const data = this.lastBoardId
if (boardID === null) {
delete data[teamID]
} else {
data[teamID] = boardID
}
UserSettings.set(UserSettingKey.LastBoardId, JSON.stringify(data))
}
static get lastViewId(): {[key: string]: string} {
const rawData = UserSettings.get(UserSettingKey.LastViewId) || '{}'
let mapping: {[key: string]: string}
try {
mapping = JSON.parse(rawData)
} catch {
// revert to empty data if JSON conversion fails.
// This will happen when users run the new code for the first time
mapping = {}
}
return mapping
}
static setLastViewId(boardID: string, viewID: string | null): void {
const data = this.lastViewId
if (viewID === null) {
delete data[boardID]
} else {
data[boardID] = viewID
}
UserSettings.set(UserSettingKey.LastViewId, JSON.stringify(data))
}
static get prefillRandomIcons(): boolean {
return UserSettings.get(UserSettingKey.RandomIcons) !== 'false'
}
static set prefillRandomIcons(newValue: boolean) {
UserSettings.set(UserSettingKey.RandomIcons, JSON.stringify(newValue))
}
static getEmojiMartSetting(key: string): any {
const prefixed = `emoji-mart.${key}`
Utils.assert((Object as any).values(UserSettingKey).includes(prefixed))
const json = UserSettings.get(prefixed as UserSettingKey)
return json ? JSON.parse(json) : null
}
static setEmojiMartSetting(key: string, value: any): void {
const prefixed = `emoji-mart.${key}`
Utils.assert((Object as any).values(UserSettingKey).includes(prefixed))
UserSettings.set(prefixed as UserSettingKey, JSON.stringify(value))
}
static get mobileWarningClosed(): boolean {
return UserSettings.get(UserSettingKey.MobileWarningClosed) === 'true'
}
static set mobileWarningClosed(newValue: boolean) {
UserSettings.set(UserSettingKey.MobileWarningClosed, String(newValue))
}
static get hideCloudMessage(): boolean {
return localStorage.getItem(UserSettingKey.HideCloudMessage) === 'true'
}
static set hideCloudMessage(newValue: boolean) {
localStorage.setItem(UserSettingKey.HideCloudMessage, JSON.stringify(newValue))
}
static get nameFormat(): string | null {
return UserSettings.get(UserSettingKey.NameFormat)
}
static set nameFormat(newValue: string | null) {
UserSettings.set(UserSettingKey.NameFormat, newValue)
}
}
export function exportUserSettingsBlob(): string {
return window.btoa(exportUserSettings())
}
function exportUserSettings(): string {
const keys = Object.values(UserSettingKey)
const settings = Object.fromEntries(keys.map((key) => [key, localStorage.getItem(key)]))
settings.timestamp = `${Date.now()}`
return JSON.stringify(settings)
}
export function importUserSettingsBlob(blob: string): string[] {
return importUserSettings(window.atob(blob))
}
function importUserSettings(json: string): string[] {
const settings = parseUserSettings(json)
if (!settings) {
return []
}
const timestamp = settings.timestamp
const lastTimestamp = localStorage.getItem('timestamp')
if (!timestamp || (lastTimestamp && Number(timestamp) <= Number(lastTimestamp))) {
return []
}
const importedKeys = []
for (const [key, value] of Object.entries(settings)) {
if (Object.values(UserSettingKey).includes(key as UserSettingKey)) {
if (value) {
localStorage.setItem(key, value as string)
} else {
localStorage.removeItem(key)
}
importedKeys.push(key)
}
}
return importedKeys
}
function parseUserSettings(json: string): any {
try {
return JSON.parse(json)
} catch (e) {
return undefined
}
}