From 2bee673a14a6dc2b5791ff9801050ac1b3707f7f Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 13 Dec 2022 14:22:27 +0100 Subject: [PATCH] refactor: user-specific storage --- composables/featureFlags.ts | 30 +---------------------- composables/statusDrafts.ts | 25 +------------------ composables/users.ts | 49 ++++++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 57 deletions(-) diff --git a/composables/featureFlags.ts b/composables/featureFlags.ts index 81dd2d89..178e1d25 100644 --- a/composables/featureFlags.ts +++ b/composables/featureFlags.ts @@ -1,4 +1,3 @@ -import type { Account } from 'masto' import { STORAGE_KEY_FEATURE_FLAGS } from '~/constants' export interface FeatureFlags { @@ -7,8 +6,6 @@ export interface FeatureFlags { } export type FeatureFlagsMap = Record -export const allFeatureFlags = useLocalStorage(STORAGE_KEY_FEATURE_FLAGS, {}, { deep: true }) - export function getDefaultFeatureFlags(): FeatureFlags { return { experimentalVirtualScroll: false, @@ -16,17 +13,7 @@ export function getDefaultFeatureFlags(): FeatureFlags { } } -export const currentUserFeatureFlags = computed(() => { - if (!currentUser.value?.account.id) - return {} as FeatureFlags - - const id = `${currentUser.value.account.acct}@${currentUser.value.server}` - - if (!allFeatureFlags.value[id]) - allFeatureFlags.value[id] = getDefaultFeatureFlags() - - return allFeatureFlags.value[id] as FeatureFlags -}) +export const currentUserFeatureFlags = useUserLocalStorage(STORAGE_KEY_FEATURE_FLAGS, getDefaultFeatureFlags) export function useFeatureFlags() { const featureFlags = currentUserFeatureFlags.value @@ -42,18 +29,3 @@ export function toggleFeatureFlag(key: keyof FeatureFlags) { else featureFlags[key] = true } - -export function clearUserFeatureFlags(account?: Account) { - if (!account) - account = currentUser.value?.account - - if (!account) - return - - const id = `${account.acct}@${currentUser.value?.server}` - if (!allFeatureFlags.value[id]) - return - - delete allFeatureFlags.value[id] -} - diff --git a/composables/statusDrafts.ts b/composables/statusDrafts.ts index 908fb463..e6848236 100644 --- a/composables/statusDrafts.ts +++ b/composables/statusDrafts.ts @@ -12,16 +12,7 @@ export interface Draft { } export type DraftMap = Record -const allDrafts = useLocalStorage>(STORAGE_KEY_DRAFTS, {}) - -export const currentUserDrafts = computed(() => { - if (!currentUser.value?.account.id) - return {} - const id = `${currentUser.value.account.acct}@${currentUser.value.server}` - if (!allDrafts.value[id]) - allDrafts.value[id] = {} - return allDrafts.value[id] -}) +export const currentUserDrafts = useUserLocalStorage(STORAGE_KEY_DRAFTS, () => ({})) export function getDefaultDraft(options: Partial> = {}): Draft { const { @@ -124,17 +115,3 @@ export function directMessageUser(account: Account) { visibility: 'direct', }), true) } - -export function clearUserDrafts(account?: Account) { - if (!account) - account = currentUser.value?.account - - if (!account) - return - - const id = `${account.acct}@${currentUser.value?.server}` - if (!allDrafts.value[id]) - return - - delete allDrafts.value[id] -} diff --git a/composables/users.ts b/composables/users.ts index 4250f85d..cf3b8b51 100644 --- a/composables/users.ts +++ b/composables/users.ts @@ -1,6 +1,6 @@ import { login as loginMasto } from 'masto' -import type { AccountCredentials, Instance, WsEvents } from 'masto' -import { clearUserDrafts } from './statusDrafts' +import type { Account, AccountCredentials, Instance, WsEvents } from 'masto' +import type { Ref } from 'vue' import type { UserLogin } from '~/types' import { DEFAULT_POST_CHARS_LIMIT, DEFAULT_SERVER, STORAGE_KEY_CURRENT_USER, STORAGE_KEY_SERVERS, STORAGE_KEY_USERS } from '~/constants' @@ -91,9 +91,8 @@ export async function signout() { if (index !== -1) { // Clear stale data + clearUserLocalStorage() delete servers.value[_currentUserId] - clearUserDrafts() - clearUserFeatureFlags() currentUserId.value = '' // Remove the current user from the users @@ -153,3 +152,45 @@ export function checkLogin() { } return true } + +const userLocalStorages = new Map>>() + +/** + * Create reactive storage for the current user + */ +export function useUserLocalStorage(key: string, initial: () => T) { + if (!userLocalStorages.has(key)) + userLocalStorages.set(key, useLocalStorage(key, {}, { deep: true })) + + const all = userLocalStorages.get(key) as Ref> + const id = currentUser.value?.account.id + ? `${currentUser.value.account.acct}@${currentUser.value.server}` + : '[anonymous]' + + all.value[id] = Object.assign(initial(), all.value[id] || {}) + return extendRef( + computed(() => all.value[id]), + { + remove: { + value: () => { + delete all.value[id] + }, + }, + }) +} + +/** + * Clear all storages for the given account + */ +export function clearUserLocalStorage(account?: Account) { + if (!account) + account = currentUser.value?.account + if (!account) + return + + const id = `${account.acct}@${currentUser.value?.server}` + userLocalStorages.forEach((storage) => { + if (storage.value[id]) + delete storage.value[id] + }) +}