import { useThemeOverrideState } from '@/composables/theming' // AUTH export const useIsLoggedIn = () => { const isLoggedIn = useState( 'isLoggedIn', () => localStorage.getItem('isLoggedIn') === 'true', ) return computed({ get: () => isLoggedIn.value, set: (value) => { isLoggedIn.value = value localStorage.setItem('isLoggedIn', value.toString()) }, }) } // LOCALE const usePreferedLocaleState = () => useState( 'preferedLocale', () => localStorage.getItem('preferedLocale') || 'auto', ) export const usePreferedLocale = () => { const preferedLocale = usePreferedLocaleState() const { locale, getBrowserLocale, defaultLocale } = useNuxtApp().$i18n return computed({ get: () => preferedLocale.value, set: (value) => { preferedLocale.value = value localStorage.setItem('preferedLocale', value) if (value === 'auto') { const browserLocale = getBrowserLocale() value = browserLocale || defaultLocale } locale.value = value }, }) } // THEME const usePreferedThemeState = () => useState( 'preferedTheme', () => localStorage.getItem('preferedTheme') || 'auto', ) export const usePreferedTheme = async () => { const preferedTheme = usePreferedThemeState() const colorMode = useColorMode() const settings = await useSettings() return computed({ get: () => preferedTheme.value, set: (value) => { preferedTheme.value = value localStorage.setItem('preferedTheme', value) if (value === 'auto') { value = settings.value.portal_theme } colorMode.preference = value }, }) } export const useRedirectUrl = () => useState('redirectUrl', () => null) export const useQueryMsg = () => useState('queryMsg', () => null) // SETTINGS type AppsSettings = Record< string, { label: string url: string description?: Record logo?: string } > export interface Settings { domain: string public: boolean portal_logo?: { is: 'img' | 'svg'; src: string } portal_theme: string portal_title?: string search_engine?: string search_engine_name?: string show_other_domains_apps: 0 | 1 portal_user_intro: string portal_public_intro: string apps: AppsSettings } const useSettingsState = () => useState('settings') export const useSettings = async () => { const settings = useSettingsState() if (!settings.value) { const { data } = await useApi('/public') const logo = data.value!.portal_logo as unknown as string | undefined if (logo) { const src = `https://${data.value.domain}/yunohost/sso/customassets/${logo}` const is = logo.slice(-4) === '.svg' ? 'svg' : 'img' data.value!.portal_logo = { is, src: is === 'svg' ? '' : src } if (is === 'svg') { // Query file content to inject inline SVG so that CSS "currentColor" can cascade to it $fetch(src) .then((blob) => blob.text()) .then((text) => { data.value!.portal_logo!.src = text.replace( '', '', ) }) } } settings.value = data.value as Settings const colorMode = useColorMode() colorMode.preference = settings.value.portal_theme const themeOverride = useThemeOverrideState() if (themeOverride.value) { useThemeOverride().init(themeOverride.value) } } return settings } // USER export interface User { username: string fullname: string mail: string mailalias: string[] mailforward: string[] groups: string[] apps: AppsSettings } export const useUserState = () => useState('user', () => null) export const useUser = async () => { const user = useUserState() const isLoggedIn = useIsLoggedIn() if (!user.value && isLoggedIn.value) { const { data } = await useApi('/me') user.value = data.value } return user as Ref } // APP export const useApps = async () => { const isLoggedIn = useIsLoggedIn() const settings = await useSettings() const user = await useUser() return computed(() => { return isLoggedIn.value ? user.value?.apps : settings.value.apps }) }