Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c7487f20f
|
||
|
|
97231c6b38
|
||
|
|
a93e4ab521
|
||
|
|
e7c48b182f
|
||
|
|
16dd3fd613
|
||
|
|
c91303d194
|
||
|
|
a76e81789b
|
||
|
|
c909973aab
|
||
|
|
28f694e4e7
|
||
|
|
508e4d1640
|
||
|
|
41a66eaf86
|
||
|
|
ac4b76fa46
|
||
|
|
2e02275c29
|
||
|
|
dbaac6a6a6
|
||
|
|
68525f161e
|
||
|
|
d386454e91
|
||
|
|
6e05aac871
|
||
|
|
fbe3feec9d
|
||
|
|
1c540ad35b
|
No files matched your search
@@ -8,7 +8,7 @@
|
|||||||
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
||||||
"@fortawesome/react-fontawesome": "3.1.1",
|
"@fortawesome/react-fontawesome": "3.2.0",
|
||||||
"@tauri-apps/api": "2.10.1",
|
"@tauri-apps/api": "2.10.1",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
||||||
"@tauri-apps/plugin-dialog": "2.6.0",
|
"@tauri-apps/plugin-dialog": "2.6.0",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"@tauri-apps/plugin-opener": "2.5.3",
|
"@tauri-apps/plugin-opener": "2.5.3",
|
||||||
"@tauri-apps/plugin-os": "2.3.2",
|
"@tauri-apps/plugin-os": "2.3.2",
|
||||||
"@tauri-apps/plugin-window-state": "2.4.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"axios": "1.13.4",
|
"axios": "1.13.5",
|
||||||
"next": "16.1.6",
|
"next": "16.1.6",
|
||||||
"pretty-bytes": "7.1.0",
|
"pretty-bytes": "7.1.0",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
"@tailwindcss/postcss": "4.1.18",
|
"@tailwindcss/postcss": "4.1.18",
|
||||||
"@tauri-apps/cli": "2.10.0",
|
"@tauri-apps/cli": "2.10.0",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/node": "25.2.0",
|
"@types/node": "25.2.2",
|
||||||
"@types/react": "19.2.10",
|
"@types/react": "19.2.13",
|
||||||
"@types/react-dom": "19.2.3",
|
"@types/react-dom": "19.2.3",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"eslint": "9.39.2",
|
"eslint": "9.39.2",
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
"@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
|
"@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
|
||||||
|
|
||||||
"@babel/generator": ["@babel/generator@7.29.0", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ=="],
|
"@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
|
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
"@fortawesome/free-solid-svg-icons": ["@fortawesome/free-solid-svg-icons@7.1.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" } }, "sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA=="],
|
"@fortawesome/free-solid-svg-icons": ["@fortawesome/free-solid-svg-icons@7.1.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" } }, "sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA=="],
|
||||||
|
|
||||||
"@fortawesome/react-fontawesome": ["@fortawesome/react-fontawesome@3.1.1", "", { "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~6 || ~7", "react": "^18.0.0 || ^19.0.0" } }, "sha512-EDllr9hpodc21odmUywHS1alXNiCd4E8sp5GJ5s7wYINz8vSmMiNWpALTiuYODb865YyQ/NlyiN4mbXp7HCNqg=="],
|
"@fortawesome/react-fontawesome": ["@fortawesome/react-fontawesome@3.2.0", "", { "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~6 || ~7", "react": "^18.0.0 || ^19.0.0" } }, "sha512-E9Gu1hqd6JussVO26EC4WqRZssXMnQr2ol7ZNWkkFOH8jZUaxDJ9Z9WF9wIVkC+kJGXUdY3tlffpDwEKfgQrQw=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
@@ -290,31 +290,31 @@
|
|||||||
|
|
||||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@25.2.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w=="],
|
"@types/node": ["@types/node@25.2.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.10", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw=="],
|
"@types/react": ["@types/react@19.2.13", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ=="],
|
||||||
|
|
||||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.54.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/type-utils": "8.54.0", "@typescript-eslint/utils": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.55.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/type-utils": "8.55.0", "@typescript-eslint/utils": "8.55.0", "@typescript-eslint/visitor-keys": "8.55.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.55.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.54.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.55.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/types": "8.55.0", "@typescript-eslint/typescript-estree": "8.55.0", "@typescript-eslint/visitor-keys": "8.55.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw=="],
|
||||||
|
|
||||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.54.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.54.0", "@typescript-eslint/types": "^8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g=="],
|
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.55.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0" } }, "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg=="],
|
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.55.0", "", { "dependencies": { "@typescript-eslint/types": "8.55.0", "@typescript-eslint/visitor-keys": "8.55.0" } }, "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q=="],
|
||||||
|
|
||||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.54.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw=="],
|
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.55.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q=="],
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA=="],
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.55.0", "", { "dependencies": { "@typescript-eslint/types": "8.55.0", "@typescript-eslint/typescript-estree": "8.55.0", "@typescript-eslint/utils": "8.55.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g=="],
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.54.0", "", {}, "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA=="],
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.55.0", "", {}, "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.54.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.54.0", "@typescript-eslint/tsconfig-utils": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA=="],
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.55.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.55.0", "@typescript-eslint/tsconfig-utils": "8.55.0", "@typescript-eslint/types": "8.55.0", "@typescript-eslint/visitor-keys": "8.55.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.54.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA=="],
|
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.55.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/types": "8.55.0", "@typescript-eslint/typescript-estree": "8.55.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow=="],
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA=="],
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.55.0", "", { "dependencies": { "@typescript-eslint/types": "8.55.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA=="],
|
||||||
|
|
||||||
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
|
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@
|
|||||||
|
|
||||||
"axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="],
|
"axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="],
|
||||||
|
|
||||||
"axios": ["axios@1.13.4", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg=="],
|
"axios": ["axios@1.13.5", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q=="],
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@
|
|||||||
|
|
||||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001767", "", {}, "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001769", "", {}, "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg=="],
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
@@ -562,7 +562,7 @@
|
|||||||
|
|
||||||
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
|
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
|
||||||
|
|
||||||
"get-tsconfig": ["get-tsconfig@4.13.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w=="],
|
"get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="],
|
||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
||||||
@@ -900,7 +900,7 @@
|
|||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.54.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.54.0", "@typescript-eslint/parser": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ=="],
|
"typescript-eslint": ["typescript-eslint@8.55.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.55.0", "@typescript-eslint/parser": "8.55.0", "@typescript-eslint/typescript-estree": "8.55.0", "@typescript-eslint/utils": "8.55.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw=="],
|
||||||
|
|
||||||
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
|
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
|
||||||
|
|
||||||
@@ -952,7 +952,7 @@
|
|||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"eslint-config-next/globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
|
"eslint-config-next/globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
|
||||||
|
|
||||||
@@ -966,13 +966,13 @@
|
|||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"is-bun-module/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"is-bun-module/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
"sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const eslintConfig = defineConfig([
|
|||||||
'.next/**',
|
'.next/**',
|
||||||
'out/**',
|
'out/**',
|
||||||
'build/**',
|
'build/**',
|
||||||
'next-env.d.ts'
|
'next-env.d.ts',
|
||||||
|
'src-tauri/**'
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "lncvrt-games-launcher",
|
"name": "lncvrt-games-launcher",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.5.4",
|
"version": "1.5.7",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
||||||
"@fortawesome/react-fontawesome": "3.1.1",
|
"@fortawesome/react-fontawesome": "3.2.0",
|
||||||
"@tauri-apps/api": "2.10.1",
|
"@tauri-apps/api": "2.10.1",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
||||||
"@tauri-apps/plugin-dialog": "2.6.0",
|
"@tauri-apps/plugin-dialog": "2.6.0",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"@tauri-apps/plugin-opener": "2.5.3",
|
"@tauri-apps/plugin-opener": "2.5.3",
|
||||||
"@tauri-apps/plugin-os": "2.3.2",
|
"@tauri-apps/plugin-os": "2.3.2",
|
||||||
"@tauri-apps/plugin-window-state": "2.4.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"axios": "1.13.4",
|
"axios": "1.13.5",
|
||||||
"next": "16.1.6",
|
"next": "16.1.6",
|
||||||
"pretty-bytes": "7.1.0",
|
"pretty-bytes": "7.1.0",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
@@ -34,8 +34,8 @@
|
|||||||
"@tailwindcss/postcss": "4.1.18",
|
"@tailwindcss/postcss": "4.1.18",
|
||||||
"@tauri-apps/cli": "2.10.0",
|
"@tauri-apps/cli": "2.10.0",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/node": "25.2.0",
|
"@types/node": "25.2.2",
|
||||||
"@types/react": "19.2.10",
|
"@types/react": "19.2.13",
|
||||||
"@types/react-dom": "19.2.3",
|
"@types/react-dom": "19.2.3",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"eslint": "9.39.2",
|
"eslint": "9.39.2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lncvrt-games-launcher"
|
name = "lncvrt-games-launcher"
|
||||||
version = "1.5.4"
|
version = "1.5.7"
|
||||||
authors = ["Lncvrt"]
|
authors = ["Lncvrt"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
@@ -9,24 +9,24 @@ name = "lncvrt_games_launcher_lib"
|
|||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2.5.4", features = [] }
|
tauri-build = { version = "2.5.5", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2.10.1", features = ["macos-private-api"] }
|
tauri = { version = "2.10.2", features = ["macos-private-api"] }
|
||||||
tauri-plugin-opener = "2.5.3"
|
tauri-plugin-opener = "2.5.3"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
tauri-plugin-os = "2.3.2"
|
tauri-plugin-os = "2.3.2"
|
||||||
reqwest = { version = "0.13.1", default-features = false, features = ["stream", "rustls"] }
|
reqwest = { version = "0.13.2", default-features = false, features = ["stream", "rustls"] }
|
||||||
tokio = "1.49.0"
|
tokio = "1.49.0"
|
||||||
futures-util = { version = "0.3.31", features = ["io"] }
|
futures-util = { version = "0.3.31", features = ["io"] }
|
||||||
tauri-plugin-decorum = "1.1.1"
|
tauri-plugin-decorum = "1.1.1"
|
||||||
tauri-plugin-fs = "2.4.5"
|
tauri-plugin-fs = "2.4.5"
|
||||||
zip = "7.2.0"
|
zip = "7.4.0"
|
||||||
libc = "0.2.180"
|
libc = "0.2.181"
|
||||||
tauri-plugin-dialog = "2.6.0"
|
tauri-plugin-dialog = "2.6.0"
|
||||||
tauri-plugin-notification = "2.3.3"
|
tauri-plugin-notification = "2.3.3"
|
||||||
sysinfo = "0.38.0"
|
sysinfo = "0.38.1"
|
||||||
sha2 = "0.10.9"
|
sha2 = "0.10.9"
|
||||||
tauri-plugin-clipboard-manager = "2.3.2"
|
tauri-plugin-clipboard-manager = "2.3.2"
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ tauri-plugin-clipboard-manager = "2.3.2"
|
|||||||
shlex = "1.3.0"
|
shlex = "1.3.0"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
tauri-plugin-single-instance = "2.3.7"
|
tauri-plugin-single-instance = "2.4.0"
|
||||||
tauri-plugin-window-state = "2.4.1"
|
tauri-plugin-window-state = "2.4.1"
|
||||||
|
|
||||||
|
|
||||||
+31
-29
@@ -22,6 +22,9 @@ use zip::ZipArchive;
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use tauri_plugin_decorum::WebviewWindowExt;
|
use tauri_plugin_decorum::WebviewWindowExt;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn is_running_by_path(path: &Path) -> bool {
|
fn is_running_by_path(path: &Path) -> bool {
|
||||||
let sys = System::new_all();
|
let sys = System::new_all();
|
||||||
@@ -37,23 +40,47 @@ fn is_running_by_path(path: &Path) -> bool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_skip(name: &str) -> bool {
|
||||||
|
name.starts_with("__MACOSX/")
|
||||||
|
|| name == "__MACOSX"
|
||||||
|
|| name.ends_with("/.DS_Store")
|
||||||
|
|| name.ends_with(".DS_Store")
|
||||||
|
}
|
||||||
|
|
||||||
async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
|
async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
|
||||||
let res = tauri::async_runtime::spawn_blocking(move || {
|
let res = tauri::async_runtime::spawn_blocking(move || {
|
||||||
let file = File::open(zip_path)?;
|
let file = File::open(zip_path)?;
|
||||||
let mut archive = ZipArchive::new(BufReader::new(file))?;
|
let mut archive = ZipArchive::new(BufReader::new(file))?;
|
||||||
|
|
||||||
for i in 0..archive.len() {
|
for i in 0..archive.len() {
|
||||||
let mut file = archive.by_index(i)?;
|
let mut entry = archive.by_index(i)?;
|
||||||
let outpath = out_dir.join(file.name());
|
let name = entry.name();
|
||||||
|
|
||||||
if file.is_dir() {
|
if should_skip(name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let outpath = out_dir.join(name);
|
||||||
|
|
||||||
|
if entry.is_dir() {
|
||||||
create_dir_all(&outpath)?;
|
create_dir_all(&outpath)?;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(mode) = entry.unix_mode() {
|
||||||
|
std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode))?;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(parent) = outpath.parent() {
|
if let Some(parent) = outpath.parent() {
|
||||||
create_dir_all(parent)?;
|
create_dir_all(parent)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut outfile = File::create(&outpath)?;
|
let mut outfile = File::create(&outpath)?;
|
||||||
copy(&mut file, &mut outfile)?;
|
copy(&mut entry, &mut outfile)?;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(mode) = entry.unix_mode() {
|
||||||
|
std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode))?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,31 +252,6 @@ async fn download(
|
|||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
|
||||||
{
|
|
||||||
use std::{fs, os::unix::fs::PermissionsExt};
|
|
||||||
|
|
||||||
let executable_path = if cfg!(target_os = "linux") {
|
|
||||||
game_path.join(&name).join(&executable)
|
|
||||||
} else {
|
|
||||||
game_path
|
|
||||||
.join(&name)
|
|
||||||
.join(&executable)
|
|
||||||
.join("Contents")
|
|
||||||
.join("MacOS")
|
|
||||||
.join(
|
|
||||||
&executable
|
|
||||||
.chars()
|
|
||||||
.take(executable.chars().count() - 4)
|
|
||||||
.collect::<String>(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut perms = fs::metadata(&executable_path).unwrap().permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&executable_path, perms).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "1".to_string();
|
return "1".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.5.4",
|
"version": "1.5.7",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.5.4",
|
"version": "1.5.7",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.5.4",
|
"version": "1.5.7",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.5.4",
|
"version": "1.5.7",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev",
|
||||||
|
|||||||
+19
-12
@@ -1,6 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { createContext, useContext, ReactNode } from 'react'
|
import {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
ReactNode,
|
||||||
|
Dispatch,
|
||||||
|
SetStateAction
|
||||||
|
} from 'react'
|
||||||
import { DownloadProgress } from './types/DownloadProgress'
|
import { DownloadProgress } from './types/DownloadProgress'
|
||||||
import { VersionsConfig } from './types/VersionsConfig'
|
import { VersionsConfig } from './types/VersionsConfig'
|
||||||
import { NormalConfig } from './types/NormalConfig'
|
import { NormalConfig } from './types/NormalConfig'
|
||||||
@@ -11,31 +17,32 @@ import { Game } from './types/Game'
|
|||||||
type GlobalCtxType = {
|
type GlobalCtxType = {
|
||||||
serverVersionList: ServerVersionsResponse | null
|
serverVersionList: ServerVersionsResponse | null
|
||||||
selectedVersionList: string[]
|
selectedVersionList: string[]
|
||||||
setSelectedVersionList: (v: string[]) => void
|
setSelectedVersionList: (value: SetStateAction<string[]>) => void
|
||||||
downloadProgress: DownloadProgress[]
|
downloadProgress: DownloadProgress[]
|
||||||
setDownloadProgress: (v: DownloadProgress[]) => void
|
setDownloadProgress: Dispatch<SetStateAction<DownloadProgress[]>>
|
||||||
showPopup: boolean
|
showPopup: boolean
|
||||||
setShowPopup: (v: boolean) => void
|
setShowPopup: Dispatch<SetStateAction<boolean>>
|
||||||
popupMode: number | null
|
popupMode: number | null
|
||||||
setPopupMode: (v: number | null) => void
|
setPopupMode: Dispatch<SetStateAction<number | null>>
|
||||||
fadeOut: boolean
|
fadeOut: boolean
|
||||||
setFadeOut: (v: boolean) => void
|
setFadeOut: Dispatch<SetStateAction<boolean>>
|
||||||
downloadedVersionsConfig: VersionsConfig | null
|
downloadedVersionsConfig: VersionsConfig | null
|
||||||
setDownloadedVersionsConfig: (v: VersionsConfig | null) => void
|
setDownloadedVersionsConfig: Dispatch<SetStateAction<VersionsConfig | null>>
|
||||||
normalConfig: NormalConfig | null
|
normalConfig: NormalConfig | null
|
||||||
setNormalConfig: (v: NormalConfig | null) => void
|
setNormalConfig: Dispatch<SetStateAction<NormalConfig | null>>
|
||||||
managingVersion: string | null
|
managingVersion: string | null
|
||||||
setManagingVersion: (v: string | null) => void
|
setManagingVersion: Dispatch<SetStateAction<string | null>>
|
||||||
setSelectedGame: (v: number | null) => void
|
setSelectedGame: Dispatch<SetStateAction<number | null>>
|
||||||
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
||||||
getGameInfo: (id: number | undefined) => Game | undefined
|
getGameInfo: (game: number | undefined) => Game | undefined
|
||||||
getListOfGames: () => Game[]
|
getListOfGames(): Game[]
|
||||||
getVersionsAmountData: (gameId: number) => {
|
getVersionsAmountData: (gameId: number) => {
|
||||||
installed: number
|
installed: number
|
||||||
total: number
|
total: number
|
||||||
} | null
|
} | null
|
||||||
viewingInfoFromDownloads: boolean
|
viewingInfoFromDownloads: boolean
|
||||||
version: string | null
|
version: string | null
|
||||||
|
downloadVersions: (list: string[]) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
||||||
|
|||||||
@@ -28,18 +28,6 @@ body {
|
|||||||
--col8: rgb(152, 128, 128);
|
--col8: rgb(152, 128, 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
.green-theme {
|
|
||||||
--col0: rgb(8, 32, 8);
|
|
||||||
--col1: rgb(16, 40, 16);
|
|
||||||
--col2: rgb(32, 56, 32);
|
|
||||||
--col3: rgb(48, 72, 48);
|
|
||||||
--col4: rgb(64, 88, 64);
|
|
||||||
--col5: rgb(80, 104, 80);
|
|
||||||
--col6: rgb(96, 120, 96);
|
|
||||||
--col7: rgb(112, 136, 112);
|
|
||||||
--col8: rgb(128, 152, 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue-theme {
|
.blue-theme {
|
||||||
--col0: rgb(8, 8, 32);
|
--col0: rgb(8, 8, 32);
|
||||||
--col1: rgb(16, 16, 40);
|
--col1: rgb(16, 16, 40);
|
||||||
@@ -64,18 +52,6 @@ body {
|
|||||||
--col8: rgb(140, 128, 152);
|
--col8: rgb(140, 128, 152);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mint-theme {
|
|
||||||
--col0: rgb(8, 32, 16);
|
|
||||||
--col1: rgb(16, 48, 32);
|
|
||||||
--col2: rgb(32, 56, 40);
|
|
||||||
--col3: rgb(48, 72, 48);
|
|
||||||
--col4: rgb(64, 88, 66);
|
|
||||||
--col5: rgb(80, 104, 65);
|
|
||||||
--col6: rgb(96, 120, 80);
|
|
||||||
--col7: rgb(112, 136, 85);
|
|
||||||
--col8: rgb(128, 152, 95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@apply rounded-md cursor-pointer text-[16px] py-1 px-2 transition-colors border;
|
@apply rounded-md cursor-pointer text-[16px] py-1 px-2 transition-colors border;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ export default function VersionInfo () {
|
|||||||
viewingInfoFromDownloads,
|
viewingInfoFromDownloads,
|
||||||
setPopupMode
|
setPopupMode
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
const [versionSize, setVersionSize] = useState<number | null>(null)
|
const [versionSize, setVersionSize] = useState<number>(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
invoke<string>('folder_size', {
|
invoke<string>('folder_size', {
|
||||||
version: managingVersion
|
version: managingVersion
|
||||||
}).then(size => {
|
}).then(size => {
|
||||||
setVersionSize(parseInt(size, 10))
|
setVersionSize(Number(size))
|
||||||
})
|
})
|
||||||
}, [managingVersion, setVersionSize])
|
}, [managingVersion, setVersionSize])
|
||||||
|
|
||||||
@@ -91,12 +91,12 @@ export default function VersionInfo () {
|
|||||||
<FontAwesomeIcon icon={faHardDrive} color='lightgray' />
|
<FontAwesomeIcon icon={faHardDrive} color='lightgray' />
|
||||||
<p>
|
<p>
|
||||||
Size on disk:{' '}
|
Size on disk:{' '}
|
||||||
{versionSize !== null
|
{versionSize > 0
|
||||||
? prettyBytes(versionSize, {
|
? prettyBytes(versionSize, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2
|
maximumFractionDigits: 2
|
||||||
})
|
})
|
||||||
: 'Loading...'}
|
: 'N/A'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='entry-info-item btntheme2' hidden={!versionInfo}>
|
<div className='entry-info-item btntheme2' hidden={!versionInfo}>
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { useGlobal } from '../GlobalProvider'
|
||||||
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
|
import { writeVersionsConfig } from '../util/BazookaManager'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
export default function VersionUpdateWarning () {
|
||||||
|
const [confirmed, setConfirmed] = useState<-1 | 0>(-1)
|
||||||
|
|
||||||
|
const {
|
||||||
|
managingVersion,
|
||||||
|
setDownloadedVersionsConfig,
|
||||||
|
setManagingVersion,
|
||||||
|
setPopupMode,
|
||||||
|
setSelectedVersionList,
|
||||||
|
downloadVersions
|
||||||
|
} = useGlobal()
|
||||||
|
if (!managingVersion) return <p>Error</p>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>Warning!</p>
|
||||||
|
<div className='popup-content text-center p-2 relative'>
|
||||||
|
<p className='mb-2'>
|
||||||
|
Before proceeding, please note that any modifications to the
|
||||||
|
installation directory <b>(NOT THE SAVE DATA)</b> will be completely
|
||||||
|
wiped/reset.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you do not want your installation directory wiped just yet, please
|
||||||
|
backup the files to another directory. When you click update, it will
|
||||||
|
be wiped.
|
||||||
|
</p>
|
||||||
|
<p className='my-2'>
|
||||||
|
Updating will have the same effect as clicking the uninstall button
|
||||||
|
then installing again.
|
||||||
|
</p>
|
||||||
|
<p>Revisions are not a frequent thing and rarely ever happen.</p>
|
||||||
|
<div className='flex flex-row gap-2 absolute bottom-2 left-1/2 -translate-x-1/2 w-max'>
|
||||||
|
<button
|
||||||
|
className='button btntheme2'
|
||||||
|
onClick={async () =>
|
||||||
|
invoke('open_folder', {
|
||||||
|
name: managingVersion
|
||||||
|
})
|
||||||
|
}
|
||||||
|
title="Click to browse the game's files."
|
||||||
|
>
|
||||||
|
Open Folder / Installation directory
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme2'
|
||||||
|
onClick={async () => {
|
||||||
|
if (confirmed == -1) {
|
||||||
|
setConfirmed(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//change popup to downloads
|
||||||
|
setManagingVersion(null)
|
||||||
|
setPopupMode(1)
|
||||||
|
|
||||||
|
//uninstall
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedList = Object.fromEntries(
|
||||||
|
Object.entries(prev.list).filter(
|
||||||
|
([k]) => k !== managingVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
list: updatedList
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
await exists('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
|
||||||
|
//reinstall
|
||||||
|
setSelectedVersionList([managingVersion])
|
||||||
|
downloadVersions([managingVersion])
|
||||||
|
}}
|
||||||
|
title='Click to update the game'
|
||||||
|
>
|
||||||
|
<span className='text-red-500 font-bold underline'>
|
||||||
|
{confirmed == -1 ? 'Update' : 'Are you sure?'}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
+89
-8
@@ -45,6 +45,21 @@ export default function Installs () {
|
|||||||
setCategory(-1)
|
setCategory(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const needsRevisionUpdate = (
|
||||||
|
lastRevision: number | undefined,
|
||||||
|
version: string
|
||||||
|
) => {
|
||||||
|
if (!lastRevision) return false
|
||||||
|
return (
|
||||||
|
lastRevision > 0 &&
|
||||||
|
(downloadedVersionsConfig == undefined
|
||||||
|
? 0
|
||||||
|
: downloadedVersionsConfig?.list[version]) /
|
||||||
|
1000 <=
|
||||||
|
lastRevision
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx-4 mt-4'>
|
<div className='mx-4 mt-4'>
|
||||||
<div className='flex justify-between items-center mb-4'>
|
<div className='flex justify-between items-center mb-4'>
|
||||||
@@ -107,7 +122,7 @@ export default function Installs () {
|
|||||||
.map(([key, value]) => {
|
.map(([key, value]) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={value}
|
key={key}
|
||||||
className={`downloads-entry ${
|
className={`downloads-entry ${
|
||||||
normalConfig?.settings.useLegacyInteractButtons
|
normalConfig?.settings.useLegacyInteractButtons
|
||||||
? ''
|
? ''
|
||||||
@@ -203,17 +218,32 @@ export default function Installs () {
|
|||||||
<div
|
<div
|
||||||
key={entry}
|
key={entry}
|
||||||
className={`downloads-entry ${
|
className={`downloads-entry ${
|
||||||
normalConfig?.settings.useLegacyInteractButtons
|
normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
? ''
|
? ''
|
||||||
: 'cursor-pointer'
|
: 'cursor-pointer'
|
||||||
}`}
|
}`}
|
||||||
title={
|
title={
|
||||||
normalConfig?.settings.useLegacyInteractButtons
|
normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
? ''
|
? ''
|
||||||
: 'Click to launch game. Right-click to manage this version install'
|
: 'Click to launch game. Right-click to manage this version install'
|
||||||
}
|
}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (normalConfig?.settings.useLegacyInteractButtons) return
|
if (
|
||||||
|
normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
const verInfo = getVersionInfo(entry)
|
const verInfo = getVersionInfo(entry)
|
||||||
if (verInfo == undefined) return
|
if (verInfo == undefined) return
|
||||||
const gameInfo = getGameInfo(verInfo.game)
|
const gameInfo = getGameInfo(verInfo.game)
|
||||||
@@ -232,7 +262,14 @@ export default function Installs () {
|
|||||||
}}
|
}}
|
||||||
onContextMenu={e => {
|
onContextMenu={e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (normalConfig?.settings.useLegacyInteractButtons) return
|
if (
|
||||||
|
normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
setManagingVersion(entry)
|
setManagingVersion(entry)
|
||||||
setPopupMode(2)
|
setPopupMode(2)
|
||||||
@@ -242,7 +279,7 @@ export default function Installs () {
|
|||||||
>
|
>
|
||||||
<div className='h-18 w-screen relative'>
|
<div className='h-18 w-screen relative'>
|
||||||
<p className='text-2xl'>
|
<p className='text-2xl'>
|
||||||
{getVersionInfo(entry)?.displayName}
|
{getVersionInfo(entry)?.displayName}{' '}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className='flex gap-2 absolute left-0 bottom-0'>
|
<div className='flex gap-2 absolute left-0 bottom-0'>
|
||||||
@@ -272,6 +309,19 @@ export default function Installs () {
|
|||||||
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
<p>Uses wine</p>
|
<p>Uses wine</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
hidden={
|
||||||
|
!needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
|
<p>Needs revision update!</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex gap-2 absolute right-0 bottom-0'>
|
<div className='flex gap-2 absolute right-0 bottom-0'>
|
||||||
@@ -284,6 +334,10 @@ export default function Installs () {
|
|||||||
setShowPopup(true)
|
setShowPopup(true)
|
||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
}}
|
}}
|
||||||
|
hidden={needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)}
|
||||||
title='Click to view version info'
|
title='Click to view version info'
|
||||||
>
|
>
|
||||||
View Info
|
View Info
|
||||||
@@ -291,7 +345,11 @@ export default function Installs () {
|
|||||||
<button
|
<button
|
||||||
className='button'
|
className='button'
|
||||||
hidden={
|
hidden={
|
||||||
!normalConfig?.settings.useLegacyInteractButtons
|
!normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
}
|
}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -326,12 +384,35 @@ export default function Installs () {
|
|||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
hidden={
|
hidden={
|
||||||
!normalConfig?.settings.useLegacyInteractButtons
|
!normalConfig?.settings.useLegacyInteractButtons ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
}
|
}
|
||||||
title='Click to launch game'
|
title='Click to launch game'
|
||||||
>
|
>
|
||||||
Launch
|
Launch
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
className='button'
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation()
|
||||||
|
setManagingVersion(entry)
|
||||||
|
setPopupMode(5)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
}}
|
||||||
|
hidden={
|
||||||
|
!needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
}
|
||||||
|
title='Click to update the game'
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+245
-180
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import Sidebar from './componets/Sidebar'
|
import Sidebar from './componets/Sidebar'
|
||||||
import './Globals.css'
|
import './Globals.css'
|
||||||
import { DownloadProgress } from './types/DownloadProgress'
|
import { DownloadProgress } from './types/DownloadProgress'
|
||||||
@@ -46,6 +46,7 @@ import {
|
|||||||
} from '@tauri-apps/plugin-notification'
|
} from '@tauri-apps/plugin-notification'
|
||||||
import VersionChangelog from './componets/VersionChangelog'
|
import VersionChangelog from './componets/VersionChangelog'
|
||||||
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
|
import VersionUpdateWarning from './componets/VersionUpdateWarning'
|
||||||
|
|
||||||
const roboto = Roboto({
|
const roboto = Roboto({
|
||||||
subsets: ['latin']
|
subsets: ['latin']
|
||||||
@@ -111,15 +112,21 @@ export default function RootLayout ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVersionInfo (id: string | undefined): GameVersion | undefined {
|
const getVersionInfo = useCallback(
|
||||||
if (!id) return undefined
|
(id: string | undefined): GameVersion | undefined => {
|
||||||
return serverVersionList?.versions.find(v => v.id === id)
|
if (!id) return undefined
|
||||||
}
|
return serverVersionList?.versions.find(v => v.id === id)
|
||||||
|
},
|
||||||
|
[serverVersionList]
|
||||||
|
)
|
||||||
|
|
||||||
function getGameInfo (game: number | undefined): Game | undefined {
|
const getGameInfo = useCallback(
|
||||||
if (!game) return undefined
|
(game: number | undefined): Game | undefined => {
|
||||||
return serverVersionList?.games.find(g => g.id === game)
|
if (!game) return undefined
|
||||||
}
|
return serverVersionList?.games.find(g => g.id === game)
|
||||||
|
},
|
||||||
|
[serverVersionList]
|
||||||
|
)
|
||||||
|
|
||||||
function getListOfGames (): Game[] {
|
function getListOfGames (): Game[] {
|
||||||
if (!downloadedVersionsConfig?.list) return []
|
if (!downloadedVersionsConfig?.list) return []
|
||||||
@@ -292,119 +299,124 @@ export default function RootLayout ({
|
|||||||
return () => document.removeEventListener('contextmenu', handler)
|
return () => document.removeEventListener('contextmenu', handler)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
async function downloadVersions (
|
const downloadVersions = useCallback(
|
||||||
list: string[],
|
async (list: string[]): Promise<void> => {
|
||||||
currentConfig: VersionsConfig
|
if (list.length === 0) return
|
||||||
): Promise<void> {
|
setSelectedVersionList([])
|
||||||
if (list.length === 0) return
|
|
||||||
setSelectedVersionList([])
|
|
||||||
|
|
||||||
const newDownloads = list.map(
|
const newDownloads = list.map(
|
||||||
version =>
|
version =>
|
||||||
new DownloadProgress(version, 0, 0, false, true, false, false, 0, 0)
|
new DownloadProgress(version, 0, 0, false, true, false, false, 0, 0)
|
||||||
)
|
|
||||||
|
|
||||||
setDownloadProgress(newDownloads)
|
|
||||||
|
|
||||||
for (const download of newDownloads) {
|
|
||||||
const info = getVersionInfo(download.version)
|
|
||||||
if (!info) {
|
|
||||||
setDownloadProgress(prev =>
|
|
||||||
prev.filter(d => d.version !== download.version)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const gameInfo = getGameInfo(info.game)
|
|
||||||
if (!gameInfo) {
|
|
||||||
setDownloadProgress(prev =>
|
|
||||||
prev.filter(d => d.version !== download.version)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
setDownloadProgress(prev =>
|
|
||||||
prev.map(d =>
|
|
||||||
d.version === download.version ? { ...d, queued: false } : d
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
setDownloadProgress(newDownloads)
|
||||||
await axios.get(
|
|
||||||
'https://games.lncvrt.xyz/api/launcher/download?id=' + info.id
|
|
||||||
)
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
const res = await invoke<string>('download', {
|
for (const download of newDownloads) {
|
||||||
url: info.downloadUrl,
|
const info = getVersionInfo(download.version)
|
||||||
name: info.id,
|
if (!info) {
|
||||||
executable: info.executable,
|
setDownloadProgress(prev =>
|
||||||
hash: info.sha512sum
|
prev.filter(d => d.version !== download.version)
|
||||||
})
|
)
|
||||||
|
continue
|
||||||
if (res === '1') {
|
|
||||||
setDownloadProgress(prev =>
|
|
||||||
prev.filter(d => d.version !== download.version)
|
|
||||||
)
|
|
||||||
const date = Date.now()
|
|
||||||
const newConfig = {
|
|
||||||
...currentConfig,
|
|
||||||
list: { ...currentConfig.list, [download.version]: date }
|
|
||||||
}
|
}
|
||||||
setDownloadedVersionsConfig(newConfig)
|
|
||||||
writeVersionsConfig(newConfig)
|
const gameInfo = getGameInfo(info.game)
|
||||||
} else {
|
if (!gameInfo) {
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.filter(d => d.version !== download.version)
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
setDownloadProgress(prev =>
|
setDownloadProgress(prev =>
|
||||||
prev.map(d =>
|
prev.map(d =>
|
||||||
d.version === download.version
|
d.version === download.version ? { ...d, queued: false } : d
|
||||||
? { ...d, queued: false, failed: true, progress: 0 }
|
|
||||||
: d
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (normalConfig?.settings.allowNotifications)
|
|
||||||
await notifyUser(
|
try {
|
||||||
'Download Failed',
|
await axios.get(
|
||||||
`The download for version ${info.displayName} has failed.`
|
'https://games.lncvrt.xyz/api/launcher/download?id=' + info.id
|
||||||
)
|
)
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
const res = await invoke<string>('download', {
|
||||||
|
url: info.downloadUrl,
|
||||||
|
name: info.id,
|
||||||
|
executable: info.executable,
|
||||||
|
hash: info.sha512sum
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res === '1') {
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.filter(d => d.version !== download.version)
|
||||||
|
)
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
|
||||||
|
const updated = {
|
||||||
|
...prev,
|
||||||
|
list: {
|
||||||
|
...prev.list,
|
||||||
|
[download.version]: Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeVersionsConfig(updated)
|
||||||
|
return updated
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.map(d =>
|
||||||
|
d.version === download.version
|
||||||
|
? { ...d, queued: false, failed: true, progress: 0 }
|
||||||
|
: d
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (normalConfig?.settings.allowNotifications)
|
||||||
|
await notifyUser(
|
||||||
|
'Download Failed',
|
||||||
|
`The download for version ${info.displayName} has failed.`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (normalConfig?.settings.allowNotifications)
|
if (normalConfig?.settings.allowNotifications)
|
||||||
await notifyUser('Downloads Finished', 'All downloads have finished.')
|
await notifyUser('Downloads Finished', 'All downloads have finished.')
|
||||||
|
|
||||||
setFadeOut(true)
|
setFadeOut(true)
|
||||||
setTimeout(() => setShowPopup(false), 200)
|
setTimeout(() => setShowPopup(false), 200)
|
||||||
}
|
},
|
||||||
|
[getGameInfo, getVersionInfo, normalConfig]
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (revisionCheck.current) return
|
if (revisionCheck.current) return
|
||||||
if (!serverVersionList || !downloadedVersionsConfig) return
|
if (!serverVersionList || !downloadedVersionsConfig) return
|
||||||
revisionCheck.current = true
|
revisionCheck.current = true
|
||||||
;(async () => {
|
;(async () => {
|
||||||
const newConfig = {
|
|
||||||
...downloadedVersionsConfig,
|
|
||||||
list: { ...downloadedVersionsConfig.list }
|
|
||||||
}
|
|
||||||
const versionsToSelect: string[] = []
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(
|
for (const [key, value] of Object.entries(
|
||||||
downloadedVersionsConfig.list
|
downloadedVersionsConfig.list
|
||||||
)) {
|
)) {
|
||||||
const verInfo = serverVersionList.versions.find(item => item.id === key)
|
const verInfo = serverVersionList.versions.find(item => item.id === key)
|
||||||
|
|
||||||
if (!verInfo || value / 1000 <= verInfo.lastRevision) {
|
if (
|
||||||
delete newConfig.list[key]
|
!verInfo ||
|
||||||
versionsToSelect.push(key)
|
(verInfo.lastRevision > 0 && value / 1000 <= verInfo.lastRevision)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
await exists('game/' + key + '/' + verInfo?.executable, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + key + '/' + verInfo?.executable, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDownloadedVersionsConfig(newConfig)
|
|
||||||
writeVersionsConfig(newConfig)
|
|
||||||
setSelectedVersionList(prev => [...prev, ...versionsToSelect])
|
|
||||||
|
|
||||||
await downloadVersions(versionsToSelect, newConfig)
|
|
||||||
})()
|
})()
|
||||||
}, [serverVersionList, downloadedVersionsConfig])
|
}, [serverVersionList, downloadedVersionsConfig, downloadVersions])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -414,13 +426,9 @@ export default function RootLayout ({
|
|||||||
normalConfig?.settings.theme === 1
|
normalConfig?.settings.theme === 1
|
||||||
? 'red-theme'
|
? 'red-theme'
|
||||||
: normalConfig?.settings.theme === 2
|
: normalConfig?.settings.theme === 2
|
||||||
? 'green-theme'
|
|
||||||
: normalConfig?.settings.theme === 3
|
|
||||||
? 'blue-theme'
|
? 'blue-theme'
|
||||||
: normalConfig?.settings.theme === 4
|
: normalConfig?.settings.theme === 3
|
||||||
? 'purple-theme'
|
? 'purple-theme'
|
||||||
: normalConfig?.settings.theme === 5
|
|
||||||
? 'mint-theme'
|
|
||||||
: 'dark-theme'
|
: 'dark-theme'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -471,7 +479,8 @@ export default function RootLayout ({
|
|||||||
setSelectedGame,
|
setSelectedGame,
|
||||||
getVersionsAmountData,
|
getVersionsAmountData,
|
||||||
viewingInfoFromDownloads,
|
viewingInfoFromDownloads,
|
||||||
version
|
version,
|
||||||
|
downloadVersions
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -591,81 +600,93 @@ export default function RootLayout ({
|
|||||||
Select a game to download
|
Select a game to download
|
||||||
</p>
|
</p>
|
||||||
<div className='popup-content'>
|
<div className='popup-content'>
|
||||||
{serverVersionList?.games.map((v, i) => (
|
{serverVersionList?.games
|
||||||
<div key={i} className='popup-entry'>
|
.filter(v => {
|
||||||
<p className='text-2xl'>{v.name}</p>
|
const data = getVersionsAmountData(v.id)
|
||||||
<div className='flex gap-2'>
|
if (!data) return false
|
||||||
<div
|
if (data.total > 0) return true
|
||||||
className='entry-info-item btntheme3'
|
})
|
||||||
title='The amount of versions installed of this game in installed/installable format.'
|
.map((v, i) => (
|
||||||
>
|
<div key={i} className='popup-entry'>
|
||||||
<p>
|
<p className='text-2xl'>{v.name}</p>
|
||||||
{(() => {
|
<div className='flex gap-2'>
|
||||||
const data = getVersionsAmountData(v.id)
|
<div
|
||||||
if (!data) return 'N/A'
|
className='entry-info-item btntheme3'
|
||||||
return `${data.installed}/${data.total}`
|
title='The amount of versions installed of this game in installed/installable format.'
|
||||||
})()}{' '}
|
>
|
||||||
versions installed
|
<p>
|
||||||
</p>
|
{(() => {
|
||||||
</div>
|
const data = getVersionsAmountData(
|
||||||
<div
|
v.id
|
||||||
className='entry-info-item btntheme3'
|
)
|
||||||
hidden={!v.official}
|
if (!data) return 'N/A'
|
||||||
title='This game is official.'
|
return `${data.installed}/${data.total}`
|
||||||
>
|
})()}{' '}
|
||||||
<FontAwesomeIcon
|
versions installed
|
||||||
icon={faCheck}
|
</p>
|
||||||
color='#19c84b'
|
</div>
|
||||||
/>
|
<div
|
||||||
<p>Official</p>
|
className='entry-info-item btntheme3'
|
||||||
</div>
|
hidden={!v.official}
|
||||||
<div
|
title='This game is official.'
|
||||||
className='entry-info-item btntheme3'
|
>
|
||||||
hidden={v.official}
|
<FontAwesomeIcon
|
||||||
title={
|
icon={faCheck}
|
||||||
v.verified
|
color='#19c84b'
|
||||||
? 'This game is verified to be safe'
|
/>
|
||||||
: 'This game is NOT verified to be save. Proceed with caution.'
|
<p>Official</p>
|
||||||
}
|
</div>
|
||||||
>
|
<div
|
||||||
<FontAwesomeIcon
|
className='entry-info-item btntheme3'
|
||||||
icon={
|
hidden={v.official}
|
||||||
v.verified ? faShieldHalved : faWarning
|
title={
|
||||||
|
v.verified
|
||||||
|
? 'This game is verified to be safe'
|
||||||
|
: 'This game is NOT verified to be save. Proceed with caution.'
|
||||||
}
|
}
|
||||||
color={v.verified ? '#19c84b' : '#ffc800'}
|
>
|
||||||
/>
|
<FontAwesomeIcon
|
||||||
<p>
|
icon={
|
||||||
{v.verified ? 'Verified' : 'Unverified'}
|
v.verified
|
||||||
</p>
|
? faShieldHalved
|
||||||
|
: faWarning
|
||||||
|
}
|
||||||
|
color={
|
||||||
|
v.verified ? '#19c84b' : '#ffc800'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
{v.verified ? 'Verified' : 'Unverified'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme3 mt-2'
|
||||||
|
hidden={v.developer == null}
|
||||||
|
title={`The developer of ${v.name} is ${v.developer}.`}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faCode}
|
||||||
|
color='lightgray'
|
||||||
|
/>
|
||||||
|
<p>Developer: {v.developer}</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className='button btntheme3 right-2 bottom-2'
|
||||||
|
onClick={() => setSelectedGame(v.id)}
|
||||||
|
title={`Click to download specific versions of the game. You have ${(() => {
|
||||||
|
const data = getVersionsAmountData(v.id)
|
||||||
|
if (!data) return 'N/A'
|
||||||
|
return `${data.installed} of ${data.total}`
|
||||||
|
})()} versions downloaded.`}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<FontAwesomeIcon icon={faDownload} />{' '}
|
||||||
|
Download
|
||||||
|
</>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
))}
|
||||||
className='entry-info-item btntheme3 mt-2'
|
|
||||||
hidden={v.developer == null}
|
|
||||||
title={`The developer of ${v.name} is ${v.developer}.`}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={faCode}
|
|
||||||
color='lightgray'
|
|
||||||
/>
|
|
||||||
<p>Developer: {v.developer}</p>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
className='button btntheme3 right-2 bottom-2'
|
|
||||||
onClick={() => setSelectedGame(v.id)}
|
|
||||||
title={`Click to download specific versions of the game. You have ${(() => {
|
|
||||||
const data = getVersionsAmountData(v.id)
|
|
||||||
if (!data) return 'N/A'
|
|
||||||
return `${data.installed} of ${data.total}`
|
|
||||||
})()} versions downloaded.`}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<FontAwesomeIcon icon={faDownload} />{' '}
|
|
||||||
Download
|
|
||||||
</>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : popupMode === 1 ? (
|
) : popupMode === 1 ? (
|
||||||
@@ -779,9 +800,6 @@ export default function RootLayout ({
|
|||||||
list: updatedList
|
list: updatedList
|
||||||
}
|
}
|
||||||
writeVersionsConfig(updatedConfig)
|
writeVersionsConfig(updatedConfig)
|
||||||
setManagingVersion(null)
|
|
||||||
setFadeOut(true)
|
|
||||||
setTimeout(() => setShowPopup(false), 200)
|
|
||||||
return updatedConfig
|
return updatedConfig
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -799,6 +817,48 @@ export default function RootLayout ({
|
|||||||
>
|
>
|
||||||
Uninstall
|
Uninstall
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme2'
|
||||||
|
disabled={downloadProgress.length != 0}
|
||||||
|
onClick={async () => {
|
||||||
|
//change popup to downloads
|
||||||
|
setManagingVersion(null)
|
||||||
|
setPopupMode(1)
|
||||||
|
|
||||||
|
//uninstall
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedList = Object.fromEntries(
|
||||||
|
Object.entries(prev.list).filter(
|
||||||
|
([k]) => k !== managingVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
list: updatedList
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
await exists('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
|
||||||
|
//reinstall
|
||||||
|
setSelectedVersionList([managingVersion])
|
||||||
|
downloadVersions([managingVersion])
|
||||||
|
}}
|
||||||
|
title="Click to reinstall this game. This will NOT remove any progress or any save files. This WILL uninstall any modifications to the game's executable files."
|
||||||
|
>
|
||||||
|
Reinstall
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className='button btntheme2'
|
className='button btntheme2'
|
||||||
onClick={async () =>
|
onClick={async () =>
|
||||||
@@ -833,6 +893,14 @@ export default function RootLayout ({
|
|||||||
No version selected
|
No version selected
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
|
) : popupMode === 5 ? (
|
||||||
|
managingVersion && downloadedVersionsConfig ? (
|
||||||
|
<VersionUpdateWarning />
|
||||||
|
) : (
|
||||||
|
<p className='text-xl text-center'>
|
||||||
|
No version selected
|
||||||
|
</p>
|
||||||
|
)
|
||||||
) : null}
|
) : null}
|
||||||
{popupMode == 0 &&
|
{popupMode == 0 &&
|
||||||
selectedGame &&
|
selectedGame &&
|
||||||
@@ -844,10 +912,7 @@ export default function RootLayout ({
|
|||||||
setFadeOut(true)
|
setFadeOut(true)
|
||||||
setTimeout(() => setShowPopup(false), 200)
|
setTimeout(() => setShowPopup(false), 200)
|
||||||
if (downloadedVersionsConfig)
|
if (downloadedVersionsConfig)
|
||||||
downloadVersions(
|
downloadVersions(selectedVersionList)
|
||||||
selectedVersionList,
|
|
||||||
downloadedVersionsConfig
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
disabled={downloadProgress.length != 0}
|
disabled={downloadProgress.length != 0}
|
||||||
title={
|
title={
|
||||||
|
|||||||
+98
-89
@@ -50,24 +50,22 @@ export default function Settings () {
|
|||||||
label='Allow sending notifications'
|
label='Allow sending notifications'
|
||||||
value={allowNotifications}
|
value={allowNotifications}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setAllowNotifications(!allowNotifications)
|
setAllowNotifications(!allowNotifications)
|
||||||
setNormalConfig({
|
setNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
allowNotifications: !allowNotifications
|
allowNotifications: !allowNotifications
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
writeNormalConfig({
|
await writeNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
allowNotifications: !allowNotifications
|
allowNotifications: !allowNotifications
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
title='This setting does as you expect, allow the launcher to send notifications for when stuff like downloading is done.'
|
title='This setting does as you expect, allow the launcher to send notifications for when stuff like downloading is done.'
|
||||||
/>
|
/>
|
||||||
@@ -75,24 +73,22 @@ export default function Settings () {
|
|||||||
label='Always show games in sidebar'
|
label='Always show games in sidebar'
|
||||||
value={alwaysShowGamesInSidebar}
|
value={alwaysShowGamesInSidebar}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setAlwaysShowGamesInSidebar(!alwaysShowGamesInSidebar)
|
setAlwaysShowGamesInSidebar(!alwaysShowGamesInSidebar)
|
||||||
setNormalConfig({
|
setNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
writeNormalConfig({
|
await writeNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
title="This setting will make it so when you are on a page like this, the games won't disappear."
|
title="This setting will make it so when you are on a page like this, the games won't disappear."
|
||||||
/>
|
/>
|
||||||
@@ -100,24 +96,22 @@ export default function Settings () {
|
|||||||
label='Show Installs/Launch/Manage Buttons'
|
label='Show Installs/Launch/Manage Buttons'
|
||||||
value={useLegacyInteractButtons}
|
value={useLegacyInteractButtons}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setUseLegacyInteractButtons(!useLegacyInteractButtons)
|
setUseLegacyInteractButtons(!useLegacyInteractButtons)
|
||||||
setNormalConfig({
|
setNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
useLegacyInteractButtons: !useLegacyInteractButtons
|
useLegacyInteractButtons: !useLegacyInteractButtons
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
writeNormalConfig({
|
await writeNormalConfig({
|
||||||
...normalConfig,
|
...normalConfig,
|
||||||
settings: {
|
settings: {
|
||||||
...normalConfig.settings,
|
...normalConfig.settings,
|
||||||
useLegacyInteractButtons: !useLegacyInteractButtons
|
useLegacyInteractButtons: !useLegacyInteractButtons
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
title='Enable the legacy method of using the installs/launch/manage buttons. In the future this setting may be removed so try and get used to the new method.'
|
title='Enable the legacy method of using the installs/launch/manage buttons. In the future this setting may be removed so try and get used to the new method.'
|
||||||
/>
|
/>
|
||||||
@@ -125,13 +119,22 @@ export default function Settings () {
|
|||||||
label='Use wine when needed to launch games'
|
label='Use wine when needed to launch games'
|
||||||
value={useWineOnUnixWhenNeeded}
|
value={useWineOnUnixWhenNeeded}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded)
|
setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded)
|
||||||
normalConfig.settings.useWineOnUnixWhenNeeded =
|
setNormalConfig({
|
||||||
!useWineOnUnixWhenNeeded
|
...normalConfig,
|
||||||
await writeNormalConfig(normalConfig)
|
settings: {
|
||||||
break
|
...normalConfig.settings,
|
||||||
}
|
useWineOnUnixWhenNeeded: !useWineOnUnixWhenNeeded
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
useWineOnUnixWhenNeeded: !useWineOnUnixWhenNeeded
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
className={platform() == 'linux' ? '' : 'hidden'}
|
className={platform() == 'linux' ? '' : 'hidden'}
|
||||||
/>
|
/>
|
||||||
@@ -142,12 +145,22 @@ export default function Settings () {
|
|||||||
type='text'
|
type='text'
|
||||||
value={wineOnUnixCommand}
|
value={wineOnUnixCommand}
|
||||||
onChange={async e => {
|
onChange={async e => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setWineOnUnixCommand(e.target.value)
|
setWineOnUnixCommand(e.target.value)
|
||||||
normalConfig.settings.wineOnUnixCommand = e.target.value
|
setNormalConfig({
|
||||||
await writeNormalConfig(normalConfig)
|
...normalConfig,
|
||||||
break
|
settings: {
|
||||||
}
|
...normalConfig.settings,
|
||||||
|
wineOnUnixCommand: e.target.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
wineOnUnixCommand: e.target.value
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
className={`input-field my-1 ${
|
className={`input-field my-1 ${
|
||||||
platform() == 'linux' && useWineOnUnixWhenNeeded ? '' : 'hidden'
|
platform() == 'linux' && useWineOnUnixWhenNeeded ? '' : 'hidden'
|
||||||
@@ -159,33 +172,29 @@ export default function Settings () {
|
|||||||
className='ml-2 bg-(--col2) border border-(--col4) rounded-md'
|
className='ml-2 bg-(--col2) border border-(--col4) rounded-md'
|
||||||
value={theme}
|
value={theme}
|
||||||
onChange={async e => {
|
onChange={async e => {
|
||||||
|
if (!normalConfig) return
|
||||||
const newTheme = parseInt(e.target.value)
|
const newTheme = parseInt(e.target.value)
|
||||||
while (normalConfig != null) {
|
setTheme(newTheme)
|
||||||
setTheme(newTheme)
|
setNormalConfig({
|
||||||
setNormalConfig({
|
...normalConfig,
|
||||||
...normalConfig,
|
settings: {
|
||||||
settings: {
|
...normalConfig.settings,
|
||||||
...normalConfig.settings,
|
theme: newTheme
|
||||||
theme: newTheme
|
}
|
||||||
}
|
})
|
||||||
})
|
await writeNormalConfig({
|
||||||
writeNormalConfig({
|
...normalConfig,
|
||||||
...normalConfig,
|
settings: {
|
||||||
settings: {
|
...normalConfig.settings,
|
||||||
...normalConfig.settings,
|
theme: newTheme
|
||||||
theme: newTheme
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value={0}>Dark (default)</option>
|
<option value={0}>Dark (default)</option>
|
||||||
<option value={1}>Red</option>
|
<option value={1}>Red</option>
|
||||||
<option value={2}>Green</option>
|
<option value={2}>Blue</option>
|
||||||
<option value={3}>Blue</option>
|
<option value={3}>Purple</option>
|
||||||
<option value={4}>Purple</option>
|
|
||||||
<option value={5}>Mint</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,7 +32,31 @@ export async function readNormalConfig (): Promise<NormalConfig> {
|
|||||||
return new NormalConfig(version)
|
return new NormalConfig(version)
|
||||||
}
|
}
|
||||||
const config = await readTextFile('config.json', options)
|
const config = await readTextFile('config.json', options)
|
||||||
return NormalConfig.import(JSON.parse(config))
|
const raw = JSON.parse(config)
|
||||||
|
if (
|
||||||
|
raw.settings &&
|
||||||
|
raw.settings.theme &&
|
||||||
|
(raw.version == '1.0.0' ||
|
||||||
|
raw.version == '1.1.0' ||
|
||||||
|
raw.version == '1.1.1' ||
|
||||||
|
raw.version == '1.2.0' ||
|
||||||
|
raw.version == '1.3.0' ||
|
||||||
|
raw.version == '1.3.1' ||
|
||||||
|
raw.version == '1.4.0' ||
|
||||||
|
raw.version == '1.5.0' ||
|
||||||
|
raw.version == '1.5.1' ||
|
||||||
|
raw.version == '1.5.2' ||
|
||||||
|
raw.version == '1.5.3' ||
|
||||||
|
raw.version == '1.5.4')
|
||||||
|
) {
|
||||||
|
const parsed = Number(raw.settings.theme)
|
||||||
|
if (parsed == 3) raw.settings.theme = 2
|
||||||
|
if (parsed == 4) raw.settings.theme = 3
|
||||||
|
else if (parsed != 0 && parsed != 1) raw.settings.theme = 0
|
||||||
|
}
|
||||||
|
raw.version = version
|
||||||
|
writeNormalConfig(raw)
|
||||||
|
return NormalConfig.import(raw)
|
||||||
} catch {
|
} catch {
|
||||||
return new NormalConfig(version)
|
return new NormalConfig(version)
|
||||||
}
|
}
|
||||||
@@ -83,8 +107,7 @@ export async function readVersionsConfig (): Promise<VersionsConfig> {
|
|||||||
}
|
}
|
||||||
const config = await readTextFile('versions.json', options)
|
const config = await readTextFile('versions.json', options)
|
||||||
const raw = JSON.parse(config)
|
const raw = JSON.parse(config)
|
||||||
if (raw.version && raw.list && raw.timestamps) {
|
if (raw.list && raw.timestamps) {
|
||||||
raw.version = version
|
|
||||||
raw.list = raw.timestamps
|
raw.list = raw.timestamps
|
||||||
delete raw.timestamps
|
delete raw.timestamps
|
||||||
|
|
||||||
@@ -94,6 +117,8 @@ export async function readVersionsConfig (): Promise<VersionsConfig> {
|
|||||||
options
|
options
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
raw.version = version
|
||||||
|
writeVersionsConfig(raw)
|
||||||
return VersionsConfig.import(raw)
|
return VersionsConfig.import(raw)
|
||||||
} catch {
|
} catch {
|
||||||
return new VersionsConfig(version)
|
return new VersionsConfig(version)
|
||||||
|
|||||||
+3
-1
@@ -28,7 +28,9 @@
|
|||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
".next/types/**/*.ts",
|
".next/types/**/*.ts",
|
||||||
".next/dev/types/**/*.ts",
|
".next/dev/types/**/*.ts",
|
||||||
"**/*.mts"
|
"**/*.mts",
|
||||||
|
"next.config.ts",
|
||||||
|
"eslint.config.ts"
|
||||||
],
|
],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user