mirror of
https://github.com/modrinth/code.git
synced 2026-08-28 10:34:53 +00:00
feat: preferences syncing frontend (#7192)
* feat: prefs frontend * fix: DI issue * fix: lint * feat: appearance settings cleanup + fix settings, remove pinia * fix: sync btn when logged out * fix: prepr * fix: sidebar issue * feat: language coverage + cleanup * feat: cleanup lang settings * fix: fmt * fix: CI * fix: ci * fix: storybook * feat: bring back loader/game version sort --------- Co-authored-by: tdgao <mr.trumgao@gmail.com>
This commit is contained in:
@@ -94,6 +94,9 @@ import SurveyPopup from '@/components/ui/SurveyPopup.vue'
|
||||
import WindowControls from '@/components/ui/WindowControls.vue'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { useError } from '@/composables/use-error.js'
|
||||
import { useTheme } from '@/composables/use-theme.ts'
|
||||
import { config } from '@/config'
|
||||
import {
|
||||
hide_ads_window,
|
||||
@@ -147,8 +150,7 @@ import { setupProviders } from '@/providers/setup'
|
||||
import { setupAppEventsProvider } from '@/providers/setup/app-events'
|
||||
import { setupAuthProvider } from '@/providers/setup/auth'
|
||||
import { setupLoadingStateProvider } from '@/providers/setup/loading-state'
|
||||
import { useError } from '@/store/error.js'
|
||||
import { useTheming } from '@/store/state'
|
||||
import { setupAppUserPreferencesProvider } from '@/providers/setup/user-preferences.ts'
|
||||
import { appMessages } from '@/utils/app-messages'
|
||||
|
||||
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
||||
@@ -157,7 +159,8 @@ import { AppNotificationManager } from './providers/app-notifications'
|
||||
import { AppPopupNotificationManager } from './providers/app-popup-notifications'
|
||||
import { appSettingsModalOpenProfileKey } from './providers/app-settings-modal'
|
||||
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const appTheme = useTheme()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { channel: appEventChannel, events: appEvents } = setupAppEventsProvider()
|
||||
@@ -201,7 +204,7 @@ const credentials = ref()
|
||||
let credentialsRefreshId = 0
|
||||
const sidebarToggled = ref(true)
|
||||
watch(
|
||||
() => themeStore.toggleSidebar,
|
||||
() => appSettings.toggleSidebar,
|
||||
(toggleSidebar) => {
|
||||
sidebarToggled.value = !toggleSidebar
|
||||
},
|
||||
@@ -221,7 +224,7 @@ const hostingUpdateRequired = computed(
|
||||
appUpdateState.updatesEnabled.value,
|
||||
)
|
||||
const prideFundraiserEnabled = computed(
|
||||
() => themeStore.getFeatureFlag('pride_fundraiser') && Date.now() < PRIDE_FUNDRAISER_END_DATE,
|
||||
() => appSettings.getFeatureFlag('pride_fundraiser') && Date.now() < PRIDE_FUNDRAISER_END_DATE,
|
||||
)
|
||||
const hostingIntercomIdentityKey = computed(() => {
|
||||
const rawServerId = route.params.id
|
||||
@@ -324,13 +327,13 @@ providePageContext({
|
||||
intercomBubble: hostingIntercom.intercomBubble,
|
||||
featureFlags: {
|
||||
serverRamAsBytesAlwaysOn: computed(() =>
|
||||
themeStore.getFeatureFlag('server_ram_as_bytes_always_on'),
|
||||
appSettings.getFeatureFlag('server_ram_as_bytes_always_on'),
|
||||
),
|
||||
},
|
||||
openExternalUrl: (url) => void openUrl(url),
|
||||
})
|
||||
provideModalBehavior({
|
||||
noblur: computed(() => !themeStore.advancedRendering),
|
||||
noblur: computed(() => !appTheme.advancedRendering),
|
||||
onShow: () => take_ads_window_hold(),
|
||||
onHide: () => release_ads_window_hold(),
|
||||
})
|
||||
@@ -634,10 +637,11 @@ async function setupApp() {
|
||||
theme,
|
||||
locale,
|
||||
telemetry,
|
||||
collapsed_navigation,
|
||||
hide_nametag_skins_page,
|
||||
advanced_rendering,
|
||||
toggle_sidebar,
|
||||
sync_theme_across_devices,
|
||||
sync_behavior_across_devices,
|
||||
developer_mode,
|
||||
feature_flags,
|
||||
pending_update_toast_for_version,
|
||||
@@ -655,13 +659,14 @@ async function setupApp() {
|
||||
nativeDecorations.value = native_decorations
|
||||
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
|
||||
|
||||
themeStore.setThemeState(theme)
|
||||
themeStore.collapsedNavigation = collapsed_navigation
|
||||
themeStore.advancedRendering = advanced_rendering
|
||||
themeStore.hideNametagSkinsPage = hide_nametag_skins_page
|
||||
themeStore.toggleSidebar = toggle_sidebar
|
||||
themeStore.devMode = developer_mode
|
||||
themeStore.featureFlags = feature_flags
|
||||
appTheme.preferred = theme
|
||||
appTheme.advancedRendering = advanced_rendering
|
||||
appTheme.syncAcrossDevices = sync_theme_across_devices
|
||||
appSettings.syncBehaviorAcrossDevices = sync_behavior_across_devices
|
||||
appSettings.hideNametagSkinsPage = hide_nametag_skins_page
|
||||
appSettings.toggleSidebar = toggle_sidebar
|
||||
appSettings.devMode = developer_mode
|
||||
Object.assign(appSettings.featureFlags, feature_flags)
|
||||
stateInitialized.value = true
|
||||
|
||||
isMaximized.value = await getCurrentWindow().isMaximized()
|
||||
@@ -959,7 +964,7 @@ watch(incompatibilityWarningModal, (modal) => {
|
||||
}
|
||||
})
|
||||
|
||||
setupAuthProvider(credentials, async (_redirectPath, flow, options) => {
|
||||
const authProvider = setupAuthProvider(credentials, async (_redirectPath, flow, options) => {
|
||||
if (options?.showModal === false) {
|
||||
await signIn(flow)
|
||||
} else {
|
||||
@@ -967,6 +972,79 @@ setupAuthProvider(credentials, async (_redirectPath, flow, options) => {
|
||||
}
|
||||
})
|
||||
|
||||
const userPreferences = setupAppUserPreferencesProvider(authProvider, notificationManager)
|
||||
let userPreferencesSync = Promise.resolve()
|
||||
|
||||
watch(
|
||||
[userPreferences.preferences, stateInitialized],
|
||||
([preferences, initialized]) => {
|
||||
if (!preferences || !initialized) return
|
||||
|
||||
userPreferencesSync = userPreferencesSync
|
||||
.then(async () => {
|
||||
const settings = await getSettings()
|
||||
const selectedTheme = preferences.appearance.auto ? 'system' : preferences.appearance.theme
|
||||
const locale = preferences.localization.locale
|
||||
const behavior = preferences.behavior
|
||||
let settingsChanged = false
|
||||
|
||||
if (appTheme.syncAcrossDevices && appTheme.preferred !== selectedTheme) {
|
||||
appTheme.preferred = selectedTheme
|
||||
}
|
||||
if (i18n.global.locale.value !== locale) {
|
||||
i18n.global.locale.value = locale
|
||||
}
|
||||
|
||||
if (appTheme.syncAcrossDevices && settings.theme !== selectedTheme) {
|
||||
settings.theme = selectedTheme
|
||||
settingsChanged = true
|
||||
}
|
||||
if (settings.locale !== locale) {
|
||||
settings.locale = locale
|
||||
settingsChanged = true
|
||||
}
|
||||
|
||||
if (behavior && appSettings.syncBehaviorAcrossDevices) {
|
||||
const behaviorFeatureFlags = {
|
||||
worlds_in_home: behavior.show_jump_in,
|
||||
show_instance_play_time: behavior.show_play_time,
|
||||
skip_unknown_pack_warning: !behavior.warn_on_unknown_modpacks,
|
||||
skip_non_essential_warnings: behavior.skip_non_essential_warnings,
|
||||
}
|
||||
|
||||
appSettings.toggleSidebar = behavior.hide_right_sidebar
|
||||
appSettings.hideNametagSkinsPage = behavior.hide_nametag
|
||||
Object.assign(appSettings.featureFlags, behaviorFeatureFlags)
|
||||
|
||||
if (settings.hide_on_process_start !== behavior.minimize_app) {
|
||||
settings.hide_on_process_start = behavior.minimize_app
|
||||
settingsChanged = true
|
||||
}
|
||||
if (settings.toggle_sidebar !== behavior.hide_right_sidebar) {
|
||||
settings.toggle_sidebar = behavior.hide_right_sidebar
|
||||
settingsChanged = true
|
||||
}
|
||||
if (settings.hide_nametag_skins_page !== behavior.hide_nametag) {
|
||||
settings.hide_nametag_skins_page = behavior.hide_nametag
|
||||
settingsChanged = true
|
||||
}
|
||||
for (const [flag, value] of Object.entries(behaviorFeatureFlags)) {
|
||||
if (settings.feature_flags[flag] !== value) {
|
||||
settings.feature_flags[flag] = value
|
||||
settingsChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsChanged) {
|
||||
await setSettings(settings)
|
||||
}
|
||||
})
|
||||
.catch(handleError)
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
async function validateSession(sessionToken) {
|
||||
try {
|
||||
const response = await tauriFetch(`${config.labrinthBaseUrl}/v2/user`, {
|
||||
@@ -1642,7 +1720,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<div
|
||||
v-if="stateInitialized"
|
||||
class="app-grid-layout relative"
|
||||
:class="{ 'disable-advanced-rendering': !themeStore.advancedRendering }"
|
||||
:class="{ 'disable-advanced-rendering': !appTheme.advancedRendering }"
|
||||
>
|
||||
<Transition name="fade">
|
||||
<div
|
||||
@@ -1828,7 +1906,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
</div>
|
||||
<section data-tauri-drag-region class="flex shrink-0 ml-auto items-center">
|
||||
<IconButton
|
||||
v-if="!forceSidebar && themeStore.toggleSidebar"
|
||||
v-if="!forceSidebar && appSettings.toggleSidebar"
|
||||
:type="sidebarToggled ? 'base' : 'quiet'"
|
||||
:label="formatMessage(messages.nextImage)"
|
||||
class="mr-3 transition-transform"
|
||||
@@ -1851,7 +1929,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
class="app-contents"
|
||||
:class="{
|
||||
'sidebar-enabled': sidebarVisible,
|
||||
'disable-advanced-rendering': !themeStore.advancedRendering,
|
||||
'disable-advanced-rendering': !appTheme.advancedRendering,
|
||||
}"
|
||||
>
|
||||
<div class="app-viewport flex-grow router-view">
|
||||
@@ -1867,7 +1945,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<LoadingBar position="absolute" />
|
||||
</div>
|
||||
<div
|
||||
v-if="themeStore.featureFlags.page_path"
|
||||
v-if="appSettings.featureFlags.page_path"
|
||||
class="absolute bottom-0 left-0 m-2 bg-tooltip-bg text-tooltip-text font-semibold rounded-full px-2 py-1 text-xs z-50"
|
||||
>
|
||||
{{ route.fullPath }}
|
||||
|
||||
Reference in New Issue
Block a user