Compare commits
24 Commits
main
...
home-refre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9351e6b361 | ||
|
|
16dfd1d4a1 | ||
|
|
694ee7e89f | ||
|
|
a48186fa63 | ||
|
|
b888d65ad6 | ||
|
|
9b7779f8eb | ||
|
|
b1496a4f24 | ||
|
|
0aff72be50 | ||
|
|
3fd1a6bb93 | ||
|
|
233c9adf47 | ||
|
|
44bb793609 | ||
|
|
4eb88119a3 | ||
|
|
77d44c697e | ||
|
|
e27d2ebd2e | ||
|
|
3afac8e66b | ||
|
|
afec787883 | ||
|
|
c140c65216 | ||
|
|
1529ef1aff | ||
|
|
f4ee876fea | ||
|
|
39b80cb484 | ||
|
|
cce9d348a9 | ||
|
|
17c0ba4662 | ||
|
|
ad1f9b3626 | ||
|
|
32a2ec4366 |
@ -14,11 +14,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^1.3.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
|
"@vintl/vintl": "^4.4.1",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"floating-vue": "^2.0.0-beta.20",
|
"floating-vue": "^2.0.0-beta.20",
|
||||||
"mixpanel-browser": "^2.47.0",
|
"mixpanel-browser": "^2.47.0",
|
||||||
"ofetch": "^1.0.1",
|
"ofetch": "^1.0.1",
|
||||||
"omorphia": "^0.4.38",
|
"omorphia": "^0.7.3",
|
||||||
"pinia": "^2.1.3",
|
"pinia": "^2.1.3",
|
||||||
"qrcode.vue": "^3.4.0",
|
"qrcode.vue": "^3.4.0",
|
||||||
"tauri-plugin-window-state-api": "github:tauri-apps/tauri-plugin-window-state#v1",
|
"tauri-plugin-window-state-api": "github:tauri-apps/tauri-plugin-window-state#v1",
|
||||||
|
|||||||
396
theseus_gui/pnpm-lock.yaml
generated
396
theseus_gui/pnpm-lock.yaml
generated
@ -8,6 +8,9 @@ dependencies:
|
|||||||
'@tauri-apps/api':
|
'@tauri-apps/api':
|
||||||
specifier: ^1.3.0
|
specifier: ^1.3.0
|
||||||
version: 1.3.0
|
version: 1.3.0
|
||||||
|
'@vintl/vintl':
|
||||||
|
specifier: ^4.4.1
|
||||||
|
version: 4.4.1(vue@3.3.4)
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
version: 1.11.7
|
version: 1.11.7
|
||||||
@ -21,8 +24,8 @@ dependencies:
|
|||||||
specifier: ^1.0.1
|
specifier: ^1.0.1
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
omorphia:
|
omorphia:
|
||||||
specifier: ^0.4.38
|
specifier: ^0.7.3
|
||||||
version: 0.4.38
|
version: 0.7.3(vue@3.3.4)
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^2.1.3
|
specifier: ^2.1.3
|
||||||
version: 2.1.3(vue@3.3.4)
|
version: 2.1.3(vue@3.3.4)
|
||||||
@ -31,7 +34,7 @@ dependencies:
|
|||||||
version: 3.4.0(vue@3.3.4)
|
version: 3.4.0(vue@3.3.4)
|
||||||
tauri-plugin-window-state-api:
|
tauri-plugin-window-state-api:
|
||||||
specifier: github:tauri-apps/tauri-plugin-window-state#v1
|
specifier: github:tauri-apps/tauri-plugin-window-state#v1
|
||||||
version: github.com/tauri-apps/tauri-plugin-window-state/5ea9eb0d4a9affd17269f92c0085935046be3f4a
|
version: github.com/tauri-apps/tauri-plugin-window-state/91fafb628cd0c83ad52bdf9029cad212381f740a
|
||||||
vite-svg-loader:
|
vite-svg-loader:
|
||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
@ -105,6 +108,118 @@ packages:
|
|||||||
'@babel/helper-validator-identifier': 7.19.1
|
'@babel/helper-validator-identifier': 7.19.1
|
||||||
to-fast-properties: 2.0.0
|
to-fast-properties: 2.0.0
|
||||||
|
|
||||||
|
/@braw/async-computed@5.0.2(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-fThqjZBTPvWtbD90Nkd4IldN7dpCkxfvthuk12ZBjkPPjh+wuRGi3HYiUqUSAOOVS0NHSxpsQFfg+qO275FtYA==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^2.7 || ^3.2.45
|
||||||
|
dependencies:
|
||||||
|
vue: 3.3.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/autocomplete@6.12.0(@codemirror/language@6.10.0)(@codemirror/state@6.4.0)(@codemirror/view@6.23.0)(@lezer/common@1.2.1):
|
||||||
|
resolution: {integrity: sha512-r4IjdYFthwbCQyvqnSlx0WBHRHi8nBvU+WjJxFUij81qsBfhNudf/XKKmmC2j3m0LaOYUQTf3qiEK1J8lO1sdg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@codemirror/language': ^6.0.0
|
||||||
|
'@codemirror/state': ^6.0.0
|
||||||
|
'@codemirror/view': ^6.0.0
|
||||||
|
'@lezer/common': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/commands@6.3.3:
|
||||||
|
resolution: {integrity: sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lang-css@6.2.1(@codemirror/view@6.23.0):
|
||||||
|
resolution: {integrity: sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.12.0(@codemirror/language@6.10.0)(@codemirror/state@6.4.0)(@codemirror/view@6.23.0)(@lezer/common@1.2.1)
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/css': 1.1.7
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@codemirror/view'
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lang-html@6.4.7:
|
||||||
|
resolution: {integrity: sha512-y9hWSSO41XlcL4uYwWyk0lEgTHcelWWfRuqmvcAmxfCs0HNWZdriWo/EU43S63SxEZpc1Hd50Itw7ktfQvfkUg==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.12.0(@codemirror/language@6.10.0)(@codemirror/state@6.4.0)(@codemirror/view@6.23.0)(@lezer/common@1.2.1)
|
||||||
|
'@codemirror/lang-css': 6.2.1(@codemirror/view@6.23.0)
|
||||||
|
'@codemirror/lang-javascript': 6.2.1
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/css': 1.1.7
|
||||||
|
'@lezer/html': 1.3.8
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lang-javascript@6.2.1:
|
||||||
|
resolution: {integrity: sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.12.0(@codemirror/language@6.10.0)(@codemirror/state@6.4.0)(@codemirror/view@6.23.0)(@lezer/common@1.2.1)
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/lint': 6.4.2
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/javascript': 1.4.13
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lang-markdown@6.2.4:
|
||||||
|
resolution: {integrity: sha512-UghkA1vSMs8bT7RSZM6vsIocigyah2bV00eRQuZy76401UmFZdsTsbQNBGdyxRQDOLeEvF5iFwap0BM8LKyd+g==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.12.0(@codemirror/language@6.10.0)(@codemirror/state@6.4.0)(@codemirror/view@6.23.0)(@lezer/common@1.2.1)
|
||||||
|
'@codemirror/lang-html': 6.4.7
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/markdown': 1.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/language@6.10.0:
|
||||||
|
resolution: {integrity: sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/highlight': 1.2.0
|
||||||
|
'@lezer/lr': 1.3.14
|
||||||
|
style-mod: 4.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lint@6.4.2:
|
||||||
|
resolution: {integrity: sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
crelt: 1.0.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/state@6.4.0:
|
||||||
|
resolution: {integrity: sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/view@6.23.0:
|
||||||
|
resolution: {integrity: sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
style-mod: 4.1.0
|
||||||
|
w3c-keyname: 2.2.8
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@esbuild/android-arm64@0.17.19:
|
/@esbuild/android-arm64@0.17.19:
|
||||||
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
|
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -350,6 +465,79 @@ packages:
|
|||||||
'@floating-ui/core': 0.3.1
|
'@floating-ui/core': 0.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/ecma402-abstract@1.18.2:
|
||||||
|
resolution: {integrity: sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/intl-localematcher': 0.5.4
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/fast-memoize@2.2.0:
|
||||||
|
resolution: {integrity: sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/icu-messageformat-parser@2.7.5:
|
||||||
|
resolution: {integrity: sha512-zCB53HdGDibh6/2ISEN3TGsFQruQ6gGKMFV94qHNyVrs0tNO6ncKhV0vq0n3Ydz8ipIQ2GaYAvfCoimNOVvKqA==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
'@formatjs/icu-skeleton-parser': 1.7.2
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/icu-skeleton-parser@1.7.2:
|
||||||
|
resolution: {integrity: sha512-nlIXVv280bjGW3ail5Np1+xgGKBnMhwQQIivgbk9xX0af8ESQO+y2VW9TOY7mCrs3WH786uVpZlLimXAlXH7SA==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/intl-displaynames@6.6.6:
|
||||||
|
resolution: {integrity: sha512-Dg5URSjx0uzF8VZXtHb6KYZ6LFEEhCbAbKoYChYHEOnMFTw/ZU3jIo/NrujzQD2EfKPgQzIq73LOUvW6Z/LpFA==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
'@formatjs/intl-localematcher': 0.5.4
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/intl-listformat@7.5.5:
|
||||||
|
resolution: {integrity: sha512-XoI52qrU6aBGJC9KJddqnacuBbPlb/bXFN+lIFVFhQ1RnFHpzuFrlFdjD9am2O7ZSYsyqzYRpkVcXeT1GHkwDQ==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
'@formatjs/intl-localematcher': 0.5.4
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/intl-localematcher@0.4.2:
|
||||||
|
resolution: {integrity: sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/intl-localematcher@0.5.4:
|
||||||
|
resolution: {integrity: sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@formatjs/intl@2.9.11:
|
||||||
|
resolution: {integrity: sha512-wJF5GKuopgeKy75e11JPjueC/XKAxrOndqVEZqg5zDrGuxALUD6Vo/x+oDTQwVZYf2zJnEzqZlUGtv5gSi/ChQ==}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: ^4.7 || 5
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
'@formatjs/fast-memoize': 2.2.0
|
||||||
|
'@formatjs/icu-messageformat-parser': 2.7.5
|
||||||
|
'@formatjs/intl-displaynames': 6.6.6
|
||||||
|
'@formatjs/intl-listformat': 7.5.5
|
||||||
|
intl-messageformat: 10.5.10
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@humanwhocodes/config-array@0.11.8:
|
/@humanwhocodes/config-array@0.11.8:
|
||||||
resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
|
resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
|
||||||
engines: {node: '>=10.10.0'}
|
engines: {node: '>=10.10.0'}
|
||||||
@ -373,6 +561,53 @@ packages:
|
|||||||
/@jridgewell/sourcemap-codec@1.4.15:
|
/@jridgewell/sourcemap-codec@1.4.15:
|
||||||
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
||||||
|
|
||||||
|
/@lezer/common@1.2.1:
|
||||||
|
resolution: {integrity: sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/css@1.1.7:
|
||||||
|
resolution: {integrity: sha512-7BlFFAKNn/b39jJLrhdLSX5A2k56GIJvyLqdmm7UU+7XvequY084iuKDMAEhAmAzHnwDE8FK4OQtsIUssW91tg==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/highlight': 1.2.0
|
||||||
|
'@lezer/lr': 1.3.14
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/highlight@1.2.0:
|
||||||
|
resolution: {integrity: sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/html@1.3.8:
|
||||||
|
resolution: {integrity: sha512-EXseJ3pUzWxE6XQBQdqWHZqqlGQRSuNMBcLb6mZWS2J2v+QZhOObD+3ZIKIcm59ntTzyor4LqFTb72iJc3k23Q==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/highlight': 1.2.0
|
||||||
|
'@lezer/lr': 1.3.14
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/javascript@1.4.13:
|
||||||
|
resolution: {integrity: sha512-5IBr8LIO3xJdJH1e9aj/ZNLE4LSbdsx25wFmGRAZsj2zSmwAYjx26JyU/BYOCpRQlu1jcv1z3vy4NB9+UkfRow==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/highlight': 1.2.0
|
||||||
|
'@lezer/lr': 1.3.14
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/lr@1.3.14:
|
||||||
|
resolution: {integrity: sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/markdown@1.2.0:
|
||||||
|
resolution: {integrity: sha512-d7MwsfAukZJo1GpPrcPGa3MxaFFOqNp0gbqF+3F7pTeNDOgeJN1muXzx1XXDPt+Ac+/voCzsH7qXqnn+xReG/g==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.1
|
||||||
|
'@lezer/highlight': 1.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@nodelib/fs.scandir@2.1.5:
|
/@nodelib/fs.scandir@2.1.5:
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -419,8 +654,8 @@ packages:
|
|||||||
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@tauri-apps/api@1.4.0:
|
/@tauri-apps/api@1.5.3:
|
||||||
resolution: {integrity: sha512-Jd6HPoTM1PZSFIzq7FB8VmMu3qSSyo/3lSwLpoapW+lQ41CL5Dow2KryLg+gyazA/58DRWI9vu/XpEeHK4uMdw==}
|
resolution: {integrity: sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==}
|
||||||
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@ -541,6 +776,21 @@ packages:
|
|||||||
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vintl/vintl@4.4.1(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-1fAnK1Ru4GlUH6v2UPqPMFXvatiZuDlgF3GBrUYDBvs4mzg+j3cmH9GgX7DqBtpRLI1iqcoQF10cnJs/e/0Dvw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.2.47
|
||||||
|
dependencies:
|
||||||
|
'@braw/async-computed': 5.0.2(vue@3.3.4)
|
||||||
|
'@formatjs/icu-messageformat-parser': 2.7.5
|
||||||
|
'@formatjs/intl': 2.9.11
|
||||||
|
'@formatjs/intl-localematcher': 0.4.2
|
||||||
|
intl-messageformat: 10.5.10
|
||||||
|
vue: 3.3.4
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- typescript
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@vitejs/plugin-vue@4.2.3(vite@4.3.9)(vue@3.3.4):
|
/@vitejs/plugin-vue@4.2.3(vite@4.3.9)(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==}
|
resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
@ -629,6 +879,10 @@ packages:
|
|||||||
/@vue/shared@3.3.4:
|
/@vue/shared@3.3.4:
|
||||||
resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
|
resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
|
||||||
|
|
||||||
|
/@yr/monotone-cubic-spline@1.0.3:
|
||||||
|
resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/acorn-jsx@5.3.2(acorn@8.8.2):
|
/acorn-jsx@5.3.2(acorn@8.8.2):
|
||||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -672,6 +926,18 @@ packages:
|
|||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/apexcharts@3.45.1:
|
||||||
|
resolution: {integrity: sha512-pPjj/SA6dfPvR/IKRZF0STdfBGpBh3WRt7K0DFuW9P8erypYkX17EHu3/molPRfo2zSiQwTVpshHC5ncysqfkA==}
|
||||||
|
dependencies:
|
||||||
|
'@yr/monotone-cubic-spline': 1.0.3
|
||||||
|
svg.draggable.js: 2.2.2
|
||||||
|
svg.easing.js: 2.0.0
|
||||||
|
svg.filter.js: 2.0.2
|
||||||
|
svg.pathmorphing.js: 0.1.3
|
||||||
|
svg.resize.js: 1.4.3
|
||||||
|
svg.select.js: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/argparse@2.0.1:
|
/argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
@ -726,7 +992,7 @@ packages:
|
|||||||
normalize-path: 3.0.0
|
normalize-path: 3.0.0
|
||||||
readdirp: 3.6.0
|
readdirp: 3.6.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/color-convert@2.0.1:
|
/color-convert@2.0.1:
|
||||||
@ -753,6 +1019,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/crelt@1.0.6:
|
||||||
|
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cross-spawn@7.0.3:
|
/cross-spawn@7.0.3:
|
||||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -1106,8 +1376,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/fsevents@2.3.2:
|
/fsevents@2.3.3:
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
@ -1193,6 +1463,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/intl-messageformat@10.5.10:
|
||||||
|
resolution: {integrity: sha512-3yzwX6t/my9WRtNiqP05r+/UkpWxwstQiwaHAiuHmDRt7ykzWJ+nceOVjNLZYYWGiSltY+C+Likd8OIVkASepw==}
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 1.18.2
|
||||||
|
'@formatjs/fast-memoize': 2.2.0
|
||||||
|
'@formatjs/icu-messageformat-parser': 2.7.5
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-binary-path@2.1.0:
|
/is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -1355,9 +1634,17 @@ packages:
|
|||||||
ufo: 1.1.2
|
ufo: 1.1.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/omorphia@0.4.38:
|
/omorphia@0.7.3(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-V0vEarmAart6Gf5WuPUZ58TuIiQf7rI5HJpmYU7FVbtdvZ3q08VqyKZflCddbeBSFQ4/N+A+sNr/ELf/jz+Cug==}
|
resolution: {integrity: sha512-Xk9o3xk/rFuZeR0LLoJNbOEvnQjAh6wOTZrksgCDAVuX30cSnpuihI9lsZNlH+4V1TXOB5FpVSHBEA/+LGzwHQ==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.3.4
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@codemirror/commands': 6.3.3
|
||||||
|
'@codemirror/lang-markdown': 6.2.4
|
||||||
|
'@codemirror/language': 6.10.0
|
||||||
|
'@codemirror/state': 6.4.0
|
||||||
|
'@codemirror/view': 6.23.0
|
||||||
|
apexcharts: 3.45.1
|
||||||
dayjs: 1.11.7
|
dayjs: 1.11.7
|
||||||
floating-vue: 2.0.0-beta.20(vue@3.3.4)
|
floating-vue: 2.0.0-beta.20(vue@3.3.4)
|
||||||
highlight.js: 11.8.0
|
highlight.js: 11.8.0
|
||||||
@ -1366,6 +1653,7 @@ packages:
|
|||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
vue-router: 4.2.1(vue@3.3.4)
|
vue-router: 4.2.1(vue@3.3.4)
|
||||||
vue-select: 4.0.0-beta.6(vue@3.3.4)
|
vue-select: 4.0.0-beta.6(vue@3.3.4)
|
||||||
|
vue3-apexcharts: 1.4.4(apexcharts@3.45.1)(vue@3.3.4)
|
||||||
xss: 1.0.14
|
xss: 1.0.14
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@ -1521,7 +1809,7 @@ packages:
|
|||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rollup@3.23.0:
|
/rollup@3.23.0:
|
||||||
@ -1529,7 +1817,7 @@ packages:
|
|||||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/run-parallel@1.2.0:
|
/run-parallel@1.2.0:
|
||||||
@ -1589,6 +1877,10 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/style-mod@4.1.0:
|
||||||
|
resolution: {integrity: sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/supports-color@7.2.0:
|
/supports-color@7.2.0:
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -1596,6 +1888,60 @@ packages:
|
|||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/svg.draggable.js@2.2.2:
|
||||||
|
resolution: {integrity: sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.easing.js@2.0.0:
|
||||||
|
resolution: {integrity: sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.filter.js@2.0.2:
|
||||||
|
resolution: {integrity: sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.js@2.7.1:
|
||||||
|
resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.pathmorphing.js@0.1.3:
|
||||||
|
resolution: {integrity: sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.resize.js@1.4.3:
|
||||||
|
resolution: {integrity: sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
svg.select.js: 2.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.select.js@2.1.2:
|
||||||
|
resolution: {integrity: sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/svg.select.js@3.0.1:
|
||||||
|
resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==}
|
||||||
|
engines: {node: '>= 0.8.0'}
|
||||||
|
dependencies:
|
||||||
|
svg.js: 2.7.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/svgo@3.0.2:
|
/svgo@3.0.2:
|
||||||
resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==}
|
resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -1624,6 +1970,10 @@ packages:
|
|||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tslib@2.6.2:
|
||||||
|
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/type-check@0.4.0:
|
/type-check@0.4.0:
|
||||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@ -1704,7 +2054,7 @@ packages:
|
|||||||
rollup: 3.23.0
|
rollup: 3.23.0
|
||||||
sass: 1.62.1
|
sass: 1.62.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vue-demi@0.14.5(vue@3.3.4):
|
/vue-demi@0.14.5(vue@3.3.4):
|
||||||
@ -1789,6 +2139,16 @@ packages:
|
|||||||
vue-resize: 2.0.0-alpha.1(vue@3.3.4)
|
vue-resize: 2.0.0-alpha.1(vue@3.3.4)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/vue3-apexcharts@1.4.4(apexcharts@3.45.1)(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-TH89uZrxGjaDvkaYAISvj8+k6Bf1rUKFillc8oJirs5XZEPiwM1ELKZQ786wz0rfPqkSHHny2lqqUCK7Rw+LcQ==}
|
||||||
|
peerDependencies:
|
||||||
|
apexcharts: '> 3.0.0'
|
||||||
|
vue: '> 3.0.0'
|
||||||
|
dependencies:
|
||||||
|
apexcharts: 3.45.1
|
||||||
|
vue: 3.3.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
/vue@3.3.4:
|
/vue@3.3.4:
|
||||||
resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
|
resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1798,6 +2158,10 @@ packages:
|
|||||||
'@vue/server-renderer': 3.3.4(vue@3.3.4)
|
'@vue/server-renderer': 3.3.4(vue@3.3.4)
|
||||||
'@vue/shared': 3.3.4
|
'@vue/shared': 3.3.4
|
||||||
|
|
||||||
|
/w3c-keyname@2.2.8:
|
||||||
|
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/which@2.0.2:
|
/which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -1838,10 +2202,10 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
github.com/tauri-apps/tauri-plugin-window-state/5ea9eb0d4a9affd17269f92c0085935046be3f4a:
|
github.com/tauri-apps/tauri-plugin-window-state/91fafb628cd0c83ad52bdf9029cad212381f740a:
|
||||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-window-state/tar.gz/5ea9eb0d4a9affd17269f92c0085935046be3f4a}
|
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-window-state/tar.gz/91fafb628cd0c83ad52bdf9029cad212381f740a}
|
||||||
name: tauri-plugin-window-state-api
|
name: tauri-plugin-window-state-api
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 1.4.0
|
'@tauri-apps/api': 1.5.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
||||||
import {
|
import {
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
LibraryIcon,
|
LibraryIcon,
|
||||||
PlusIcon,
|
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
FileIcon,
|
FileIcon,
|
||||||
Button,
|
Button,
|
||||||
Notifications,
|
Notifications,
|
||||||
XIcon,
|
XIcon,
|
||||||
Card,
|
Card,
|
||||||
|
TextLogo,
|
||||||
|
PlusIcon,
|
||||||
|
Avatar,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
|
|
||||||
import { useLoading, useTheming } from '@/store/state'
|
import { useLoading, useTheming } from '@/store/state'
|
||||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
import { useInstances } from '@/store/instances'
|
||||||
|
// import AccountsCard from './components/ui/AccountsCard.vue'
|
||||||
|
import AccountDropdown from '@/components/ui/platform/AccountDropdown.vue'
|
||||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||||
import { get } from '@/helpers/settings'
|
import { get } from '@/helpers/settings'
|
||||||
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
||||||
@ -23,29 +28,42 @@ import SplashScreen from '@/components/ui/SplashScreen.vue'
|
|||||||
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
|
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
|
||||||
import { handleError, useNotifications } from '@/store/notifications.js'
|
import { handleError, useNotifications } from '@/store/notifications.js'
|
||||||
import { offline_listener, command_listener, warning_listener } from '@/helpers/events.js'
|
import { offline_listener, command_listener, warning_listener } from '@/helpers/events.js'
|
||||||
import { MinimizeIcon, MaximizeIcon, ChatIcon } from '@/assets/icons'
|
import {
|
||||||
import { type } from '@tauri-apps/api/os'
|
MinimizeIcon,
|
||||||
import { appWindow } from '@tauri-apps/api/window'
|
MaximizeIcon,
|
||||||
|
ChatIcon,
|
||||||
|
ArrowLeftFromLineIcon,
|
||||||
|
ArrowRightFromLineIcon,
|
||||||
|
} from '@/assets/icons'
|
||||||
import { isDev, getOS, isOffline, showLauncherLogsFolder } from '@/helpers/utils.js'
|
import { isDev, getOS, isOffline, showLauncherLogsFolder } from '@/helpers/utils.js'
|
||||||
import {
|
import {
|
||||||
mixpanel_track,
|
mixpanel_track,
|
||||||
mixpanel_init,
|
mixpanel_init,
|
||||||
mixpanel_opt_out_tracking,
|
mixpanel_opt_out_tracking,
|
||||||
mixpanel_is_loaded,
|
mixpanel_is_loaded,
|
||||||
} from '@/helpers/mixpanel'
|
} from '@/helpers/mixpanel.js'
|
||||||
|
import { useDisableClicks } from '@/composables/click.js'
|
||||||
|
import { openExternal } from '@/helpers/external.js'
|
||||||
|
import { await_sync, check_safe_loading_bars_complete } from '@/helpers/state.js'
|
||||||
|
import { install_from_file } from '@/helpers/pack.js'
|
||||||
|
import { iconPathAsUrl } from '@/helpers/icon'
|
||||||
|
|
||||||
|
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||||
|
import StickyTitleBar from '@/components/ui/tutorial/StickyTitleBar.vue'
|
||||||
|
import OnboardingScreen from '@/components/ui/tutorial/OnboardingScreen.vue'
|
||||||
|
|
||||||
import { saveWindowState, StateFlags } from 'tauri-plugin-window-state-api'
|
import { saveWindowState, StateFlags } from 'tauri-plugin-window-state-api'
|
||||||
import { getVersion } from '@tauri-apps/api/app'
|
import { getVersion } from '@tauri-apps/api/app'
|
||||||
import { window as TauriWindow } from '@tauri-apps/api'
|
import { window as TauriWindow } from '@tauri-apps/api'
|
||||||
import { TauriEvent } from '@tauri-apps/api/event'
|
import { TauriEvent } from '@tauri-apps/api/event'
|
||||||
import { await_sync, check_safe_loading_bars_complete } from './helpers/state'
|
|
||||||
import { confirm } from '@tauri-apps/api/dialog'
|
import { confirm } from '@tauri-apps/api/dialog'
|
||||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
import { type } from '@tauri-apps/api/os'
|
||||||
import StickyTitleBar from '@/components/ui/tutorial/StickyTitleBar.vue'
|
import { appWindow } from '@tauri-apps/api/window'
|
||||||
import OnboardingScreen from '@/components/ui/tutorial/OnboardingScreen.vue'
|
import { storeToRefs } from 'pinia'
|
||||||
import { install_from_file } from './helpers/pack'
|
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const themeStore = useTheming()
|
||||||
const urlModal = ref(null)
|
const urlModal = ref(null)
|
||||||
|
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
|
|
||||||
const videoPlaying = ref(false)
|
const videoPlaying = ref(false)
|
||||||
@ -53,11 +71,16 @@ const offline = ref(false)
|
|||||||
const showOnboarding = ref(false)
|
const showOnboarding = ref(false)
|
||||||
const nativeDecorations = ref(false)
|
const nativeDecorations = ref(false)
|
||||||
|
|
||||||
|
const sidebarOpen = ref(false)
|
||||||
|
|
||||||
const onboardingVideo = ref()
|
const onboardingVideo = ref()
|
||||||
|
|
||||||
const failureText = ref(null)
|
const failureText = ref(null)
|
||||||
const os = ref('')
|
const os = ref('')
|
||||||
|
|
||||||
|
const instances = useInstances()
|
||||||
|
const { instancesByPlayed } = storeToRefs(instances)
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initialize: async () => {
|
initialize: async () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
@ -154,18 +177,12 @@ const handleClose = async () => {
|
|||||||
await TauriWindow.getCurrent().close()
|
await TauriWindow.getCurrent().close()
|
||||||
}
|
}
|
||||||
|
|
||||||
const openSupport = async () => {
|
const openSupport = () => openExternal(window, 'https://support.modrinth.com/')
|
||||||
window.__TAURI_INVOKE__('tauri', {
|
|
||||||
__tauriModule: 'Shell',
|
|
||||||
message: {
|
|
||||||
cmd: 'open',
|
|
||||||
path: 'https://discord.gg/modrinth',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
TauriWindow.getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async () => {
|
onMounted(() => {
|
||||||
await handleClose()
|
return TauriWindow.getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async () => {
|
||||||
|
await handleClose()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -186,47 +203,9 @@ watch(notificationsWrapper, () => {
|
|||||||
notifications.setNotifs(notificationsWrapper.value)
|
notifications.setNotifs(notificationsWrapper.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
document.querySelector('body').addEventListener('click', function (e) {
|
useDisableClicks(document, window)
|
||||||
let target = e.target
|
|
||||||
while (target != null) {
|
|
||||||
if (target.matches('a')) {
|
|
||||||
if (
|
|
||||||
target.href &&
|
|
||||||
['http://', 'https://', 'mailto:', 'tel:'].some((v) => target.href.startsWith(v)) &&
|
|
||||||
!target.classList.contains('router-link-active') &&
|
|
||||||
!target.href.startsWith('http://localhost') &&
|
|
||||||
!target.href.startsWith('https://tauri.localhost')
|
|
||||||
) {
|
|
||||||
window.__TAURI_INVOKE__('tauri', {
|
|
||||||
__tauriModule: 'Shell',
|
|
||||||
message: {
|
|
||||||
cmd: 'open',
|
|
||||||
path: target.href,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
e.preventDefault()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
target = target.parentElement
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
document.querySelector('body').addEventListener('auxclick', function (e) {
|
// const accounts = ref(null)
|
||||||
// disables middle click -> new tab
|
|
||||||
if (e.button === 1) {
|
|
||||||
e.preventDefault()
|
|
||||||
// instead do a left click
|
|
||||||
const event = new MouseEvent('click', {
|
|
||||||
view: window,
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
})
|
|
||||||
e.target.dispatchEvent(event)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const accounts = ref(null)
|
|
||||||
|
|
||||||
command_listener(async (e) => {
|
command_listener(async (e) => {
|
||||||
if (e.event === 'RunMRPack') {
|
if (e.event === 'RunMRPack') {
|
||||||
@ -242,6 +221,10 @@ command_listener(async (e) => {
|
|||||||
urlModal.value.show(e)
|
urlModal.value.show(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const toggleSidebar = () => {
|
||||||
|
sidebarOpen.value = !sidebarOpen.value
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -288,8 +271,6 @@ command_listener(async (e) => {
|
|||||||
|
|
||||||
<div class="button-row push-right">
|
<div class="button-row push-right">
|
||||||
<Button @click="showLauncherLogsFolder"><FileIcon />Open launcher logs</Button>
|
<Button @click="showLauncherLogsFolder"><FileIcon />Open launcher logs</Button>
|
||||||
|
|
||||||
<Button @click="openSupport"><ChatIcon />Get support</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
@ -297,14 +278,35 @@ command_listener(async (e) => {
|
|||||||
<SplashScreen v-else-if="!videoPlaying && isLoading" app-loading />
|
<SplashScreen v-else-if="!videoPlaying && isLoading" app-loading />
|
||||||
<OnboardingScreen v-else-if="showOnboarding" :finish="() => (showOnboarding = false)" />
|
<OnboardingScreen v-else-if="showOnboarding" :finish="() => (showOnboarding = false)" />
|
||||||
<div v-else class="container">
|
<div v-else class="container">
|
||||||
<div class="nav-container">
|
<div
|
||||||
<div class="nav-section">
|
class="nav-container"
|
||||||
<suspense>
|
data-tauri-drag-region
|
||||||
|
:class="`${sidebarOpen ? 'nav-container__open' : ''}`"
|
||||||
|
:style="{
|
||||||
|
'--sidebar-label-opacity': sidebarOpen ? '1' : '0',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="pages-list">
|
||||||
|
<div class="square-collapsed-space">
|
||||||
|
<Button
|
||||||
|
transparent
|
||||||
|
icon-only
|
||||||
|
class="collapsed-button non-collapse"
|
||||||
|
@click="toggleSidebar"
|
||||||
|
>
|
||||||
|
<ArrowRightFromLineIcon v-if="!sidebarOpen" />
|
||||||
|
<ArrowLeftFromLineIcon v-else />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pages-list">
|
||||||
|
<!-- <suspense>
|
||||||
<AccountsCard ref="accounts" mode="small" />
|
<AccountsCard ref="accounts" mode="small" />
|
||||||
</suspense>
|
</suspense> -->
|
||||||
<div class="pages-list">
|
<div class="pages-list">
|
||||||
<RouterLink v-tooltip="'Home'" to="/" class="btn icon-only collapsed-button">
|
<RouterLink v-tooltip="'Home'" to="/" class="btn icon-only collapsed-button">
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
|
<span class="collapsed-button__label">Home</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
v-tooltip="'Browse'"
|
v-tooltip="'Browse'"
|
||||||
@ -315,35 +317,73 @@ command_listener(async (e) => {
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
|
<span class="collapsed-button__label">Browse</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink v-tooltip="'Library'" to="/library" class="btn icon-only collapsed-button">
|
<RouterLink v-tooltip="'Library'" to="/library" class="btn icon-only collapsed-button">
|
||||||
<LibraryIcon />
|
<LibraryIcon />
|
||||||
|
<span class="collapsed-button__label">Library</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<Suspense>
|
<suspense>
|
||||||
<InstanceCreationModal ref="installationModal" />
|
<InstanceCreationModal ref="installationModal" />
|
||||||
</Suspense>
|
</suspense>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="divider">
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div class="instances pages-list">
|
||||||
|
<RouterLink
|
||||||
|
v-for="instance in instancesByPlayed"
|
||||||
|
:key="instance.id"
|
||||||
|
v-tooltip="instance.metadata.name"
|
||||||
|
:to="`/instance/${encodeURIComponent(instance.path)}`"
|
||||||
|
class="btn icon-only collapsed-button"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
class="collapsed-button__icon"
|
||||||
|
:src="iconPathAsUrl(instance.metadata?.icon)"
|
||||||
|
size="xs"
|
||||||
|
/>
|
||||||
|
<span class="collapsed-button__label">{{ instance.metadata.name }}</span>
|
||||||
|
</RouterLink>
|
||||||
|
</div>
|
||||||
<div class="settings pages-list">
|
<div class="settings pages-list">
|
||||||
|
<Button
|
||||||
|
v-tooltip="'Get Support'"
|
||||||
|
transparent
|
||||||
|
icon-only
|
||||||
|
class="page-item collapsed-button"
|
||||||
|
@click="openSupport"
|
||||||
|
>
|
||||||
|
<ChatIcon />
|
||||||
|
<span class="collapsed-button__label">Support</span>
|
||||||
|
</Button>
|
||||||
|
<RouterLink v-tooltip="'Settings'" to="/settings" class="btn icon-only collapsed-button">
|
||||||
|
<SettingsIcon />
|
||||||
|
<span class="collapsed-button__label">Settings</span>
|
||||||
|
</RouterLink>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="'Create profile'"
|
v-tooltip="'Create profile'"
|
||||||
class="sleek-primary collapsed-button"
|
class="page-item collapsed-button"
|
||||||
icon-only
|
icon-only
|
||||||
:disabled="offline"
|
:disabled="offline"
|
||||||
@click="() => $refs.installationModal.show()"
|
@click="() => $refs.installationModal.show()"
|
||||||
>
|
>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
|
<span class="collapsed-button__label">Create profile</span>
|
||||||
</Button>
|
</Button>
|
||||||
<RouterLink v-tooltip="'Settings'" to="/settings" class="btn icon-only collapsed-button">
|
<AccountDropdown />
|
||||||
<SettingsIcon />
|
|
||||||
</RouterLink>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="view">
|
<div class="view">
|
||||||
<div class="appbar-row">
|
<div class="appbar-row">
|
||||||
|
<!-- Top Bar -->
|
||||||
<div data-tauri-drag-region class="appbar">
|
<div data-tauri-drag-region class="appbar">
|
||||||
<section class="navigation-controls">
|
<section class="navigation-controls">
|
||||||
<Breadcrumbs data-tauri-drag-region />
|
<router-link :to="'/'">
|
||||||
|
<TextLogo class="logo" :animate="false" />
|
||||||
|
</router-link>
|
||||||
|
<Breadcrumbs after-logo data-tauri-drag-region />
|
||||||
</section>
|
</section>
|
||||||
<section class="mod-stats">
|
<section class="mod-stats">
|
||||||
<Suspense>
|
<Suspense>
|
||||||
@ -375,7 +415,7 @@ command_listener(async (e) => {
|
|||||||
<div class="router-view">
|
<div class="router-view">
|
||||||
<ModrinthLoadingIndicator
|
<ModrinthLoadingIndicator
|
||||||
offset-height="var(--appbar-height)"
|
offset-height="var(--appbar-height)"
|
||||||
offset-width="var(--sidebar-width)"
|
:offset-width="sidebarOpen ? 'var(--sidebar-open-width)' : 'var(--sidebar-width)'"
|
||||||
/>
|
/>
|
||||||
<RouterView v-slot="{ Component }">
|
<RouterView v-slot="{ Component }">
|
||||||
<template v-if="Component">
|
<template v-if="Component">
|
||||||
@ -397,9 +437,18 @@ command_listener(async (e) => {
|
|||||||
transition: all ease-in-out 0.1s;
|
transition: all ease-in-out 0.1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: calc(var(--appbar-height) - 2.5rem);
|
||||||
|
width: auto;
|
||||||
|
min-height: 100%;
|
||||||
|
color: var(--color-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
.navigation-controls {
|
.navigation-controls {
|
||||||
flex-grow: 1;
|
display: flex;
|
||||||
width: min-content;
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appbar-row {
|
.appbar-row {
|
||||||
@ -422,7 +471,7 @@ command_listener(async (e) => {
|
|||||||
background-color: var(--color-raised-bg);
|
background-color: var(--color-raised-bg);
|
||||||
color: var(--color-base);
|
color: var(--color-base);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
height: 3.25rem;
|
height: var(--appbar-height);
|
||||||
|
|
||||||
&.close {
|
&.close {
|
||||||
&:hover,
|
&:hover,
|
||||||
@ -441,8 +490,17 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
--appbar-height: 3.25rem;
|
--appbar-height: 4.5rem;
|
||||||
|
|
||||||
|
--sidebar-gap: 0.35rem;
|
||||||
|
|
||||||
--sidebar-width: 4.5rem;
|
--sidebar-width: 4.5rem;
|
||||||
|
--sidebar-open-width: 15rem;
|
||||||
|
--sidebar-padding: 0.75rem;
|
||||||
|
|
||||||
|
--sidebar-icon-size: 1.5rem;
|
||||||
|
--sidebar-button-size: calc(var(--sidebar-width) - calc(var(--sidebar-padding) * 2));
|
||||||
|
--sidebar-open-button-size: calc(var(--sidebar-open-width) - calc(var(--sidebar-padding) * 2));
|
||||||
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -456,11 +514,13 @@ command_listener(async (e) => {
|
|||||||
.appbar {
|
.appbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
background: var(--color-raised-bg);
|
background: var(--color-raised-bg);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: var(--gap-md);
|
padding: var(--gap-md);
|
||||||
height: 3.25rem;
|
height: var(--appbar-height);
|
||||||
gap: var(--gap-sm);
|
gap: var(--gap-sm);
|
||||||
//no select
|
//no select
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -469,7 +529,7 @@ command_listener(async (e) => {
|
|||||||
|
|
||||||
.router-view {
|
.router-view {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 3.125rem);
|
height: calc(100% - var(--appbar-height));
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
@ -488,7 +548,7 @@ command_listener(async (e) => {
|
|||||||
.appbar-failure {
|
.appbar-failure {
|
||||||
display: flex; /* Change to flex to align items horizontally */
|
display: flex; /* Change to flex to align items horizontally */
|
||||||
justify-content: flex-end; /* Align items to the right */
|
justify-content: flex-end; /* Align items to the right */
|
||||||
height: 3.25rem;
|
height: var(--appbar-height);
|
||||||
//no select
|
//no select
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
@ -528,12 +588,75 @@ command_listener(async (e) => {
|
|||||||
.nav-container {
|
.nav-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
padding-left: var(--sidebar-padding);
|
||||||
|
padding-right: var(--sidebar-padding);
|
||||||
|
padding-bottom: var(--sidebar-padding);
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
background-color: var(--color-raised-bg);
|
background-color: var(--color-raised-bg);
|
||||||
box-shadow: var(--shadow-inset-sm), var(--shadow-floating);
|
box-shadow: var(--shadow-inset-sm), var(--shadow-floating);
|
||||||
padding: var(--gap-md);
|
|
||||||
|
transition: all ease-in-out 0.1s;
|
||||||
|
|
||||||
|
width: var(--sidebar-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-container__open {
|
||||||
|
width: var(--sidebar-open-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.square-collapsed-space {
|
||||||
|
height: var(--appbar-height);
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||||
|
.square-collapsed-space {
|
||||||
|
height: auto;
|
||||||
|
padding-bottom: var(--gap-md);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: var(--color-button-bg);
|
||||||
|
border: none;
|
||||||
|
color: var(--color-button-bg);
|
||||||
|
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin-top: var(--sidebar-gap);
|
||||||
|
// div should always have + 1 --sidebar-gap margin to the bottom to be equal
|
||||||
|
margin-bottom: calc(var(--sidebar-gap) * 2);
|
||||||
|
|
||||||
|
padding-left: var(--sidebar-padding);
|
||||||
|
padding-right: var(--sidebar-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.instances {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
flex-flow: column wrap; // This hides any elements that aren't fully visible
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pages-list {
|
.pages-list {
|
||||||
@ -541,9 +664,12 @@ command_listener(async (e) => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
width: 100%;
|
|
||||||
gap: 0.5rem;
|
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
gap: var(--sidebar-gap);
|
||||||
|
|
||||||
|
.page-item,
|
||||||
a {
|
a {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -551,19 +677,20 @@ command_listener(async (e) => {
|
|||||||
background: inherit;
|
background: inherit;
|
||||||
transition: all ease-in-out 0.1s;
|
transition: all ease-in-out 0.1s;
|
||||||
color: var(--color-base);
|
color: var(--color-base);
|
||||||
box-shadow: none;
|
|
||||||
|
|
||||||
&.router-link-active {
|
&.router-link-active {
|
||||||
color: var(--color-contrast);
|
color: var(--color-brand);
|
||||||
background: var(--color-button-bg);
|
background: var(--color-brand-highlight);
|
||||||
box-shadow: var(--shadow-floating);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-button-bg);
|
|
||||||
color: var(--color-contrast);
|
color: var(--color-contrast);
|
||||||
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
background: var(--color-button-bg);
|
||||||
text-decoration: none;
|
}
|
||||||
|
|
||||||
|
&.router-link-active:hover {
|
||||||
|
color: var(--color-brand);
|
||||||
|
background: var(--color-brand-highlight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,78 +700,45 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsed-button {
|
:deep {
|
||||||
height: 3rem !important;
|
.non-collapse {
|
||||||
width: 3rem !important;
|
width: var(--sidebar-button-size) !important;
|
||||||
padding: 0.75rem;
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
box-shadow: none;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 1.5rem !important;
|
|
||||||
height: 1.5rem !important;
|
|
||||||
max-width: 1.5rem !important;
|
|
||||||
max-height: 1.5rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
width: 70%;
|
|
||||||
margin: 0.4rem;
|
|
||||||
|
|
||||||
p:nth-child(1) {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& > p {
|
.collapsed-button {
|
||||||
color: var(--color-base);
|
|
||||||
margin: 0.8rem 0;
|
|
||||||
font-size: 0.7rem;
|
|
||||||
line-height: 0.8125rem;
|
|
||||||
font-weight: 500;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-section {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 4.375rem;
|
|
||||||
|
|
||||||
section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
text-align: left;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
// width: var(--sidebar-icon-size);
|
||||||
margin-bottom: 0.3rem;
|
height: var(--sidebar-button-size);
|
||||||
font-weight: 400;
|
width: 100%;
|
||||||
line-height: 1.25rem;
|
|
||||||
color: var(--color-contrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
flex-shrink: 0;
|
||||||
font-weight: 400;
|
|
||||||
color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-section {
|
padding: var(--sidebar-padding) !important;
|
||||||
display: flex;
|
border-radius: 99999px;
|
||||||
flex-direction: column;
|
box-shadow: none;
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
white-space: nowrap;
|
||||||
width: 100%;
|
overflow: hidden;
|
||||||
height: 100%;
|
|
||||||
gap: 1rem;
|
transition: all ease-in-out 0.1s;
|
||||||
|
|
||||||
|
.collapsed-button__icon,
|
||||||
|
svg {
|
||||||
|
width: var(--sidebar-icon-size) !important;
|
||||||
|
height: var(--sidebar-icon-size) !important;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
border-radius: var(--radius-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-button__label {
|
||||||
|
word-spacing: normal; // Why is this even needed?
|
||||||
|
opacity: var(--sidebar-label-opacity);
|
||||||
|
transition: all ease-in-out 0.1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.video {
|
.video {
|
||||||
|
|||||||
1
theseus_gui/src/assets/icons/arrow-left-from-line.svg
Normal file
1
theseus_gui/src/assets/icons/arrow-left-from-line.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left-from-line"><path d="m9 6-6 6 6 6"/><path d="M3 12h14"/><path d="M21 19V5"/></svg>
|
||||||
|
After Width: | Height: | Size: 294 B |
1
theseus_gui/src/assets/icons/arrow-right-from-line.svg
Normal file
1
theseus_gui/src/assets/icons/arrow-right-from-line.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right-from-line"><path d="M3 5v14"/><path d="M21 12H7"/><path d="m15 18 6-6-6-6"/></svg>
|
||||||
|
After Width: | Height: | Size: 296 B |
@ -12,3 +12,5 @@ export { default as NewInstanceImage } from './new-instance.svg'
|
|||||||
export { default as MenuIcon } from './menu.svg'
|
export { default as MenuIcon } from './menu.svg'
|
||||||
export { default as BugIcon } from './bug.svg'
|
export { default as BugIcon } from './bug.svg'
|
||||||
export { default as ChatIcon } from './messages-square.svg'
|
export { default as ChatIcon } from './messages-square.svg'
|
||||||
|
export { default as ArrowLeftFromLineIcon } from './arrow-left-from-line.svg'
|
||||||
|
export { default as ArrowRightFromLineIcon } from './arrow-right-from-line.svg'
|
||||||
|
|||||||
35
theseus_gui/src/assets/stylesheets/components.scss
Normal file
35
theseus_gui/src/assets/stylesheets/components.scss
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Quick snippets stolen from knossos project to make omorphia components fit
|
||||||
|
|
||||||
|
.btn,
|
||||||
|
.button-base,
|
||||||
|
a {
|
||||||
|
// filter will change
|
||||||
|
will-change: filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconified-input {
|
||||||
|
align-items: center;
|
||||||
|
display: inline-flex;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding-left: 2.25rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within svg {
|
||||||
|
color: var(--color-button-text-active);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
position: absolute;
|
||||||
|
left: 0.75rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
color: var(--color-button-text);
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
XIcon,
|
XIcon,
|
||||||
Button,
|
Button,
|
||||||
formatCategoryHeader,
|
formatCategoryHeader,
|
||||||
ModalConfirm,
|
ConfirmModal,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
@ -233,7 +233,7 @@ const filteredResults = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ModalConfirm
|
<ConfirmModal
|
||||||
ref="confirmModal"
|
ref="confirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
@ -246,7 +246,7 @@ const filteredResults = computed(() => {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
||||||
<Button @click="() => (search = '')">
|
<Button class="r-btn" @click="() => (search = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
ExternalIcon,
|
ExternalIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
ModalConfirm,
|
ConfirmModal,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
import Instance from '@/components/ui/Instance.vue'
|
import Instance from '@/components/ui/Instance.vue'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
@ -227,7 +227,7 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ModalConfirm
|
<ConfirmModal
|
||||||
ref="deleteConfirmModal"
|
ref="deleteConfirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
|
|||||||
@ -83,6 +83,7 @@
|
|||||||
v-tooltip="'Open link'"
|
v-tooltip="'Open link'"
|
||||||
icon-only
|
icon-only
|
||||||
color="raised"
|
color="raised"
|
||||||
|
class="r-btn"
|
||||||
@click="() => clipboardWrite(loginUrl)"
|
@click="() => clipboardWrite(loginUrl)"
|
||||||
>
|
>
|
||||||
<GlobeIcon />
|
<GlobeIcon />
|
||||||
|
|||||||
@ -1,53 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<Button class="breadcrumbs__back transparent" icon-only @click="$router.back()">
|
<div
|
||||||
<ChevronLeftIcon />
|
v-if="props.afterLogo && breadcrumbContext.routeBreadcrumbs.value?.length > 0"
|
||||||
</Button>
|
class="breadcrumbs__item"
|
||||||
<Button class="breadcrumbs__forward transparent" icon-only @click="$router.forward()">
|
>
|
||||||
<ChevronRightIcon />
|
<ChevronRightIcon class="chevron" />
|
||||||
</Button>
|
</div>
|
||||||
{{ breadcrumbData.resetToNames(breadcrumbs) }}
|
<div
|
||||||
<div v-for="breadcrumb in breadcrumbs" :key="breadcrumb.name" class="breadcrumbs__item">
|
v-for="breadcrumb in breadcrumbContext.routeBreadcrumbs.value"
|
||||||
|
:key="breadcrumb.name"
|
||||||
|
class="breadcrumbs__item"
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="breadcrumb.link"
|
v-if="breadcrumb.link"
|
||||||
:to="{
|
:to="{
|
||||||
path: breadcrumb.link.replace('{id}', encodeURIComponent($route.params.id)),
|
path: breadcrumb.link.replace('{id}', encodeURIComponent($route.params.id)),
|
||||||
query: breadcrumb.query,
|
query: breadcrumb.query,
|
||||||
}"
|
}"
|
||||||
>{{
|
>
|
||||||
breadcrumb.name.charAt(0) === '?'
|
{{ breadcrumbName(breadcrumb.name) }}
|
||||||
? breadcrumbData.getName(breadcrumb.name.slice(1))
|
|
||||||
: breadcrumb.name
|
|
||||||
}}
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<span v-else class="selected">{{
|
<span v-else class="selected">
|
||||||
breadcrumb.name.charAt(0) === '?'
|
{{ breadcrumbName(breadcrumb.name) }}
|
||||||
? breadcrumbData.getName(breadcrumb.name.slice(1))
|
</span>
|
||||||
: breadcrumb.name
|
|
||||||
}}</span>
|
|
||||||
<ChevronRightIcon v-if="breadcrumb.link" class="chevron" />
|
<ChevronRightIcon v-if="breadcrumb.link" class="chevron" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ChevronRightIcon, Button, ChevronLeftIcon } from 'omorphia'
|
import { ChevronRightIcon } from 'omorphia'
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs, useBreadcrumbContext } from '@/store/breadcrumbs'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const props = defineProps({
|
||||||
|
afterLogo: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const breadcrumbData = useBreadcrumbs()
|
const breadcrumbData = useBreadcrumbs()
|
||||||
const breadcrumbs = computed(() => {
|
|
||||||
const additionalContext =
|
const route = useRoute()
|
||||||
route.meta.useContext === true
|
const breadcrumbContext = useBreadcrumbContext(route)
|
||||||
? breadcrumbData.context
|
|
||||||
: route.meta.useRootContext === true
|
breadcrumbData.$subscribe(() => {
|
||||||
? breadcrumbData.rootContext
|
breadcrumbData?.resetToNames(breadcrumbContext.routeBreadcrumbs.value)
|
||||||
: null
|
|
||||||
return additionalContext ? [additionalContext, ...route.meta.breadcrumb] : route.meta.breadcrumb
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const breadcrumbName = (bcn) => {
|
||||||
|
if (bcn.charAt(0) === '?') {
|
||||||
|
return breadcrumbData.getName(bcn.slice(1))
|
||||||
|
}
|
||||||
|
return bcn
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -61,7 +68,10 @@ const breadcrumbs = computed(() => {
|
|||||||
vertical-align: center;
|
vertical-align: center;
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
|
|
||||||
.chevron,
|
.chevron {
|
||||||
|
margin: auto 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,7 +112,7 @@ const exportPack = async () => {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<PackageIcon />
|
<PackageIcon />
|
||||||
<input v-model="nameInput" type="text" placeholder="Modpack name" class="input" />
|
<input v-model="nameInput" type="text" placeholder="Modpack name" class="input" />
|
||||||
<Button @click="nameInput = ''">
|
<Button class="r-btn" @click="nameInput = ''">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -122,7 +122,7 @@ const exportPack = async () => {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<VersionIcon />
|
<VersionIcon />
|
||||||
<input v-model="versionInput" type="text" placeholder="1.0.0" class="input" />
|
<input v-model="versionInput" type="text" placeholder="1.0.0" class="input" />
|
||||||
<Button @click="versionInput = ''">
|
<Button class="r-btn" @click="versionInput = ''">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -110,7 +110,7 @@
|
|||||||
placeholder="Path to launcher"
|
placeholder="Path to launcher"
|
||||||
@change="setPath"
|
@change="setPath"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (selectedLauncherPath = '')">
|
<Button class="r-btn" @click="() => (selectedLauncherPath = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Modal, CheckIcon, Badge } from 'omorphia'
|
import { Button, Modal, CheckIcon, Badge, Card } from 'omorphia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useTheming } from '@/store/theme'
|
import { useTheming } from '@/store/theme'
|
||||||
import { update_managed_modrinth_version } from '@/helpers/profile'
|
import { update_managed_modrinth_version } from '@/helpers/profile'
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="action-groups">
|
<div class="action-groups">
|
||||||
<a href="https://discord.modrinth.com" class="link">
|
|
||||||
<ChatIcon />
|
|
||||||
<span> Get support </span>
|
|
||||||
</a>
|
|
||||||
<Button
|
<Button
|
||||||
v-if="currentLoadingBars.length > 0"
|
v-if="currentLoadingBars.length > 0"
|
||||||
ref="infoButton"
|
ref="infoButton"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button show-card-icon"
|
class="download icon-button"
|
||||||
@click="toggleCard()"
|
@click="toggleCard()"
|
||||||
>
|
>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
@ -34,17 +30,17 @@
|
|||||||
<DropdownIcon />
|
<DropdownIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button v-tooltip="'Stop instance'" icon-only class="icon-button stop" @click="stop()">
|
<Button v-tooltip="'Stop instance'" icon-only class="stop icon-button" @click="stop()">
|
||||||
<StopCircleIcon />
|
<StopCircleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-tooltip="'View logs'" icon-only class="icon-button" @click="goToTerminal()">
|
<Button v-tooltip="'View logs'" icon-only class="utility icon-button" @click="goToTerminal()">
|
||||||
<TerminalSquareIcon />
|
<TerminalSquareIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-if="currentLoadingBars.length > 0"
|
v-if="currentLoadingBars.length > 0"
|
||||||
ref="infoButton"
|
ref="infoButton"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button show-card-icon"
|
class="download icon-button"
|
||||||
@click="toggleCard()"
|
@click="toggleCard()"
|
||||||
>
|
>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
@ -84,7 +80,7 @@
|
|||||||
<Button
|
<Button
|
||||||
v-tooltip="'Stop instance'"
|
v-tooltip="'Stop instance'"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button stop"
|
class="stop icon-button"
|
||||||
@click.stop="stop(profile.path)"
|
@click.stop="stop(profile.path)"
|
||||||
>
|
>
|
||||||
<StopCircleIcon />
|
<StopCircleIcon />
|
||||||
@ -92,7 +88,7 @@
|
|||||||
<Button
|
<Button
|
||||||
v-tooltip="'View logs'"
|
v-tooltip="'View logs'"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button"
|
class="utility icon-button"
|
||||||
@click.stop="goToTerminal(profile.path)"
|
@click.stop="goToTerminal(profile.path)"
|
||||||
>
|
>
|
||||||
<TerminalSquareIcon />
|
<TerminalSquareIcon />
|
||||||
@ -124,7 +120,6 @@ import { refreshOffline, isOffline } from '@/helpers/utils.js'
|
|||||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||||
import { ChatIcon } from '@/assets/icons'
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const card = ref(null)
|
const card = ref(null)
|
||||||
@ -327,12 +322,16 @@ onBeforeUnmount(() => {
|
|||||||
.icon-button {
|
.icon-button {
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
width: 1.25rem !important;
|
|
||||||
height: 1.25rem !important;
|
|
||||||
|
|
||||||
&.stop {
|
padding: 0 !important;
|
||||||
--text-color: var(--color-red) !important;
|
}
|
||||||
}
|
|
||||||
|
.stop {
|
||||||
|
color: var(--color-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.utility {
|
||||||
|
color: var(--color-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-card {
|
.info-card {
|
||||||
@ -394,7 +393,7 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.show-card-icon {
|
.download {
|
||||||
color: var(--color-brand);
|
color: var(--color-brand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
94
theseus_gui/src/components/ui/platform/AccountDropdown.vue
Normal file
94
theseus_gui/src/components/ui/platform/AccountDropdown.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div class="account-dropdown">
|
||||||
|
<Modal
|
||||||
|
ref="modrinthLoginModal"
|
||||||
|
class="login-screen-modal"
|
||||||
|
:noblur="!themeStore.advancedRendering"
|
||||||
|
>
|
||||||
|
<ModrinthLoginScreen :modal="true" :prev-page="signInAfter" :next-page="signInAfter" />
|
||||||
|
</Modal>
|
||||||
|
<PopoutMenu class="btn btn-transparent collapsed-button" direction="up" position="right">
|
||||||
|
<Avatar class="collapsed-button__icon" circle size="sm" :src="auth?.user?.avatar_url" />
|
||||||
|
<span class="collapsed-button__label">
|
||||||
|
<template v-if="auth?.user">
|
||||||
|
{{ auth.user.username }}
|
||||||
|
</template>
|
||||||
|
<template v-else> Sign in </template>
|
||||||
|
</span>
|
||||||
|
<template #menu>
|
||||||
|
<div class="selection-menu">
|
||||||
|
<template v-if="auth?.user">
|
||||||
|
<Button color="danger" transparent hover-filled-only @click="() => mrAuth.logout()">
|
||||||
|
<LogOutIcon /> Sign out
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
transparent
|
||||||
|
hover-filled-only
|
||||||
|
@click="() => $refs.modrinthLoginModal.show()"
|
||||||
|
>
|
||||||
|
<LogInIcon /> Sign in
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</PopoutMenu>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Avatar, Button, PopoutMenu, LogOutIcon, LogInIcon, Modal } from 'omorphia'
|
||||||
|
|
||||||
|
import { useTheming } from '@/store/state'
|
||||||
|
import { useModrinthAuth } from '@/store/mr_auth.js'
|
||||||
|
|
||||||
|
import ModrinthLoginScreen from '@/components/ui/tutorial/ModrinthLoginScreen.vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
const themeStore = useTheming()
|
||||||
|
const mrAuth = useModrinthAuth()
|
||||||
|
const { auth } = storeToRefs(mrAuth)
|
||||||
|
|
||||||
|
const modrinthLoginModal = ref(null)
|
||||||
|
|
||||||
|
const signInAfter = async () => {
|
||||||
|
modrinthLoginModal.value?.hide()
|
||||||
|
await mrAuth.get()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.account-dropdown {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep {
|
||||||
|
.login-screen-modal {
|
||||||
|
.modal-container .modal-body {
|
||||||
|
width: auto;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -23,7 +23,7 @@ defineProps({
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
||||||
<Button @click="() => (search = '')">
|
<Button class="r-btn" @click="() => (search = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -189,7 +189,7 @@ defineProps({
|
|||||||
type="text"
|
type="text"
|
||||||
:placeholder="`Search ${projectType}s...`"
|
:placeholder="`Search ${projectType}s...`"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (query = '')">
|
<Button class="r-btn" @click="() => (query = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -132,7 +132,7 @@ const next = async () => {
|
|||||||
placeholder="Path to launcher"
|
placeholder="Path to launcher"
|
||||||
@change="setPath"
|
@change="setPath"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (selectedLauncherPath = '')">
|
<Button class="r-btn" @click="() => (selectedLauncherPath = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -119,7 +119,7 @@ const clipboardWrite = async (a) => {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<LogInIcon />
|
<LogInIcon />
|
||||||
<input type="text" :value="loginUrl" readonly />
|
<input type="text" :value="loginUrl" readonly />
|
||||||
<Button v-tooltip="'Open link'" icon-only color="raised" @click="openUrl">
|
<Button v-tooltip="'Open link'" icon-only color="raised" class="r-btn" @click="openUrl">
|
||||||
<GlobeIcon />
|
<GlobeIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
47
theseus_gui/src/composables/click.js
Normal file
47
theseus_gui/src/composables/click.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { openExternal } from '@/helpers/external'
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
|
const disableMiddleClick = (e) => {
|
||||||
|
// disables middle click -> new tab
|
||||||
|
if (e.button === 1) {
|
||||||
|
e.preventDefault()
|
||||||
|
// instead do a left click
|
||||||
|
const event = new MouseEvent('click', {
|
||||||
|
view: window,
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
})
|
||||||
|
e.target.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableExternalNavigation = (e, window) => {
|
||||||
|
let target = e.target
|
||||||
|
|
||||||
|
while (target != null) {
|
||||||
|
if (target.matches('a')) {
|
||||||
|
if (
|
||||||
|
target.href &&
|
||||||
|
['http://', 'https://', 'mailto:', 'tel:'].some((v) => target.href.startsWith(v)) &&
|
||||||
|
!target.classList.contains('router-link-active') &&
|
||||||
|
!target.href.startsWith('http://localhost') &&
|
||||||
|
!target.href.startsWith('https://tauri.localhost')
|
||||||
|
) {
|
||||||
|
openExternal(window, target.href)
|
||||||
|
}
|
||||||
|
e.preventDefault()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
target = target.parentElement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDisableClicks = (document, window) => {
|
||||||
|
onMounted(() => {
|
||||||
|
document
|
||||||
|
.querySelector('body')
|
||||||
|
.addEventListener('click', (e) => disableExternalNavigation(e, window))
|
||||||
|
|
||||||
|
document.querySelector('body').addEventListener('auxclick', disableMiddleClick)
|
||||||
|
})
|
||||||
|
}
|
||||||
9
theseus_gui/src/helpers/external.js
Normal file
9
theseus_gui/src/helpers/external.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export const openExternal = (window, url) => {
|
||||||
|
window.__TAURI_INVOKE__('tauri', {
|
||||||
|
__tauriModule: 'Shell',
|
||||||
|
message: {
|
||||||
|
cmd: 'open',
|
||||||
|
path: url,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
12
theseus_gui/src/helpers/icon.js
Normal file
12
theseus_gui/src/helpers/icon.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||||
|
|
||||||
|
export const iconPathAsUrl = (iconPath) => {
|
||||||
|
if (!iconPath) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const startsWithHttp = iconPath.startsWith('http')
|
||||||
|
if (startsWithHttp) {
|
||||||
|
return iconPath
|
||||||
|
}
|
||||||
|
return convertFileSrc(iconPath)
|
||||||
|
}
|
||||||
@ -2,8 +2,10 @@ import { createApp } from 'vue'
|
|||||||
import router from '@/routes'
|
import router from '@/routes'
|
||||||
import App from '@/App.vue'
|
import App from '@/App.vue'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
import { createPlugin as createVintl } from '@vintl/vintl/plugin'
|
||||||
import 'omorphia/dist/style.css'
|
import 'omorphia/dist/style.css'
|
||||||
import '@/assets/stylesheets/global.scss'
|
import '@/assets/stylesheets/global.scss'
|
||||||
|
import '@/assets/stylesheets/components.scss'
|
||||||
import 'floating-vue/dist/style.css'
|
import 'floating-vue/dist/style.css'
|
||||||
import FloatingVue from 'floating-vue'
|
import FloatingVue from 'floating-vue'
|
||||||
import { get_opening_command, initialize_state } from '@/helpers/state'
|
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||||
@ -14,9 +16,25 @@ import { isDev } from './helpers/utils.js'
|
|||||||
|
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
|
const vintl = createVintl({
|
||||||
|
controllerOpts: {
|
||||||
|
defaultLocale: 'en-US',
|
||||||
|
locale: 'en-US',
|
||||||
|
locales: [
|
||||||
|
{
|
||||||
|
tag: 'en-US',
|
||||||
|
meta: {
|
||||||
|
displayName: 'American English',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
let app = createApp(App)
|
let app = createApp(App)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
|
app.use(vintl)
|
||||||
app.use(FloatingVue)
|
app.use(FloatingVue)
|
||||||
app.mixin(loadCssMixin)
|
app.mixin(loadCssMixin)
|
||||||
|
|
||||||
@ -54,7 +72,7 @@ initialize_state()
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
mountedApp.initialize()
|
mountedApp.initialize()
|
||||||
get_opening_command().then((command) => {
|
get_opening_command().then((command) => {
|
||||||
console.log(JSON.stringify(command)) // change me to use whatever FE command handler is made
|
console.log('Opening Command', JSON.stringify(command)) // change me to use whatever FE command handler is made
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -705,7 +705,7 @@ onUnmounted(() => unlistenOffline())
|
|||||||
:placeholder="`Search ${projectType}s...`"
|
:placeholder="`Search ${projectType}s...`"
|
||||||
@input="onSearchChange(1)"
|
@input="onSearchChange(1)"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => clearSearch()">
|
<Button class="r-btn" @click="() => clearSearch()">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -843,13 +843,6 @@ onUnmounted(() => unlistenOffline())
|
|||||||
min-height: min-content !important;
|
min-height: min-content !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconified-input {
|
|
||||||
input {
|
|
||||||
max-width: none !important;
|
|
||||||
flex-basis: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-panel-container {
|
.search-panel-container {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onUnmounted, shallowRef, computed } from 'vue'
|
import { ref, onUnmounted, computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import RowDisplay from '@/components/RowDisplay.vue'
|
import RowDisplay from '@/components/RowDisplay.vue'
|
||||||
import { list } from '@/helpers/profile.js'
|
|
||||||
import { offline_listener, profile_listener } from '@/helpers/events'
|
import { offline_listener, profile_listener } from '@/helpers/events'
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||||
import { useFetch } from '@/helpers/fetch.js'
|
import { useFetch } from '@/helpers/fetch.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import { isOffline } from '@/helpers/utils'
|
import { isOffline } from '@/helpers/utils'
|
||||||
|
import { useInstances } from '@/store/instances'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const featuredModpacks = ref({})
|
const featuredModpacks = ref({})
|
||||||
const featuredMods = ref({})
|
const featuredMods = ref({})
|
||||||
@ -19,18 +18,17 @@ const breadcrumbs = useBreadcrumbs()
|
|||||||
|
|
||||||
breadcrumbs.setRootContext({ name: 'Home', link: route.path })
|
breadcrumbs.setRootContext({ name: 'Home', link: route.path })
|
||||||
|
|
||||||
const recentInstances = shallowRef([])
|
|
||||||
|
|
||||||
const offline = ref(await isOffline())
|
const offline = ref(await isOffline())
|
||||||
|
|
||||||
const getInstances = async () => {
|
const instancesStore = useInstances()
|
||||||
const profiles = await list(true).catch(handleError)
|
const { instancesByPlayed } = storeToRefs(instancesStore)
|
||||||
recentInstances.value = Object.values(profiles).sort((a, b) => {
|
|
||||||
return dayjs(b.metadata.last_played ?? 0).diff(dayjs(a.metadata.last_played ?? 0))
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const getInstances = async () => {
|
||||||
|
await instancesStore.refreshInstances()
|
||||||
|
|
||||||
|
// filter? TODO: Change this to be reactive along with fetching the rest.
|
||||||
let filters = []
|
let filters = []
|
||||||
for (const instance of recentInstances.value) {
|
for (const instance of instancesByPlayed.value) {
|
||||||
if (instance.metadata.linked_data && instance.metadata.linked_data.project_id) {
|
if (instance.metadata.linked_data && instance.metadata.linked_data.project_id) {
|
||||||
filters.push(`NOT"project_id"="${instance.metadata.linked_data.project_id}"`)
|
filters.push(`NOT"project_id"="${instance.metadata.linked_data.project_id}"`)
|
||||||
}
|
}
|
||||||
@ -84,7 +82,7 @@ const unlistenOffline = await offline_listener(async (b) => {
|
|||||||
// computed sums of recentInstances, featuredModpacks, featuredMods, treating them as arrays if they are not
|
// computed sums of recentInstances, featuredModpacks, featuredMods, treating them as arrays if they are not
|
||||||
const total = computed(() => {
|
const total = computed(() => {
|
||||||
return (
|
return (
|
||||||
(recentInstances.value?.length ?? 0) +
|
(instancesByPlayed.value?.length ?? 0) +
|
||||||
(featuredModpacks.value?.length ?? 0) +
|
(featuredModpacks.value?.length ?? 0) +
|
||||||
(featuredMods.value?.length ?? 0)
|
(featuredMods.value?.length ?? 0)
|
||||||
)
|
)
|
||||||
@ -104,7 +102,7 @@ onUnmounted(() => {
|
|||||||
{
|
{
|
||||||
label: 'Jump back in',
|
label: 'Jump back in',
|
||||||
route: '/library',
|
route: '/library',
|
||||||
instances: recentInstances,
|
instances: instancesByPlayed,
|
||||||
downloaded: true,
|
downloaded: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { onUnmounted, ref, shallowRef } from 'vue'
|
import { onUnmounted, ref } from 'vue'
|
||||||
import GridDisplay from '@/components/GridDisplay.vue'
|
import GridDisplay from '@/components/GridDisplay.vue'
|
||||||
import { list } from '@/helpers/profile.js'
|
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||||
import { offline_listener, profile_listener } from '@/helpers/events.js'
|
import { offline_listener, profile_listener } from '@/helpers/events.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
|
||||||
import { Button, PlusIcon } from 'omorphia'
|
import { Button, PlusIcon } from 'omorphia'
|
||||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||||
import { NewInstanceImage } from '@/assets/icons'
|
import { NewInstanceImage } from '@/assets/icons'
|
||||||
import { isOffline } from '@/helpers/utils'
|
import { isOffline } from '@/helpers/utils'
|
||||||
|
import { useInstances } from '@/store/instances'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const breadcrumbs = useBreadcrumbs()
|
const breadcrumbs = useBreadcrumbs()
|
||||||
|
|
||||||
breadcrumbs.setRootContext({ name: 'Library', link: route.path })
|
breadcrumbs.setRootContext({ name: 'Library', link: route.path })
|
||||||
|
|
||||||
const profiles = await list(true).catch(handleError)
|
const instancesStore = useInstances()
|
||||||
const instances = shallowRef(Object.values(profiles))
|
const { instanceList } = storeToRefs(instancesStore)
|
||||||
|
|
||||||
const offline = ref(await isOffline())
|
const offline = ref(await isOffline())
|
||||||
const unlistenOffline = await offline_listener((b) => {
|
const unlistenOffline = await offline_listener((b) => {
|
||||||
@ -25,9 +25,9 @@ const unlistenOffline = await offline_listener((b) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const unlistenProfile = await profile_listener(async () => {
|
const unlistenProfile = await profile_listener(async () => {
|
||||||
const profiles = await list(true).catch(handleError)
|
await instancesStore.refreshInstances()
|
||||||
instances.value = Object.values(profiles)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
unlistenProfile()
|
unlistenProfile()
|
||||||
unlistenOffline()
|
unlistenOffline()
|
||||||
@ -35,7 +35,7 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<GridDisplay v-if="instances.length > 0" label="Instances" :instances="instances" />
|
<GridDisplay v-if="instanceList.length > 0" label="Instances" :instances="instanceList" />
|
||||||
<div v-else class="no-instance">
|
<div v-else class="no-instance">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<NewInstanceImage />
|
<NewInstanceImage />
|
||||||
|
|||||||
@ -16,13 +16,16 @@ import {
|
|||||||
import { handleError, useTheming } from '@/store/state'
|
import { handleError, useTheming } from '@/store/state'
|
||||||
import { is_dir_writeable, change_config_dir, get, set } from '@/helpers/settings'
|
import { is_dir_writeable, change_config_dir, get, set } from '@/helpers/settings'
|
||||||
import { get_max_memory } from '@/helpers/jre'
|
import { get_max_memory } from '@/helpers/jre'
|
||||||
import { get as getCreds, logout } from '@/helpers/mr_auth.js'
|
|
||||||
|
import { useModrinthAuth } from '@/store/mr_auth.js'
|
||||||
|
|
||||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||||
import ModrinthLoginScreen from '@/components/ui/tutorial/ModrinthLoginScreen.vue'
|
import ModrinthLoginScreen from '@/components/ui/tutorial/ModrinthLoginScreen.vue'
|
||||||
import { mixpanel_opt_out_tracking, mixpanel_opt_in_tracking } from '@/helpers/mixpanel'
|
import { mixpanel_opt_out_tracking, mixpanel_opt_in_tracking } from '@/helpers/mixpanel'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/api/dialog'
|
||||||
import { getOS } from '@/helpers/utils.js'
|
import { getOS } from '@/helpers/utils.js'
|
||||||
import { version } from '../../package.json'
|
import { version } from '../../package.json'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const pageOptions = ['Home', 'Library']
|
const pageOptions = ['Home', 'Library']
|
||||||
|
|
||||||
@ -105,17 +108,13 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
const credentials = ref(await getCreds().catch(handleError))
|
const mrAuth = useModrinthAuth()
|
||||||
|
const { auth } = storeToRefs(mrAuth)
|
||||||
const loginScreenModal = ref()
|
const loginScreenModal = ref()
|
||||||
|
|
||||||
async function logOut() {
|
|
||||||
await logout().catch(handleError)
|
|
||||||
credentials.value = await getCreds().catch(handleError)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function signInAfter() {
|
async function signInAfter() {
|
||||||
loginScreenModal.value.hide()
|
loginScreenModal.value.hide()
|
||||||
credentials.value = await getCreds().catch(handleError)
|
await mrAuth.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findLauncherDir() {
|
async function findLauncherDir() {
|
||||||
@ -163,12 +162,12 @@ async function refreshDir() {
|
|||||||
<div class="adjacent-input">
|
<div class="adjacent-input">
|
||||||
<label for="theme">
|
<label for="theme">
|
||||||
<span class="label__title">Manage account</span>
|
<span class="label__title">Manage account</span>
|
||||||
<span v-if="credentials" class="label__description">
|
<span v-if="auth" class="label__description">
|
||||||
You are currently logged in as {{ credentials.user.username }}.
|
You are currently logged in as {{ auth?.user.username }}.
|
||||||
</span>
|
</span>
|
||||||
<span v-else> Sign in to your Modrinth account. </span>
|
<span v-else> Sign in to your Modrinth account. </span>
|
||||||
</label>
|
</label>
|
||||||
<button v-if="credentials" class="btn" @click="logOut">
|
<button v-if="auth" class="btn" @click="mrAuth.logout()">
|
||||||
<LogOutIcon />
|
<LogOutIcon />
|
||||||
Sign out
|
Sign out
|
||||||
</button>
|
</button>
|
||||||
@ -187,7 +186,7 @@ async function refreshDir() {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<BoxIcon />
|
<BoxIcon />
|
||||||
<input id="appDir" v-model="settingsDir" type="text" class="input" />
|
<input id="appDir" v-model="settingsDir" type="text" class="input" />
|
||||||
<Button @click="findLauncherDir">
|
<Button class="r-btn" @click="findLauncherDir">
|
||||||
<FolderSearchIcon />
|
<FolderSearchIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -146,20 +146,39 @@ import {
|
|||||||
} from '@/helpers/process'
|
} from '@/helpers/process'
|
||||||
import { offline_listener, process_listener, profile_listener } from '@/helpers/events'
|
import { offline_listener, process_listener, profile_listener } from '@/helpers/events'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ref, onUnmounted } from 'vue'
|
import { ref, onUnmounted, defineProps, watch } from 'vue'
|
||||||
import { handleError, useBreadcrumbs, useLoading } from '@/store/state'
|
import { handleError, useBreadcrumbs, useLoading } from '@/store/state'
|
||||||
import { isOffline, showProfileInFolder } from '@/helpers/utils.js'
|
import { isOffline, showProfileInFolder } from '@/helpers/utils.js'
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||||
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||||
import { useFetch } from '@/helpers/fetch'
|
import { useFetch } from '@/helpers/fetch'
|
||||||
|
import { useInstances } from '@/store/instances'
|
||||||
|
|
||||||
const route = useRoute()
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const breadcrumbs = useBreadcrumbs()
|
const breadcrumbs = useBreadcrumbs()
|
||||||
|
|
||||||
const instance = ref(await get(route.params.id).catch(handleError))
|
const instance = ref(await get(route.params.id || props.id).catch(handleError))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.params.id,
|
||||||
|
async (id) => {
|
||||||
|
if (!id) return
|
||||||
|
instance.value = await get(id).catch(handleError)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const instancesStore = useInstances()
|
||||||
|
|
||||||
breadcrumbs.setName(
|
breadcrumbs.setName(
|
||||||
'Instance',
|
'Instance',
|
||||||
@ -194,6 +213,8 @@ const startInstance = async (context) => {
|
|||||||
game_version: instance.value.metadata.game_version,
|
game_version: instance.value.metadata.game_version,
|
||||||
source: context,
|
source: context,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await instancesStore.refreshInstances()
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkProcess = async () => {
|
const checkProcess = async () => {
|
||||||
@ -419,6 +440,7 @@ Button {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
justify-content: start;
|
||||||
|
|
||||||
&.router-link-exact-active {
|
&.router-link-exact-active {
|
||||||
box-shadow: var(--shadow-inset-lg);
|
box-shadow: var(--shadow-inset-lg);
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
class="text-input"
|
class="text-input"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (searchFilter = '')">
|
<Button class="r-btn" @click="() => (searchFilter = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -43,23 +43,27 @@
|
|||||||
Update all
|
Update all
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<DropdownButton
|
<div v-if="!isPackLocked" class="joined-buttons">
|
||||||
v-if="!isPackLocked"
|
<Button color="primary" @click="onSearchContent">
|
||||||
:options="['search', 'from_file']"
|
|
||||||
default-value="search"
|
|
||||||
name="add-content-dropdown"
|
|
||||||
color="primary"
|
|
||||||
@option-click="handleContentOptionClick"
|
|
||||||
>
|
|
||||||
<template #search>
|
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
<span class="no-wrap"> Add content </span>
|
Add content
|
||||||
</template>
|
</Button>
|
||||||
<template #from_file>
|
<OverflowMenu
|
||||||
<FolderOpenIcon />
|
:options="[
|
||||||
<span class="no-wrap"> Add from file </span>
|
{
|
||||||
</template>
|
id: 'file',
|
||||||
</DropdownButton>
|
action: onFileContent,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
class="btn btn-primary btn-dropdown-animation icon-only"
|
||||||
|
>
|
||||||
|
<DropdownIcon />
|
||||||
|
<template #file>
|
||||||
|
<FolderOpenIcon />
|
||||||
|
Add from file
|
||||||
|
</template>
|
||||||
|
</OverflowMenu>
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Pagination
|
<Pagination
|
||||||
v-if="projects.length > 0"
|
v-if="projects.length > 0"
|
||||||
@ -283,23 +287,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3>No projects found</h3>
|
<h3>No projects found</h3>
|
||||||
<p class="empty-subtitle">Add a project to get started</p>
|
<p class="empty-subtitle">Add a project to get started</p>
|
||||||
<div class="empty-action">
|
<div v-if="!isPackLocked" class="joined-buttons">
|
||||||
<DropdownButton
|
<Button color="primary" @click="onSearchContent">
|
||||||
:options="['search', 'from_file']"
|
<SearchIcon />
|
||||||
default-value="search"
|
Add content
|
||||||
name="add-content-dropdown-from-empty"
|
</Button>
|
||||||
color="primary"
|
<OverflowMenu
|
||||||
@option-click="handleContentOptionClick"
|
:options="[
|
||||||
|
{
|
||||||
|
id: 'file',
|
||||||
|
action: onFileContent,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
class="btn btn-primary btn-dropdown-animation icon-only"
|
||||||
>
|
>
|
||||||
<template #search>
|
<DropdownIcon />
|
||||||
<SearchIcon />
|
<template #file>
|
||||||
<span class="no-wrap"> Add content </span>
|
|
||||||
</template>
|
|
||||||
<template #from_file>
|
|
||||||
<FolderOpenIcon />
|
<FolderOpenIcon />
|
||||||
<span class="no-wrap"> Add from file </span>
|
Add from file
|
||||||
</template>
|
</template>
|
||||||
</DropdownButton>
|
</OverflowMenu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Pagination
|
<Pagination
|
||||||
@ -378,7 +385,6 @@ import {
|
|||||||
FolderOpenIcon,
|
FolderOpenIcon,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
formatProjectType,
|
formatProjectType,
|
||||||
DropdownButton,
|
|
||||||
Modal,
|
Modal,
|
||||||
XIcon,
|
XIcon,
|
||||||
ShareIcon,
|
ShareIcon,
|
||||||
@ -391,6 +397,7 @@ import {
|
|||||||
CodeIcon,
|
CodeIcon,
|
||||||
Pagination,
|
Pagination,
|
||||||
DropdownSelect,
|
DropdownSelect,
|
||||||
|
OverflowMenu,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@ -433,10 +440,22 @@ const props = defineProps({
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
playing: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
},
|
||||||
versions: {
|
versions: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
installed: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const projects = ref([])
|
const projects = ref([])
|
||||||
@ -844,21 +863,21 @@ const handleRightClick = (event, mod) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleContentOptionClick = async (args) => {
|
const onSearchContent = async () => {
|
||||||
if (args.option === 'search') {
|
await router.push({
|
||||||
await router.push({
|
path: `/browse/${props.instance.metadata.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||||
path: `/browse/${props.instance.metadata.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
query: { i: props.instance.path },
|
||||||
query: { i: props.instance.path },
|
})
|
||||||
})
|
}
|
||||||
} else if (args.option === 'from_file') {
|
|
||||||
const newProject = await open({ multiple: true })
|
|
||||||
if (!newProject) return
|
|
||||||
|
|
||||||
for (const project of newProject) {
|
const onFileContent = async () => {
|
||||||
await add_project_from_path(props.instance.path, project, 'mod').catch(handleError)
|
const newProject = await open({ multiple: true })
|
||||||
}
|
if (!newProject) return
|
||||||
initProjects(await get(props.instance.path).catch(handleError))
|
|
||||||
|
for (const project of newProject) {
|
||||||
|
await add_project_from_path(props.instance.path, project, 'mod').catch(handleError)
|
||||||
}
|
}
|
||||||
|
initProjects(await get(props.instance.path).catch(handleError))
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(selectAll, () => {
|
watch(selectAll, () => {
|
||||||
@ -959,9 +978,17 @@ onUnmounted(() => {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
:deep(.dropdown-row) {
|
:deep {
|
||||||
.btn {
|
.popup-container {
|
||||||
height: 2.5rem !important;
|
.btn {
|
||||||
|
height: 2.5rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-row {
|
||||||
|
.btn {
|
||||||
|
height: 2.5rem !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<ModalConfirm
|
<ConfirmModal
|
||||||
ref="modal_confirm"
|
ref="modal_confirm"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
@ -525,7 +525,7 @@ import {
|
|||||||
SaveIcon,
|
SaveIcon,
|
||||||
LockIcon,
|
LockIcon,
|
||||||
HammerIcon,
|
HammerIcon,
|
||||||
ModalConfirm,
|
ConfirmModal,
|
||||||
DownloadIcon,
|
DownloadIcon,
|
||||||
ClipboardCopyIcon,
|
ClipboardCopyIcon,
|
||||||
Button,
|
Button,
|
||||||
|
|||||||
@ -325,7 +325,9 @@ async function fetchProjectData() {
|
|||||||
installed.value =
|
installed.value =
|
||||||
instance.value?.path &&
|
instance.value?.path &&
|
||||||
(await check_installed(instance.value.path, data.value.id).catch(handleError))
|
(await check_installed(instance.value.path, data.value.id).catch(handleError))
|
||||||
|
|
||||||
breadcrumbs.setName('Project', data.value.title)
|
breadcrumbs.setName('Project', data.value.title)
|
||||||
|
|
||||||
installedVersion.value = instance.value
|
installedVersion.value = instance.value
|
||||||
? Object.values(instance.value.projects).find(
|
? Object.values(instance.value.projects).find(
|
||||||
(p) => p?.metadata?.version?.project_id === data.value.id
|
(p) => p?.metadata?.version?.project_id === data.value.id
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const useBreadcrumbs = defineStore('breadcrumbsStore', {
|
export const useBreadcrumbs = defineStore('breadcrumbsStore', {
|
||||||
@ -34,3 +36,28 @@ export const useBreadcrumbs = defineStore('breadcrumbsStore', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const useBreadcrumbContext = (route) => {
|
||||||
|
const breadcrumbs = useBreadcrumbs()
|
||||||
|
|
||||||
|
const routeContext = computed(() => {
|
||||||
|
const { meta } = route
|
||||||
|
if (meta?.useContext) {
|
||||||
|
return breadcrumbs.context
|
||||||
|
} else if (meta?.useRootContext) {
|
||||||
|
return breadcrumbs.rootContext
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const routeBreadcrumbs = computed(() => {
|
||||||
|
const { meta } = route
|
||||||
|
return routeContext.value ? [routeContext.value, ...meta.breadcrumb] : meta.breadcrumb
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
routeContext,
|
||||||
|
routeBreadcrumbs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
43
theseus_gui/src/store/instances.js
Normal file
43
theseus_gui/src/store/instances.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
import { list } from '@/helpers/profile.js'
|
||||||
|
import { handleError } from '@/store/notifications'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useInstances = defineStore('instancesStore', () => {
|
||||||
|
const instances = ref({})
|
||||||
|
|
||||||
|
const instanceList = computed(() => {
|
||||||
|
return Object.values(instances.value)
|
||||||
|
})
|
||||||
|
const instancesByPlayed = computed(() => {
|
||||||
|
return instanceList.value.sort((a, b) => {
|
||||||
|
return dayjs(b?.metadata?.last_played ?? 0).diff(dayjs(a?.metadata?.last_played ?? 0))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const setInstances = async () => {
|
||||||
|
try {
|
||||||
|
const p = await list(true)
|
||||||
|
instances.value = p
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await setInstances()
|
||||||
|
})
|
||||||
|
|
||||||
|
const refreshInstances = async () => {
|
||||||
|
await setInstances()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
instanceList,
|
||||||
|
instancesByPlayed,
|
||||||
|
|
||||||
|
refreshInstances,
|
||||||
|
}
|
||||||
|
})
|
||||||
40
theseus_gui/src/store/mr_auth.js
Normal file
40
theseus_gui/src/store/mr_auth.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { get as getCredentials, logout as removeCredentials } from '@/helpers/mr_auth.js'
|
||||||
|
import { handleError } from '@/store/state.js'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useModrinthAuth = defineStore('modrinthAuthStore', () => {
|
||||||
|
const auth = ref(null)
|
||||||
|
|
||||||
|
const get = async () => {
|
||||||
|
try {
|
||||||
|
const creds = await getCredentials()
|
||||||
|
auth.value = creds
|
||||||
|
return creds
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
const result = await removeCredentials()
|
||||||
|
auth.value = null
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
get()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
auth,
|
||||||
|
get,
|
||||||
|
logout,
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user