This commit is contained in:
pa
2026-03-11 22:03:57 +09:00
parent bf9b66bdf4
commit 884744cb30
35 changed files with 892 additions and 515 deletions

575
package-lock.json generated
View File

@@ -24,7 +24,7 @@
"@kamiya4047/eslint-plugin-pretty-import": "^0.1.6",
"@pinia/testing": "^1.0.3",
"@sentry/vite-plugin": "^4.9.1",
"@sentry/vue": "^10.42.0",
"@sentry/vue": "^10.43.0",
"@sigma/edge-curve": "^3.1.0",
"@sigma/node-border": "^3.0.0",
"@tailwindcss/vite": "^4.2.1",
@@ -56,12 +56,12 @@
"graphology-layout-forceatlas2": "^0.10.1",
"graphology-layout-noverlap": "^0.4.2",
"jsdom": "^28.1.0",
"lightningcss": "^1.31.1",
"lightningcss": "^1.32.0",
"lucide-vue-next": "^0.562.0",
"noty": "^3.2.0-beta-deprecated",
"pinia": "^3.0.4",
"prettier": "^3.8.1",
"reka-ui": "^2.9.0",
"reka-ui": "^2.9.1",
"remixicon": "^4.9.1",
"sigma": "^3.0.2",
"tailwind-merge": "^3.5.0",
@@ -70,7 +70,7 @@
"vee-validate": "^4.15.1",
"vite": "^7.3.1",
"vitest": "^4.0.18",
"vue": "^3.5.29",
"vue": "^3.5.30",
"vue-advanced-cropper": "^2.8.9",
"vue-i18n": "^11.3.0",
"vue-input-otp": "^0.3.2",
@@ -3067,54 +3067,54 @@
]
},
"node_modules/@sentry-internal/browser-utils": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.42.0.tgz",
"integrity": "sha512-HCEICKvepxN4/6NYfnMMMlppcSwIEwtS66X6d1/mwaHdi2ivw0uGl52p7Nfhda/lIJArbrkWprxl0WcjZajhQA==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.43.0.tgz",
"integrity": "sha512-8zYTnzhAPvNkVH1Irs62wl0J/c+0QcJ62TonKnzpSFUUD3V5qz8YDZbjIDGfxy+1EB9fO0sxtddKCzwTHF/MbQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry/core": "10.42.0"
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/feedback": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.42.0.tgz",
"integrity": "sha512-lpPcHsog10MVYFTWE0Pf8vQRqQWwZHJpkVl2FEb9/HDdHFyTBUhCVoWo1KyKaG7GJl9AVKMAg7bp9SSNArhFNQ==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.43.0.tgz",
"integrity": "sha512-YoXuwluP6eOcQxTeTtaWb090++MrLyWOVsUTejzUQQ6LFL13Jwt+bDPF1kvBugMq4a7OHw/UNKQfd6//rZMn2g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry/core": "10.42.0"
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.42.0.tgz",
"integrity": "sha512-Zh3EoaH39x2lqVY1YyVB2vJEyCIrT+YLUQxYl1yvP0MJgLxaR6akVjkgxbSUJahan4cX5DxpZiEHfzdlWnYPyQ==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.43.0.tgz",
"integrity": "sha512-khCXlGrlH1IU7P5zCEAJFestMeH97zDVCekj8OsNNDtN/1BmCJ46k6Xi0EqAUzdJgrOLJeLdoYdgtiIjovZ8Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "10.42.0",
"@sentry/core": "10.42.0"
"@sentry-internal/browser-utils": "10.43.0",
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.42.0.tgz",
"integrity": "sha512-am3m1Fj8ihoPfoYo41Qq4KeCAAICn4bySso8Oepu9dMNe9Lcnsf+reMRS2qxTPg3pZDc4JEMOcLyNCcgnAfrHw==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.43.0.tgz",
"integrity": "sha512-ZIw1UNKOFXo1LbPCJPMAx9xv7D8TMZQusLDUgb6BsPQJj0igAuwd7KRGTkjjgnrwBp2O/sxcQFRhQhknWk7QPg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry-internal/replay": "10.42.0",
"@sentry/core": "10.42.0"
"@sentry-internal/replay": "10.43.0",
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
@@ -3131,17 +3131,17 @@
}
},
"node_modules/@sentry/browser": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.42.0.tgz",
"integrity": "sha512-iXxYjXNEBwY1MH4lDSDZZUNjzPJDK7/YLwVIJq/3iBYpIQVIhaJsoJnf3clx9+NfJ8QFKyKfcvgae61zm+hgTA==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.43.0.tgz",
"integrity": "sha512-2V3I3sXi3SMeiZpKixd9ztokSgK27cmvsD9J5oyOyjhGLTW/6QKCwHbKnluMgQMXq20nixQk5zN4wRjRUma3sg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "10.42.0",
"@sentry-internal/feedback": "10.42.0",
"@sentry-internal/replay": "10.42.0",
"@sentry-internal/replay-canvas": "10.42.0",
"@sentry/core": "10.42.0"
"@sentry-internal/browser-utils": "10.43.0",
"@sentry-internal/feedback": "10.43.0",
"@sentry-internal/replay": "10.43.0",
"@sentry-internal/replay-canvas": "10.43.0",
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
@@ -3342,9 +3342,9 @@
}
},
"node_modules/@sentry/core": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.42.0.tgz",
"integrity": "sha512-L4rMrXMqUKBanpjpMT+TuAVk6xAijz6AWM6RiEYpohAr7SGcCEc1/T0+Ep1eLV8+pwWacfU27OvELIyNeOnGzA==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.43.0.tgz",
"integrity": "sha512-l0SszQAPiQGWl/ferw8GP3ALyHXiGiRKJaOvNmhGO+PrTQyZTZ6OYyPnGijAFRg58dE1V3RCH/zw5d2xSUIiNg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3366,14 +3366,14 @@
}
},
"node_modules/@sentry/vue": {
"version": "10.42.0",
"resolved": "https://registry.npmjs.org/@sentry/vue/-/vue-10.42.0.tgz",
"integrity": "sha512-D6mYt6zRV1YXMZ8xmGKXzb0VHSLANUxpDAC3tfCeRYZ9P0MEHlNI6aapvjiNAh+0Vi9bOaHIUkzpatbE1gWhOg==",
"version": "10.43.0",
"resolved": "https://registry.npmjs.org/@sentry/vue/-/vue-10.43.0.tgz",
"integrity": "sha512-PYBJVHfd7JwnQv92sTnsfLVNwVEKY2wQzXt9aux6QNcKh4g3pyK68PoEBrcCSEHpUb7zs3lJedk3+aeX+kN7fw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sentry/browser": "10.42.0",
"@sentry/core": "10.42.0"
"@sentry/browser": "10.43.0",
"@sentry/core": "10.43.0"
},
"engines": {
"node": ">=18"
@@ -3491,6 +3491,279 @@
"tailwindcss": "4.2.1"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz",
"integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
},
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-android-arm64": "1.31.1",
"lightningcss-darwin-arm64": "1.31.1",
"lightningcss-darwin-x64": "1.31.1",
"lightningcss-freebsd-x64": "1.31.1",
"lightningcss-linux-arm-gnueabihf": "1.31.1",
"lightningcss-linux-arm64-gnu": "1.31.1",
"lightningcss-linux-arm64-musl": "1.31.1",
"lightningcss-linux-x64-gnu": "1.31.1",
"lightningcss-linux-x64-musl": "1.31.1",
"lightningcss-win32-arm64-msvc": "1.31.1",
"lightningcss-win32-x64-msvc": "1.31.1"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-android-arm64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz",
"integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-arm64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz",
"integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-x64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz",
"integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-freebsd-x64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz",
"integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm-gnueabihf": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz",
"integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==",
"cpu": [
"arm"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-gnu": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz",
"integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-musl": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz",
"integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-gnu": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz",
"integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-musl": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz",
"integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-win32-arm64-msvc": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz",
"integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/lightningcss-win32-x64-msvc": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz",
"integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MPL-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@tailwindcss/node/node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -4380,42 +4653,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.29.tgz",
"integrity": "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz",
"integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.0",
"@vue/shared": "3.5.29",
"@vue/shared": "3.5.30",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.29.tgz",
"integrity": "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz",
"integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.29",
"@vue/shared": "3.5.29"
"@vue/compiler-core": "3.5.30",
"@vue/shared": "3.5.30"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.29.tgz",
"integrity": "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz",
"integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.0",
"@vue/compiler-core": "3.5.29",
"@vue/compiler-dom": "3.5.29",
"@vue/compiler-ssr": "3.5.29",
"@vue/shared": "3.5.29",
"@vue/compiler-core": "3.5.30",
"@vue/compiler-dom": "3.5.30",
"@vue/compiler-ssr": "3.5.30",
"@vue/shared": "3.5.30",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
"postcss": "^8.5.8",
"source-map-js": "^1.2.1"
}
},
@@ -4429,13 +4702,13 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.29.tgz",
"integrity": "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz",
"integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.29",
"@vue/shared": "3.5.29"
"@vue/compiler-dom": "3.5.30",
"@vue/shared": "3.5.30"
}
},
"node_modules/@vue/devtools-api": {
@@ -4475,53 +4748,53 @@
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.29.tgz",
"integrity": "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz",
"integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.5.29"
"@vue/shared": "3.5.30"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.29.tgz",
"integrity": "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz",
"integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.29",
"@vue/shared": "3.5.29"
"@vue/reactivity": "3.5.30",
"@vue/shared": "3.5.30"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.29.tgz",
"integrity": "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz",
"integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.29",
"@vue/runtime-core": "3.5.29",
"@vue/shared": "3.5.29",
"@vue/reactivity": "3.5.30",
"@vue/runtime-core": "3.5.30",
"@vue/shared": "3.5.30",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.29.tgz",
"integrity": "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz",
"integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.5.29",
"@vue/shared": "3.5.29"
"@vue/compiler-ssr": "3.5.30",
"@vue/shared": "3.5.30"
},
"peerDependencies": {
"vue": "3.5.29"
"vue": "3.5.30"
}
},
"node_modules/@vue/shared": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.29.tgz",
"integrity": "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz",
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==",
"license": "MIT"
},
"node_modules/@vue/test-utils": {
@@ -8684,9 +8957,9 @@
}
},
"node_modules/lightningcss": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz",
"integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -8700,23 +8973,23 @@
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-android-arm64": "1.31.1",
"lightningcss-darwin-arm64": "1.31.1",
"lightningcss-darwin-x64": "1.31.1",
"lightningcss-freebsd-x64": "1.31.1",
"lightningcss-linux-arm-gnueabihf": "1.31.1",
"lightningcss-linux-arm64-gnu": "1.31.1",
"lightningcss-linux-arm64-musl": "1.31.1",
"lightningcss-linux-x64-gnu": "1.31.1",
"lightningcss-linux-x64-musl": "1.31.1",
"lightningcss-win32-arm64-msvc": "1.31.1",
"lightningcss-win32-x64-msvc": "1.31.1"
"lightningcss-android-arm64": "1.32.0",
"lightningcss-darwin-arm64": "1.32.0",
"lightningcss-darwin-x64": "1.32.0",
"lightningcss-freebsd-x64": "1.32.0",
"lightningcss-linux-arm-gnueabihf": "1.32.0",
"lightningcss-linux-arm64-gnu": "1.32.0",
"lightningcss-linux-arm64-musl": "1.32.0",
"lightningcss-linux-x64-gnu": "1.32.0",
"lightningcss-linux-x64-musl": "1.32.0",
"lightningcss-win32-arm64-msvc": "1.32.0",
"lightningcss-win32-x64-msvc": "1.32.0"
}
},
"node_modules/lightningcss-android-arm64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz",
"integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
"cpu": [
"arm64"
],
@@ -8735,9 +9008,9 @@
}
},
"node_modules/lightningcss-darwin-arm64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz",
"integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
"cpu": [
"arm64"
],
@@ -8756,9 +9029,9 @@
}
},
"node_modules/lightningcss-darwin-x64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz",
"integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
"cpu": [
"x64"
],
@@ -8777,9 +9050,9 @@
}
},
"node_modules/lightningcss-freebsd-x64": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz",
"integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
"cpu": [
"x64"
],
@@ -8798,9 +9071,9 @@
}
},
"node_modules/lightningcss-linux-arm-gnueabihf": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz",
"integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
"cpu": [
"arm"
],
@@ -8819,13 +9092,16 @@
}
},
"node_modules/lightningcss-linux-arm64-gnu": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz",
"integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8840,13 +9116,16 @@
}
},
"node_modules/lightningcss-linux-arm64-musl": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz",
"integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8861,13 +9140,16 @@
}
},
"node_modules/lightningcss-linux-x64-gnu": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz",
"integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
"integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8882,13 +9164,16 @@
}
},
"node_modules/lightningcss-linux-x64-musl": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz",
"integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
"integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8903,9 +9188,9 @@
}
},
"node_modules/lightningcss-win32-arm64-msvc": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz",
"integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
"cpu": [
"arm64"
],
@@ -8924,9 +9209,9 @@
}
},
"node_modules/lightningcss-win32-x64-msvc": {
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz",
"integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
"cpu": [
"x64"
],
@@ -10032,9 +10317,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"funding": [
{
"type": "opencollective",
@@ -10272,9 +10557,9 @@
}
},
"node_modules/reka-ui": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.9.0.tgz",
"integrity": "sha512-5dpp80u109iLTbRBu+jhAk8R/877/JN20gYGjb3GsuAgS7E/5QTX5ZxuzWtZAVbChBDYDpXc8pkaQAFpa6s+4w==",
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.9.1.tgz",
"integrity": "sha512-5Oa77f4VVNgUsMtGZKh3AnMCjJvA4TJ9phcN+TxPfGutdENaqleXO+NvhCkgK02PEHcyys8fqIF9CdcvSq5Flw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11907,16 +12192,16 @@
}
},
"node_modules/vue": {
"version": "3.5.29",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.29.tgz",
"integrity": "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA==",
"version": "3.5.30",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz",
"integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.29",
"@vue/compiler-sfc": "3.5.29",
"@vue/runtime-dom": "3.5.29",
"@vue/server-renderer": "3.5.29",
"@vue/shared": "3.5.29"
"@vue/compiler-dom": "3.5.30",
"@vue/compiler-sfc": "3.5.30",
"@vue/runtime-dom": "3.5.30",
"@vue/server-renderer": "3.5.30",
"@vue/shared": "3.5.30"
},
"peerDependencies": {
"typescript": "*"

View File

@@ -43,7 +43,7 @@
"@kamiya4047/eslint-plugin-pretty-import": "^0.1.6",
"@pinia/testing": "^1.0.3",
"@sentry/vite-plugin": "^4.9.1",
"@sentry/vue": "^10.42.0",
"@sentry/vue": "^10.43.0",
"@sigma/edge-curve": "^3.1.0",
"@sigma/node-border": "^3.0.0",
"@tailwindcss/vite": "^4.2.1",
@@ -75,12 +75,12 @@
"graphology-layout-forceatlas2": "^0.10.1",
"graphology-layout-noverlap": "^0.4.2",
"jsdom": "^28.1.0",
"lightningcss": "^1.31.1",
"lightningcss": "^1.32.0",
"lucide-vue-next": "^0.562.0",
"noty": "^3.2.0-beta-deprecated",
"pinia": "^3.0.4",
"prettier": "^3.8.1",
"reka-ui": "^2.9.0",
"reka-ui": "^2.9.1",
"remixicon": "^4.9.1",
"sigma": "^3.0.2",
"tailwind-merge": "^3.5.0",
@@ -89,7 +89,7 @@
"vee-validate": "^4.15.1",
"vite": "^7.3.1",
"vitest": "^4.0.18",
"vue": "^3.5.29",
"vue": "^3.5.30",
"vue-advanced-cropper": "^2.8.9",
"vue-i18n": "^11.3.0",
"vue-input-otp": "^0.3.2",

View File

@@ -145,15 +145,17 @@ function mountComponent(overrides = {}) {
});
const groupStore = useGroupStore(pinia);
groupStore.groupDialog = {
id: 'grp_1',
visible: true,
ref: {
galleries: [...MOCK_GALLERIES]
},
galleries: { ...MOCK_GALLERY_IMAGES },
...overrides
};
groupStore.$patch({
groupDialog: {
id: 'grp_1',
visible: true,
ref: {
galleries: [...MOCK_GALLERIES]
},
galleries: { ...MOCK_GALLERY_IMAGES },
...overrides
}
});
return mount(GroupDialogPhotosTab, {
global: {

View File

@@ -138,21 +138,23 @@ function mountComponent(overrides = {}) {
});
const groupStore = useGroupStore(pinia);
groupStore.groupDialog = {
id: 'grp_1',
visible: true,
posts: [...MOCK_POSTS],
postsFiltered: [...MOCK_POSTS],
postsSearch: '',
ref: {
roles: [
{ id: 'role_1', name: 'Admin' },
{ id: 'role_2', name: 'Member' }
],
permissions: []
},
...overrides
};
groupStore.$patch({
groupDialog: {
id: 'grp_1',
visible: true,
posts: [...MOCK_POSTS],
postsFiltered: [...MOCK_POSTS],
postsSearch: '',
ref: {
roles: [
{ id: 'role_1', name: 'Admin' },
{ id: 'role_2', name: 'Member' }
],
permissions: []
},
...overrides
}
});
return mount(GroupDialogPostsTab, {
global: {

View File

@@ -118,20 +118,22 @@ function mountComponent(overrides = {}) {
});
const userStore = useUserStore(pinia);
userStore.userDialog = {
id: 'usr_me',
ref: { id: 'usr_me' },
avatars: [...MOCK_AVATARS],
avatarSorting: 'name',
avatarReleaseStatus: 'all',
isAvatarsLoading: false,
isWorldsLoading: false,
...overrides
};
userStore.currentUser = {
id: 'usr_me',
...overrides.currentUser
};
userStore.$patch({
userDialog: {
id: 'usr_me',
ref: { id: 'usr_me' },
avatars: [...MOCK_AVATARS],
avatarSorting: 'name',
avatarReleaseStatus: 'all',
isAvatarsLoading: false,
isWorldsLoading: false,
...overrides
},
currentUser: {
id: 'usr_me',
...overrides.currentUser
}
});
return mount(UserDialogAvatarsTab, {
global: {

View File

@@ -109,92 +109,100 @@ function mountComponent(overrides = {}) {
});
const appearanceSettingsStore = useAppearanceSettingsStore(pinia);
appearanceSettingsStore.hideUserNotes = false;
appearanceSettingsStore.hideUserMemos = false;
appearanceSettingsStore.$patch({
hideUserNotes: false,
hideUserMemos: false
});
const advancedSettingsStore = useAdvancedSettingsStore(pinia);
advancedSettingsStore.bioLanguage = 'en';
advancedSettingsStore.translationApi = '';
advancedSettingsStore.translationApiType = 'google';
advancedSettingsStore.translateText = vi.fn().mockResolvedValue('');
advancedSettingsStore.$patch({
bioLanguage: 'en',
translationApi: '',
translationApiType: 'google'
});
const advancedSettings = advancedSettingsStore;
advancedSettings.translateText = vi.fn().mockResolvedValue('');
const userStore = useUserStore(pinia);
userStore.userDialog = {
id: 'usr_target',
friend: {
state: 'online',
ref: {
location: 'wrld_test:123'
}
},
ref: {
userStore.$patch({
userDialog: {
id: 'usr_target',
location: 'wrld_test:123',
travelingToLocation: '',
profilePicOverride: '',
currentAvatarImageUrl: '',
currentAvatarTags: [],
bio: '',
bioLinks: [],
state: 'online',
$online_for: 1000,
last_login: '2025-01-01T00:00:00.000Z',
last_activity: '2025-01-01T00:00:00.000Z',
date_joined: '2020-01-01',
friend: {
state: 'online',
ref: {
location: 'wrld_test:123'
}
},
ref: {
id: 'usr_target',
location: 'wrld_test:123',
travelingToLocation: '',
profilePicOverride: '',
currentAvatarImageUrl: '',
currentAvatarTags: [],
bio: '',
bioLinks: [],
state: 'online',
$online_for: 1000,
last_login: '2025-01-01T00:00:00.000Z',
last_activity: '2025-01-01T00:00:00.000Z',
date_joined: '2020-01-01',
allowAvatarCopying: true,
displayName: 'Target'
},
$location: {
tag: 'wrld_test:123',
shortName: 'Test',
userId: '',
user: null
},
instance: {
ref: {},
friendCount: 0
},
users: [
{
id: 'usr_friend_1',
displayName: 'Friend A',
$userColour: '#ffffff',
location: 'traveling',
$travelingToTime: Date.now(),
$location_at: Date.now()
}
],
note: '',
memo: '',
isRepresentedGroupLoading: false,
representedGroup: null,
lastSeen: '2025-01-01T00:00:00.000Z',
joinCount: 0,
timeSpent: 0,
dateFriendedInfo: [],
unFriended: false,
dateFriended: '2025-01-01T00:00:00.000Z',
$homeLocationName: '',
...overrides.userDialog
},
currentUser: {
id: 'usr_me',
allowAvatarCopying: true,
displayName: 'Target'
},
$location: {
tag: 'wrld_test:123',
shortName: 'Test',
userId: '',
user: null
},
instance: {
ref: {},
friendCount: 0
},
users: [
{
id: 'usr_friend_1',
displayName: 'Friend A',
$userColour: '#ffffff',
location: 'traveling',
$travelingToTime: Date.now(),
$location_at: Date.now()
}
],
note: '',
memo: '',
isRepresentedGroupLoading: false,
representedGroup: null,
lastSeen: '2025-01-01T00:00:00.000Z',
joinCount: 0,
timeSpent: 0,
dateFriendedInfo: [],
unFriended: false,
dateFriended: '2025-01-01T00:00:00.000Z',
$homeLocationName: '',
...overrides.userDialog
};
userStore.currentUser = {
id: 'usr_me',
allowAvatarCopying: true,
isBoopingEnabled: true,
hasSharedConnectionsOptOut: false,
hasDiscordFriendsOptOut: false,
homeLocation: '',
...overrides.currentUser
};
isBoopingEnabled: true,
hasSharedConnectionsOptOut: false,
hasDiscordFriendsOptOut: false,
homeLocation: '',
...overrides.currentUser
}
});
const locationStore = useLocationStore(pinia);
locationStore.lastLocation = {
location: 'wrld_test:123'
};
locationStore.$patch({
lastLocation: {
location: 'wrld_test:123'
}
});
const modalStore = useModalStore(pinia);
modalStore.confirm = vi.fn().mockResolvedValue({ ok: false });
const modal = useModalStore(pinia);
modal.confirm = vi.fn().mockResolvedValue({ ok: false });
return shallowMount(UserDialogInfoTab, {
global: {

View File

@@ -127,19 +127,22 @@ function mountComponent(overrides = {}) {
});
const userStore = useUserStore(pinia);
userStore.userDialog = {
id: 'usr_target',
ref: { id: 'usr_target' },
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
mutualFriendSorting: userDialogMutualFriendSortingOptions.alphabetical,
isMutualFriendsLoading: false,
...overrides
};
userStore.currentUser = {
id: 'usr_me',
hasSharedConnectionsOptOut: false,
...overrides.currentUser
};
userStore.$patch({
userDialog: {
id: 'usr_target',
ref: { id: 'usr_target' },
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
mutualFriendSorting:
userDialogMutualFriendSortingOptions.alphabetical,
isMutualFriendsLoading: false,
...overrides
},
currentUser: {
id: 'usr_me',
hasSharedConnectionsOptOut: false,
...overrides.currentUser
}
});
return mount(UserDialogMutualFriendsTab, {
global: {
@@ -215,15 +218,17 @@ describe('UserDialogMutualFriendsTab.vue', () => {
test('calls showUserDialog when a friend is clicked', async () => {
const pinia = createTestingPinia({ stubActions: false });
const userStore = useUserStore(pinia);
userStore.userDialog = {
id: 'usr_target',
ref: { id: 'usr_target' },
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
mutualFriendSorting:
userDialogMutualFriendSortingOptions.alphabetical,
isMutualFriendsLoading: false
};
userStore.currentUser = { id: 'usr_me' };
userStore.$patch({
userDialog: {
id: 'usr_target',
ref: { id: 'usr_target' },
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
mutualFriendSorting:
userDialogMutualFriendSortingOptions.alphabetical,
isMutualFriendsLoading: false
},
currentUser: { id: 'usr_me' }
});
const showUserDialogSpy = vi
.spyOn(userCoordinatorModule, 'showUserDialog')
.mockImplementation(() => {});

View File

@@ -137,19 +137,21 @@ function mountComponent(overrides = {}) {
});
const userStore = useUserStore(pinia);
userStore.userDialog = {
id: 'usr_me',
ref: { id: 'usr_me' },
worlds: [...MOCK_WORLDS],
worldSorting: userDialogWorldSortingOptions.name,
worldOrder: userDialogWorldOrderOptions.descending,
isWorldsLoading: false,
...overrides
};
userStore.currentUser = {
id: 'usr_me',
...overrides.currentUser
};
userStore.$patch({
userDialog: {
id: 'usr_me',
ref: { id: 'usr_me' },
worlds: [...MOCK_WORLDS],
worldSorting: userDialogWorldSortingOptions.name,
worldOrder: userDialogWorldOrderOptions.descending,
isWorldsLoading: false,
...overrides
},
currentUser: {
id: 'usr_me',
...overrides.currentUser
}
});
return mount(UserDialogWorldsTab, {
global: {
@@ -245,15 +247,17 @@ describe('UserDialogWorldsTab.vue', () => {
.spyOn(worldCoordinatorModule, 'showWorldDialog')
.mockImplementation(() => {});
userStore.userDialog = {
id: 'usr_me',
ref: { id: 'usr_me' },
worlds: [...MOCK_WORLDS],
worldSorting: userDialogWorldSortingOptions.name,
worldOrder: userDialogWorldOrderOptions.descending,
isWorldsLoading: false
};
userStore.currentUser = { id: 'usr_me' };
userStore.$patch({
userDialog: {
id: 'usr_me',
ref: { id: 'usr_me' },
worlds: [...MOCK_WORLDS],
worldSorting: userDialogWorldSortingOptions.name,
worldOrder: userDialogWorldOrderOptions.descending,
isWorldsLoading: false
},
currentUser: { id: 'usr_me' }
});
const wrapper = mount(UserDialogWorldsTab, {
global: {

View File

@@ -0,0 +1,128 @@
import { beforeEach, describe, expect, test, vi } from 'vitest';
const mocks = vi.hoisted(() => ({
useAppearanceSettingsStore: vi.fn()
}));
vi.mock('../../stores', () => ({
useAppearanceSettingsStore: (...args) =>
mocks.useAppearanceSettingsStore(...args)
}));
import { formatDateFilter } from '../dateCoordinator';
describe('dateCoordinator.formatDateFilter', () => {
beforeEach(() => {
vi.restoreAllMocks();
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: false,
currentCulture: 'en-gb'
});
});
test('returns "-" for empty and invalid input', () => {
expect(formatDateFilter('', 'long')).toBe('-');
expect(formatDateFilter(null, 'long')).toBe('-');
expect(formatDateFilter(undefined, 'long')).toBe('-');
expect(formatDateFilter('invalid-date', 'long')).toBe('-');
});
test('uses ISO long format when dtIsoFormat is enabled', () => {
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: true,
dtHour12: false,
currentCulture: 'ja-jp'
});
const result = formatDateFilter('2024-01-02T03:04:05Z', 'long');
expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
});
test('keeps culture unchanged when underscore is not at index 4', () => {
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: false,
currentCulture: 'en_us'
});
const localeSpy = vi.spyOn(Date.prototype, 'toLocaleDateString');
localeSpy.mockReturnValue('01/02/2024');
formatDateFilter('2024-01-02T03:04:05Z', 'date');
expect(localeSpy).toHaveBeenCalledWith(
'en_us',
expect.objectContaining({
year: 'numeric'
})
);
});
test('truncates culture when underscore is at index 4', () => {
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: false,
currentCulture: 'abcd_ef'
});
const localeSpy = vi.spyOn(Date.prototype, 'toLocaleDateString');
localeSpy.mockReturnValue('01/02/2024');
formatDateFilter('2024-01-02T03:04:05Z', 'date');
expect(localeSpy).toHaveBeenCalledWith(
'abcd',
expect.objectContaining({
year: 'numeric'
})
);
});
test('falls back to en-gb when currentCulture is empty', () => {
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: false,
currentCulture: ''
});
const localeSpy = vi.spyOn(Date.prototype, 'toLocaleDateString');
localeSpy.mockReturnValue('02/01/2024');
formatDateFilter('2024-01-02T03:04:05Z', 'date');
expect(localeSpy).toHaveBeenCalledWith(
'en-gb',
expect.objectContaining({
year: 'numeric'
})
);
});
test('uses hourCycle h12 and lowercases AM/PM in short format', () => {
mocks.useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: true,
currentCulture: 'en-us'
});
const localeSpy = vi.spyOn(Date.prototype, 'toLocaleDateString');
localeSpy.mockReturnValue('01/02, 10:30 PM');
const result = formatDateFilter('2024-01-02T22:30:00Z', 'short');
expect(localeSpy).toHaveBeenCalledWith(
'en-us',
expect.objectContaining({
hourCycle: 'h12'
})
);
expect(result).toContain('pm');
expect(result).not.toContain('PM');
});
test('returns "-" and warns when format is unknown', () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const result = formatDateFilter('2024-01-02T03:04:05Z', 'unknown');
expect(result).toBe('-');
expect(warnSpy).toHaveBeenCalledWith('Unknown date format: unknown');
});
});

View File

@@ -54,7 +54,6 @@ export async function runLogoutFlow() {
*/
export function runLoginSuccessFlow(json) {
const updateLoopStore = useUpdateLoopStore();
const userStore = useUserStore();
updateLoopStore.setNextCurrentUserRefresh(420); // 7mins
applyCurrentUser(json);

View File

@@ -185,7 +185,7 @@ export async function getAvatarHistory() {
}
applyAvatar(avatar);
}
avatarStore.avatarHistory = historyArray;
avatarStore.setAvatarHistory(historyArray);
}
/**
@@ -530,8 +530,8 @@ export async function checkAvatarCacheRemote(fileId, ownerUserId) {
if (advancedSettingsStore.avatarRemoteDatabase) {
try {
toast.dismiss(avatarStore.loadingToastId);
avatarStore.loadingToastId = toast.loading(
t('message.avatar_lookup.loading')
avatarStore.setLoadingToastId(
toast.loading(t('message.avatar_lookup.loading'))
);
const avatarId = await lookupAvatarByImageFileId(
ownerUserId,

View File

@@ -113,8 +113,8 @@ export function handleFavoriteAtDelete(ref) {
favoriteStore.cachedFavoritesByObjectId.delete(ref.favoriteId);
favoriteStore.state.favoriteObjects.delete(ref.favoriteId);
friendStore.localFavoriteFriends.delete(ref.favoriteId);
favoriteStore.favoritesSortOrder = favoriteStore.favoritesSortOrder.filter(
(id) => id !== ref.favoriteId
favoriteStore.setFavoritesSortOrder(
favoriteStore.favoritesSortOrder.filter((id) => id !== ref.favoriteId)
);
runUpdateFriendFlow(ref.favoriteId);
@@ -389,14 +389,14 @@ export function refreshFavorites() {
if (favoriteStore.isFavoriteLoading) {
return;
}
favoriteStore.isFavoriteLoading = true;
favoriteStore.setIsFavoriteLoading(true);
queryRequest
.fetch('favoriteLimits')
.then((args) => {
favoriteStore.favoriteLimits = {
favoriteStore.setFavoriteLimits({
...favoriteStore.favoriteLimits,
...args.json
};
});
})
.catch((err) => {
console.error(err);
@@ -430,12 +430,12 @@ export function refreshFavorites() {
}
}
}
favoriteStore.favoritesSortOrder = newFavoriteSortOrder;
favoriteStore.setFavoritesSortOrder(newFavoriteSortOrder);
}
refreshFavoriteItems();
favoriteStore.refreshFavoriteGroups();
friendStore.updateLocalFavoriteFriends();
favoriteStore.isFavoriteLoading = false;
favoriteStore.setIsFavoriteLoading(false);
watchState.isFavoritesLoaded = true;
favoriteStore.countFavoriteGroups();
}
@@ -445,7 +445,7 @@ export function refreshFavorites() {
/**
*
* @param {string} tag
* @returns {void}
* @returns {Promise<void>}
*/
export async function refreshFavoriteAvatars(tag) {
const params = {

View File

@@ -5,7 +5,6 @@ import { friendRequest, userRequest } from '../api';
import { getNameColour } from '../shared/utils';
import { handleFavoriteDelete } from './favoriteCoordinator';
import { useAppearanceSettingsStore } from '../stores/settings/appearance';
import { useFavoriteStore } from '../stores/favorite';
import { useFriendStore } from '../stores/friend';
import { useModalStore } from '../stores/modal';
import { useNotificationStore } from '../stores/notification';
@@ -342,7 +341,6 @@ export function runDeleteFriendshipFlow(
const userStore = useUserStore();
const notificationStore = useNotificationStore();
const sharedFeedStore = useSharedFeedStore();
const favoriteStore = useFavoriteStore();
const uiStore = useUiStore();
const appearanceSettingsStore = useAppearanceSettingsStore();

View File

@@ -17,7 +17,6 @@ import configRepository from '../services/config';
*/
export async function runRefreshFriendsListFlow() {
const updateLoopStore = useUpdateLoopStore();
const userStore = useUserStore();
const friendStore = useFriendStore();
// If we just got user less then 2 min before code call, don't call it again
@@ -38,7 +37,7 @@ export async function runInitFriendsListFlow(t) {
const authStore = useAuthStore();
const userId = userStore.currentUser.id;
friendStore.isRefreshFriendsLoading = true;
friendStore.setIsRefreshFriendsLoading(true);
watchState.isFriendsLoaded = false;
friendStore.resetFriendLog();

View File

@@ -33,10 +33,8 @@ export async function runGameRunningChangedFlow(isGameRunning) {
const userStore = useUserStore();
const instanceStore = useInstanceStore();
const updateLoopStore = useUpdateLoopStore();
const locationStore = useLocationStore();
const gameLogStore = useGameLogStore();
const vrStore = useVrStore();
const avatarStore = useAvatarStore();
const gameStore = useGameStore();
if (isGameRunning) {

View File

@@ -304,7 +304,7 @@ export function addGameLogEntry(gameLog, location) {
if (gameLogStore.lastVideoUrl === gameLog.videoUrl) {
break;
}
gameLogStore.lastVideoUrl = gameLog.videoUrl;
gameLogStore.setLastVideoUrl(gameLog.videoUrl);
gameLogStore.addGameLogVideo(gameLog, location, userId);
break;
case 'video-sync':
@@ -321,7 +321,7 @@ export function addGameLogEntry(gameLog, location) {
) {
break;
}
gameLogStore.lastResourceloadUrl = gameLog.resourceUrl;
gameLogStore.setLastResourceloadUrl(gameLog.resourceUrl);
entry = createResourceLoadEntry(
gameLog.type,
gameLog.dt,

View File

@@ -57,7 +57,6 @@ function applyGroupLanguage(ref) {
*/
export function applyGroup(json) {
const groupStore = useGroupStore();
const userStore = useUserStore();
let ref = groupStore.cachedGroups.get(json.id);
sanitizeEntityJson(json, ['rules', 'name', 'description']);
if (typeof ref === 'undefined') {
@@ -629,7 +628,7 @@ export async function loadCurrentUserGroups(userId, groups) {
await Promise.allSettled(promises);
}
groupStore.currentUserGroupsInit = true;
groupStore.setCurrentUserGroupsInit(true);
getCurrentUserGroups();
}
@@ -691,7 +690,7 @@ export async function updateInGameGroupOrder() {
const groupStore = useGroupStore();
const gameStore = useGameStore();
const userStore = useUserStore();
groupStore.inGameGroupOrder = [];
groupStore.setInGameGroupOrder([]);
try {
const json = await gameStore.getVRChatRegistryKey(
`VRC_GROUP_ORDER_${userStore.currentUser.id}`
@@ -699,7 +698,7 @@ export async function updateInGameGroupOrder() {
if (!json) {
return;
}
groupStore.inGameGroupOrder = JSON.parse(json);
groupStore.setInGameGroupOrder(JSON.parse(json));
} catch (err) {
console.error(err);
}
@@ -925,7 +924,7 @@ export function handleGroupMember(args) {
export async function handleGroupUserInstances(args) {
const groupStore = useGroupStore();
const instanceStore = useInstanceStore();
groupStore.groupInstances = [];
groupStore.setGroupInstances([]);
for (const json of args.json.instances) {
if (args.json.fetchedAt) {
// tack on fetchedAt

View File

@@ -669,7 +669,7 @@ export function handleConfig(args) {
if (!languages) {
return;
}
userStore.subsetOfLanguages = languages;
userStore.setSubsetOfLanguages(languages);
const data = [];
for (const key in languages) {
const value = languages[key];
@@ -678,7 +678,7 @@ export function handleConfig(args) {
value
});
}
userStore.languageDialog.languages = data;
userStore.setLanguageDialogLanguages(data);
}
/**

View File

@@ -1,7 +1,6 @@
import { getGroupName, getWorldName, parseLocation } from '../shared/utils';
import { AppDebug } from '../services/appConfig';
import { database } from '../services/database';
import { useAvatarStore } from '../stores/avatar';
import { getAvatarName } from './avatarCoordinator';
import { useFeedStore } from '../stores/feed';
import { useFriendStore } from '../stores/friend';
@@ -35,7 +34,6 @@ export async function runHandleUserUpdateFlow(
const feedStore = useFeedStore();
const notificationStore = useNotificationStore();
const sharedFeedStore = useSharedFeedStore();
const avatarStore = useAvatarStore();
const generalSettingsStore = useGeneralSettingsStore();
const { state, userDialog, applyUserDialogLocation, checkNote } = userStore;

View File

@@ -4,11 +4,8 @@ import {
updateUserCurrentStatus
} from './friendRelationshipCoordinator';
import { useAuthStore } from '../stores/auth';
import { useAvatarStore } from '../stores/avatar';
import { addAvatarToHistory, addAvatarWearTime } from './avatarCoordinator';
import { useFriendStore } from '../stores/friend';
import { useGameStore } from '../stores/game';
import { useGroupStore } from '../stores/group';
import { applyPresenceGroups } from './groupCoordinator';
import { useInstanceStore } from '../stores/instance';
import { useUserStore } from '../stores/user';
@@ -26,7 +23,6 @@ export function runAvatarSwapFlow(
{ json, ref, isLoggedIn },
{ now = Date.now } = {}
) {
const avatarStore = useAvatarStore();
const gameStore = useGameStore();
if (!isLoggedIn) {
@@ -56,7 +52,7 @@ export function runFirstLoginFlow(ref, { now = Date.now } = {}) {
ref.$previousAvatarSwapTime = now();
}
userStore.cachedUsers.clear(); // clear before running applyUser
userStore.currentUser = ref;
userStore.setCurrentUser(ref);
authStore.loginComplete();
}
@@ -65,9 +61,7 @@ export function runFirstLoginFlow(ref, { now = Date.now } = {}) {
* @param {object} ref Current user state reference.
*/
export function runPostApplySyncFlow(ref) {
const groupStore = useGroupStore();
const instanceStore = useInstanceStore();
const friendStore = useFriendStore();
applyPresenceGroups(ref);
instanceStore.applyQueuedInstance(ref.queuedInstance);

View File

@@ -3,7 +3,6 @@ import { toast } from 'vue-sonner';
import { i18n } from '../plugins/i18n';
import {
checkVRChatCache,
createDefaultWorldRef,
evictMapCache,
getAvailablePlatforms,

View File

@@ -2055,7 +2055,7 @@
"action": "Action",
"auto_backup": "Auto backup every 3 days (deletes after 2 weeks)",
"ask_to_restore": "Ask to restore when no VRC registry settings are present",
"restore_prompt": "VRCX has noticed auto backup of VRC registry settings is enabled but this computer doesn't have any, if you'd like to restore from backup you can do so from here."
"restore_prompt": "VRCX has noticed auto backup of VRChat registry settings is enabled but this computer doesn't have any, if you'd like to restore from backup you can do so from here."
},
"avatar_database_provider": {
"header": "Avatar Database Provider",

View File

@@ -1,100 +0,0 @@
import { beforeEach, describe, expect, test, vi } from 'vitest';
// Mock the store
vi.mock('../../../../stores', () => ({
useAppearanceSettingsStore: vi.fn()
}));
// Mock transitive deps
vi.mock('../../../../views/Feed/Feed.vue', () => ({
default: { template: '<div />' }
}));
vi.mock('../../../../views/Feed/columns.jsx', () => ({ columns: [] }));
vi.mock('../../../../plugins/router', () => ({
default: { push: vi.fn(), currentRoute: { value: {} } }
}));
import { useAppearanceSettingsStore } from '../../../../stores';
import { formatDateFilter } from '../../../../coordinators/dateCoordinator';
describe('formatDateFilter', () => {
beforeEach(() => {
useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: false,
currentCulture: 'en-gb'
});
});
test('returns dash for empty dateStr', () => {
expect(formatDateFilter('', 'long')).toBe('-');
expect(formatDateFilter(null, 'long')).toBe('-');
expect(formatDateFilter(undefined, 'long')).toBe('-');
});
test('returns dash for invalid dateStr', () => {
expect(formatDateFilter('not-a-date', 'long')).toBe('-');
});
test('formats long ISO format', () => {
useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: true,
dtHour12: false,
currentCulture: 'en-gb'
});
const result = formatDateFilter('2023-06-15T14:30:45Z', 'long');
// ISO format: YYYY-MM-DD HH:MM:SS (in local timezone)
expect(result).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
});
test('formats long locale format', () => {
const result = formatDateFilter('2023-06-15T14:30:45Z', 'long');
// Result is locale-dependent; just verify it produces something
expect(result).not.toBe('-');
expect(result.length).toBeGreaterThan(5);
});
test('formats short locale format', () => {
const result = formatDateFilter('2023-06-15T14:30:45Z', 'short');
expect(result).not.toBe('-');
});
test('formats time only', () => {
const result = formatDateFilter('2023-06-15T14:30:45Z', 'time');
expect(result).not.toBe('-');
});
test('formats date only', () => {
const result = formatDateFilter('2023-06-15T14:30:45Z', 'date');
expect(result).not.toBe('-');
});
test('handles culture with no underscore at position 4', () => {
useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: true,
currentCulture: 'en-us'
});
const result = formatDateFilter('2023-06-15T14:30:45Z', 'long');
expect(result).not.toBe('-');
});
test('returns dash for unknown format', () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const result = formatDateFilter('2023-06-15T14:30:45Z', 'unknown');
expect(result).toBe('-');
expect(warnSpy).toHaveBeenCalled();
warnSpy.mockRestore();
});
test('uses hour12 setting', () => {
useAppearanceSettingsStore.mockReturnValue({
dtIsoFormat: false,
dtHour12: true,
currentCulture: 'en-us'
});
const result = formatDateFilter('2023-06-15T14:30:45Z', 'short');
// hour12 should produce am/pm in the output
expect(result).not.toBe('-');
});
});

View File

@@ -187,6 +187,20 @@ export const useAvatarStore = defineStore('Avatar', () => {
database.clearAvatarHistory();
}
/**
* @param {Array} value
*/
function setAvatarHistory(value) {
avatarHistory.value = value;
}
/**
* @param {*} value
*/
function setLoadingToastId(value) {
loadingToastId.value = value;
}
return {
avatarDialog,
avatarHistory,
@@ -200,6 +214,8 @@ export const useAvatarStore = defineStore('Avatar', () => {
getAvatarGallery,
updateVRChatAvatarCache,
clearAvatarHistory,
setAvatarHistory,
setLoadingToastId,
setAvatarDialogVisible,
setAvatarDialogIsFavorite,
setAvatarDialogLoading

View File

@@ -6,7 +6,6 @@ import { useI18n } from 'vue-i18n';
import {
compareByName,
createDefaultFavoriteGroupRef,
removeFromArray,
replaceReactiveObject
} from '../shared/utils';
import { favoriteRequest } from '../api';
@@ -16,8 +15,6 @@ import { useAppearanceSettingsStore } from './settings/appearance';
import { watchState } from '../services/watchState';
import { onLoginStateChanged } from '../coordinators/favoriteCoordinator';
import configRepository from '../services/config';
export const useFavoriteStore = defineStore('Favorite', () => {
const appearanceSettingsStore = useAppearanceSettingsStore();
@@ -736,6 +733,27 @@ export const useFavoriteStore = defineStore('Favorite', () => {
return indexA - indexB;
}
/**
* @param {boolean} value
*/
function setIsFavoriteLoading(value) {
isFavoriteLoading.value = value;
}
/**
* @param {object} value
*/
function setFavoriteLimits(value) {
favoriteLimits.value = value;
}
/**
* @param {Array} value
*/
function setFavoritesSortOrder(value) {
favoritesSortOrder.value = value;
}
return {
state,
@@ -799,6 +817,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
hasLocalFriendFavorite,
isInAnyLocalFriendGroup,
newLocalFriendFavoriteGroup,
countFavoriteGroups
countFavoriteGroups,
setIsFavoriteLoading,
setFavoriteLimits,
setFavoritesSortOrder
};
});

View File

@@ -12,10 +12,7 @@ import {
} from '../shared/utils';
import { getUserMemo } from '../coordinators/memoCoordinator';
import { friendRequest, userRequest } from '../api';
import {
runInitFriendsListFlow,
runRefreshFriendsListFlow
} from '../coordinators/friendSyncCoordinator';
import { runInitFriendsListFlow } from '../coordinators/friendSyncCoordinator';
import {
runPendingOfflineTickFlow,
runUpdateFriendFlow
@@ -45,7 +42,6 @@ export const useFriendStore = defineStore('Friend', () => {
const userStore = useUserStore();
const groupStore = useGroupStore();
const locationStore = useLocationStore();
const favoriteStore = useFavoriteStore();
const router = useRouter();
const t = i18n.global.t;
@@ -1134,6 +1130,13 @@ export const useFriendStore = defineStore('Friend', () => {
friendLog.clear();
}
/**
* @param {boolean} value
*/
function setIsRefreshFriendsLoading(value) {
isRefreshFriendsLoading.value = value;
}
return {
state,
@@ -1169,6 +1172,7 @@ export const useFriendStore = defineStore('Friend', () => {
getFriendLog,
tryApplyFriendOrder,
resetFriendLog,
initFriendLogHistoryTable
initFriendLogHistoryTable,
setIsRefreshFriendsLoading
};
});

View File

@@ -31,8 +31,6 @@ export const useGameStore = defineStore('Game', () => {
init();
// --- Atomic setters ---
/**
* @param {boolean} value Game running flag.
*/
@@ -68,8 +66,6 @@ export const useGameStore = defineStore('Game', () => {
state.lastCrashedTime = value;
}
// --- Self-contained operations (no cross-store deps) ---
/**
* Fetches VRChat cache size from AssetBundleManager.
*/

View File

@@ -2,8 +2,6 @@ import { reactive, ref, shallowRef, watch } from 'vue';
import { defineStore } from 'pinia';
import { useRouter } from 'vue-router';
import dayjs from 'dayjs';
import {
compareGameLogRows,
findUserByDisplayName,
@@ -16,11 +14,7 @@ import { database } from '../../services/database';
import { tryLoadPlayerList } from '../../coordinators/gameLogCoordinator';
import { useAdvancedSettingsStore } from '../settings/advanced';
import { useFriendStore } from '../friend';
import { useGameStore } from '../game';
import { useInstanceStore } from '../instance';
import { useLocationStore } from '../location';
import { useNotificationStore } from '../notification';
import { useSharedFeedStore } from '../sharedFeed';
import { useUiStore } from '../ui';
import { useUserStore } from '../user';
import { useVrStore } from '../vr';
@@ -34,15 +28,11 @@ import * as workerTimers from 'worker-timers';
export const useGameLogStore = defineStore('GameLog', () => {
const notificationStore = useNotificationStore();
const vrStore = useVrStore();
const locationStore = useLocationStore();
const friendStore = useFriendStore();
const instanceStore = useInstanceStore();
const userStore = useUserStore();
const uiStore = useUiStore();
const vrcxStore = useVrcxStore();
const advancedSettingsStore = useAdvancedSettingsStore();
const gameStore = useGameStore();
const sharedFeedStore = useSharedFeedStore();
const router = useRouter();
@@ -449,6 +439,20 @@ export const useGameLogStore = defineStore('GameLog', () => {
gameLogTable.value.loading = false;
}
/**
* @param {string} value
*/
function setLastVideoUrl(value) {
lastVideoUrl.value = value;
}
/**
* @param {string} value
*/
function setLastResourceloadUrl(value) {
lastResourceloadUrl.value = value;
}
return {
state,
@@ -472,6 +476,8 @@ export const useGameLogStore = defineStore('GameLog', () => {
addGameLogVRDancing,
addGameLogZuwaZuwaDance,
addGameLogLSMedia,
addGameLogPopcornPalace
addGameLogPopcornPalace,
setLastVideoUrl,
setLastResourceloadUrl
};
});

View File

@@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
import { hasGroupPermission, replaceBioSymbols } from '../shared/utils';
import { groupRequest, queryRequest } from '../api';
import { groupDialogFilterOptions } from '../shared/constants/';
import { watchState } from '../services/watchState';
export const useGroupStore = defineStore('Group', () => {
@@ -288,6 +287,27 @@ export const useGroupStore = defineStore('Group', () => {
D.visible = true;
}
/**
* @param {boolean} value
*/
function setCurrentUserGroupsInit(value) {
currentUserGroupsInit.value = value;
}
/**
* @param {Array} value
*/
function setInGameGroupOrder(value) {
inGameGroupOrder.value = value;
}
/**
* @param {Array} value
*/
function setGroupInstances(value) {
groupInstances.value = value;
}
return {
groupDialog,
currentUserGroups,
@@ -306,6 +326,9 @@ export const useGroupStore = defineStore('Group', () => {
clearGroupInstances,
setGroupDialogVisible,
showModerateGroupDialog,
showGroupMemberModerationDialog
showGroupMemberModerationDialog,
setCurrentUserGroupsInit,
setInGameGroupOrder,
setGroupInstances
};
});

View File

@@ -75,7 +75,6 @@ export const useNotificationStore = defineStore('Notification', () => {
const sharedFeedStore = useSharedFeedStore();
const instanceStore = useInstanceStore();
const modalStore = useModalStore();
const groupStore = useGroupStore();
const notificationInitStatus = ref(false);
const notificationTable = ref({

View File

@@ -9,9 +9,7 @@ import { instanceRequest, userRequest } from '../api';
import { groupRequest } from '../api/';
import removeConfusables, { removeWhitespace } from '../services/confusables';
import { useAppearanceSettingsStore } from './settings/appearance';
import { useAvatarStore } from './avatar';
import { useFriendStore } from './friend';
import { useGroupStore } from './group';
import { showGroupDialog } from '../coordinators/groupCoordinator';
import { showWorldDialog } from '../coordinators/worldCoordinator';
import { showAvatarDialog } from '../coordinators/avatarCoordinator';
@@ -22,7 +20,6 @@ import {
} from '../coordinators/userCoordinator';
import { useModalStore } from './modal';
import { useUserStore } from './user';
import { useWorldStore } from './world';
import { watchState } from '../services/watchState';
export const useSearchStore = defineStore('Search', () => {
@@ -30,9 +27,6 @@ export const useSearchStore = defineStore('Search', () => {
const router = useRouter();
const appearanceSettingsStore = useAppearanceSettingsStore();
const friendStore = useFriendStore();
const worldStore = useWorldStore();
const avatarStore = useAvatarStore();
const groupStore = useGroupStore();
const modalStore = useModalStore();
const { t } = useI18n();

View File

@@ -22,10 +22,6 @@ import { useWorldStore } from './world';
export const useUiStore = defineStore('Ui', () => {
const notificationStore = useNotificationStore();
const userStore = useUserStore();
const worldStore = useWorldStore();
const avatarStore = useAvatarStore();
const groupStore = useGroupStore();
const instanceStore = useInstanceStore();
const router = useRouter();
const keys = useMagicKeys();

View File

@@ -11,14 +11,11 @@ import { clearVRCXCache } from '../coordinators/vrcxCoordinator';
import { useAuthStore } from './auth';
import { useDiscordPresenceSettingsStore } from './settings/discordPresence';
import { useFriendStore } from './friend';
import { useGameStore } from './game';
import { useGroupStore } from './group';
import { handleGroupUserInstances } from '../coordinators/groupCoordinator';
import {
getCurrentUser,
updateAutoStateChange
} from '../coordinators/userCoordinator';
import { useModerationStore } from './moderation';
import { useUserStore } from './user';
import { useVRCXUpdaterStore } from './vrcxUpdater';
import { useVrStore } from './vr';
@@ -31,12 +28,9 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
const authStore = useAuthStore();
const userStore = useUserStore();
const friendStore = useFriendStore();
const gameStore = useGameStore();
const moderationStore = useModerationStore();
const vrcxStore = useVrcxStore();
const discordPresenceSettingsStore = useDiscordPresenceSettingsStore();
const vrcxUpdaterStore = useVRCXUpdaterStore();
const groupStore = useGroupStore();
const vrStore = useVrStore();
const state = {
nextCurrentUserRefresh: 300,
@@ -152,7 +146,7 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
}
}
} catch (err) {
friendStore.isRefreshFriendsLoading = false;
friendStore.setIsRefreshFriendsLoading(false);
console.error(err);
}
workerTimers.setTimeout(() => updateLoop(), 1000);

View File

@@ -12,13 +12,12 @@ import {
parseLocation,
replaceBioSymbols
} from '../shared/utils';
import { getAllUserMemos, getUserMemo } from '../coordinators/memoCoordinator';
import { getAllUserMemos } from '../coordinators/memoCoordinator';
import { instanceRequest, userRequest } from '../api';
import { AppDebug } from '../services/appConfig';
import { database } from '../services/database';
import { runUpdateCurrentUserLocationFlow } from '../coordinators/locationCoordinator';
import { useAppearanceSettingsStore } from './settings/appearance';
import { useFavoriteStore } from './favorite';
import { useFriendStore } from './friend';
import { useInstanceStore } from './instance';
import { useLocationStore } from './location';
@@ -30,7 +29,6 @@ import * as workerTimers from 'worker-timers';
export const useUserStore = defineStore('User', () => {
const appearanceSettingsStore = useAppearanceSettingsStore();
const friendStore = useFriendStore();
const favoriteStore = useFavoriteStore();
const locationStore = useLocationStore();
const instanceStore = useInstanceStore();
const uiStore = useUiStore();
@@ -657,6 +655,27 @@ export const useUserStore = defineStore('User', () => {
currentUser.value.$travelingToTime = value;
}
/**
* @param {object} value
*/
function setCurrentUser(value) {
currentUser.value = value;
}
/**
* @param {object} value
*/
function setSubsetOfLanguages(value) {
subsetOfLanguages.value = value;
}
/**
* @param {Array} value
*/
function setLanguageDialogLanguages(value) {
languageDialog.value.languages = value;
}
/**
*/
function markCurrentUserGameStarted() {
@@ -715,6 +734,9 @@ export const useUserStore = defineStore('User', () => {
setCurrentUserColour,
setCurrentUserLocationState,
setCurrentUserTravelingToTime,
setCurrentUser,
setSubsetOfLanguages,
setLanguageDialogLanguages,
markCurrentUserGameStarted,
markCurrentUserGameStopped,
checkNote,

View File

@@ -17,21 +17,16 @@ import {
import { debounce, parseLocation } from '../shared/utils';
import { AppDebug } from '../services/appConfig';
import { database } from '../services/database';
import { failedGetRequests } from '../services/request';
import { refreshCustomScript } from '../shared/utils/base/ui';
import { useAdvancedSettingsStore } from './settings/advanced';
import { useAvatarProviderStore } from './avatarProvider';
import { useAvatarStore } from './avatar';
import {
addLocalWorldFavorite,
addLocalAvatarFavorite
} from '../coordinators/favoriteCoordinator';
import { useFavoriteStore } from './favorite';
import { useFriendStore } from './friend';
import { useGalleryStore } from './gallery';
import { useGameLogStore } from './gameLog';
import { useGameStore } from './game';
import { useGroupStore } from './group';
import { showGroupDialog } from '../coordinators/groupCoordinator';
import { showWorldDialog } from '../coordinators/worldCoordinator';
import {
@@ -40,7 +35,6 @@ import {
selectAvatarWithoutConfirmation
} from '../coordinators/avatarCoordinator';
import { showUserDialog, addCustomTag } from '../coordinators/userCoordinator';
import { useInstanceStore } from './instance';
import { useLocationStore } from './location';
import { useModalStore } from './modal';
import { useNotificationStore } from './notification';
@@ -49,7 +43,6 @@ import { useSearchStore } from './search';
import { useUpdateLoopStore } from './updateLoop';
import { useUserStore } from './user';
import { useVrcStatusStore } from './vrcStatus';
import { useWorldStore } from './world';
import { clearVRCXCache } from '../coordinators/vrcxCoordinator';
import { watchState } from '../services/watchState';
@@ -59,12 +52,8 @@ export const useVrcxStore = defineStore('Vrcx', () => {
const gameStore = useGameStore();
const locationStore = useLocationStore();
const notificationStore = useNotificationStore();
const avatarStore = useAvatarStore();
const worldStore = useWorldStore();
const instanceStore = useInstanceStore();
const friendStore = useFriendStore();
const favoriteStore = useFavoriteStore();
const groupStore = useGroupStore();
const userStore = useUserStore();
const photonStore = usePhotonStore();
const advancedSettingsStore = useAdvancedSettingsStore();
@@ -73,7 +62,6 @@ export const useVrcxStore = defineStore('Vrcx', () => {
const gameLogStore = useGameLogStore();
const updateLoopStore = useUpdateLoopStore();
const vrcStatusStore = useVrcStatusStore();
const galleryStore = useGalleryStore();
const { t } = useI18n();
const modalStore = useModalStore();
@@ -279,10 +267,6 @@ export const useVrcxStore = defineStore('Vrcx', () => {
searchLimit.value = value;
}
/**
*
*/
/**
*
* @param data
@@ -644,10 +628,12 @@ export const useVrcxStore = defineStore('Vrcx', () => {
toast.error('Invalid local favorite world command');
break;
}
queryRequest.fetch('world.location', { worldId: id }).then(() => {
searchStore.directAccessWorld(id);
addLocalWorldFavorite(id, group);
});
queryRequest
.fetch('world.location', { worldId: id })
.then(() => {
searchStore.directAccessWorld(id);
addLocalWorldFavorite(id, group);
});
break;
case 'local-favorite-avatar':
console.log('local-favorite-avatar', commandArg);