From 55aff4778b2f1b652caaa228494dfafc23ca39bd Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 14 Jan 2023 10:34:53 +0100 Subject: [PATCH] refactor: use head script instead of cookie --- app.vue | 1 + composables/users.ts | 9 +++---- constants/index.ts | 4 +-- pages/settings.vue | 4 ++- plugins/setup-font-size.client.ts | 10 ++++++++ plugins/setup-font-size.ts | 26 -------------------- plugins/setup-head-script.server.ts | 38 +++++++++++++++++++++++++++++ plugins/setup-i18n.ts | 15 ++++-------- 8 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 plugins/setup-font-size.client.ts delete mode 100644 plugins/setup-font-size.ts create mode 100644 plugins/setup-head-script.server.ts diff --git a/app.vue b/app.vue index cc034a6b..3ce0a951 100644 --- a/app.vue +++ b/app.vue @@ -3,6 +3,7 @@ setupPageHeader() provideGlobalCommands() const route = useRoute() + if (process.server && !route.path.startsWith('/settings')) { useHead({ meta: [ diff --git a/composables/users.ts b/composables/users.ts index 9eebfc58..c68d90d2 100644 --- a/composables/users.ts +++ b/composables/users.ts @@ -6,6 +6,7 @@ import type { ElkMasto, UserLogin } from '~/types' import { DEFAULT_POST_CHARS_LIMIT, STORAGE_KEY_CURRENT_USER, + STORAGE_KEY_CURRENT_USER_HANDLE, STORAGE_KEY_NOTIFICATION, STORAGE_KEY_NOTIFICATION_POLICY, STORAGE_KEY_SERVERS, @@ -89,12 +90,10 @@ if (process.client) { window.addEventListener('visibilitychange', windowReload, { capture: true }) } }, { immediate: true, flush: 'post' }) -} -export const currentUserHandle = computed(() => currentUser.value?.account.id - ? `${currentUser.value.account.acct}@${currentInstance.value?.uri || currentServer.value}` - : '[anonymous]', -) + // for injected script to read + useLocalStorage(STORAGE_KEY_CURRENT_USER_HANDLE, computed(() => currentUser.value?.account.acct || '')) +} export const useUsers = () => users export const useSelfAccount = (user: MaybeComputedRef) => diff --git a/constants/index.ts b/constants/index.ts index bbe25a44..a431c01f 100644 --- a/constants/index.ts +++ b/constants/index.ts @@ -8,6 +8,7 @@ export const STORAGE_KEY_DRAFTS = 'elk-drafts' export const STORAGE_KEY_USERS = 'elk-users' export const STORAGE_KEY_SERVERS = 'elk-servers' export const STORAGE_KEY_CURRENT_USER = 'elk-current-user' +export const STORAGE_KEY_CURRENT_USER_HANDLE = 'elk-current-user-handle' export const STORAGE_KEY_NOTIFY_TAB = 'elk-notify-tab' export const STORAGE_KEY_FIRST_VISIT = 'elk-first-visit' export const STORAGE_KEY_SETTINGS = 'elk-settings' @@ -20,7 +21,4 @@ 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_LOCALE = 'elk-lang' - export const HANDLED_MASTO_URLS = /^(https?:\/\/)?([\w\d-]+\.)+\w+\/(@[@\w\d-\.]+)(\/objects)?(\/\d+)?$/ diff --git a/pages/settings.vue b/pages/settings.vue index d104e544..9f339f8e 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -80,7 +80,9 @@ const isRootPath = computedEager(() => route.name === 'settings')
- + + +
diff --git a/plugins/setup-font-size.client.ts b/plugins/setup-font-size.client.ts new file mode 100644 index 00000000..ab814ca1 --- /dev/null +++ b/plugins/setup-font-size.client.ts @@ -0,0 +1,10 @@ +import { fontSizeMap } from '~/constants/options' +import { DEFAULT_FONT_SIZE } from '~/constants' + +export default defineNuxtPlugin(() => { + const userSettings = useUserSettings() + const html = document.querySelector('html')! + watchEffect(() => { + html.style.setProperty('--font-size', fontSizeMap[userSettings.value.fontSize || DEFAULT_FONT_SIZE]) + }) +}) diff --git a/plugins/setup-font-size.ts b/plugins/setup-font-size.ts deleted file mode 100644 index eb61992e..00000000 --- a/plugins/setup-font-size.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { FontSize } from '~/composables/settings' -import { COOKIE_KEY_FONT_SIZE, COOKIE_MAX_AGE, DEFAULT_FONT_SIZE } from '~/constants' -import { fontSizeMap } from '~/constants/options' - -export default defineNuxtPlugin(() => { - const userSettings = useUserSettings() - const cookieFontSize = useCookie(COOKIE_KEY_FONT_SIZE, { default: () => DEFAULT_FONT_SIZE, maxAge: COOKIE_MAX_AGE }) - if (!cookieFontSize.value || !fontSizeMap[cookieFontSize.value]) - cookieFontSize.value = DEFAULT_FONT_SIZE - - if (process.server) { - userSettings.value.fontSize = cookieFontSize.value - useHead({ - style: [ - { innerHTML: `:root { --font-size: ${fontSizeMap[cookieFontSize.value]}; }` }, - ], - }) - return - } - - userSettings.value.fontSize = cookieFontSize.value - watch(() => userSettings.value.fontSize, (size) => { - document.documentElement.style.setProperty('--font-size', fontSizeMap[size]) - cookieFontSize.value = size - }, { immediate: true }) -}) diff --git a/plugins/setup-head-script.server.ts b/plugins/setup-head-script.server.ts new file mode 100644 index 00000000..36cccad1 --- /dev/null +++ b/plugins/setup-head-script.server.ts @@ -0,0 +1,38 @@ +import { STORAGE_KEY_CURRENT_USER_HANDLE, STORAGE_KEY_SETTINGS } from '~/constants' +import { fontSizeMap } from '~/constants/options' + +/** + * Injecting scripts before renders + */ +export default defineNuxtPlugin(() => { + useHead({ + script: [ + { + innerHTML: ` +;(function() { + const handle = localStorage.getItem('${STORAGE_KEY_CURRENT_USER_HANDLE}') + if (!handle) + return + const allSettings = JSON.parse(localStorage.getItem('${STORAGE_KEY_SETTINGS}') || '{}') + const settings = allSettings[handle] + if (!settings) + return + + const html = document.querySelector('html') + ${process.dev ? 'console.log(\'settings\', settings)' : ''} + + const { fontSize, language } = settings || {} + + if (fontSize) { + const fontSizeMap = ${JSON.stringify(fontSizeMap)} + html.style.setProperty('--font-size', fontSizeMap[fontSize]) + } + + if (language) { + html.setAttribute('lang', language) + } +})()`.trim().replace(/\s*\n+\s*/g, ';'), + }, + ], + }) +}) diff --git a/plugins/setup-i18n.ts b/plugins/setup-i18n.ts index c9a1cdac..cdd4b647 100644 --- a/plugins/setup-i18n.ts +++ b/plugins/setup-i18n.ts @@ -1,18 +1,17 @@ import type { VueI18n } from 'vue-i18n' import type { LocaleObject } from 'vue-i18n-routing' -import { COOKIE_KEY_LOCALE, COOKIE_MAX_AGE, DEFAULT_LANGUAGE } from '~/constants' +import { DEFAULT_LANGUAGE } from '~/constants' export default defineNuxtPlugin(async (nuxt) => { const i18n = nuxt.vueApp.config.globalProperties.$i18n as VueI18n const { setLocale, locales } = i18n const supportLanguages = (locales as LocaleObject[]).map(locale => locale.code) - const cookieLocale = useCookie(COOKIE_KEY_LOCALE, { maxAge: COOKIE_MAX_AGE }) const userSettings = useUserSettings() if (process.server) { const headers = useRequestHeaders() - let lang = cookieLocale.value + let lang = userSettings.value.language if (!lang || !supportLanguages.includes(lang)) { // first visit if (headers['accept-language']) { @@ -24,22 +23,18 @@ export default defineNuxtPlugin(async (nuxt) => { lang = DEFAULT_LANGUAGE } } - userSettings.value.language = cookieLocale.value = lang if (lang !== i18n.locale) - await setLocale(cookieLocale.value) + await setLocale(userSettings.value.language) return } // could be null if browser don't accept cookie - if (!cookieLocale.value || !supportLanguages.includes(cookieLocale.value)) - cookieLocale.value = DEFAULT_LANGUAGE - userSettings.value.language = cookieLocale.value + if (!userSettings.value.language || !supportLanguages.includes(userSettings.value.language)) + userSettings.value.language = DEFAULT_LANGUAGE watch(() => userSettings.value.language, (lang) => { - if (lang !== cookieLocale.value) - cookieLocale.value = lang if (lang !== i18n.locale) setLocale(lang) }, { immediate: true })