disable avatar DB log cleanup UI and functionality

This commit is contained in:
pa
2026-03-17 21:53:07 +09:00
parent ded9ce6da2
commit 1a16a2116a
5 changed files with 168 additions and 152 deletions

74
package-lock.json generated
View File

@@ -77,7 +77,7 @@
"vue-router": "^4.6.4", "vue-router": "^4.6.4",
"vue-showdown": "^4.2.0", "vue-showdown": "^4.2.0",
"vue-sonner": "^2.0.9", "vue-sonner": "^2.0.9",
"worker-timers": "^8.0.30", "worker-timers": "^8.0.31",
"yargs": "^18.0.0", "yargs": "^18.0.0",
"zod": "^3.25.76" "zod": "^3.25.76"
}, },
@@ -530,9 +530,9 @@
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
"version": "7.28.6", "version": "7.29.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -5267,16 +5267,16 @@
} }
}, },
"node_modules/broker-factory": { "node_modules/broker-factory": {
"version": "3.1.13", "version": "3.1.14",
"resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.13.tgz", "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.14.tgz",
"integrity": "sha512-H2VALe31mEtO/SRcNp4cUU5BAm1biwhc/JaF77AigUuni/1YT0FLCJfbUxwIEs9y6Kssjk2fmXgf+Y9ALvmKlw==", "integrity": "sha512-L45k5HMbPIrMid0nTOZ/UPXG/c0aRuQKVrSDFIb1zOkvfiyHgYmIjc3cSiN1KwQIvRDOtKE0tfb3I9EZ3CmpQQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"fast-unique-numbers": "^9.0.26", "fast-unique-numbers": "^9.0.27",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"worker-factory": "^7.0.48" "worker-factory": "^7.0.49"
} }
}, },
"node_modules/broker-factory/node_modules/tslib": { "node_modules/broker-factory/node_modules/tslib": {
@@ -7343,13 +7343,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-unique-numbers": { "node_modules/fast-unique-numbers": {
"version": "9.0.26", "version": "9.0.27",
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.26.tgz", "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.27.tgz",
"integrity": "sha512-3Mtq8p1zQinjGyWfKeuBunbuFoixG72AUkk4VvzbX4ykCW9Q4FzRaNyIlfQhUjnKw2ARVP+/CKnoyr6wfHftig==", "integrity": "sha512-nDA9ADeINN8SA2u2wCtU+siWFTTDqQR37XvgPIDDmboWQeExz7X0mImxuaN+kJddliIqy2FpVRmnvRZ+j8i1/A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"tslib": "^2.8.1" "tslib": "^2.8.1"
}, },
"engines": { "engines": {
@@ -12364,14 +12364,14 @@
} }
}, },
"node_modules/worker-factory": { "node_modules/worker-factory": {
"version": "7.0.48", "version": "7.0.49",
"resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.48.tgz", "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.49.tgz",
"integrity": "sha512-CGmBy3tJvpBPjUvb0t4PrpKubUsfkI1Ohg0/GGFU2RvA9j/tiVYwKU8O7yu7gH06YtzbeJLzdUR29lmZKn5pag==", "integrity": "sha512-lW7tpgy6aUv2dFsQhv1yv+XFzdkCf/leoKRTGMPVK5/die6RrUjqgJHJf556qO+ZfytNG6wPXc17E8zzsOLUDw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"fast-unique-numbers": "^9.0.26", "fast-unique-numbers": "^9.0.27",
"tslib": "^2.8.1" "tslib": "^2.8.1"
} }
}, },
@@ -12383,30 +12383,30 @@
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/worker-timers": { "node_modules/worker-timers": {
"version": "8.0.30", "version": "8.0.31",
"resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.30.tgz", "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.31.tgz",
"integrity": "sha512-8P7YoMHWN0Tz7mg+9oEhuZdjBIn2z6gfjlJqFcHiDd9no/oLnMGCARCDkV1LR3ccQus62ZdtIp7t3aTKrMLHOg==", "integrity": "sha512-ngkq5S6JuZyztom8tDgBzorLo9byhBMko/sXfgiUD945AuzKGg1GCgDMCC3NaYkicLpGKXutONM36wEX8UbBCA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"worker-timers-broker": "^8.0.15", "worker-timers-broker": "^8.0.16",
"worker-timers-worker": "^9.0.13" "worker-timers-worker": "^9.0.14"
} }
}, },
"node_modules/worker-timers-broker": { "node_modules/worker-timers-broker": {
"version": "8.0.15", "version": "8.0.16",
"resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.15.tgz", "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.16.tgz",
"integrity": "sha512-Te+EiVUMzG5TtHdmaBZvBrZSFNauym6ImDaCAnzQUxvjnw+oGjMT2idmAOgDy30vOZMLejd0bcsc90Axu6XPWA==", "integrity": "sha512-JyP3AvUGyPGbBGW7XiUewm2+0pN/aYo1QpVf5kdXAfkDZcN3p7NbWrG6XnyDEpDIvfHk/+LCnOW/NsuiU9riYA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"broker-factory": "^3.1.13", "broker-factory": "^3.1.14",
"fast-unique-numbers": "^9.0.26", "fast-unique-numbers": "^9.0.27",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"worker-timers-worker": "^9.0.13" "worker-timers-worker": "^9.0.14"
} }
}, },
"node_modules/worker-timers-broker/node_modules/tslib": { "node_modules/worker-timers-broker/node_modules/tslib": {
@@ -12417,15 +12417,15 @@
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/worker-timers-worker": { "node_modules/worker-timers-worker": {
"version": "9.0.13", "version": "9.0.14",
"resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.13.tgz", "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.14.tgz",
"integrity": "sha512-qjn18szGb1kjcmh2traAdki1eiIS5ikFo+L90nfMOvSRpuDw1hAcR1nzkP2+Hkdqz5thIRnfuWx7QSpsEUsA6Q==", "integrity": "sha512-/qF06C60sXmSLfUl7WglvrDIbspmPOM8UrG63Dnn4bi2x4/DfqHS/+dxF5B+MdHnYO5tVuZYLHdAodrKdabTIg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"worker-factory": "^7.0.48" "worker-factory": "^7.0.49"
} }
}, },
"node_modules/worker-timers-worker/node_modules/tslib": { "node_modules/worker-timers-worker/node_modules/tslib": {

View File

@@ -97,7 +97,7 @@
"vue-router": "^4.6.4", "vue-router": "^4.6.4",
"vue-showdown": "^4.2.0", "vue-showdown": "^4.2.0",
"vue-sonner": "^2.0.9", "vue-sonner": "^2.0.9",
"worker-timers": "^8.0.30", "worker-timers": "^8.0.31",
"yargs": "^18.0.0", "yargs": "^18.0.0",
"zod": "^3.25.76" "zod": "^3.25.76"
}, },

