This commit is contained in:
pa
2026-03-19 16:58:59 +09:00
parent cb7d6b78b3
commit 4eb781eaff
4 changed files with 172 additions and 100 deletions
@@ -2,12 +2,7 @@
<div class="flex flex-col" style="min-height: 200px"> <div class="flex flex-col" style="min-height: 200px">
<div style="display: flex; align-items: center; justify-content: space-between"> <div style="display: flex; align-items: center; justify-content: space-between">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<Button <Button class="rounded-full" variant="ghost" size="icon-sm" :disabled="isLoading" @click="loadData">
class="rounded-full"
variant="ghost"
size="icon-sm"
:disabled="isLoading"
@click="loadData">
<Spinner v-if="isLoading" /> <Spinner v-if="isLoading" />
<RefreshCw v-else /> <RefreshCw v-else />
</Button> </Button>
@@ -44,15 +39,16 @@
<div v-if="!isLoading && !hasAnyData" class="flex items-center justify-center flex-1 mt-8"> <div v-if="!isLoading && !hasAnyData" class="flex items-center justify-center flex-1 mt-8">
<DataTableEmpty type="nodata" /> <DataTableEmpty type="nodata" />
</div> </div>
<div v-if="!isLoading && hasAnyData && filteredEventCount === 0" class="flex items-center justify-center flex-1 mt-8"> <div
v-if="!isLoading && hasAnyData && filteredEventCount === 0"
class="flex items-center justify-center flex-1 mt-8">
<span class="text-muted-foreground text-sm">{{ t('dialog.user.activity.no_data_in_period') }}</span> <span class="text-muted-foreground text-sm">{{ t('dialog.user.activity.no_data_in_period') }}</span>
</div> </div>
<div <div
v-show="filteredEventCount > 0" v-show="filteredEventCount > 0"
ref="chartRef" ref="chartRef"
style="width: 100%; height: 240px" style="width: 100%; height: 240px"
@contextmenu.prevent="onChartRightClick"> @contextmenu.prevent="onChartRightClick"></div>
</div>
<!-- Online Overlap Section --> <!-- Online Overlap Section -->
<div v-if="hasAnyData" class="mt-4 border-t border-border pt-3"> <div v-if="hasAnyData" class="mt-4 border-t border-border pt-3">
@@ -62,16 +58,12 @@
<Spinner v-if="isOverlapLoading" class="h-3.5 w-3.5" /> <Spinner v-if="isOverlapLoading" class="h-3.5 w-3.5" />
</div> </div>
<div v-if="hasOverlapData" class="flex items-center gap-1.5 flex-shrink-0"> <div v-if="hasOverlapData" class="flex items-center gap-1.5 flex-shrink-0">
<Switch <Switch :model-value="excludeHoursEnabled" class="scale-75" @update:model-value="onExcludeToggle" />
:model-value="excludeHoursEnabled" <span class="text-sm text-muted-foreground whitespace-nowrap">{{
class="scale-75" t('dialog.user.activity.overlap.exclude_hours')
@update:model-value="onExcludeToggle" /> }}</span>
<span class="text-sm text-muted-foreground whitespace-nowrap">{{ t('dialog.user.activity.overlap.exclude_hours') }}</span>
<Select v-model="excludeStartHour" @update:model-value="onExcludeRangeChange"> <Select v-model="excludeStartHour" @update:model-value="onExcludeRangeChange">
<SelectTrigger <SelectTrigger size="sm" class="w-[78px] h-6 text-xs px-2" @click.stop>
size="sm"
class="w-[78px] h-6 text-xs px-2"
@click.stop>
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
@@ -82,10 +74,7 @@
</Select> </Select>
<span class="text-xs text-muted-foreground"></span> <span class="text-xs text-muted-foreground"></span>
<Select v-model="excludeEndHour" @update:model-value="onExcludeRangeChange"> <Select v-model="excludeEndHour" @update:model-value="onExcludeRangeChange">
<SelectTrigger <SelectTrigger size="sm" class="w-[78px] h-6 text-xs px-2" @click.stop>
size="sm"
class="w-[78px] h-6 text-xs px-2"
@click.stop>
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
@@ -99,7 +88,9 @@
<div v-if="!isOverlapLoading && hasOverlapData" class="flex flex-col gap-1 mb-2"> <div v-if="!isOverlapLoading && hasOverlapData" class="flex flex-col gap-1 mb-2">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class="text-sm font-medium" :class="overlapPercent > 0 ? 'text-accent-foreground' : 'text-muted-foreground'"> <span
class="text-sm font-medium"
:class="overlapPercent > 0 ? 'text-accent-foreground' : 'text-muted-foreground'">
{{ overlapPercent }}% {{ overlapPercent }}%
</span> </span>
<div class="flex-1 h-2 rounded-full bg-muted overflow-hidden"> <div class="flex-1 h-2 rounded-full bg-muted overflow-hidden">
@@ -207,7 +198,7 @@
dayLabels.value[4], // Thu dayLabels.value[4], // Thu
dayLabels.value[5], // Fri dayLabels.value[5], // Fri
dayLabels.value[6], // Sat dayLabels.value[6], // Sat
dayLabels.value[0] // Sun dayLabels.value[0] // Sun
]); ]);
const hourLabels = Array.from({ length: 24 }, (_, i) => `${String(i).padStart(2, '0')}:00`); const hourLabels = Array.from({ length: 24 }, (_, i) => `${String(i).padStart(2, '0')}:00`);
@@ -218,11 +209,7 @@
echartsInstance = null; echartsInstance = null;
if (hasAnyData.value && chartRef.value) { if (hasAnyData.value && chartRef.value) {
nextTick(() => { nextTick(() => {
echartsInstance = echarts.init( echartsInstance = echarts.init(chartRef.value, isDarkMode.value ? 'dark' : null, { height: 240 });
chartRef.value,
isDarkMode.value ? 'dark' : null,
{ height: 240 }
);
initChart(); initChart();
}); });
} }
@@ -232,11 +219,9 @@
overlapEchartsInstance = null; overlapEchartsInstance = null;
if (hasOverlapData.value && overlapChartRef.value) { if (hasOverlapData.value && overlapChartRef.value) {
nextTick(() => { nextTick(() => {
overlapEchartsInstance = echarts.init( overlapEchartsInstance = echarts.init(overlapChartRef.value, isDarkMode.value ? 'dark' : null, {
overlapChartRef.value, height: 240
isDarkMode.value ? 'dark' : null, });
{ height: 240 }
);
updateOverlapChart(); updateOverlapChart();
}); });
} }
@@ -495,11 +480,7 @@
await nextTick(); await nextTick();
if (!echartsInstance && chartRef.value) { if (!echartsInstance && chartRef.value) {
echartsInstance = echarts.init( echartsInstance = echarts.init(chartRef.value, isDarkMode.value ? 'dark' : null, { height: 240 });
chartRef.value,
isDarkMode.value ? 'dark' : null,
{ height: 240 }
);
resizeObserver = new ResizeObserver((entries) => { resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) { for (const entry of entries) {
if (echartsInstance) { if (echartsInstance) {
@@ -561,11 +542,10 @@
function onOverlapChartRightClick() { function onOverlapChartRightClick() {
if (easterEggTimer) { if (easterEggTimer) {
toast('You can\'t farm this.', { position: 'bottom-center', icon: h(Sprout) }); toast(t('dialog.user.activity.easter_egg_reply'), { position: 'bottom-center', icon: h(Sprout) });
} }
} }
async function loadOverlapData(userId) { async function loadOverlapData(userId) {
if (!userId) return; if (!userId) return;
@@ -590,11 +570,9 @@
await nextTick(); await nextTick();
if (!overlapEchartsInstance && overlapChartRef.value) { if (!overlapEchartsInstance && overlapChartRef.value) {
overlapEchartsInstance = echarts.init( overlapEchartsInstance = echarts.init(overlapChartRef.value, isDarkMode.value ? 'dark' : null, {
overlapChartRef.value, height: 240
isDarkMode.value ? 'dark' : null, });
{ height: 240 }
);
overlapResizeObserver = new ResizeObserver((entries) => { overlapResizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) { for (const entry of entries) {
if (overlapEchartsInstance) { if (overlapEchartsInstance) {
@@ -69,7 +69,10 @@
@click="showAvatarDialog(avatar.id)"> @click="showAvatarDialog(avatar.id)">
<div class="relative inline-block flex-none size-9 mr-2.5"> <div class="relative inline-block flex-none size-9 mr-2.5">
<Avatar class="size-9"> <Avatar class="size-9">
<AvatarImage v-if="avatar.thumbnailImageUrl" :src="avatar.thumbnailImageUrl" class="object-cover" /> <AvatarImage
v-if="avatar.thumbnailImageUrl"
:src="avatar.thumbnailImageUrl"
class="object-cover" />
<AvatarFallback> <AvatarFallback>
<Image class="size-4 text-muted-foreground" /> <Image class="size-4 text-muted-foreground" />
</AvatarFallback> </AvatarFallback>
@@ -112,6 +115,7 @@
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Spinner } from '@/components/ui/spinner'; import { Spinner } from '@/components/ui/spinner';
import DeprecationAlert from '@/components/DeprecationAlert.vue'; import DeprecationAlert from '@/components/DeprecationAlert.vue';
import { refreshUserDialogAvatars } from '@/coordinators/userCoordinator';
import { useAdvancedSettingsStore, useAvatarStore, useUserStore } from '../../../stores'; import { useAdvancedSettingsStore, useAvatarStore, useUserStore } from '../../../stores';
@@ -119,7 +123,7 @@
const userStore = useUserStore(); const userStore = useUserStore();
const { userDialog, currentUser } = storeToRefs(userStore); const { userDialog, currentUser } = storeToRefs(userStore);
const { sortUserDialogAvatars, refreshUserDialogAvatars } = userStore; const { sortUserDialogAvatars } = userStore;
import { showAvatarDialog, lookupAvatars } from '../../../coordinators/avatarCoordinator'; import { showAvatarDialog, lookupAvatars } from '../../../coordinators/avatarCoordinator';
const { cachedAvatars } = useAvatarStore(); const { cachedAvatars } = useAvatarStore();
+4 -1
View File
@@ -1182,7 +1182,10 @@
"purge_option_730": "2 years", "purge_option_730": "2 years",
"purge_option_all": "All data", "purge_option_all": "All data",
"purge_confirm_title": "Purge Avatar Feed Data", "purge_confirm_title": "Purge Avatar Feed Data",
"purge_confirm_description": "This will permanently delete avatar change records from the database and reclaim disk space. This action cannot be undone!\n\nIt is strongly recommended to back up your database file before proceeding.\n\nVRCX will restart after the operation completes.", "purge_confirm_description_1": "This will permanently delete avatar change records from the database and reclaim disk space.",
"purge_confirm_description_2": "This action cannot be undone!",
"purge_confirm_description_3": "VRCX will restart after the operation completes.",
"purge_confirm_alert": "It is strongly recommended to back up your database file before proceeding!",
"purge_confirm_button": "Purge & Restart", "purge_confirm_button": "Purge & Restart",
"purge_in_progress": "Purging avatar data...", "purge_in_progress": "Purging avatar data...",
"purge_complete": "Avatar data purged successfully. Restarting...", "purge_complete": "Avatar data purged successfully. Restarting...",
@@ -1,29 +1,34 @@
<template> <template>
<div class="flex flex-col gap-10 py-2"> <div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.advanced.advanced.vrchat_settings.header')"> <SettingsGroup :title="t('view.settings.advanced.advanced.vrchat_settings.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.relaunch_vrchat.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.relaunch_vrchat.header')"
:description="t('view.settings.advanced.advanced.relaunch_vrchat.description')"> :description="t('view.settings.advanced.advanced.relaunch_vrchat.description')">
<Switch :model-value="relaunchVRChatAfterCrash" @update:modelValue="setRelaunchVRChatAfterCrash" /> <Switch :model-value="relaunchVRChatAfterCrash" @update:modelValue="setRelaunchVRChatAfterCrash" />
</SettingsItem> </SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.vrchat_quit_fix.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.vrchat_quit_fix.header')"
:description="t('view.settings.advanced.advanced.vrchat_quit_fix.description')"> :description="t('view.settings.advanced.advanced.vrchat_quit_fix.description')">
<Switch :model-value="vrcQuitFix" @update:modelValue="setVrcQuitFix" /> <Switch :model-value="vrcQuitFix" @update:modelValue="setVrcQuitFix" />
</SettingsItem> </SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.auto_cache_management.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.auto_cache_management.header')"
:description="t('view.settings.advanced.advanced.auto_cache_management.description')"> :description="t('view.settings.advanced.advanced.auto_cache_management.description')">
<Switch :model-value="autoSweepVRChatCache" @update:modelValue="setAutoSweepVRChatCache" /> <Switch :model-value="autoSweepVRChatCache" @update:modelValue="setAutoSweepVRChatCache" />
</SettingsItem> </SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.self_invite.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.self_invite.header')"
:description="t('view.settings.advanced.advanced.self_invite.description')"> :description="t('view.settings.advanced.advanced.self_invite.description')">
<Switch :model-value="selfInviteOverride" @update:modelValue="setSelfInviteOverride" /> <Switch :model-value="selfInviteOverride" @update:modelValue="setSelfInviteOverride" />
</SettingsItem> </SettingsItem>
</SettingsGroup> </SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced_groups.security.header')"> <SettingsGroup :title="t('view.settings.advanced_groups.security.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.primary_password.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.primary_password.header')"
:description="t('view.settings.advanced.advanced.primary_password.description')"> :description="t('view.settings.advanced.advanced.primary_password.description')">
<Switch <Switch
:model-value="enablePrimaryPassword" :model-value="enablePrimaryPassword"
@@ -49,7 +54,8 @@
<Switch :model-value="autoLoginDelayEnabled" @update:modelValue="setAutoLoginDelayEnabled" /> <Switch :model-value="autoLoginDelayEnabled" @update:modelValue="setAutoLoginDelayEnabled" />
</SettingsItem> </SettingsItem>
<SettingsItem v-if="autoLoginDelayEnabled" <SettingsItem
v-if="autoLoginDelayEnabled"
:label="t('view.settings.general.logging.auto_login_delay_button')"> :label="t('view.settings.general.logging.auto_login_delay_button')">
<Button size="sm" variant="outline" @click="promptAutoLoginDelaySeconds"> <Button size="sm" variant="outline" @click="promptAutoLoginDelaySeconds">
{{ t('view.settings.general.logging.auto_login_delay_button') }} {{ t('view.settings.general.logging.auto_login_delay_button') }}
@@ -65,7 +71,8 @@
}}</Button> }}</Button>
</SettingsItem> </SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.remote_database.enable')" <SettingsItem
:label="t('view.settings.advanced.advanced.remote_database.enable')"
:description="t('view.settings.advanced.advanced.app_launcher.folder_tooltip')"> :description="t('view.settings.advanced.advanced.app_launcher.folder_tooltip')">
<Switch :model-value="enableAppLauncher" @update:modelValue="setEnableAppLauncher" /> <Switch :model-value="enableAppLauncher" @update:modelValue="setEnableAppLauncher" />
</SettingsItem> </SettingsItem>
@@ -87,7 +94,9 @@
<SettingsGroup :title="t('view.settings.advanced.advanced.launch_commands.header')"> <SettingsGroup :title="t('view.settings.advanced.advanced.launch_commands.header')">
<SettingsItem <SettingsItem
:label="t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_enable')" :label="t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_enable')"
:description="t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_tooltip')"> :description="
t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_tooltip')
">
<Switch <Switch
:model-value="showConfirmationOnSwitchAvatar" :model-value="showConfirmationOnSwitchAvatar"
@update:modelValue="setShowConfirmationOnSwitchAvatar" /> @update:modelValue="setShowConfirmationOnSwitchAvatar" />
@@ -128,12 +137,30 @@
</SettingsItem> </SettingsItem>
<div class="flex flex-col gap-1 text-sm"> <div class="flex flex-col gap-1 text-sm">
<span>{{ t('view.settings.advanced.advanced.cache_debug.user_cache') }} <span v-text="cacheSize.cachedUsers"></span></span> <span
<span>{{ t('view.settings.advanced.advanced.cache_debug.world_cache') }} <span v-text="cacheSize.cachedWorlds"></span></span> >{{ t('view.settings.advanced.advanced.cache_debug.user_cache') }}
<span>{{ t('view.settings.advanced.advanced.cache_debug.avatar_cache') }} <span v-text="cacheSize.cachedAvatars"></span></span> <span v-text="cacheSize.cachedUsers"></span
<span>{{ t('view.settings.advanced.advanced.cache_debug.group_cache') }} <span v-text="cacheSize.cachedGroups"></span></span> ></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }} <span v-text="cacheSize.cachedAvatarNames"></span></span> <span
<span>{{ t('view.settings.advanced.advanced.cache_debug.instance_cache') }} <span v-text="cacheSize.cachedInstances"></span></span> >{{ t('view.settings.advanced.advanced.cache_debug.world_cache') }}
<span v-text="cacheSize.cachedWorlds"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.cache_debug.avatar_cache') }}
<span v-text="cacheSize.cachedAvatars"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.cache_debug.group_cache') }}
<span v-text="cacheSize.cachedGroups"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }}
<span v-text="cacheSize.cachedAvatarNames"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.cache_debug.instance_cache') }}
<span v-text="cacheSize.cachedInstances"></span
></span>
</div> </div>
<SettingsItem :label="t('view.settings.advanced.advanced.cache_debug.show_console')"> <SettingsItem :label="t('view.settings.advanced.advanced.cache_debug.show_console')">
@@ -151,18 +178,54 @@
</SettingsItem> </SettingsItem>
<div class="flex flex-col gap-1 text-sm"> <div class="flex flex-col gap-1 text-sm">
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.gps') }} <span v-text="sqliteTableSizes.gps"></span></span> <span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.status') }} <span v-text="sqliteTableSizes.status"></span></span> >{{ t('view.settings.advanced.advanced.sqlite_table_size.gps') }}
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.bio') }} <span v-text="sqliteTableSizes.bio"></span></span> <span v-text="sqliteTableSizes.gps"></span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.avatar') }} <span v-text="sqliteTableSizes.avatar"></span></span> ></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }} <span v-text="sqliteTableSizes.onlineOffline"></span></span> <span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }} <span v-text="sqliteTableSizes.friendLogHistory"></span></span> >{{ t('view.settings.advanced.advanced.sqlite_table_size.status') }}
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.notification') }} <span v-text="sqliteTableSizes.notification"></span></span> <span v-text="sqliteTableSizes.status"></span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.location') }} <span v-text="sqliteTableSizes.location"></span></span> ></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }} <span v-text="sqliteTableSizes.joinLeave"></span></span> <span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }} <span v-text="sqliteTableSizes.portalSpawn"></span></span> >{{ t('view.settings.advanced.advanced.sqlite_table_size.bio') }}
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.video_play') }} <span v-text="sqliteTableSizes.videoPlay"></span></span> <span v-text="sqliteTableSizes.bio"></span
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }} <span v-text="sqliteTableSizes.event"></span></span> ></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.avatar') }}
<span v-text="sqliteTableSizes.avatar"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }}
<span v-text="sqliteTableSizes.onlineOffline"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }}
<span v-text="sqliteTableSizes.friendLogHistory"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.notification') }}
<span v-text="sqliteTableSizes.notification"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.location') }}
<span v-text="sqliteTableSizes.location"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }}
<span v-text="sqliteTableSizes.joinLeave"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }}
<span v-text="sqliteTableSizes.portalSpawn"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.video_play') }}
<span v-text="sqliteTableSizes.videoPlay"></span
></span>
<span
>{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }}
<span v-text="sqliteTableSizes.event"></span
></span>
</div> </div>
<SettingsItem <SettingsItem
@@ -174,11 +237,21 @@
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
<SelectItem value="Off">{{ t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_off') }}</SelectItem> <SelectItem value="Off">{{
<SelectItem value="30">{{ t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_30') }}</SelectItem> t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_off')
<SelectItem value="90">{{ t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_90') }}</SelectItem> }}</SelectItem>
<SelectItem value="180">{{ t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_180') }}</SelectItem> <SelectItem value="30">{{
<SelectItem value="365">{{ t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_365') }}</SelectItem> t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_30')
}}</SelectItem>
<SelectItem value="90">{{
t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_90')
}}</SelectItem>
<SelectItem value="180">{{
t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_180')
}}</SelectItem>
<SelectItem value="365">{{
t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_365')
}}</SelectItem>
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
@@ -190,22 +263,35 @@
{{ t('view.settings.advanced.advanced.database_cleanup.purge') }} {{ t('view.settings.advanced.advanced.database_cleanup.purge') }}
</Button> </Button>
</SettingsItem> </SettingsItem>
</SettingsGroup> </SettingsGroup>
<Dialog :open="isPurgeDialogVisible" @update:open="(open) => { if (!open) isPurgeDialogVisible = false; }"> <Dialog
:open="isPurgeDialogVisible"
@update:open="
(open) => {
if (!open) isPurgeDialogVisible = false;
}
">
<DialogContent class="x-dialog sm:max-w-md"> <DialogContent class="x-dialog sm:max-w-md">
<DialogHeader> <DialogHeader>
<DialogTitle>{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_title') }}</DialogTitle> <DialogTitle>{{
t('view.settings.advanced.advanced.database_cleanup.purge_confirm_title')
}}</DialogTitle>
</DialogHeader> </DialogHeader>
<Alert variant="warning" class="mb-3"> <Alert variant="warning" class="mb-3">
<TriangleAlert /> <TriangleAlert />
<AlertDescription> <AlertDescription>
{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_description') }} {{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_alert') }}
</AlertDescription> </AlertDescription>
</Alert> </Alert>
<div class="flex flex-col gap-1 text-sm text-muted-foreground mb-3">
<p>{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_description_1') }}</p>
<p>{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_description_2') }}</p>
<p>{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_description_3') }}</p>
</div>
<SettingsItem :label="t('view.settings.advanced.advanced.database_cleanup.purge_older_than')"> <SettingsItem :label="t('view.settings.advanced.advanced.database_cleanup.purge_older_than')">
<Select v-model="selectedPurgePeriod"> <Select v-model="selectedPurgePeriod">
<SelectTrigger class="w-36"> <SelectTrigger class="w-36">
@@ -213,10 +299,18 @@
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
<SelectItem value="180">{{ t('view.settings.advanced.advanced.database_cleanup.purge_option_180') }}</SelectItem> <SelectItem value="180">{{
<SelectItem value="365">{{ t('view.settings.advanced.advanced.database_cleanup.purge_option_365') }}</SelectItem> t('view.settings.advanced.advanced.database_cleanup.purge_option_180')
<SelectItem value="730">{{ t('view.settings.advanced.advanced.database_cleanup.purge_option_730') }}</SelectItem> }}</SelectItem>
<SelectItem value="all">{{ t('view.settings.advanced.advanced.database_cleanup.purge_option_all') }}</SelectItem> <SelectItem value="365">{{
t('view.settings.advanced.advanced.database_cleanup.purge_option_365')
}}</SelectItem>
<SelectItem value="730">{{
t('view.settings.advanced.advanced.database_cleanup.purge_option_730')
}}</SelectItem>
<SelectItem value="all">{{
t('view.settings.advanced.advanced.database_cleanup.purge_option_all')
}}</SelectItem>
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
@@ -226,18 +320,13 @@
<Button variant="outline" size="sm" @click="isPurgeDialogVisible = false"> <Button variant="outline" size="sm" @click="isPurgeDialogVisible = false">
{{ t('confirm.cancel_button') }} {{ t('confirm.cancel_button') }}
</Button> </Button>
<Button <Button size="sm" variant="destructive" :disabled="purgeInProgress" @click="handlePurge">
size="sm"
variant="destructive"
:disabled="purgeInProgress"
@click="handlePurge">
<Trash2 class="h-4 w-4 mr-1" /> <Trash2 class="h-4 w-4 mr-1" />
{{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_button') }} {{ t('view.settings.advanced.advanced.database_cleanup.purge_confirm_button') }}
</Button> </Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
<SettingsGroup :title="t('view.settings.advanced_groups.diagnostics.header')"> <SettingsGroup :title="t('view.settings.advanced_groups.diagnostics.header')">
<SettingsGroup :title="t('view.profile.game_info.header')"> <SettingsGroup :title="t('view.profile.game_info.header')">
@@ -283,7 +372,8 @@
<template v-if="branch === 'Nightly'"> <template v-if="branch === 'Nightly'">
<SettingsGroup :title="t('view.settings.advanced_groups.nightly.header')"> <SettingsGroup :title="t('view.settings.advanced_groups.nightly.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.anonymous_error_reporting.header')" <SettingsItem
:label="t('view.settings.advanced.advanced.anonymous_error_reporting.header')"
:description="t('view.settings.advanced.advanced.anonymous_error_reporting.description')"> :description="t('view.settings.advanced.advanced.anonymous_error_reporting.description')">
<Switch :model-value="sentryErrorReporting" @update:modelValue="setSentryErrorReporting()" /> <Switch :model-value="sentryErrorReporting" @update:modelValue="setSentryErrorReporting()" />
</SettingsItem> </SettingsItem>
@@ -296,7 +386,7 @@
</template> </template>
<script setup> <script setup>
import { RefreshCcw, Trash2,TriangleAlert } from 'lucide-vue-next'; import { RefreshCcw, Trash2, TriangleAlert } from 'lucide-vue-next';
import { computed, reactive, ref } from 'vue'; import { computed, reactive, ref } from 'vue';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
@@ -412,10 +502,7 @@
const isLinux = computed(() => LINUX); const isLinux = computed(() => LINUX);
function handlePurge() { function handlePurge() {
const days = const days = selectedPurgePeriod.value === 'all' ? null : parseInt(selectedPurgePeriod.value, 10);
selectedPurgePeriod.value === 'all'
? null
: parseInt(selectedPurgePeriod.value, 10);
isPurgeDialogVisible.value = false; isPurgeDialogVisible.value = false;
purgeAvatarFeedData(days); purgeAvatarFeedData(days);
} }