mirror of
https://github.com/modrinth/code.git
synced 2026-09-01 12:36:44 +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:
@@ -41,6 +41,7 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { useAppServerBrowse } from '@/composables/browse/use-app-server-browse'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { get_project, get_search_results_v3, get_version_many } from '@/helpers/cache.js'
|
||||
import {
|
||||
get_installed_project_ids as getInstalledProjectIds,
|
||||
@@ -63,7 +64,6 @@ import {
|
||||
createServerInstallContent,
|
||||
provideServerInstallContent,
|
||||
} from '@/providers/setup/server-install-content'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -109,7 +109,7 @@ const breadcrumbLabel = computed(() => {
|
||||
),
|
||||
})
|
||||
})
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const browseRouteActive = computed(() => route.path.startsWith('/browse/'))
|
||||
const serverSetupModalRef = ref<InstanceType<typeof CreationFlowModal> | null>(null)
|
||||
const serverInstallContent = createServerInstallContent({ serverSetupModalRef })
|
||||
@@ -384,7 +384,7 @@ async function initInstanceContext() {
|
||||
}
|
||||
|
||||
function setBrowseHideInstalledFlag(flag: 'hide_installed_modpacks', value: boolean) {
|
||||
themeStore.featureFlags[flag] = value
|
||||
appSettings.featureFlags[flag] = value
|
||||
getSettings()
|
||||
.then((settings) => {
|
||||
settings.feature_flags[flag] = value
|
||||
@@ -394,7 +394,7 @@ function setBrowseHideInstalledFlag(flag: 'hide_installed_modpacks', value: bool
|
||||
}
|
||||
|
||||
const hideInstalledModpacks = computed({
|
||||
get: () => themeStore.getFeatureFlag('hide_installed_modpacks'),
|
||||
get: () => appSettings.getFeatureFlag('hide_installed_modpacks'),
|
||||
set: (value: boolean) => setBrowseHideInstalledFlag('hide_installed_modpacks', value),
|
||||
})
|
||||
|
||||
@@ -742,7 +742,7 @@ const installContext = computed(() => {
|
||||
queuedCount: queuedServerInstallCount.value,
|
||||
selectedProjects: selectedServerInstallProjects.value,
|
||||
isInstallingSelected: isInstallingQueuedServerInstalls.value,
|
||||
skipNonEssentialWarnings: themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
skipNonEssentialWarnings: appSettings.getFeatureFlag('skip_non_essential_warnings'),
|
||||
installProgress: queuedInstallProgress.value,
|
||||
clearQueued: clearQueuedServerInstalls,
|
||||
clearSelected: clearQueuedServerInstalls,
|
||||
@@ -1222,9 +1222,9 @@ function getProjectBrowseQuery() {
|
||||
}
|
||||
|
||||
const advancedFiltersCollapsed = computed({
|
||||
get: () => themeStore.getFeatureFlag('advanced_filters_collapsed'),
|
||||
get: () => appSettings.getFeatureFlag('advanced_filters_collapsed'),
|
||||
set: (value) => {
|
||||
themeStore.featureFlags['advanced_filters_collapsed'] = value
|
||||
appSettings.featureFlags['advanced_filters_collapsed'] = value
|
||||
getSettings()
|
||||
.then((settings) => {
|
||||
settings.feature_flags['advanced_filters_collapsed'] = value
|
||||
@@ -1235,9 +1235,9 @@ const advancedFiltersCollapsed = computed({
|
||||
})
|
||||
|
||||
const dismissedPhotosensitivityFilterWarning = computed({
|
||||
get: () => themeStore.getFeatureFlag('dismissed_photosensitivity_filter_warning'),
|
||||
get: () => appSettings.getFeatureFlag('dismissed_photosensitivity_filter_warning'),
|
||||
set: (value) => {
|
||||
themeStore.featureFlags['dismissed_photosensitivity_filter_warning'] = value
|
||||
appSettings.featureFlags['dismissed_photosensitivity_filter_warning'] = value
|
||||
getSettings()
|
||||
.then((settings) => {
|
||||
settings.feature_flags['dismissed_photosensitivity_filter_warning'] = value
|
||||
|
||||
@@ -9,12 +9,12 @@ import LibrarySection from '@/components/ui/library/index.vue'
|
||||
import WelcomeScreen from '@/components/ui/WelcomeScreen.vue'
|
||||
import RecentWorldsList from '@/components/ui/world/RecentWorldsList.vue'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import { list } from '@/helpers/instance'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { useRootBreadcrumb } from '@/providers/breadcrumbs'
|
||||
import { injectOnboardingChecklist } from '@/providers/onboarding-checklist'
|
||||
import { useTheming } from '@/store/theme.ts'
|
||||
|
||||
defineOptions({
|
||||
name: 'LibraryPage',
|
||||
@@ -25,7 +25,7 @@ const { formatMessage } = useVIntl()
|
||||
const { hasCreatedInstance, isReady } = injectOnboardingChecklist()
|
||||
const showCreationModal = inject<() => void>('showCreationModal')
|
||||
const pageOptions = ref<InstanceType<typeof ContextMenu>>()
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
|
||||
const messages = defineMessages({
|
||||
home: {
|
||||
@@ -106,7 +106,7 @@ function handlePageOption({ option }: { option: string }) {
|
||||
@contextmenu="openPageContextMenu"
|
||||
>
|
||||
<RecentWorldsList
|
||||
v-if="recentInstances?.length > 0 && themeStore.getFeatureFlag('worlds_in_home')"
|
||||
v-if="recentInstances?.length > 0 && appSettings.getFeatureFlag('worlds_in_home')"
|
||||
:recent-instances="recentInstances"
|
||||
/>
|
||||
<LibrarySection :instances="instances" />
|
||||
|
||||
@@ -32,6 +32,8 @@ import EarsModIcon from '@/assets/skins/ears-mod.png'
|
||||
import type AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue'
|
||||
import VirtualSkinSectionList from '@/components/ui/skin/VirtualSkinSectionList.vue'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { handleSevereError } from '@/composables/use-error.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { check_reachable, get_default_user, login as login_flow, users } from '@/helpers/auth'
|
||||
import type { RenderResult } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
@@ -58,8 +60,6 @@ import {
|
||||
} from '@/helpers/skins.ts'
|
||||
import { hasPride26Badge } from '@/helpers/user-campaigns.ts'
|
||||
import { useRootBreadcrumb } from '@/providers/breadcrumbs'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import { useTheming } from '@/store/state'
|
||||
import { appMessages } from '@/utils/app-messages'
|
||||
|
||||
useRootBreadcrumb({
|
||||
@@ -217,7 +217,7 @@ const { addNotification, handleError } = notifications
|
||||
const auth = injectAuth()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const skins = ref<Skin[]>([])
|
||||
const capes = ref<Cape[]>([])
|
||||
const offline = ref(!navigator.onLine)
|
||||
@@ -339,7 +339,7 @@ const skinTexture = computedAsync(async () => {
|
||||
})
|
||||
const capeTexture = computed(() => currentCape.value?.texture)
|
||||
const skinVariant = computed(() => selectedSkin.value?.variant)
|
||||
const skinNametag = computed(() => (themeStore.hideNametagSkinsPage ? undefined : username.value))
|
||||
const skinNametag = computed(() => (appSettings.hideNametagSkinsPage ? undefined : username.value))
|
||||
const isSkinManagementReadOnly = computed(
|
||||
() =>
|
||||
!!currentUser.value &&
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:layout-mode="isContainedServerRoute ? 'contained' : 'page'"
|
||||
:reload-page="() => router.go(0)"
|
||||
:resolve-viewer="resolveViewer"
|
||||
:show-copy-id-action="themeStore.devMode"
|
||||
:show-copy-id-action="appSettings.devMode"
|
||||
:auth-user="authUser"
|
||||
:navigate-to-billing="() => openUrl('https://modrinth.com/settings/billing')"
|
||||
:navigate-to-servers="() => router.push('/hosting/manage')"
|
||||
@@ -61,17 +61,17 @@ import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { get_user } from '@/helpers/cache'
|
||||
import { get as getCreds } from '@/helpers/mr_auth'
|
||||
import { provideBreadcrumbParent, useBreadcrumb } from '@/providers/breadcrumbs'
|
||||
import { useTheming } from '@/store/theme'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const auth = injectAuth()
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const isContainedServerRoute = computed(() => route.name === 'ServerManageOverview')
|
||||
|
||||
+3
-3
@@ -16,6 +16,7 @@ import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useManagedContentPolicy } from '@/composables/instances/use-managed-content-policy'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_versions, get_version } from '@/helpers/cache'
|
||||
import {
|
||||
@@ -34,7 +35,6 @@ import { get_loader_versions } from '@/helpers/metadata'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import { injectAppEvents } from '@/providers/app-events'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
import type { Manifest } from '../../../../helpers/types'
|
||||
import { instanceKeys } from '../../query-options.ts'
|
||||
@@ -47,12 +47,12 @@ const filePicker = injectFilePicker()
|
||||
const { formatMessage } = useVIntl()
|
||||
const queryClient = useQueryClient()
|
||||
const debug = useDebugLogger('AppInstallationSettings')
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
|
||||
const { instance, offline, isMinecraftServer, onUnlinked, closeModal } = injectInstanceSettings()
|
||||
const managedContentPolicy = useManagedContentPolicy(instance)
|
||||
const skipNonEssentialWarnings = computed(() =>
|
||||
themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
appSettings.getFeatureFlag('skip_non_essential_warnings'),
|
||||
)
|
||||
|
||||
debug('metadata load: start', {
|
||||
|
||||
@@ -127,6 +127,7 @@ import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
import { useManagedContentPolicy } from '@/composables/instances/use-managed-content-policy'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { type FeatureFlag, useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_versions, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import {
|
||||
@@ -149,8 +150,6 @@ import type { CacheBehaviour } from '@/helpers/types'
|
||||
import { highlightModInInstance } from '@/helpers/utils.js'
|
||||
import { type AppEventPayload, injectAppEvents } from '@/providers/app-events'
|
||||
import { injectContentInstall } from '@/providers/content-install'
|
||||
import { useTheming } from '@/store/state'
|
||||
import type { FeatureFlag } from '@/store/theme'
|
||||
|
||||
import { injectInstancePage } from '../instance-context'
|
||||
import { instanceContentQueryOptions, instanceKeys } from '../query-options'
|
||||
@@ -234,10 +233,10 @@ const { installingItems, installRevisionByInstance, installFailureRevisionByInst
|
||||
const router = useRouter()
|
||||
const queryClient = useQueryClient()
|
||||
const debug = useDebugLogger('Mods:ContentUpdate')
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const skipUnknownFileWarningFeatureFlag = 'skip_unknown_pack_warning' as FeatureFlag
|
||||
const skipNonEssentialWarnings = computed(() =>
|
||||
themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
appSettings.getFeatureFlag('skip_non_essential_warnings'),
|
||||
)
|
||||
|
||||
const instancePage = injectInstancePage()
|
||||
@@ -759,7 +758,7 @@ async function handleUploadFiles() {
|
||||
}
|
||||
|
||||
function confirmUnknownFileInstallation(fileName: string) {
|
||||
if (themeStore.getFeatureFlag(skipUnknownFileWarningFeatureFlag)) {
|
||||
if (appSettings.getFeatureFlag(skipUnknownFileWarningFeatureFlag)) {
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
|
||||
@@ -779,7 +778,7 @@ function resolveUnknownFileWarning(confirmed: boolean) {
|
||||
|
||||
async function handleUnknownFileContinue(dontShowAgain: boolean) {
|
||||
if (dontShowAgain) {
|
||||
themeStore.featureFlags[skipUnknownFileWarningFeatureFlag] = true
|
||||
appSettings.featureFlags[skipUnknownFileWarningFeatureFlag] = true
|
||||
try {
|
||||
const settings = await getSettings()
|
||||
settings.feature_flags[skipUnknownFileWarningFeatureFlag] = true
|
||||
|
||||
@@ -133,6 +133,8 @@ import {
|
||||
getFreshCachedServerStatus,
|
||||
} from '@/composables/instances/use-server-status-query'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { handleSevereError } from '@/composables/use-error.js'
|
||||
import { useInstanceConsole } from '@/composables/useInstanceConsole'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { toError } from '@/helpers/errors'
|
||||
@@ -159,8 +161,6 @@ import type { ServerStatus } from '@/helpers/worlds'
|
||||
import { useRootBreadcrumb } from '@/providers/breadcrumbs'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
import { injectServerInstall } from '@/providers/server-install'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
import InstanceAdmonitions from './components/admonitions/index.vue'
|
||||
import InstancePageHeader from './components/page-header/index.vue'
|
||||
@@ -216,8 +216,8 @@ watch(
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
const themeStore = useTheming()
|
||||
const showInstancePlayTime = computed(() => themeStore.getFeatureFlag('show_instance_play_time'))
|
||||
const appSettings = useAppSettings()
|
||||
const showInstancePlayTime = computed(() => appSettings.getFeatureFlag('show_instance_play_time'))
|
||||
|
||||
const online = useOnline()
|
||||
const offline = computed(() => !online.value)
|
||||
|
||||
@@ -157,6 +157,7 @@ import EditServerModal from '@/components/ui/world/modal/EditServerModal.vue'
|
||||
import EditWorldModal from '@/components/ui/world/modal/EditSingleplayerWorldModal.vue'
|
||||
import WorldItem from '@/components/ui/world/WorldItem.vue'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { handleSevereError } from '@/composables/use-error.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project, get_project_v3 } from '@/helpers/cache.js'
|
||||
import { get_game_versions } from '@/helpers/tags'
|
||||
@@ -186,7 +187,6 @@ import {
|
||||
type World,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import { injectServerInstall } from '@/providers/server-install'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
|
||||
import { injectInstancePage } from '../instance-context'
|
||||
import { instanceKeys, instanceWorldsQueryOptions } from '../query-options'
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<InstanceIndicator v-if="instance && !projectInstallContext" :instance="instance" />
|
||||
<template v-if="data">
|
||||
<Teleport
|
||||
v-if="themeStore.featureFlags.project_background"
|
||||
v-if="appSettings.featureFlags.project_background"
|
||||
to="#background-teleport-target"
|
||||
>
|
||||
<ProjectBackgroundGradient :project="data" />
|
||||
@@ -294,6 +294,7 @@ import {
|
||||
getFreshCachedServerStatus,
|
||||
} from '@/composables/instances/use-server-status-query'
|
||||
import { useAppEvent } from '@/composables/use-app-event'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import {
|
||||
get_organization,
|
||||
get_project,
|
||||
@@ -317,7 +318,6 @@ import { provideBreadcrumbParent, useBreadcrumb } from '@/providers/breadcrumbs'
|
||||
import { injectContentInstall } from '@/providers/content-install'
|
||||
import { injectServerInstall } from '@/providers/server-install'
|
||||
import { createServerInstallContent } from '@/providers/setup/server-install-content'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
@@ -348,7 +348,7 @@ const projectBreadcrumbTo = computed(() => {
|
||||
return currentRoute.fullPath
|
||||
})
|
||||
const queryClient = useQueryClient()
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const messages = defineMessages({
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:game-versions="gameVersions"
|
||||
:versions="versions"
|
||||
:project="project"
|
||||
:show-environment-column="themeStore.featureFlags.show_version_environment_column"
|
||||
:show-environment-column="appSettings.featureFlags.show_version_environment_column"
|
||||
:version-link="(version) => buildProjectHref(`/project/${project.id}/version/${version.id}`)"
|
||||
>
|
||||
<template #actions="{ version }">
|
||||
@@ -63,11 +63,11 @@ import { ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { SwapIcon } from '@/assets/icons/index.js'
|
||||
import { useAppSettings } from '@/composables/use-app-settings.ts'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
|
||||
import { useTheming } from '@/store/theme.ts'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const themeStore = useTheming()
|
||||
const appSettings = useAppSettings()
|
||||
|
||||
const messages = defineMessages({
|
||||
alreadyInstalled: {
|
||||
|
||||
Reference in New Issue
Block a user