focalboard/webapp/src/userSettings.ts

164 lines
5 KiB
TypeScript
Raw Normal View History

// 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
Merge Onboarding feature branch into main (#2406) * Persistent user config (#2133) * Added user config API * Add unit tests * lint fix * Fixed webapp tests * Fixed webapp tests * Updated props in store after updating * Minor fixes * Removed redundent data from audit logs * Onboarding Tour (#2287) * Created private board * Roughly displayed tour * Synced with Dhama's changes * WIP * Trying to add GIF * Added 3 tour steps * WIP * WIP * WIP * checked in missed file * Synced with feature branch * WIp * Adde skip tour option * Fixed image loading for on-prem * Made tour work on presonal server: * Adde missed file * Adding telemetry * Adding telemetry * Added tour tip telemetry * Fixed pulsating dot styling for personal server * reverted personal config * Added reset tour button * Displayed share tour tip of feature is enabled * Lint fixes * Fixed webapp tests * Fixed webapp tests * Completed webapp tests * Completed webapp tests * Webapp lint fixes * Added server tests * Testing cypress skip tour fix * Fixed Cypress tests * Added share board tour step * Added share board tour step * webapp lint fixes * Updated logic to pick welcome board * Updated tests: * lint fixes * Updating UI changes * Fixed a bug causing card tour to re-appear * FIxed minor issue * FIxed bug where card tour didn't start in clickingh on card * Fixed tests * Make update user props use string instead of interface * Fixed a value type * Updating gif size * Updating resolution breakpoint * Updating tutorial tip * Updating view selector * Refactored tour components * Misc fixes * minor refactoring * GH-2258: allow date range to overflow (#2268) * allow date range to overflow * Fixed issue with date overflowing into neighbouring column Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com> * Update readme with accurate Linux standalone app build instructions (#2351) * Bump follow-redirects from 1.14.7 to 1.14.8 in /experiments/webext (#2339) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Switch component style fixed: selector specificity increased by adding additional class. (#2179) * Adding sever side undelete endpoint (#2222) * Adding sever side undelete endpoint * Removing long lines golangci-lint errors * Fixing linter errors * Fixing a test problem * Fixing tests Co-authored-by: Mattermod <mattermod@users.noreply.github.com> * Removing transactions from sqlite backend (#2361) * Removing transactions from sqlite backend * Skipping tests in sqlite because the lack of transactions * Generating the mocks * Fixing golangci-lint * Fixing problem opening the tour tooltip on card open * Fixing texts missmatch * Adding the Product Tour entry in the user settings menu * Fixing some tests * Fixing tests Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com> Co-authored-by: Scott Bishel <scott.bishel@mattermost.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Doug Lauder <wiggin77@warpmail.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kamre <eremchenko@gmail.com> Co-authored-by: Jesús Espino <jespinog@gmail.com> * Restored package json * Restored package json Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com> Co-authored-by: Scott Bishel <scott.bishel@mattermost.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Doug Lauder <wiggin77@warpmail.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kamre <eremchenko@gmail.com> Co-authored-by: Jesús Espino <jespinog@gmail.com>
2022-02-28 12:28:16 +01:00
export enum UserSettingKey {
Language = 'language',
Theme = 'theme',
LastWorkspaceId = 'lastWorkspaceId',
LastBoardId = 'lastBoardId',
LastViewId = 'lastViewId',
EmojiMartSkin = 'emoji-mart.skin',
EmojiMartLast = 'emoji-mart.last',
EmojiMartFrequently = 'emoji-mart.frequently',
RandomIcons = 'randomIcons',
MobileWarningClosed = 'mobileWarningClosed',
WelcomePageViewed = 'welcomePageViewed',
DashboardShowEmpty = 'dashboardShowEmpty'
}
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 lastWorkspaceId(): string | null {
return UserSettings.get(UserSettingKey.LastWorkspaceId)
}
static set lastWorkspaceId(newValue: string | null) {
UserSettings.set(UserSettingKey.LastWorkspaceId, newValue)
}
static get lastBoardId(): string | null {
return UserSettings.get(UserSettingKey.LastBoardId)
}
static set lastBoardId(newValue: string | null) {
UserSettings.set(UserSettingKey.LastBoardId, newValue)
}
static get lastViewId(): string | null {
return UserSettings.get(UserSettingKey.LastViewId)
}
static set lastViewId(newValue: string | null) {
UserSettings.set(UserSettingKey.LastViewId, newValue)
}
static get prefillRandomIcons(): boolean {
return UserSettings.get(UserSettingKey.RandomIcons) !== 'false'
}
static set prefillRandomIcons(newValue: boolean) {
UserSettings.set(UserSettingKey.RandomIcons, JSON.stringify(newValue))
}
static get dashboardShowEmpty(): boolean {
return localStorage.getItem(UserSettingKey.DashboardShowEmpty) !== 'false'
}
static set dashboardShowEmpty(newValue: boolean) {
localStorage.setItem(UserSettingKey.DashboardShowEmpty, 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))
}
}
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)
2021-05-24 18:59:30 +02:00
}
}
return importedKeys
}
function parseUserSettings(json: string): any {
try {
return JSON.parse(json)
} catch (e) {
return undefined
}
}