View File

@@ -839,7 +839,8 @@ export const useAuthStore = defineStore('Auth', () => {
*/ */
async function loginComplete() { async function loginComplete() {
await database.initUserTables(userStore.currentUser.id); await database.initUserTables(userStore.currentUser.id);
advancedSettingsStore.runAvatarAutoCleanup(userStore.currentUser.id); // [Disabled] Avatar DB log auto-cleanup on login
// advancedSettingsStore.runAvatarAutoCleanup(userStore.currentUser.id);
watchState.isLoggedIn = true; watchState.isLoggedIn = true;
AppApi.CheckGameRunning(); // restore state from hot-reload AppApi.CheckGameRunning(); // restore state from hot-reload
} }

View File

@@ -529,100 +529,103 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
); );
} }
async function setAvatarAutoCleanup(value) { // [Disabled] Avatar DB log cleanup - setAvatarAutoCleanup
avatarAutoCleanup.value = value; // async function setAvatarAutoCleanup(value) {
await configRepository.setString('VRCX_avatarAutoCleanup', value); // avatarAutoCleanup.value = value;
} // await configRepository.setString('VRCX_avatarAutoCleanup', value);
// }
/** // /**
* @param {number|null} days - Number of days to keep. Null means delete all. // * @param {number|null} days - Number of days to keep. Null means delete all.
*/ // */
async function purgeAvatarFeedData(days) { // [Disabled] Avatar DB log cleanup - purgeAvatarFeedData
let cutoffDate = null; // async function purgeAvatarFeedData(days) {
if (days !== null) { // let cutoffDate = null;
const cutoff = new Date(); // if (days !== null) {
cutoff.setDate(cutoff.getDate() - days); // const cutoff = new Date();
cutoffDate = cutoff.toJSON(); // cutoff.setDate(cutoff.getDate() - days);
} // cutoffDate = cutoff.toJSON();
// }
//
// purgeInProgress.value = true;
// const msgBox = toast.warning(
// t(
// 'view.settings.advanced.advanced.database_cleanup.purge_in_progress'
// ),
// { duration: Infinity }
// );
//
// try {
// await database.purgeAvatarFeedData(cutoffDate);
// await database.vacuum();
// toast.dismiss(msgBox);
// toast.success(
// t(
// 'view.settings.advanced.advanced.database_cleanup.purge_complete'
// )
// );
// // Brief delay before restart to show success message
// await new Promise((resolve) =>
// setTimeout(resolve, 1500)
// );
// VRCXUpdaterStore.restartVRCX(false);
// } catch (err) {
// console.error(err);
// toast.dismiss(msgBox);
// toast.error(t('view.settings.advanced.advanced.database_cleanup.purge_failed', { error: err }));
// } finally {
// purgeInProgress.value = false;
// }
// }
purgeInProgress.value = true; // /**
const msgBox = toast.warning( // * Run auto-cleanup on startup if configured and enough time has passed.
t( // * Reads config directly from configRepository to avoid race condition
'view.settings.advanced.advanced.database_cleanup.purge_in_progress' // * with initAdvancedSettings not having completed yet.
), // * @param {string} userId - Current user ID for per-user cleanup tracking.
{ duration: Infinity } // */
); // [Disabled] Avatar DB log cleanup - runAvatarAutoCleanup
// async function runAvatarAutoCleanup(userId) {
try { // const cleanupSetting = await configRepository.getString(
await database.purgeAvatarFeedData(cutoffDate); // 'VRCX_avatarAutoCleanup',
await database.vacuum(); // 'Off'
toast.dismiss(msgBox); // );
toast.success( // if (cleanupSetting === 'Off') return;
t( //
'view.settings.advanced.advanced.database_cleanup.purge_complete' // const configKey = `VRCX_lastAvatarCleanupDate_${userId}`;
) // const lastCleanupStr = await configRepository.getString(
); // configKey,
// Brief delay before restart to show success message // ''
await new Promise((resolve) => // );
setTimeout(resolve, 1500) // const now = new Date();
); //
VRCXUpdaterStore.restartVRCX(false); // if (lastCleanupStr) {
} catch (err) { // const lastCleanup = new Date(lastCleanupStr);
console.error(err); // const daysSinceLastCleanup =
toast.dismiss(msgBox); // (now - lastCleanup) / (1000 * 60 * 60 * 24);
toast.error(t('view.settings.advanced.advanced.database_cleanup.purge_failed', { error: err })); // if (daysSinceLastCleanup < 7) return;
} finally { // }
purgeInProgress.value = false; //
} // const days = parseInt(cleanupSetting, 10);
} // if (isNaN(days) || days <= 0) return;
//
/** // const cutoff = new Date();
* Run auto-cleanup on startup if configured and enough time has passed. // cutoff.setDate(cutoff.getDate() - days);
* Reads config directly from configRepository to avoid race condition // const cutoffDate = cutoff.toJSON();
* with initAdvancedSettings not having completed yet. //
* @param {string} userId - Current user ID for per-user cleanup tracking. // try {
*/ // await database.purgeAvatarFeedData(cutoffDate);
async function runAvatarAutoCleanup(userId) { // await configRepository.setString(
const cleanupSetting = await configRepository.getString( // configKey,
'VRCX_avatarAutoCleanup', // now.toJSON()
'Off' // );
); // console.log(
if (cleanupSetting === 'Off') return; // `Auto-cleaned avatar feed data older than ${days} days`
// );
const configKey = `VRCX_lastAvatarCleanupDate_${userId}`; // } catch (err) {
const lastCleanupStr = await configRepository.getString( // console.error('Avatar auto-cleanup failed:', err);
configKey, // }
'' // }
);
const now = new Date();
if (lastCleanupStr) {
const lastCleanup = new Date(lastCleanupStr);
const daysSinceLastCleanup =
(now - lastCleanup) / (1000 * 60 * 60 * 24);
if (daysSinceLastCleanup < 7) return;
}
const days = parseInt(cleanupSetting, 10);
if (isNaN(days) || days <= 0) return;
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - days);
const cutoffDate = cutoff.toJSON();
try {
await database.purgeAvatarFeedData(cutoffDate);
await configRepository.setString(
configKey,
now.toJSON()
);
console.log(
`Auto-cleaned avatar feed data older than ${days} days`
);
} catch (err) {
console.error('Avatar auto-cleanup failed:', err);
}
}
async function setSaveInstanceEmoji() { async function setSaveInstanceEmoji() {
saveInstanceEmoji.value = !saveInstanceEmoji.value; saveInstanceEmoji.value = !saveInstanceEmoji.value;
@@ -1171,9 +1174,10 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
setProgressPieFilter, setProgressPieFilter,
setShowConfirmationOnSwitchAvatar, setShowConfirmationOnSwitchAvatar,
setGameLogDisabled, setGameLogDisabled,
setAvatarAutoCleanup, // [Disabled] Avatar DB log cleanup exports
purgeAvatarFeedData, // setAvatarAutoCleanup,
runAvatarAutoCleanup, // purgeAvatarFeedData,
// runAvatarAutoCleanup,
setUGCFolderPath, setUGCFolderPath,
cropPrintsChanged, cropPrintsChanged,
setAutoDeleteOldPrints, setAutoDeleteOldPrints,

View File

@@ -165,6 +165,7 @@
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }} <span v-text="sqliteTableSizes.event"></span></span> <span>{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }} <span v-text="sqliteTableSizes.event"></span></span>
</div> </div>
<!-- [Disabled] Avatar DB log cleanup UI - auto cleanup select & purge button & dialog
<SettingsItem <SettingsItem
:label="t('view.settings.advanced.advanced.database_cleanup.auto_cleanup')" :label="t('view.settings.advanced.advanced.database_cleanup.auto_cleanup')"
:description="t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_description')"> :description="t('view.settings.advanced.advanced.database_cleanup.auto_cleanup_description')">
@@ -190,8 +191,10 @@
{{ t('view.settings.advanced.advanced.database_cleanup.purge') }} {{ t('view.settings.advanced.advanced.database_cleanup.purge') }}
</Button> </Button>
</SettingsItem> </SettingsItem>
-->
</SettingsGroup> </SettingsGroup>
<!-- [Disabled] Avatar DB log cleanup - purge dialog
<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>
@@ -236,6 +239,7 @@
</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')">
@@ -294,13 +298,16 @@
</template> </template>
<script setup> <script setup>
import { RefreshCcw, Trash2, TriangleAlert } from 'lucide-vue-next'; import { RefreshCcw, Trash2 } from 'lucide-vue-next';
// [Disabled] Avatar DB log cleanup - unused imports
// import { 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';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; // [Disabled] Avatar DB log cleanup - unused imports
import { Alert, AlertDescription } from '@/components/ui/alert'; // import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; // import { Alert, AlertDescription } from '@/components/ui/alert';
// import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@@ -372,8 +379,9 @@
showConfirmationOnSwitchAvatar, showConfirmationOnSwitchAvatar,
gameLogDisabled, gameLogDisabled,
sqliteTableSizes, sqliteTableSizes,
avatarAutoCleanup, // [Disabled] Avatar DB log cleanup
purgeInProgress, // avatarAutoCleanup,
// purgeInProgress,
sentryErrorReporting sentryErrorReporting
} = storeToRefs(advancedSettingsStore); } = storeToRefs(advancedSettingsStore);
@@ -387,16 +395,18 @@
setEnableAppLauncherRunProcessOnce, setEnableAppLauncherRunProcessOnce,
setShowConfirmationOnSwitchAvatar, setShowConfirmationOnSwitchAvatar,
getSqliteTableSizes, getSqliteTableSizes,
setAvatarAutoCleanup, // [Disabled] Avatar DB log cleanup
purgeAvatarFeedData, // setAvatarAutoCleanup,
// purgeAvatarFeedData,
promptAutoClearVRCXCacheFrequency, promptAutoClearVRCXCacheFrequency,
setSentryErrorReporting setSentryErrorReporting
} = advancedSettingsStore; } = advancedSettingsStore;
const configTreeData = ref({}); const configTreeData = ref({});
const visits = ref(0); const visits = ref(0);
const selectedPurgePeriod = ref('180'); // [Disabled] Avatar DB log cleanup
const isPurgeDialogVisible = ref(false); // const selectedPurgePeriod = ref('180');
// const isPurgeDialogVisible = ref(false);
const cacheSize = reactive({ const cacheSize = reactive({
cachedUsers: 0, cachedUsers: 0,
@@ -409,14 +419,15 @@
const isLinux = computed(() => LINUX); const isLinux = computed(() => LINUX);
function handlePurge() { // [Disabled] Avatar DB log cleanup - handlePurge
const days = // function handlePurge() {
selectedPurgePeriod.value === 'all' // const days =
? null // selectedPurgePeriod.value === 'all'
: parseInt(selectedPurgePeriod.value, 10); // ? null
isPurgeDialogVisible.value = false; // : parseInt(selectedPurgePeriod.value, 10);
purgeAvatarFeedData(days); // isPurgeDialogVisible.value = false;
} // purgeAvatarFeedData(days);
// }
/** /**
* *