{
{
:command="command"
@click="toggleFavourite()"
>
-
+
status.account.id === currentUser.value?.account.id)
diff --git a/components/status/StatusCard.vue b/components/status/StatusCard.vue
index 9e227114..2fc94e0c 100644
--- a/components/status/StatusCard.vue
+++ b/components/status/StatusCard.vue
@@ -22,6 +22,7 @@ const props = withDefaults(
}>(),
{ actions: true },
)
+const userSettings = useUserSettings()
const status = $computed(() => {
if (props.status.reblog && !props.status.content)
diff --git a/composables/command.ts b/composables/command.ts
index 1a73918d..aa8c48d1 100644
--- a/composables/command.ts
+++ b/composables/command.ts
@@ -244,6 +244,7 @@ export const provideGlobalCommands = () => {
const users = useUsers()
const masto = useMasto()
const colorMode = useColorMode()
+ const userSettings = useUserSettings()
useCommand({
scope: 'Navigation',
diff --git a/composables/injections.ts b/composables/injections.ts
index c43e910f..b304fbc1 100644
--- a/composables/injections.ts
+++ b/composables/injections.ts
@@ -1,8 +1,4 @@
-import { InjectionKeyDropdownContext, InjectionKeyFontSize } from '~/constants/symbols'
-
-export function useFontSizeRef() {
- return inject(InjectionKeyFontSize)!
-}
+import { InjectionKeyDropdownContext } from '~/constants/symbols'
export function useDropdownContext() {
return inject(InjectionKeyDropdownContext, undefined)
diff --git a/composables/settings/definition.ts b/composables/settings/definition.ts
new file mode 100644
index 00000000..951be211
--- /dev/null
+++ b/composables/settings/definition.ts
@@ -0,0 +1,46 @@
+import { DEFAULT_FONT_SIZE, DEFAULT_LANGUAGE } from '~/constants'
+
+export type FontSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+export type ColorMode = 'light' | 'dark'
+
+export interface FeatureFlags {
+ experimentalVirtualScroller: boolean
+ experimentalGitHubCards: boolean
+ experimentalUserPicker: boolean
+}
+
+export interface WellnessSettings {
+ hideBoostCount: boolean
+ hideFavoriteCount: boolean
+ hideFollowerCount: boolean
+}
+
+export interface UserSettings {
+ featureFlags: Partial
+ wellnessSettings: Partial
+ colorMode?: ColorMode
+ fontSize: FontSize
+ language: string
+ zenMode?: boolean
+}
+
+export function getDefaultUserSettings(): UserSettings {
+ return {
+ language: DEFAULT_LANGUAGE,
+ fontSize: DEFAULT_FONT_SIZE,
+ featureFlags: {},
+ wellnessSettings: {},
+ }
+}
+
+export const DEFAULT_WELLNESS_SETTINGS: WellnessSettings = {
+ hideBoostCount: false,
+ hideFavoriteCount: false,
+ hideFollowerCount: false,
+}
+
+export const DEFAULT_FEATURE_FLAGS: FeatureFlags = {
+ experimentalVirtualScroller: true,
+ experimentalGitHubCards: true,
+ experimentalUserPicker: true,
+}
diff --git a/composables/settings/featureFlags.ts b/composables/settings/featureFlags.ts
deleted file mode 100644
index 611f6a77..00000000
--- a/composables/settings/featureFlags.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import type { Ref } from 'vue'
-import { userSettings } from '.'
-
-export interface FeatureFlags {
- experimentalVirtualScroller: boolean
- experimentalGitHubCards: boolean
- experimentalUserPicker: boolean
-}
-export type FeatureFlagsMap = Record
-
-const DEFAULT_FEATURE_FLAGS: FeatureFlags = {
- experimentalVirtualScroller: true,
- experimentalGitHubCards: true,
- experimentalUserPicker: true,
-}
-
-export function useFeatureFlag(name: T): Ref {
- return computed({
- get() {
- return getFeatureFlag(name)
- },
- set(value) {
- if (userSettings.value)
- userSettings.value.featureFlags[name] = value
- },
- })
-}
-
-export function getFeatureFlag(name: T): FeatureFlags[T] {
- return userSettings.value?.featureFlags?.[name] ?? DEFAULT_FEATURE_FLAGS[name]
-}
-
-export function toggleFeatureFlag(key: keyof FeatureFlags) {
- const flag = useFeatureFlag(key)
- flag.value = !flag.value
-}
diff --git a/composables/settings/index.ts b/composables/settings/index.ts
index e53fb847..556503f5 100644
--- a/composables/settings/index.ts
+++ b/composables/settings/index.ts
@@ -1,24 +1,2 @@
-import type { FeatureFlags } from './featureFlags'
-import type { WellnessSettings } from './wellness'
-import type { ColorMode, FontSize } from '~/types'
-import { STORAGE_KEY_SETTINGS } from '~/constants'
-
-export interface UserSettings {
- featureFlags: Partial
- wellnessSettings: Partial
- colorMode?: ColorMode
- fontSize?: FontSize
- lang?: string
- zenMode?: boolean
-}
-
-export function getDefaultUserSettings(): UserSettings {
- return {
- featureFlags: {},
- wellnessSettings: {},
- }
-}
-
-export const userSettings = process.server
- ? computed(getDefaultUserSettings)
- : useUserLocalStorage(STORAGE_KEY_SETTINGS, getDefaultUserSettings)
+export * from './definition'
+export * from './storage'
diff --git a/composables/settings/storage.ts b/composables/settings/storage.ts
new file mode 100644
index 00000000..917e398e
--- /dev/null
+++ b/composables/settings/storage.ts
@@ -0,0 +1,53 @@
+import type { Ref } from 'vue'
+import type { FeatureFlags, UserSettings, WellnessSettings } from './definition'
+import { STORAGE_KEY_SETTINGS } from '~/constants'
+
+export const useUserSettings = () => {
+ if (process.server)
+ return useState('user-settings', getDefaultUserSettings)
+ return useUserLocalStorage(STORAGE_KEY_SETTINGS, getDefaultUserSettings)
+}
+
+// TODO: refactor & simplify this
+
+export function useWellnessSetting(name: T): Ref {
+ const userSettings = useUserSettings()
+ return computed({
+ get() {
+ return getWellnessSetting(userSettings.value, name)
+ },
+ set(value) {
+ userSettings.value.wellnessSettings[name] = value
+ },
+ })
+}
+
+export function getWellnessSetting(userSettings: UserSettings, name: T): WellnessSettings[T] {
+ return userSettings?.wellnessSettings?.[name] ?? DEFAULT_WELLNESS_SETTINGS[name]
+}
+
+export function toggleWellnessSetting(key: keyof WellnessSettings) {
+ const flag = useWellnessSetting(key)
+ flag.value = !flag.value
+}
+
+export function useFeatureFlag(name: T): Ref {
+ const userSettings = useUserSettings()
+ return computed({
+ get() {
+ return getFeatureFlag(userSettings.value, name)
+ },
+ set(value) {
+ userSettings.value.featureFlags[name] = value
+ },
+ })
+}
+
+export function getFeatureFlag(userSettings: UserSettings, name: T): FeatureFlags[T] {
+ return userSettings?.featureFlags?.[name] ?? DEFAULT_FEATURE_FLAGS[name]
+}
+
+export function toggleFeatureFlag(key: keyof FeatureFlags) {
+ const flag = useFeatureFlag(key)
+ flag.value = !flag.value
+}
diff --git a/composables/settings/wellness.ts b/composables/settings/wellness.ts
deleted file mode 100644
index 164365e6..00000000
--- a/composables/settings/wellness.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import type { Ref } from 'vue'
-import { userSettings } from '.'
-
-export interface WellnessSettings {
- hideBoostCount: boolean
- hideFavoriteCount: boolean
- hideFollowerCount: boolean
-}
-export type WellnessSettingsMap = Record
-
-const DEFAULT_WELLNESS_SETTINGS: WellnessSettings = {
- hideBoostCount: false,
- hideFavoriteCount: false,
- hideFollowerCount: false,
-}
-
-export function useWellnessSetting(name: T): Ref {
- return computed({
- get() {
- return getWellnessSetting(name)
- },
- set(value) {
- if (userSettings.value)
- userSettings.value.wellnessSettings[name] = value
- },
- })
-}
-
-export function getWellnessSetting(name: T): WellnessSettings[T] {
- return userSettings.value?.wellnessSettings?.[name] ?? DEFAULT_WELLNESS_SETTINGS[name]
-}
-
-export function toggleWellnessSetting(key: keyof WellnessSettings) {
- const flag = useWellnessSetting(key)
- flag.value = !flag.value
-}
diff --git a/composables/users.ts b/composables/users.ts
index 9af04f68..6bad13b8 100644
--- a/composables/users.ts
+++ b/composables/users.ts
@@ -271,13 +271,7 @@ export function checkLogin() {
* Create reactive storage for the current user
*/
export function useUserLocalStorage(key: string, initial: () => T) {
- // @ts-expect-error bind value to the function
- const storages = useUserLocalStorage._ = useUserLocalStorage._ || new Map>>()
-
- if (!storages.has(key))
- storages.set(key, useLocalStorage(key, {}, { deep: true }))
- const all = storages.get(key) as Ref>
-
+ const all = useLocalStorage>(key, {}, { deep: true })
return computed(() => {
const id = currentUser.value?.account.id
? currentUser.value.account.acct
diff --git a/constants/index.ts b/constants/index.ts
index 2c33a9ca..bbe25a44 100644
--- a/constants/index.ts
+++ b/constants/index.ts
@@ -2,6 +2,7 @@ export const APP_NAME = 'Elk'
export const DEFAULT_POST_CHARS_LIMIT = 500
export const DEFAULT_FONT_SIZE = 'md'
+export const DEFAULT_LANGUAGE = 'en-US'
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
export const STORAGE_KEY_USERS = 'elk-users'
@@ -20,7 +21,6 @@ export const STORAGE_KEY_NOTIFICATION_POLICY = 'elk-notification-policy'
export const COOKIE_MAX_AGE = 10 * 365 * 24 * 60 * 60 * 1000
export const COOKIE_KEY_FONT_SIZE = 'elk-font-size'
-export const COOKIE_KEY_COLOR_MODE = 'elk-color-mode'
export const COOKIE_KEY_LOCALE = 'elk-lang'
export const HANDLED_MASTO_URLS = /^(https?:\/\/)?([\w\d-]+\.)+\w+\/(@[@\w\d-\.]+)(\/objects)?(\/\d+)?$/
diff --git a/constants/symbols.ts b/constants/symbols.ts
index bf8a9291..8e04e1b4 100644
--- a/constants/symbols.ts
+++ b/constants/symbols.ts
@@ -1,7 +1,4 @@
-import type { InjectionKey, Ref } from 'vue'
-import type { FontSize } from '~/types'
-
-export const InjectionKeyFontSize: InjectionKey[> = Symbol('font-size')
+import type { InjectionKey } from 'vue'
export const InjectionKeyDropdownContext: InjectionKey<{
hide: () => void
diff --git a/layouts/default.vue b/layouts/default.vue
index bff152d8..4bd08925 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -1,7 +1,8 @@
@@ -18,19 +20,19 @@ useHeadFixed({
{{ $t('settings.feature_flags.title') }}
{{ $t('settings.feature_flags.virtual_scroll') }}
{{ $t('settings.feature_flags.github_cards') }}
{{ $t('settings.feature_flags.user_picker') }}
diff --git a/pages/settings/wellness/index.vue b/pages/settings/wellness/index.vue
index 14b6e0fa..546dbb93 100644
--- a/pages/settings/wellness/index.vue
+++ b/pages/settings/wellness/index.vue
@@ -4,6 +4,8 @@ const { t } = useI18n()
useHeadFixed({
title: () => `${t('settings.wellness.label')} | ${t('nav.settings')}`,
})
+
+const userSettings = useUserSettings()
@@ -14,19 +16,19 @@ useHeadFixed({
]