Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
138275d752
|
||
|
|
1f035882f7
|
||
|
|
68cd3c891d
|
||
|
|
65bd6cfe82
|
||
|
|
d91314112d
|
||
|
|
da27bcb32c
|
||
|
|
6c8dfd1200
|
||
|
|
e09d125980
|
||
|
|
35dd842576
|
||
|
|
55714c8edb
|
||
|
|
04d1f2822b
|
||
|
|
dfd99ab12e
|
||
|
|
837c4a8863
|
No files matched your search
@@ -18,8 +18,10 @@
|
|||||||
"@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-store": "2.4.2",
|
"@tauri-apps/plugin-store": "2.4.2",
|
||||||
|
"@tauri-apps/plugin-updater": "2.10.0",
|
||||||
"@tauri-apps/plugin-window-state": "2.4.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"next": "16.2.1",
|
"dompurify": "3.3.3",
|
||||||
|
"next": "16.2.2",
|
||||||
"pretty-bytes": "7.1.0",
|
"pretty-bytes": "7.1.0",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4",
|
"react-dom": "19.2.4",
|
||||||
@@ -29,14 +31,14 @@
|
|||||||
"@tailwindcss/postcss": "4.2.2",
|
"@tailwindcss/postcss": "4.2.2",
|
||||||
"@tauri-apps/cli": "2.10.1",
|
"@tauri-apps/cli": "2.10.1",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/node": "25.5.0",
|
"@types/node": "25.5.2",
|
||||||
"@types/react": "19.2.14",
|
"@types/react": "19.2.14",
|
||||||
"@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.4",
|
"eslint": "9.39.4",
|
||||||
"eslint-config-next": "16.2.1",
|
"eslint-config-next": "16.2.2",
|
||||||
"tailwindcss": "4.2.2",
|
"tailwindcss": "4.2.2",
|
||||||
"typescript": "5.9.3",
|
"typescript": "6.0.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -75,11 +77,11 @@
|
|||||||
|
|
||||||
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
||||||
|
|
||||||
"@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="],
|
"@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="],
|
"@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
|
||||||
|
|
||||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
|
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
|
||||||
|
|
||||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
|
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
|
||||||
|
|
||||||
@@ -179,25 +181,25 @@
|
|||||||
|
|
||||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
||||||
|
|
||||||
"@next/env": ["@next/env@16.2.1", "", {}, "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg=="],
|
"@next/env": ["@next/env@16.2.2", "", {}, "sha512-LqSGz5+xGk9EL/iBDr2yo/CgNQV6cFsNhRR2xhSXYh7B/hb4nePCxlmDvGEKG30NMHDFf0raqSyOZiQrO7BkHQ=="],
|
||||||
|
|
||||||
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.2.1", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-r0epZGo24eT4g08jJlg2OEryBphXqO8aL18oajoTKLzHJ6jVr6P6FI58DLMug04MwD3j8Fj0YK0slyzneKVyzA=="],
|
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.2.2", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-IOPbWzDQ+76AtjZioaCjpIY72xNSDMnarZ2GMQ4wjNLvnJEJHqxQwGFhgnIWLV9klb4g/+amg88Tk5OXVpyLTw=="],
|
||||||
|
|
||||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q=="],
|
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B92G3ulrwmkDSEJEp9+XzGLex5wC1knrmCSIylyVeiAtCIfvEJYiN3v5kXPlYt5R4RFlsfO/v++aKV63Acrugg=="],
|
||||||
|
|
||||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA=="],
|
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-7ZwSgNKJNQiwW0CKhNm9B1WS2L1Olc4B2XY0hPYCAL3epFnugMhuw5TMWzMilQ3QCZcCHoYm9NGWTHbr5REFxw=="],
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw=="],
|
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-c3m8kBHMziMgo2fICOP/cd/5YlrxDU5YYjAJeQLyFsCqVF8xjOTH/QYG4a2u48CvvZZSj1eHQfBCbyh7kBr30Q=="],
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ=="],
|
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-VKLuscm0P/mIfzt+SDdn2+8TNNJ7f0qfEkA+az7OqQbjzKdBxAHs0UvuiVoCtbwX+dqMEL9U54b5wQ/aN3dHeg=="],
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg=="],
|
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-kU3OPHJq6sBUjOk7wc5zJ7/lipn8yGldMoAv4z67j6ov6Xo/JvzA7L7LCsyzzsXmgLEhk3Qkpwqaq/1+XpNR3g=="],
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg=="],
|
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-CKXRILyErMtUftp+coGcZ38ZwE/Aqq45VMCcRLr2I4OXKrgxIBDXHnBgeX/UMil0S09i2JXaDL3Q+TN8D/cKmg=="],
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA=="],
|
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-sS/jSk5VUoShUqINJFvNjVT7JfR5ORYj/+/ZpOYbbIohv/lQfduWnGAycq2wlknbOql2xOR0DoV0s6Xfcy49+g=="],
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg=="],
|
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-aHaKceJgdySReT7qeck5oShucxWRiiEuwCGK8HHALe6yZga8uyFpLkPgaRw3kkF04U7ROogL/suYCNt/+CuXGA=="],
|
||||||
|
|
||||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||||
|
|
||||||
@@ -283,6 +285,8 @@
|
|||||||
|
|
||||||
"@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A=="],
|
"@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A=="],
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-updater": ["@tauri-apps/plugin-updater@2.10.0", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-window-state": ["@tauri-apps/plugin-window-state@2.4.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw=="],
|
"@tauri-apps/plugin-window-state": ["@tauri-apps/plugin-window-state@2.4.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw=="],
|
||||||
|
|
||||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||||
@@ -295,31 +299,33 @@
|
|||||||
|
|
||||||
"@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.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
"@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||||
|
|
||||||
"@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.57.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/type-utils": "8.57.2", "@typescript-eslint/utils": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w=="],
|
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.58.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.58.0", "@typescript-eslint/type-utils": "8.58.0", "@typescript-eslint/utils": "8.58.0", "@typescript-eslint/visitor-keys": "8.58.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.58.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg=="],
|
||||||
|
|
||||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.2", "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.58.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.58.0", "@typescript-eslint/types": "8.58.0", "@typescript-eslint/typescript-estree": "8.58.0", "@typescript-eslint/visitor-keys": "8.58.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA=="],
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2" } }, "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw=="],
|
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.0", "@typescript-eslint/types": "^8.58.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg=="],
|
||||||
|
|
||||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw=="],
|
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.58.0", "", { "dependencies": { "@typescript-eslint/types": "8.58.0", "@typescript-eslint/visitor-keys": "8.58.0" } }, "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg=="],
|
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A=="],
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.2", "", {}, "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA=="],
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.58.0", "", { "dependencies": { "@typescript-eslint/types": "8.58.0", "@typescript-eslint/typescript-estree": "8.58.0", "@typescript-eslint/utils": "8.58.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.2", "@typescript-eslint/tsconfig-utils": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA=="],
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.58.0", "", {}, "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg=="],
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.0", "@typescript-eslint/tsconfig-utils": "8.58.0", "@typescript-eslint/types": "8.58.0", "@typescript-eslint/visitor-keys": "8.58.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA=="],
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw=="],
|
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.58.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.58.0", "@typescript-eslint/types": "8.58.0", "@typescript-eslint/typescript-estree": "8.58.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.0", "", { "dependencies": { "@typescript-eslint/types": "8.58.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ=="],
|
||||||
|
|
||||||
"@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=="],
|
||||||
|
|
||||||
@@ -393,19 +399,19 @@
|
|||||||
|
|
||||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||||
|
|
||||||
"axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="],
|
"axe-core": ["axe-core@4.11.2", "", {}, "sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw=="],
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.10", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ=="],
|
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-fOVLPAsFTsQfuCkvahZkzq6nf8KvGWanlYoTh0SVA0A/PIUxQGU2AOZAoD95n2gFLVDW/jP6sbGLny95nmEuHA=="],
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
"brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="],
|
||||||
|
|
||||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||||
|
|
||||||
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
|
"browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="],
|
||||||
|
|
||||||
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
||||||
|
|
||||||
@@ -415,7 +421,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.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001784", "", {}, "sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw=="],
|
||||||
|
|
||||||
"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=="],
|
||||||
|
|
||||||
@@ -455,9 +461,11 @@
|
|||||||
|
|
||||||
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
||||||
|
|
||||||
|
"dompurify": ["dompurify@3.3.3", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA=="],
|
||||||
|
|
||||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.322", "", {}, "sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.331", "", {}, "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
@@ -485,9 +493,9 @@
|
|||||||
|
|
||||||
"eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
|
"eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
|
||||||
|
|
||||||
"eslint-config-next": ["eslint-config-next@16.2.1", "", { "dependencies": { "@next/eslint-plugin-next": "16.2.1", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-qhabwjQZ1Mk53XzXvmogf8KQ0tG0CQXF0CZ56+2/lVhmObgmaqj7x5A1DSrWdZd3kwI7GTPGUjFne+krRxYmFg=="],
|
"eslint-config-next": ["eslint-config-next@16.2.2", "", { "dependencies": { "@next/eslint-plugin-next": "16.2.2", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-6VlvEhwoug2JpVgjZDhyXrJXUEuPY++TddzIpTaIRvlvlXXFgvQUtm3+Zr84IjFm0lXtJt73w19JA08tOaZVwg=="],
|
||||||
|
|
||||||
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
|
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.10", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.16.1", "resolve": "^2.0.0-next.6" } }, "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ=="],
|
||||||
|
|
||||||
"eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="],
|
"eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="],
|
||||||
|
|
||||||
@@ -729,11 +737,11 @@
|
|||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
"next": ["next@16.2.1", "", { "dependencies": { "@next/env": "16.2.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.1", "@next/swc-darwin-x64": "16.2.1", "@next/swc-linux-arm64-gnu": "16.2.1", "@next/swc-linux-arm64-musl": "16.2.1", "@next/swc-linux-x64-gnu": "16.2.1", "@next/swc-linux-x64-musl": "16.2.1", "@next/swc-win32-arm64-msvc": "16.2.1", "@next/swc-win32-x64-msvc": "16.2.1", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q=="],
|
"next": ["next@16.2.2", "", { "dependencies": { "@next/env": "16.2.2", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.2", "@next/swc-darwin-x64": "16.2.2", "@next/swc-linux-arm64-gnu": "16.2.2", "@next/swc-linux-arm64-musl": "16.2.2", "@next/swc-linux-x64-gnu": "16.2.2", "@next/swc-linux-x64-musl": "16.2.2", "@next/swc-win32-arm64-msvc": "16.2.2", "@next/swc-win32-x64-msvc": "16.2.2", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-i6AJdyVa4oQjyvX/6GeER8dpY/xlIV+4NMv/svykcLtURJSy/WzDnnUk/TM4d0uewFHK7xSQz4TbIwPgjky+3A=="],
|
||||||
|
|
||||||
"node-exports-info": ["node-exports-info@1.6.0", "", { "dependencies": { "array.prototype.flatmap": "^1.3.3", "es-errors": "^1.3.0", "object.entries": "^1.1.9", "semver": "^6.3.1" } }, "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw=="],
|
"node-exports-info": ["node-exports-info@1.6.0", "", { "dependencies": { "array.prototype.flatmap": "^1.3.3", "es-errors": "^1.3.0", "object.entries": "^1.1.9", "semver": "^6.3.1" } }, "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw=="],
|
||||||
|
|
||||||
"node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="],
|
"node-releases": ["node-releases@2.0.37", "", {}, "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg=="],
|
||||||
|
|
||||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||||
|
|
||||||
@@ -795,7 +803,7 @@
|
|||||||
|
|
||||||
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
|
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
|
||||||
|
|
||||||
"resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
|
"resolve": ["resolve@2.0.0-next.6", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA=="],
|
||||||
|
|
||||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||||
|
|
||||||
@@ -887,9 +895,9 @@
|
|||||||
|
|
||||||
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
|
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.57.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.57.2", "@typescript-eslint/parser": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A=="],
|
"typescript-eslint": ["typescript-eslint@8.58.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.58.0", "@typescript-eslint/parser": "8.58.0", "@typescript-eslint/typescript-estree": "8.58.0", "@typescript-eslint/utils": "8.58.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA=="],
|
||||||
|
|
||||||
"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=="],
|
||||||
|
|
||||||
@@ -925,13 +933,13 @@
|
|||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" }, "bundled": true }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.2", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||||
|
|
||||||
@@ -939,7 +947,7 @@
|
|||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
@@ -953,8 +961,6 @@
|
|||||||
|
|
||||||
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||||
|
|
||||||
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.6", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA=="],
|
|
||||||
|
|
||||||
"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.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
"is-bun-module/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|||||||
+7
-5
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "lncvrt-games-launcher",
|
"name": "lncvrt-games-launcher",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.8.1",
|
"version": "1.9.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -24,8 +24,10 @@
|
|||||||
"@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-store": "2.4.2",
|
"@tauri-apps/plugin-store": "2.4.2",
|
||||||
|
"@tauri-apps/plugin-updater": "2.10.0",
|
||||||
"@tauri-apps/plugin-window-state": "2.4.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"next": "16.2.1",
|
"dompurify": "3.3.3",
|
||||||
|
"next": "16.2.2",
|
||||||
"pretty-bytes": "7.1.0",
|
"pretty-bytes": "7.1.0",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4"
|
"react-dom": "19.2.4"
|
||||||
@@ -35,13 +37,13 @@
|
|||||||
"@tailwindcss/postcss": "4.2.2",
|
"@tailwindcss/postcss": "4.2.2",
|
||||||
"@tauri-apps/cli": "2.10.1",
|
"@tauri-apps/cli": "2.10.1",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/node": "25.5.0",
|
"@types/node": "25.5.2",
|
||||||
"@types/react": "19.2.14",
|
"@types/react": "19.2.14",
|
||||||
"@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.4",
|
"eslint": "9.39.4",
|
||||||
"eslint-config-next": "16.2.1",
|
"eslint-config-next": "16.2.2",
|
||||||
"tailwindcss": "4.2.2",
|
"tailwindcss": "4.2.2",
|
||||||
"typescript": "5.9.3"
|
"typescript": "6.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lncvrt-games-launcher"
|
name = "lncvrt-games-launcher"
|
||||||
version = "1.8.1"
|
version = "1.9.0"
|
||||||
authors = ["Lncvrt"]
|
authors = ["Lncvrt"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@ 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.2", default-features = false, features = ["stream", "rustls"] }
|
reqwest = { version = "0.13.2", default-features = false, features = ["stream", "rustls"] }
|
||||||
tokio = "1.50.0"
|
tokio = "1.51.0"
|
||||||
futures-util = { version = "0.3.32", features = ["io"] }
|
futures-util = { version = "0.3.32", 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 = "8.4.0"
|
zip = "8.5.0"
|
||||||
tauri-plugin-dialog = "2.6.0"
|
tauri-plugin-dialog = "2.6.0"
|
||||||
tauri-plugin-notification = "2.3.3"
|
tauri-plugin-notification = "2.3.3"
|
||||||
sha2 = "0.11.0"
|
sha2 = "0.11.0"
|
||||||
@@ -40,6 +40,7 @@ sysinfo = "0.38.4"
|
|||||||
|
|
||||||
[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.4.0"
|
tauri-plugin-single-instance = "2.4.0"
|
||||||
|
tauri-plugin-updater = "2.10.0"
|
||||||
tauri-plugin-window-state = "2.4.1"
|
tauri-plugin-window-state = "2.4.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
@@ -47,6 +48,7 @@ tauri-plugin-decorum = "1.1.1"
|
|||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
lto = true
|
lto = "fat"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
strip = true
|
strip = true
|
||||||
|
panic = "abort"
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"fs:allow-applocaldata-write",
|
"fs:allow-applocaldata-write",
|
||||||
{
|
{
|
||||||
"identifier": "fs:scope",
|
"identifier": "fs:scope",
|
||||||
"allow": [{ "path": "$APPLOCALDATA/game/**" }]
|
"allow": [{ "path": "$APPLOCALDATA/game/**" }, { "path": "$APPCONFIG/versions.json" }]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identifier": "opener:allow-open-path",
|
"identifier": "opener:allow-open-path",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"main"
|
"main"
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"window-state:default"
|
"window-state:default",
|
||||||
|
"updater:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+81
-2
@@ -30,6 +30,9 @@ use sysinfo::System;
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
use tauri_plugin_updater::UpdaterExt;
|
||||||
|
|
||||||
static CANCEL_MAP: OnceLock<DashMap<String, bool>> = OnceLock::new();
|
static CANCEL_MAP: OnceLock<DashMap<String, bool>> = OnceLock::new();
|
||||||
|
|
||||||
fn cancel_map() -> &'static DashMap<String, bool> {
|
fn cancel_map() -> &'static DashMap<String, bool> {
|
||||||
@@ -520,6 +523,7 @@ async fn cancel_download(name: String) {
|
|||||||
pub fn run() {
|
pub fn run() {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.plugin(tauri_plugin_store::Builder::new().build())
|
.plugin(tauri_plugin_store::Builder::new().build())
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
.plugin(
|
.plugin(
|
||||||
@@ -559,17 +563,92 @@ pub fn run() {
|
|||||||
cancel_download
|
cancel_download
|
||||||
])
|
])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
|
let window = app.get_webview_window("main").unwrap();
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
use tauri_plugin_decorum::WebviewWindowExt;
|
use tauri_plugin_decorum::WebviewWindowExt;
|
||||||
if let Some(main_window) = app.get_webview_window("main") {
|
if let Err(e) = window.create_overlay_titlebar() {
|
||||||
if let Err(e) = main_window.create_overlay_titlebar() {
|
|
||||||
eprintln!("Failed to create overlay titlebar: {:?}", e);
|
eprintln!("Failed to create overlay titlebar: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
{
|
||||||
|
let handle = app.handle().clone();
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
update(handle, window.clone()).await.unwrap();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let mut new_url = app.config().build.dev_url.clone().unwrap();
|
||||||
|
new_url.set_path("/main");
|
||||||
|
window.navigate(new_url).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
async fn update(
|
||||||
|
app: tauri::AppHandle,
|
||||||
|
window: tauri::WebviewWindow,
|
||||||
|
) -> tauri_plugin_updater::Result<()> {
|
||||||
|
let target = {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
if std::path::Path::new("/etc/debian_version").exists() {
|
||||||
|
"linux-debian"
|
||||||
|
} else if std::path::Path::new("/etc/redhat-release").exists() {
|
||||||
|
"linux-fedora"
|
||||||
|
} else {
|
||||||
|
let mut new_url = window.url().unwrap();
|
||||||
|
new_url.set_path("/update/outdated");
|
||||||
|
window.navigate(new_url).unwrap();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
{
|
||||||
|
tauri_plugin_updater::target().unwrap_or("unknown".to_string())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(update) = app
|
||||||
|
.updater_builder()
|
||||||
|
.target(target)
|
||||||
|
.build()?
|
||||||
|
.check()
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
let mut new_url = window.url().unwrap();
|
||||||
|
new_url.set_path("/update/updating");
|
||||||
|
window.navigate(new_url).unwrap();
|
||||||
|
|
||||||
|
let mut downloaded = 0;
|
||||||
|
|
||||||
|
update
|
||||||
|
.download_and_install(
|
||||||
|
|chunk_length, content_length| {
|
||||||
|
downloaded += chunk_length;
|
||||||
|
println!("downloaded {downloaded} from {content_length:?}");
|
||||||
|
},
|
||||||
|
|| {
|
||||||
|
println!("download finished");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
println!("update installed");
|
||||||
|
app.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_url = window.url().unwrap();
|
||||||
|
new_url.set_path("/main");
|
||||||
|
window.navigate(new_url).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -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.8.1",
|
"version": "1.9.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev --webpack",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
|
|||||||
@@ -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.8.1",
|
"version": "1.9.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev --webpack",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
|
"url": "/update/checking",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"minWidth": 875,
|
"minWidth": 875,
|
||||||
@@ -24,6 +25,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": false
|
"active": true,
|
||||||
|
"targets": ["deb", "rpm"],
|
||||||
|
"icon": ["icons/icon.png"],
|
||||||
|
"createUpdaterArtifacts": true
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"updater": {
|
||||||
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IERFODI3MTAwQkNBMjE4REEKUldUYUdLSzhBSEdDM3J0N1NvbENsdDQ3c3BOdWlFajErVnlLZitSc2l5WVI0VjQ1ZHNMWjYzaUwK",
|
||||||
|
"endpoints": [
|
||||||
|
"https://games.lncvrt.xyz/api/launcher/update?target={{target}}&arch={{arch}}¤tVersion={{current_version}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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.8.1",
|
"version": "1.9.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev --webpack",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
|
"url": "/update/checking",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"minWidth": 875,
|
"minWidth": 875,
|
||||||
@@ -28,10 +29,19 @@
|
|||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": ["app"],
|
"targets": ["dmg", "app"],
|
||||||
|
"icon": ["icons/icon.icns"],
|
||||||
|
"createUpdaterArtifacts": true,
|
||||||
"macOS": {
|
"macOS": {
|
||||||
"minimumSystemVersion": "13.0"
|
"minimumSystemVersion": "13.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"icon": ["icons/icon.icns"]
|
"plugins": {
|
||||||
|
"updater": {
|
||||||
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IERFODI3MTAwQkNBMjE4REEKUldUYUdLSzhBSEdDM3J0N1NvbENsdDQ3c3BOdWlFajErVnlLZitSc2l5WVI0VjQ1ZHNMWjYzaUwK",
|
||||||
|
"endpoints": [
|
||||||
|
"https://games.lncvrt.xyz/api/launcher/update?target={{target}}&arch={{arch}}¤tVersion={{current_version}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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.8.1",
|
"version": "1.9.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev --webpack",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
@@ -14,12 +14,11 @@
|
|||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
|
"url": "/update/checking",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 632,
|
"height": 632,
|
||||||
"minWidth": 875,
|
"minWidth": 875,
|
||||||
"minHeight": 532,
|
"minHeight": 532,
|
||||||
"titleBarStyle": "Overlay",
|
|
||||||
"hiddenTitle": true,
|
|
||||||
"decorations": false,
|
"decorations": false,
|
||||||
"shadow": true
|
"shadow": true
|
||||||
}
|
}
|
||||||
@@ -29,7 +28,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": false,
|
"active": true,
|
||||||
"icon": ["icons/icon.ico"]
|
"targets": ["msi"],
|
||||||
|
"icon": ["icons/icon.ico"],
|
||||||
|
"createUpdaterArtifacts": true
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"updater": {
|
||||||
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IERFODI3MTAwQkNBMjE4REEKUldUYUdLSzhBSEdDM3J0N1NvbENsdDQ3c3BOdWlFajErVnlLZitSc2l5WVI0VjQ1ZHNMWjYzaUwK",
|
||||||
|
"endpoints": [
|
||||||
|
"https://games.lncvrt.xyz/api/launcher/update?target={{target}}&arch={{arch}}¤tVersion={{current_version}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
+4
-4
@@ -1,14 +1,14 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import './styles.css'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { BirdColor } from '@/types/BerryDash/BirdColor'
|
import { BirdColor } from '@/types/BerryDash/BirdColor'
|
||||||
import { GetIconForUser } from '@/lib/BerryDash'
|
import { GetIconForUser } from '@/lib/berrydashutil'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import './styles.css'
|
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
import { fetch } from '@tauri-apps/plugin-http'
|
import { fetch } from '@tauri-apps/plugin-http'
|
||||||
import { verifySignature } from '@/lib/Util'
|
import { verifySignature } from '@/lib/util'
|
||||||
|
|
||||||
interface BaseEntry {
|
interface BaseEntry {
|
||||||
id: number
|
id: number
|
||||||
@@ -174,7 +174,7 @@ export default function BerryDashLeaderboards () {
|
|||||||
<button
|
<button
|
||||||
className='button btntheme1'
|
className='button btntheme1'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (selected == -1) router.push('/game?id=1')
|
if (selected == -1) router.push('/main/game?id=1')
|
||||||
else {
|
else {
|
||||||
setSelected(-1)
|
setSelected(-1)
|
||||||
setSelectedBerryOption(0)
|
setSelectedBerryOption(0)
|
||||||
File renamed without changes.
@@ -1,38 +1,35 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import '../Installs.css'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import '@/app/Installs.css'
|
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import { useRouter, useSearchParams } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
import { faWarning } from '@fortawesome/free-solid-svg-icons'
|
import { faWarning } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { ask } from '@tauri-apps/plugin-dialog'
|
import { ask } from '@tauri-apps/plugin-dialog'
|
||||||
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
import { openFolder } from '@/lib/util'
|
||||||
import { openFolder } from '@/lib/Util'
|
|
||||||
|
|
||||||
export default function Installs () {
|
export default function Installs () {
|
||||||
const {
|
const {
|
||||||
|
versionsList,
|
||||||
|
serverVersionList,
|
||||||
showPopup,
|
showPopup,
|
||||||
setShowPopup,
|
setShowPopup,
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
setFadeOut,
|
setFadeOut,
|
||||||
setSelectedVersionList,
|
setSelectedVersionList,
|
||||||
downloadedVersionsConfig,
|
|
||||||
setManagingVersion,
|
setManagingVersion,
|
||||||
getVersionInfo,
|
|
||||||
getGameInfo,
|
|
||||||
setSelectedGame,
|
setSelectedGame,
|
||||||
serverVersionList,
|
|
||||||
category,
|
category,
|
||||||
setCategory,
|
setCategory,
|
||||||
setDownloadedVersionsConfig,
|
|
||||||
downloadVersions,
|
downloadVersions,
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
linuxUseWine,
|
linuxUseWine,
|
||||||
linuxWineCommand
|
linuxWineCommand,
|
||||||
|
versions
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
const params = useSearchParams()
|
const params = useSearchParams()
|
||||||
@@ -55,10 +52,7 @@ export default function Installs () {
|
|||||||
if (!lastRevision) return false
|
if (!lastRevision) return false
|
||||||
return (
|
return (
|
||||||
lastRevision > 0 &&
|
lastRevision > 0 &&
|
||||||
(downloadedVersionsConfig == undefined
|
(versionsList == undefined ? 0 : versionsList[version]) / 1000 <=
|
||||||
? 0
|
|
||||||
: downloadedVersionsConfig?.list[version]) /
|
|
||||||
1000 <=
|
|
||||||
lastRevision
|
lastRevision
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -81,7 +75,7 @@ export default function Installs () {
|
|||||||
<button
|
<button
|
||||||
className='button btntheme1'
|
className='button btntheme1'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
router.push('/game/berrydash/leaderboards')
|
router.push('/main/game/berrydash/leaderboards')
|
||||||
}}
|
}}
|
||||||
title='View the leaderboards for this game.'
|
title='View the leaderboards for this game.'
|
||||||
hidden={game.id != 1}
|
hidden={game.id != 1}
|
||||||
@@ -122,12 +116,11 @@ export default function Installs () {
|
|||||||
>
|
>
|
||||||
{category == -1 &&
|
{category == -1 &&
|
||||||
Object.entries(game.categoryNames)
|
Object.entries(game.categoryNames)
|
||||||
.sort(([a], [b]) => Number(b) - Number(a))
|
|
||||||
.filter(([key]) => {
|
.filter(([key]) => {
|
||||||
const count = Object.keys(
|
const count = Object.keys(versionsList).filter(v => {
|
||||||
downloadedVersionsConfig?.list ?? {}
|
const info = serverVersionList?.versions.find(
|
||||||
).filter(v => {
|
vf => vf.id == v
|
||||||
const info = getVersionInfo(v)
|
)
|
||||||
if (!info) return false
|
if (!info) return false
|
||||||
|
|
||||||
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
||||||
@@ -138,6 +131,7 @@ export default function Installs () {
|
|||||||
|
|
||||||
return count >= 1
|
return count >= 1
|
||||||
})
|
})
|
||||||
|
.sort(([a], [b]) => Number(b) - Number(a))
|
||||||
.map(([key, value]) => {
|
.map(([key, value]) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -157,10 +151,10 @@ export default function Installs () {
|
|||||||
<p>
|
<p>
|
||||||
{(() => {
|
{(() => {
|
||||||
const count =
|
const count =
|
||||||
Object.keys(
|
Object.keys(versionsList).filter(v => {
|
||||||
downloadedVersionsConfig?.list ?? []
|
const info = serverVersionList?.versions.find(
|
||||||
).filter(v => {
|
vf => vf.id == v
|
||||||
const info = getVersionInfo(v)
|
)
|
||||||
if (!info) return false
|
if (!info) return false
|
||||||
if (
|
if (
|
||||||
platform() == 'linux' &&
|
platform() == 'linux' &&
|
||||||
@@ -181,20 +175,9 @@ export default function Installs () {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{Object.keys(downloadedVersionsConfig?.list ?? []).filter(v => {
|
{Object.keys(versionsList)
|
||||||
const info = getVersionInfo(v)
|
|
||||||
if (!info) return false
|
|
||||||
return info.game === id
|
|
||||||
}).length != 0 ? (
|
|
||||||
Object.keys(downloadedVersionsConfig?.list ?? [])
|
|
||||||
.sort((a, b) => {
|
|
||||||
const infoA = getVersionInfo(a)
|
|
||||||
const infoB = getVersionInfo(b)
|
|
||||||
if (!infoA || !infoB) return 0
|
|
||||||
return infoB.place - infoA.place
|
|
||||||
})
|
|
||||||
.filter(v => {
|
.filter(v => {
|
||||||
const info = getVersionInfo(v)
|
const info = serverVersionList?.versions.find(vf => vf.id == v)
|
||||||
if (!info) return false
|
if (!info) return false
|
||||||
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
||||||
return false
|
return false
|
||||||
@@ -205,20 +188,27 @@ export default function Installs () {
|
|||||||
: info.category == category)
|
: info.category == category)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(entry => (
|
.sort((a, b) => {
|
||||||
|
const infoA = serverVersionList?.versions.find(vf => vf.id == a)
|
||||||
|
const infoB = serverVersionList?.versions.find(vf => vf.id == b)
|
||||||
|
if (!infoA || !infoB) return 0
|
||||||
|
return infoB.place - infoA.place
|
||||||
|
})
|
||||||
|
.map(v => {
|
||||||
|
const versionInfo = serverVersionList?.versions.find(
|
||||||
|
vf => vf.id == v
|
||||||
|
)
|
||||||
|
if (!versionInfo) return
|
||||||
|
|
||||||
|
return (
|
||||||
<div
|
<div
|
||||||
key={entry}
|
key={v}
|
||||||
className={'downloads-entry'}
|
className={'downloads-entry'}
|
||||||
title={
|
title={
|
||||||
'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 (
|
if (needsRevisionUpdate(versionInfo.lastRevision, v)) {
|
||||||
needsRevisionUpdate(
|
|
||||||
getVersionInfo(entry)?.lastRevision,
|
|
||||||
entry
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const answer = await ask(
|
const answer = await ask(
|
||||||
'Before proceeding, if you do not want your installation directory wiped just yet, please backup the files to another directory. When you click "Yes", it will be wiped. Click "No" if you want to open the installation folder instead.',
|
'Before proceeding, if you do not want your installation directory wiped just yet, please backup the files to another directory. When you click "Yes", it will be wiped. Click "No" if you want to open the installation folder instead.',
|
||||||
{
|
{
|
||||||
@@ -242,55 +232,45 @@ export default function Installs () {
|
|||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
|
|
||||||
//uninstall
|
//uninstall
|
||||||
setDownloadedVersionsConfig(prev => {
|
versions?.set(
|
||||||
if (!prev) return prev
|
'list',
|
||||||
const updatedList = Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev.list).filter(
|
Object.entries(versionsList).filter(
|
||||||
([k]) => k !== entry
|
([k]) => k !== v
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
const updatedConfig = {
|
|
||||||
...prev,
|
|
||||||
list: updatedList
|
|
||||||
}
|
|
||||||
writeVersionsConfig(updatedConfig)
|
|
||||||
return updatedConfig
|
|
||||||
})
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
await exists('game/' + entry, {
|
await exists('game/' + v, {
|
||||||
baseDir: BaseDirectory.AppLocalData
|
baseDir: BaseDirectory.AppLocalData
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
await remove('game/' + entry, {
|
await remove('game/' + v, {
|
||||||
baseDir: BaseDirectory.AppLocalData,
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
recursive: true
|
recursive: true
|
||||||
})
|
})
|
||||||
|
|
||||||
//reinstall
|
//reinstall
|
||||||
setSelectedVersionList([entry])
|
setSelectedVersionList([v])
|
||||||
downloadVersions([
|
downloadVersions([
|
||||||
{
|
{
|
||||||
id: entry,
|
id: v,
|
||||||
type: 0
|
type: 0
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
openFolder(entry)
|
openFolder(v)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const verInfo = getVersionInfo(entry)
|
|
||||||
if (verInfo == undefined) return
|
|
||||||
const gameInfo = getGameInfo(verInfo.game)
|
|
||||||
if (gameInfo == undefined) return
|
|
||||||
invoke('launch_game', {
|
invoke('launch_game', {
|
||||||
name: verInfo.id,
|
name: versionInfo.id,
|
||||||
executable: verInfo.executable,
|
executable: versionInfo.executable,
|
||||||
displayName: verInfo.displayName,
|
displayName: versionInfo.displayName,
|
||||||
useWine: !!(
|
useWine: !!(
|
||||||
platform() == 'linux' &&
|
platform() == 'linux' &&
|
||||||
verInfo.wine &&
|
versionInfo.wine &&
|
||||||
linuxUseWine
|
linuxUseWine
|
||||||
),
|
),
|
||||||
wineCommand: linuxWineCommand
|
wineCommand: linuxWineCommand
|
||||||
@@ -298,16 +278,14 @@ export default function Installs () {
|
|||||||
}}
|
}}
|
||||||
onContextMenu={e => {
|
onContextMenu={e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setManagingVersion(entry)
|
setManagingVersion(v)
|
||||||
setPopupMode(2)
|
setPopupMode(2)
|
||||||
setShowPopup(true)
|
setShowPopup(true)
|
||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='h-18 w-screen relative'>
|
<div className='h-18 w-screen relative'>
|
||||||
<p className='text-2xl'>
|
<p className='text-2xl'>{versionInfo.displayName}</p>
|
||||||
{getVersionInfo(entry)?.displayName}{' '}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className='flex gap-2 absolute left-0 bottom-0'>
|
<div className='flex gap-2 absolute left-0 bottom-0'>
|
||||||
<div
|
<div
|
||||||
@@ -317,7 +295,7 @@ export default function Installs () {
|
|||||||
<p>
|
<p>
|
||||||
Installed{' '}
|
Installed{' '}
|
||||||
{new Intl.DateTimeFormat(undefined).format(
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
downloadedVersionsConfig?.list[entry]
|
versionsList[v]
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -325,13 +303,8 @@ export default function Installs () {
|
|||||||
className='entry-info-item'
|
className='entry-info-item'
|
||||||
title='This version is using wine. It cannot be guarenteed to work fully and might not work at all.'
|
title='This version is using wine. It cannot be guarenteed to work fully and might not work at all.'
|
||||||
hidden={
|
hidden={
|
||||||
!(
|
!(platform() == 'linux' && versionInfo.wine) ||
|
||||||
platform() == 'linux' && getVersionInfo(entry)?.wine
|
needsRevisionUpdate(versionInfo.lastRevision, v)
|
||||||
) ||
|
|
||||||
needsRevisionUpdate(
|
|
||||||
getVersionInfo(entry)?.lastRevision,
|
|
||||||
entry
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
@@ -340,10 +313,7 @@ export default function Installs () {
|
|||||||
<div
|
<div
|
||||||
className='entry-info-item'
|
className='entry-info-item'
|
||||||
hidden={
|
hidden={
|
||||||
!needsRevisionUpdate(
|
!needsRevisionUpdate(versionInfo.lastRevision, v)
|
||||||
getVersionInfo(entry)?.lastRevision,
|
|
||||||
entry
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
@@ -357,45 +327,41 @@ export default function Installs () {
|
|||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(await exists('game/' + entry + '/BepInEx', {
|
!(await exists('game/' + v + '/BepInEx', {
|
||||||
baseDir: BaseDirectory.AppLocalData
|
baseDir: BaseDirectory.AppLocalData
|
||||||
}))
|
}))
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
(await ask(
|
(await ask(
|
||||||
"You don't have BepInEx (the mod loader for Unity Games), would you like to install it now? It is about 1MB in size. If you choose yes, it will download the recommended BepInEx version for " +
|
"You don't have BepInEx (the mod loader for Unity Games), would you like to install it now? It is about 1MB in size. If you choose yes, it will download the recommended BepInEx version for " +
|
||||||
getVersionInfo(entry)?.displayName +
|
versionInfo.displayName +
|
||||||
'.',
|
'.',
|
||||||
{ title: 'BepInEx not found!', kind: 'error' }
|
{ title: 'BepInEx not found!', kind: 'error' }
|
||||||
)) &&
|
)) &&
|
||||||
!downloadProgress.find(d => d.version == entry)
|
!downloadProgress.find(d => d.version == v)
|
||||||
) {
|
) {
|
||||||
downloadVersions([
|
downloadVersions([
|
||||||
{
|
{
|
||||||
id: entry,
|
id: v,
|
||||||
type: 1
|
type: 1
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setManagingVersion(entry)
|
setManagingVersion(v)
|
||||||
setPopupMode(3)
|
setPopupMode(3)
|
||||||
setShowPopup(true)
|
setShowPopup(true)
|
||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
}}
|
}}
|
||||||
hidden={!getVersionInfo(entry)?.modSupportDownload}
|
hidden={!versionInfo.modSupportDownload}
|
||||||
>
|
>
|
||||||
Mod Manager
|
Mod Manager
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
)
|
||||||
) : (
|
})}
|
||||||
<div className='flex justify-center items-center h-full'>
|
|
||||||
<p className='text-3xl'>No versions installed</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,21 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import './Globals.css'
|
import '@/styles/globals.css'
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import Sidebar from '@/components/Sidebar'
|
import Sidebar from '@/components/Sidebar'
|
||||||
import { DownloadProgress } from '@/types/DownloadProgress'
|
import { DownloadProgress } from '@/types/DownloadProgress'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
||||||
import { faChevronLeft, faXmark } from '@fortawesome/free-solid-svg-icons'
|
|
||||||
import { readVersionsConfig, writeVersionsConfig } from '@/lib/BazookaManager'
|
|
||||||
import { VersionsConfig } from '@/types/VersionsConfig'
|
|
||||||
import { app } from '@tauri-apps/api'
|
import { app } from '@tauri-apps/api'
|
||||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
import { GlobalProvider } from '@/providers/GlobalProvider'
|
||||||
import { GlobalProvider } from './GlobalProvider'
|
|
||||||
import { Roboto } from 'next/font/google'
|
import { Roboto } from 'next/font/google'
|
||||||
import { ServerVersionsResponse } from '@/types/ServerVersionsResponse'
|
import { ServerVersionsResponse } from '@/types/ServerVersionsResponse'
|
||||||
import { GameVersion } from '@/types/GameVersion'
|
|
||||||
import { Game } from '@/types/Game'
|
|
||||||
import { listen } from '@tauri-apps/api/event'
|
import { listen } from '@tauri-apps/api/event'
|
||||||
import { usePathname } from 'next/navigation'
|
import { usePathname } from 'next/navigation'
|
||||||
import { arch, platform } from '@tauri-apps/plugin-os'
|
import { arch, platform } from '@tauri-apps/plugin-os'
|
||||||
@@ -25,22 +17,28 @@ import {
|
|||||||
} from '@tauri-apps/plugin-notification'
|
} from '@tauri-apps/plugin-notification'
|
||||||
import {
|
import {
|
||||||
BaseDirectory,
|
BaseDirectory,
|
||||||
|
copyFile,
|
||||||
exists,
|
exists,
|
||||||
readTextFile,
|
readTextFile,
|
||||||
remove
|
remove
|
||||||
} from '@tauri-apps/plugin-fs'
|
} from '@tauri-apps/plugin-fs'
|
||||||
import { fetch } from '@tauri-apps/plugin-http'
|
import { fetch } from '@tauri-apps/plugin-http'
|
||||||
import { verifySignature } from '@/lib/Util'
|
import { verifySignature } from '@/lib/util'
|
||||||
import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window'
|
import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window'
|
||||||
|
|
||||||
import VersionsDownloadPopup from '@/components/popups/VersionsDownload'
|
|
||||||
import GamesDownloadPopup from '@/components/popups/GamesDownload'
|
|
||||||
import DownloadsPopup from '@/components/popups/Downloads'
|
|
||||||
import ManageVersionPopup from '@/components/popups/ManageVersion'
|
|
||||||
import ModDownloadsPopup from '@/components/popups/ModDownloads'
|
|
||||||
import { Mod } from '@/types/Mod'
|
import { Mod } from '@/types/Mod'
|
||||||
import { load, Store } from '@tauri-apps/plugin-store'
|
import { load, Store } from '@tauri-apps/plugin-store'
|
||||||
import { notifyUser } from '@/lib/Notifications'
|
import { notifyUser } from '@/lib/notifications'
|
||||||
|
import { GameVersion } from '@/types/GameVersion'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { faChevronLeft, faXmark } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
|
||||||
|
import VersionsDownloadPopup from '@/popups/VersionsDownload'
|
||||||
|
import GamesDownloadPopup from '@/popups/GamesDownload'
|
||||||
|
import DownloadsPopup from '@/popups/Downloads'
|
||||||
|
import ManageVersionPopup from '@/popups/ManageVersion'
|
||||||
|
import ModDownloadsPopup from '@/popups/ModDownloads'
|
||||||
|
import VersionChangelogPopup from '@/popups/VersionChangelog'
|
||||||
|
|
||||||
const roboto = Roboto({
|
const roboto = Roboto({
|
||||||
subsets: ['latin']
|
subsets: ['latin']
|
||||||
@@ -53,7 +51,6 @@ export default function RootLayout ({
|
|||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [loadingText, setLoadingText] = useState('Loading...')
|
const [loadingText, setLoadingText] = useState('Loading...')
|
||||||
const [outdated, setOutdated] = useState(false)
|
|
||||||
const [version, setVersion] = useState<string | null>(null)
|
const [version, setVersion] = useState<string | null>(null)
|
||||||
const [platformName, setPlatformName] = useState<string | null>(null)
|
const [platformName, setPlatformName] = useState<string | null>(null)
|
||||||
|
|
||||||
@@ -61,9 +58,6 @@ export default function RootLayout ({
|
|||||||
useState<null | ServerVersionsResponse>(null)
|
useState<null | ServerVersionsResponse>(null)
|
||||||
const [selectedVersionList, setSelectedVersionList] = useState<string[]>([])
|
const [selectedVersionList, setSelectedVersionList] = useState<string[]>([])
|
||||||
|
|
||||||
const [downloadedVersionsConfig, setDownloadedVersionsConfig] =
|
|
||||||
useState<VersionsConfig | null>(null)
|
|
||||||
|
|
||||||
const [showPopup, setShowPopup] = useState(false)
|
const [showPopup, setShowPopup] = useState(false)
|
||||||
const [popupMode, setPopupMode] = useState<null | number>(null)
|
const [popupMode, setPopupMode] = useState<null | number>(null)
|
||||||
const [fadeOut, setFadeOut] = useState(false)
|
const [fadeOut, setFadeOut] = useState(false)
|
||||||
@@ -85,6 +79,7 @@ export default function RootLayout ({
|
|||||||
const revisionCheck = useRef(false)
|
const revisionCheck = useRef(false)
|
||||||
|
|
||||||
const [settings, setSettings] = useState<Store | null>(null)
|
const [settings, setSettings] = useState<Store | null>(null)
|
||||||
|
const [versions, setVersions] = useState<Store | null>(null)
|
||||||
|
|
||||||
const [notificationsAllowed, setNotificationsAllowed] =
|
const [notificationsAllowed, setNotificationsAllowed] =
|
||||||
useState<boolean>(false)
|
useState<boolean>(false)
|
||||||
@@ -95,13 +90,16 @@ export default function RootLayout ({
|
|||||||
useState<string>('wine %path%')
|
useState<string>('wine %path%')
|
||||||
const [theme, setTheme] = useState<string>('dark')
|
const [theme, setTheme] = useState<string>('dark')
|
||||||
|
|
||||||
|
const [versionsList, setVersionsList] = useState<Record<string, number>>({})
|
||||||
|
const [modsList, setModsList] = useState<
|
||||||
|
Record<string, Record<string, number>>
|
||||||
|
>({})
|
||||||
|
|
||||||
function getSpecialVersionsList (game?: number): GameVersion[] {
|
function getSpecialVersionsList (game?: number): GameVersion[] {
|
||||||
if (!serverVersionList) return []
|
if (!serverVersionList) return []
|
||||||
|
|
||||||
return serverVersionList.versions
|
return serverVersionList.versions
|
||||||
.filter(
|
.filter(v => !Object.keys(versionsList).includes(v.id))
|
||||||
v => !Object.keys(downloadedVersionsConfig?.list ?? []).includes(v.id)
|
|
||||||
)
|
|
||||||
.filter(v => {
|
.filter(v => {
|
||||||
if (platformName == 'linux' && v.wine && linuxUseWine) return false
|
if (platformName == 'linux' && v.wine && linuxUseWine) return false
|
||||||
|
|
||||||
@@ -118,62 +116,6 @@ export default function RootLayout ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getVersionInfo = useCallback(
|
|
||||||
(id: string | undefined): GameVersion | undefined => {
|
|
||||||
if (!id) return undefined
|
|
||||||
return serverVersionList?.versions.find(v => v.id === id)
|
|
||||||
},
|
|
||||||
[serverVersionList]
|
|
||||||
)
|
|
||||||
|
|
||||||
const getGameInfo = useCallback(
|
|
||||||
(game: number | undefined): Game | undefined => {
|
|
||||||
if (!game) return undefined
|
|
||||||
return serverVersionList?.games.find(g => g.id === game)
|
|
||||||
},
|
|
||||||
[serverVersionList]
|
|
||||||
)
|
|
||||||
|
|
||||||
function getListOfGames (): Game[] {
|
|
||||||
if (!downloadedVersionsConfig?.list) return []
|
|
||||||
|
|
||||||
const gamesMap = new Map<number, Game>()
|
|
||||||
|
|
||||||
Object.keys(downloadedVersionsConfig.list).forEach(i => {
|
|
||||||
const version = getVersionInfo(i)
|
|
||||||
if (!version) return
|
|
||||||
const game = getGameInfo(version.game)
|
|
||||||
if (!game) return
|
|
||||||
gamesMap.set(game.id, game)
|
|
||||||
})
|
|
||||||
|
|
||||||
return Array.from(gamesMap.values())
|
|
||||||
}
|
|
||||||
|
|
||||||
function getVersionsAmountData (gameId: number): {
|
|
||||||
installed: number
|
|
||||||
total: number
|
|
||||||
} | null {
|
|
||||||
if (!downloadedVersionsConfig || !serverVersionList) return null
|
|
||||||
|
|
||||||
const allowWine = platformName !== 'linux' || linuxUseWine
|
|
||||||
|
|
||||||
const installed = Object.keys(downloadedVersionsConfig.list).filter(v => {
|
|
||||||
const info = getVersionInfo(v)
|
|
||||||
if (!info) return false
|
|
||||||
if (info.wine && !allowWine) return false
|
|
||||||
return getGameInfo(info.game)?.id === gameId
|
|
||||||
}).length
|
|
||||||
|
|
||||||
const total = serverVersionList.versions.filter(v => {
|
|
||||||
if (!v) return false
|
|
||||||
if (v.wine && !allowWine) return false
|
|
||||||
return getGameInfo(v.game)?.id === gameId
|
|
||||||
}).length
|
|
||||||
|
|
||||||
return { installed, total }
|
|
||||||
}
|
|
||||||
|
|
||||||
const closePopup = useCallback(() => {
|
const closePopup = useCallback(() => {
|
||||||
if (popupMode == 0 && selectedGame && pathname === '/') {
|
if (popupMode == 0 && selectedGame && pathname === '/') {
|
||||||
setSelectedGame(null)
|
setSelectedGame(null)
|
||||||
@@ -183,6 +125,8 @@ export default function RootLayout ({
|
|||||||
setPopupMode(0)
|
setPopupMode(0)
|
||||||
} else if (popupMode == 3 && showModInfo) {
|
} else if (popupMode == 3 && showModInfo) {
|
||||||
setShowModInfo(null)
|
setShowModInfo(null)
|
||||||
|
} else if (popupMode == 4) {
|
||||||
|
setPopupMode(2)
|
||||||
} else {
|
} else {
|
||||||
setFadeOut(true)
|
setFadeOut(true)
|
||||||
setTimeout(() => setShowPopup(false), 200)
|
setTimeout(() => setShowPopup(false), 200)
|
||||||
@@ -321,27 +265,6 @@ export default function RootLayout ({
|
|||||||
setPlatformName(platform())
|
setPlatformName(platform())
|
||||||
const client = await app.getVersion()
|
const client = await app.getVersion()
|
||||||
setVersion(client)
|
setVersion(client)
|
||||||
if (process.env.NODE_ENV === 'production') {
|
|
||||||
try {
|
|
||||||
const response = await fetch(
|
|
||||||
'https://games.lncvrt.xyz/api/launcher/latest'
|
|
||||||
)
|
|
||||||
const signature = response.headers.get('x-signature') ?? ''
|
|
||||||
const data = await response.text()
|
|
||||||
if (await verifySignature(data, signature)) {
|
|
||||||
if (data !== client) {
|
|
||||||
setOutdated(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setLoadingText('Failed to check latest version.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
setLoadingText('Failed to check latest version.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://games.lncvrt.xyz/api/launcher/versions?platform=${platform()}&arch=${arch()}`
|
`https://games.lncvrt.xyz/api/launcher/versions?platform=${platform()}&arch=${arch()}`
|
||||||
@@ -358,6 +281,29 @@ export default function RootLayout ({
|
|||||||
setLoadingText('Failed to download versions list.')
|
setLoadingText('Failed to download versions list.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const legacyOptions = {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
platform() == 'windows' &&
|
||||||
|
(await exists('versions.json', legacyOptions))
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
await exists('versions.json', {
|
||||||
|
baseDir: BaseDirectory.AppConfig
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('versions.json', {
|
||||||
|
baseDir: BaseDirectory.AppConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
await copyFile('versions.json', 'versions.json', {
|
||||||
|
fromPathBaseDir: BaseDirectory.AppLocalData,
|
||||||
|
toPathBaseDir: BaseDirectory.AppConfig
|
||||||
|
})
|
||||||
|
await remove('versions.json', legacyOptions)
|
||||||
|
}
|
||||||
|
|
||||||
const settingsLocal = await load('settings.json', {
|
const settingsLocal = await load('settings.json', {
|
||||||
autoSave: true,
|
autoSave: true,
|
||||||
defaults: {
|
defaults: {
|
||||||
@@ -369,12 +315,18 @@ export default function RootLayout ({
|
|||||||
theme: 'dark'
|
theme: 'dark'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
settingsLocal.set('version', client)
|
const versionsLocal = await load('versions.json', {
|
||||||
const oldSettingsOptions = {
|
autoSave: true,
|
||||||
baseDir: BaseDirectory.AppLocalData
|
defaults: {
|
||||||
|
version: client,
|
||||||
|
list: {},
|
||||||
|
mods: {}
|
||||||
}
|
}
|
||||||
if (await exists('config.json', oldSettingsOptions)) {
|
})
|
||||||
const config = await readTextFile('config.json', oldSettingsOptions)
|
settingsLocal.set('version', client)
|
||||||
|
versionsLocal.set('version', client)
|
||||||
|
if (await exists('config.json', legacyOptions)) {
|
||||||
|
const config = await readTextFile('config.json', legacyOptions)
|
||||||
const raw = JSON.parse(config)
|
const raw = JSON.parse(config)
|
||||||
if (
|
if (
|
||||||
raw.settings &&
|
raw.settings &&
|
||||||
@@ -432,11 +384,10 @@ export default function RootLayout ({
|
|||||||
})()
|
})()
|
||||||
settingsLocal?.set('theme', tempTheme)
|
settingsLocal?.set('theme', tempTheme)
|
||||||
}
|
}
|
||||||
await remove('config.json', oldSettingsOptions)
|
await remove('config.json', legacyOptions)
|
||||||
}
|
}
|
||||||
const versionsConfig = await readVersionsConfig()
|
|
||||||
setDownloadedVersionsConfig(versionsConfig)
|
|
||||||
setSettings(settingsLocal)
|
setSettings(settingsLocal)
|
||||||
|
setVersions(versionsLocal)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
|
||||||
if (!(await isPermissionGranted())) {
|
if (!(await isPermissionGranted())) {
|
||||||
@@ -511,7 +462,7 @@ export default function RootLayout ({
|
|||||||
const versionId = downloadQueue[0]
|
const versionId = downloadQueue[0]
|
||||||
const downloadInfo = downloadProgress.find(d => d.version == versionId)
|
const downloadInfo = downloadProgress.find(d => d.version == versionId)
|
||||||
if (!downloadInfo) return
|
if (!downloadInfo) return
|
||||||
const info = getVersionInfo(versionId)
|
const info = serverVersionList?.versions.find(vf => vf.id == versionId)
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
||||||
@@ -520,7 +471,7 @@ export default function RootLayout ({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const gameInfo = getGameInfo(info.game)
|
const gameInfo = serverVersionList?.games.find(vf => vf.id == info.game)
|
||||||
if (!gameInfo) {
|
if (!gameInfo) {
|
||||||
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
||||||
setDownloadQueue(prev => prev.slice(1))
|
setDownloadQueue(prev => prev.slice(1))
|
||||||
@@ -590,31 +541,19 @@ export default function RootLayout ({
|
|||||||
if (res === '1') {
|
if (res === '1') {
|
||||||
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
setDownloadProgress(prev => prev.filter(d => d.version !== versionId))
|
||||||
if (downloadInfo.type != 1) {
|
if (downloadInfo.type != 1) {
|
||||||
setDownloadedVersionsConfig(prev => {
|
if (downloadInfo.type == 2) {
|
||||||
if (!prev) return prev
|
versions?.set('mods', {
|
||||||
|
...modsList,
|
||||||
const updated =
|
|
||||||
downloadInfo.type == 2
|
|
||||||
? {
|
|
||||||
...prev,
|
|
||||||
mods: {
|
|
||||||
...prev.mods,
|
|
||||||
[downloadInfo.modGame! + '-' + downloadInfo.modId!]: {
|
[downloadInfo.modGame! + '-' + downloadInfo.modId!]: {
|
||||||
[downloadInfo.modVersion!]: Date.now()
|
[downloadInfo.modVersion!]: Date.now()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
...prev,
|
|
||||||
list: {
|
|
||||||
...prev.list,
|
|
||||||
[versionId]: Date.now()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeVersionsConfig(updated)
|
|
||||||
return updated
|
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
versions?.set('list', {
|
||||||
|
...versionsList,
|
||||||
|
[versionId]: Date.now()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (res == '0') {
|
} else if (res == '0') {
|
||||||
setDownloadProgress(prev => {
|
setDownloadProgress(prev => {
|
||||||
@@ -658,20 +597,20 @@ export default function RootLayout ({
|
|||||||
}, [
|
}, [
|
||||||
downloadQueue,
|
downloadQueue,
|
||||||
isProcessingQueue,
|
isProcessingQueue,
|
||||||
getVersionInfo,
|
|
||||||
getGameInfo,
|
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
settings
|
serverVersionList,
|
||||||
|
settings,
|
||||||
|
versions,
|
||||||
|
versionsList,
|
||||||
|
modsList
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (revisionCheck.current) return
|
if (revisionCheck.current) return
|
||||||
if (!serverVersionList || !downloadedVersionsConfig) return
|
if (!serverVersionList) return
|
||||||
revisionCheck.current = true
|
revisionCheck.current = true
|
||||||
;(async () => {
|
;(async () => {
|
||||||
for (const [key, value] of Object.entries(
|
for (const [key, value] of Object.entries(versionsList)) {
|
||||||
downloadedVersionsConfig.list
|
|
||||||
)) {
|
|
||||||
const verInfo = serverVersionList.versions.find(item => item.id === key)
|
const verInfo = serverVersionList.versions.find(item => item.id === key)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -690,7 +629,7 @@ export default function RootLayout ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
}, [serverVersionList, downloadedVersionsConfig, downloadVersions])
|
}, [serverVersionList, downloadVersions, versionsList])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@@ -719,30 +658,40 @@ export default function RootLayout ({
|
|||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!settings) return
|
if (!settings || !versions) return
|
||||||
const unlisteners: Promise<() => void>[] = []
|
const unlisteners: Promise<() => void>[] = []
|
||||||
|
|
||||||
function watch<T> (key: string, fn: (v: T | undefined) => void) {
|
function watchSettings<T> (key: string, fn: (v: T | undefined) => void) {
|
||||||
settings!.get<T>(key).then(fn)
|
settings!.get<T>(key).then(fn)
|
||||||
unlisteners.push(settings!.onKeyChange<T>(key, fn))
|
unlisteners.push(settings!.onKeyChange<T>(key, fn))
|
||||||
}
|
}
|
||||||
|
|
||||||
watch<string>('theme', v => setTheme(v ?? 'dark'))
|
function watchVersions<T> (key: string, fn: (v: T | undefined) => void) {
|
||||||
watch<boolean>('notificationsAllowed', v =>
|
versions!.get<T>(key).then(fn)
|
||||||
|
unlisteners.push(versions!.onKeyChange<T>(key, fn))
|
||||||
|
}
|
||||||
|
|
||||||
|
watchSettings<string>('theme', v => setTheme(v ?? 'dark'))
|
||||||
|
watchSettings<boolean>('notificationsAllowed', v =>
|
||||||
setNotificationsAllowed(v ?? true)
|
setNotificationsAllowed(v ?? true)
|
||||||
)
|
)
|
||||||
watch<boolean>('sidebarAlwaysShowGames', v =>
|
watchSettings<boolean>('sidebarAlwaysShowGames', v =>
|
||||||
setSidebarAlwaysShowGames(v ?? true)
|
setSidebarAlwaysShowGames(v ?? true)
|
||||||
)
|
)
|
||||||
watch<boolean>('linuxUseWine', v => setLinuxUseWine(v ?? false))
|
watchSettings<boolean>('linuxUseWine', v => setLinuxUseWine(v ?? false))
|
||||||
watch<string>('linuxWineCommand', v =>
|
watchSettings<string>('linuxWineCommand', v =>
|
||||||
setLinuxWineCommand(v ?? 'wine %path%')
|
setLinuxWineCommand(v ?? 'wine %path%')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watchVersions<Record<string, number>>('list', v => setVersionsList(v ?? {}))
|
||||||
|
watchVersions<Record<string, Record<string, number>>>('mods', v =>
|
||||||
|
setModsList(v ?? {})
|
||||||
|
)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unlisteners.forEach(u => u.then(fn => fn()))
|
unlisteners.forEach(u => u.then(fn => fn()))
|
||||||
}
|
}
|
||||||
}, [settings])
|
}, [settings, versions])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -761,24 +710,7 @@ export default function RootLayout ({
|
|||||||
: 'h-screen'
|
: 'h-screen'
|
||||||
} flex items-center justify-center`}
|
} flex items-center justify-center`}
|
||||||
>
|
>
|
||||||
{outdated ? (
|
|
||||||
<div className='text-center'>
|
|
||||||
<p className='text-6xl mb-4'>Outdated Launcher!</p>
|
|
||||||
<p className='text-2xl mb-4'>
|
|
||||||
Please update to the latest version to continue.
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
className='button btntheme1'
|
|
||||||
onClick={() =>
|
|
||||||
openUrl('https://games.lncvrt.xyz/download')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Download latest version!
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<p className='text-7xl text-center'>{loadingText}</p>
|
<p className='text-7xl text-center'>{loadingText}</p>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -795,15 +727,9 @@ export default function RootLayout ({
|
|||||||
setPopupMode,
|
setPopupMode,
|
||||||
fadeOut,
|
fadeOut,
|
||||||
setFadeOut,
|
setFadeOut,
|
||||||
downloadedVersionsConfig,
|
|
||||||
setDownloadedVersionsConfig,
|
|
||||||
managingVersion,
|
managingVersion,
|
||||||
setManagingVersion,
|
setManagingVersion,
|
||||||
getVersionInfo,
|
|
||||||
getGameInfo,
|
|
||||||
getListOfGames,
|
|
||||||
setSelectedGame,
|
setSelectedGame,
|
||||||
getVersionsAmountData,
|
|
||||||
viewingInfoFromDownloads,
|
viewingInfoFromDownloads,
|
||||||
version,
|
version,
|
||||||
downloadVersions,
|
downloadVersions,
|
||||||
@@ -812,17 +738,20 @@ export default function RootLayout ({
|
|||||||
downloadQueue,
|
downloadQueue,
|
||||||
setDownloadQueue,
|
setDownloadQueue,
|
||||||
closePopup,
|
closePopup,
|
||||||
getSpecialVersionsList,
|
|
||||||
selectedGame,
|
selectedGame,
|
||||||
setViewingInfoFromDownloads,
|
setViewingInfoFromDownloads,
|
||||||
showModInfo,
|
showModInfo,
|
||||||
setShowModInfo,
|
setShowModInfo,
|
||||||
|
getSpecialVersionsList,
|
||||||
settings,
|
settings,
|
||||||
|
versions,
|
||||||
notificationsAllowed,
|
notificationsAllowed,
|
||||||
sidebarAlwaysShowGames,
|
sidebarAlwaysShowGames,
|
||||||
linuxUseWine,
|
linuxUseWine,
|
||||||
linuxWineCommand,
|
linuxWineCommand,
|
||||||
theme
|
theme,
|
||||||
|
versionsList,
|
||||||
|
modsList
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -867,7 +796,8 @@ export default function RootLayout ({
|
|||||||
selectedGame &&
|
selectedGame &&
|
||||||
pathname === '/') ||
|
pathname === '/') ||
|
||||||
viewingInfoFromDownloads ||
|
viewingInfoFromDownloads ||
|
||||||
(popupMode == 3 && showModInfo)
|
(popupMode == 3 && showModInfo) ||
|
||||||
|
popupMode == 4
|
||||||
? faChevronLeft
|
? faChevronLeft
|
||||||
: faXmark
|
: faXmark
|
||||||
}
|
}
|
||||||
@@ -883,6 +813,8 @@ export default function RootLayout ({
|
|||||||
<ManageVersionPopup />
|
<ManageVersionPopup />
|
||||||
) : popupMode === 3 ? (
|
) : popupMode === 3 ? (
|
||||||
<ModDownloadsPopup />
|
<ModDownloadsPopup />
|
||||||
|
) : popupMode === 4 ? (
|
||||||
|
<VersionChangelogPopup />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import './Installs.css'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import {
|
||||||
|
faCheck,
|
||||||
|
faShieldHalved,
|
||||||
|
faWarning
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
|
export default function Installs () {
|
||||||
|
const {
|
||||||
|
versionsList,
|
||||||
|
serverVersionList,
|
||||||
|
showPopup,
|
||||||
|
setShowPopup,
|
||||||
|
setPopupMode,
|
||||||
|
setFadeOut,
|
||||||
|
setSelectedVersionList,
|
||||||
|
setSelectedGame,
|
||||||
|
setCategory
|
||||||
|
} = useGlobal()
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showPopup) return
|
||||||
|
setSelectedVersionList([])
|
||||||
|
}, [setSelectedVersionList, showPopup])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mx-4 mt-4'>
|
||||||
|
<div className='flex justify-between items-center mb-4'>
|
||||||
|
<p className='text-3xl'>Games</p>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedGame(null)
|
||||||
|
setPopupMode(0)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
}}
|
||||||
|
title='Click to download more games.'
|
||||||
|
>
|
||||||
|
Download game
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className='downloads-container'>
|
||||||
|
<div
|
||||||
|
className={`downloads-scroll ${
|
||||||
|
platform() == 'windows'
|
||||||
|
? 'h-[calc(100vh-116px)]'
|
||||||
|
: 'h-[calc(100vh-84px)]'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{serverVersionList?.games
|
||||||
|
.filter(g =>
|
||||||
|
serverVersionList.versions
|
||||||
|
.filter(v => v.game === g.id)
|
||||||
|
.some(v => Object.keys(versionsList).includes(v.id))
|
||||||
|
)
|
||||||
|
.map(i => (
|
||||||
|
<div
|
||||||
|
key={i.id}
|
||||||
|
className={'downloads-entry'}
|
||||||
|
title={'Click to view game installs'}
|
||||||
|
onClick={() => {
|
||||||
|
setCategory(-1)
|
||||||
|
router.push('/main/game?id=' + i.id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='h-18 w-screen relative'>
|
||||||
|
<p className='text-2xl'>{i.name}</p>
|
||||||
|
|
||||||
|
<div className='flex gap-2 absolute left-0 bottom-0'>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
title='The amount of versions installed of this game in installed/installable format.'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{(() => {
|
||||||
|
const gameVersions =
|
||||||
|
serverVersionList.versions.filter(
|
||||||
|
v => v.game === i.id
|
||||||
|
)
|
||||||
|
const installed = gameVersions.filter(v =>
|
||||||
|
Object.keys(versionsList).includes(v.id)
|
||||||
|
).length
|
||||||
|
return gameVersions.length
|
||||||
|
? `${installed}/${gameVersions.length}`
|
||||||
|
: 'N/A'
|
||||||
|
})()}{' '}
|
||||||
|
versions installed
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
hidden={!i.official}
|
||||||
|
title='This game is official.'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
|
||||||
|
<p>Official</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
hidden={i.official}
|
||||||
|
title={
|
||||||
|
i.verified
|
||||||
|
? 'This game is verified to be safe'
|
||||||
|
: 'This game is not verified to be save. Proceed with caution.'
|
||||||
|
}
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={i.verified ? faShieldHalved : faWarning}
|
||||||
|
color={i.verified ? '#19c84b' : '#ffc800'}
|
||||||
|
/>
|
||||||
|
<p>{i.verified ? 'Verified' : 'Unverified'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { Setting } from '@/components/Setting'
|
import { Setting } from '@/components/Setting'
|
||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import { copyToClipboard } from '@/lib/Clipboard'
|
import { copyToClipboard } from '@/lib/clipboard'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
|
||||||
export default function Settings () {
|
export default function Settings () {
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useEffect } from 'react'
|
|
||||||
import './Installs.css'
|
|
||||||
import { useGlobal } from './GlobalProvider'
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
||||||
import {
|
|
||||||
faCheck,
|
|
||||||
faShieldHalved,
|
|
||||||
faWarning
|
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
|
||||||
import { useRouter } from 'next/navigation'
|
|
||||||
|
|
||||||
export default function Installs () {
|
|
||||||
const {
|
|
||||||
showPopup,
|
|
||||||
setShowPopup,
|
|
||||||
setPopupMode,
|
|
||||||
setFadeOut,
|
|
||||||
setSelectedVersionList,
|
|
||||||
downloadedVersionsConfig,
|
|
||||||
setSelectedGame,
|
|
||||||
getListOfGames,
|
|
||||||
getVersionsAmountData,
|
|
||||||
setCategory
|
|
||||||
} = useGlobal()
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!showPopup) return
|
|
||||||
setSelectedVersionList([])
|
|
||||||
}, [setSelectedVersionList, showPopup])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='mx-4 mt-4'>
|
|
||||||
<div className='flex justify-between items-center mb-4'>
|
|
||||||
<p className='text-3xl'>Games</p>
|
|
||||||
<button
|
|
||||||
className='button btntheme1'
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedGame(null)
|
|
||||||
setPopupMode(0)
|
|
||||||
setShowPopup(true)
|
|
||||||
setFadeOut(false)
|
|
||||||
}}
|
|
||||||
title='Click to download more games.'
|
|
||||||
>
|
|
||||||
Download game
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className='downloads-container'>
|
|
||||||
<div
|
|
||||||
className={`downloads-scroll ${
|
|
||||||
platform() == 'windows'
|
|
||||||
? 'h-[calc(100vh-116px)]'
|
|
||||||
: 'h-[calc(100vh-84px)]'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{downloadedVersionsConfig &&
|
|
||||||
Object.keys(downloadedVersionsConfig.list).length ? (
|
|
||||||
getListOfGames()
|
|
||||||
.sort((a, b) => {
|
|
||||||
return a.id - b.id
|
|
||||||
})
|
|
||||||
.map(i => (
|
|
||||||
<div
|
|
||||||
key={i.id}
|
|
||||||
className={'downloads-entry'}
|
|
||||||
title={'Click to view game installs'}
|
|
||||||
onClick={() => {
|
|
||||||
setCategory(-1)
|
|
||||||
router.push('/game?id=' + i.id)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='h-18 w-screen relative'>
|
|
||||||
<p className='text-2xl'>{i.name}</p>
|
|
||||||
|
|
||||||
<div className='flex gap-2 absolute left-0 bottom-0'>
|
|
||||||
<div
|
|
||||||
className='entry-info-item'
|
|
||||||
title='The amount of versions installed of this game in installed/installable format.'
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
{(() => {
|
|
||||||
const data = getVersionsAmountData(i.id)
|
|
||||||
if (!data) return 'N/A'
|
|
||||||
return `${data.installed}/${data.total}`
|
|
||||||
})()}{' '}
|
|
||||||
versions installed
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className='entry-info-item'
|
|
||||||
hidden={!i.official}
|
|
||||||
title='This game is official.'
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
|
|
||||||
<p>Official</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className='entry-info-item'
|
|
||||||
hidden={i.official}
|
|
||||||
title={
|
|
||||||
i.verified
|
|
||||||
? 'This game is verified to be safe'
|
|
||||||
: 'This game is not verified to be save. Proceed with caution.'
|
|
||||||
}
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={i.verified ? faShieldHalved : faWarning}
|
|
||||||
color={i.verified ? '#19c84b' : '#ffc800'}
|
|
||||||
/>
|
|
||||||
<p>{i.verified ? 'Verified' : 'Unverified'}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<div className='flex justify-center items-center h-full'>
|
|
||||||
<p className='text-3xl'>No games installed</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
export default function UpdateCheckingPage () {
|
||||||
|
return <p className='text-5xl text-center'>Checking for updates</p>
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import '@/styles/globals.css'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { Roboto } from 'next/font/google'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
const roboto = Roboto({
|
||||||
|
subsets: ['latin']
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function RootLayout ({
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
}) {
|
||||||
|
const [platformName, setPlatformName] = useState<string | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => setPlatformName(platform()), 0)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<html lang='en' className={roboto.className}>
|
||||||
|
<body className='dark-theme'>
|
||||||
|
<div
|
||||||
|
className='relative z-2 w-screen border-b border-b-(--col3) h-8.25 bg-(--col1)'
|
||||||
|
hidden={platformName != 'windows'}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`w-screen ${
|
||||||
|
platformName == 'windows' ? 'h-[calc(100vh-64px)]' : 'h-screen'
|
||||||
|
} flex items-center justify-center`}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||||
|
|
||||||
|
export default function UpdateCheckingPage () {
|
||||||
|
return (
|
||||||
|
<div className='text-center'>
|
||||||
|
<p className='text-6xl mb-4'>Outdated Launcher!</p>
|
||||||
|
<p className='text-2xl mb-4'>
|
||||||
|
Please update to the latest version to continue.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => openUrl('https://games.lncvrt.xyz/download')}
|
||||||
|
>
|
||||||
|
Download latest version!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
export default function UpdateCheckingPage () {
|
||||||
|
return <p className='text-5xl text-center'>Updating launcher</p>
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import './Setting.css'
|
import '@/styles/setting.css'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { SettingProps } from '@/types/SettingProps'
|
import { SettingProps } from '@/types/SettingProps'
|
||||||
|
|||||||
+29
-25
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import './Sidebar.css'
|
import '@/styles/sidebar.css'
|
||||||
import Icon from '@/assets/Icon.png'
|
import Icon from '@/assets/Icon.png'
|
||||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
||||||
@@ -27,13 +27,12 @@ const lexend = Lexend({
|
|||||||
|
|
||||||
export default function Sidebar () {
|
export default function Sidebar () {
|
||||||
const {
|
const {
|
||||||
getListOfGames,
|
serverVersionList,
|
||||||
|
versionsList,
|
||||||
setShowPopup,
|
setShowPopup,
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
setFadeOut,
|
setFadeOut,
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
downloadedVersionsConfig,
|
|
||||||
getVersionInfo,
|
|
||||||
category,
|
category,
|
||||||
setCategory,
|
setCategory,
|
||||||
sidebarAlwaysShowGames,
|
sidebarAlwaysShowGames,
|
||||||
@@ -83,37 +82,42 @@ export default function Sidebar () {
|
|||||||
<nav className='nav-links overflow-auto pt-2'>
|
<nav className='nav-links overflow-auto pt-2'>
|
||||||
<Link
|
<Link
|
||||||
draggable={false}
|
draggable={false}
|
||||||
href='/'
|
href='/main'
|
||||||
className={`link relative flex items-center ${
|
className={`link relative flex items-center ${
|
||||||
pathname === '/' || pathname.startsWith('/game') ? 'active' : ''
|
pathname === '/main' || pathname.startsWith('/main/game')
|
||||||
|
? 'active'
|
||||||
|
: ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faHexagonNodes} className='mr-2' /> Games
|
<FontAwesomeIcon icon={faHexagonNodes} className='mr-2' /> Games
|
||||||
</Link>
|
</Link>
|
||||||
{getListOfGames()
|
{serverVersionList?.games
|
||||||
.sort((a, b) => {
|
.filter(g =>
|
||||||
return a.id - b.id
|
serverVersionList.versions
|
||||||
})
|
.filter(v => v.game === g.id)
|
||||||
|
.some(v => Object.keys(versionsList).includes(v.id))
|
||||||
|
)
|
||||||
.map(i => (
|
.map(i => (
|
||||||
<React.Fragment key={i.id}>
|
<React.Fragment key={i.id}>
|
||||||
<div
|
<div
|
||||||
draggable={false}
|
draggable={false}
|
||||||
className={`link ${
|
className={`link ${
|
||||||
(pathname === '/game' &&
|
(pathname === '/main/game' &&
|
||||||
Number(params.get('id') || 0) == i.id) ||
|
Number(params.get('id') || 0) == i.id) ||
|
||||||
(i.id == 1 && pathname === '/game/berrydash/leaderboards')
|
(i.id == 1 &&
|
||||||
|
pathname === '/main/game/berrydash/leaderboards')
|
||||||
? 'active'
|
? 'active'
|
||||||
: ''
|
: ''
|
||||||
} ml-auto w-50 ${
|
} ml-auto w-50 ${
|
||||||
sidebarAlwaysShowGames ||
|
sidebarAlwaysShowGames ||
|
||||||
pathname === '/' ||
|
pathname === '/' ||
|
||||||
pathname.startsWith('/game')
|
pathname.startsWith('/main/game')
|
||||||
? ''
|
? ''
|
||||||
: 'hidden'
|
: 'hidden'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCategory(-1)
|
setCategory(-1)
|
||||||
router.push('/game?id=' + i.id)
|
router.push('/main/game?id=' + i.id)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
@@ -131,10 +135,10 @@ export default function Sidebar () {
|
|||||||
{Object.entries(i.categoryNames)
|
{Object.entries(i.categoryNames)
|
||||||
.sort(([a], [b]) => Number(b) - Number(a))
|
.sort(([a], [b]) => Number(b) - Number(a))
|
||||||
.filter(([key]) => {
|
.filter(([key]) => {
|
||||||
const count = Object.keys(
|
const count = Object.keys(versionsList).filter(v => {
|
||||||
downloadedVersionsConfig?.list ?? {}
|
const info = serverVersionList.versions.find(
|
||||||
).filter(v => {
|
vf => vf.id == v
|
||||||
const info = getVersionInfo(v)
|
)
|
||||||
if (!info) return false
|
if (!info) return false
|
||||||
|
|
||||||
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
if (platform() == 'linux' && info.wine && !linuxUseWine)
|
||||||
@@ -150,23 +154,23 @@ export default function Sidebar () {
|
|||||||
key={`${i.id}-${key}`}
|
key={`${i.id}-${key}`}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
className={`link ${
|
className={`link ${
|
||||||
((pathname === '/game' &&
|
((pathname === '/main/game' &&
|
||||||
Number(params.get('id') || 0) == i.id) ||
|
Number(params.get('id') || 0) == i.id) ||
|
||||||
(i.id == 1 &&
|
(i.id == 1 &&
|
||||||
pathname === '/game/berrydash/leaderboards')) &&
|
pathname === '/main/game/berrydash/leaderboards')) &&
|
||||||
category == Number(key)
|
category == Number(key)
|
||||||
? 'active'
|
? 'active'
|
||||||
: ''
|
: ''
|
||||||
} ml-auto w-47.5 ${
|
} ml-auto w-47.5 ${
|
||||||
sidebarAlwaysShowGames ||
|
sidebarAlwaysShowGames ||
|
||||||
pathname === '/' ||
|
pathname === '/' ||
|
||||||
pathname.startsWith('/game')
|
pathname.startsWith('/main/game')
|
||||||
? ''
|
? ''
|
||||||
: 'hidden'
|
: 'hidden'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCategory(Number(key))
|
setCategory(Number(key))
|
||||||
router.push('/game?id=' + i.id)
|
router.push('/main/game?id=' + i.id)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
@@ -179,8 +183,8 @@ export default function Sidebar () {
|
|||||||
))}
|
))}
|
||||||
<Link
|
<Link
|
||||||
draggable={false}
|
draggable={false}
|
||||||
href='/settings'
|
href='/main/settings'
|
||||||
className={`link ${pathname === '/settings' ? 'active' : ''}`}
|
className={`link ${pathname === '/main/settings' ? 'active' : ''}`}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faCog} className='mr-1' /> Settings
|
<FontAwesomeIcon icon={faCog} className='mr-1' /> Settings
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
import { app } from '@tauri-apps/api'
|
|
||||||
import {
|
|
||||||
BaseDirectory,
|
|
||||||
create,
|
|
||||||
exists,
|
|
||||||
mkdir,
|
|
||||||
readTextFile,
|
|
||||||
writeFile
|
|
||||||
} from '@tauri-apps/plugin-fs'
|
|
||||||
import { VersionsConfig } from '@/types/VersionsConfig'
|
|
||||||
|
|
||||||
export async function readVersionsConfig (): Promise<VersionsConfig> {
|
|
||||||
const version = await app.getVersion()
|
|
||||||
try {
|
|
||||||
const options = {
|
|
||||||
baseDir: BaseDirectory.AppLocalData
|
|
||||||
}
|
|
||||||
const doesFolderExist = await exists('', options)
|
|
||||||
const doesConfigExist = await exists('versions.json', options)
|
|
||||||
if (!doesFolderExist || !doesConfigExist) {
|
|
||||||
if (!doesFolderExist) {
|
|
||||||
await mkdir('', options)
|
|
||||||
}
|
|
||||||
const file = await create('versions.json', options)
|
|
||||||
await file.write(
|
|
||||||
new TextEncoder().encode(
|
|
||||||
JSON.stringify(new VersionsConfig(version), null, 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await file.close()
|
|
||||||
return new VersionsConfig(version)
|
|
||||||
}
|
|
||||||
const config = await readTextFile('versions.json', options)
|
|
||||||
const raw = JSON.parse(config)
|
|
||||||
if (raw.list && raw.timestamps) {
|
|
||||||
raw.list = raw.timestamps
|
|
||||||
delete raw.timestamps
|
|
||||||
|
|
||||||
await writeFile(
|
|
||||||
'versions.json',
|
|
||||||
new TextEncoder().encode(JSON.stringify(raw, null, 2)),
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
|
||||||
raw.version = version
|
|
||||||
writeVersionsConfig(raw)
|
|
||||||
return VersionsConfig.import(raw)
|
|
||||||
} catch {
|
|
||||||
return new VersionsConfig(version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function writeVersionsConfig (data: VersionsConfig) {
|
|
||||||
const options = {
|
|
||||||
baseDir: BaseDirectory.AppLocalData
|
|
||||||
}
|
|
||||||
const doesFolderExist = await exists('', options)
|
|
||||||
const doesConfigExist = await exists('versions.json', options)
|
|
||||||
if (!doesFolderExist || !doesConfigExist) {
|
|
||||||
if (!doesFolderExist) {
|
|
||||||
await mkdir('', options)
|
|
||||||
}
|
|
||||||
const file = await create('versions.json', options)
|
|
||||||
await file.write(new TextEncoder().encode(JSON.stringify(data, null, 2)))
|
|
||||||
await file.close()
|
|
||||||
} else {
|
|
||||||
await writeFile(
|
|
||||||
'versions.json',
|
|
||||||
new TextEncoder().encode(JSON.stringify(data, null, 2)),
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File renamed without changes.
@@ -1,5 +1,5 @@
|
|||||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager'
|
import { writeText } from '@tauri-apps/plugin-clipboard-manager'
|
||||||
import { notifyUser } from './Notifications'
|
import { notifyUser } from './notifications'
|
||||||
|
|
||||||
export async function copyToClipboard (
|
export async function copyToClipboard (
|
||||||
text: string,
|
text: string,
|
||||||
File renamed without changes.
File renamed without changes.
@@ -1,7 +1,7 @@
|
|||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import prettyBytes from 'pretty-bytes'
|
||||||
import ProgressBar from '../ProgressBar'
|
import ProgressBar from '@/components/ProgressBar'
|
||||||
import { formatEtaSmart } from '@/lib/Util'
|
import { formatEtaSmart } from '@/lib/util'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import {
|
import {
|
||||||
faCancel,
|
faCancel,
|
||||||
@@ -10,19 +10,20 @@ import {
|
|||||||
faTrash
|
faTrash
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
import { notifyUser } from '@/lib/notifications'
|
||||||
import { notifyUser } from '@/lib/Notifications'
|
|
||||||
import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window'
|
import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window'
|
||||||
|
|
||||||
export default function DownloadsPopup () {
|
export default function DownloadsPopup () {
|
||||||
const {
|
const {
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
getVersionInfo,
|
|
||||||
setDownloadProgress,
|
setDownloadProgress,
|
||||||
downloadQueue,
|
downloadQueue,
|
||||||
setDownloadQueue,
|
setDownloadQueue,
|
||||||
setDownloadedVersionsConfig,
|
notificationsAllowed,
|
||||||
notificationsAllowed
|
versionsList,
|
||||||
|
modsList,
|
||||||
|
versions,
|
||||||
|
serverVersionList
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -68,31 +69,19 @@ export default function DownloadsPopup () {
|
|||||||
prev.filter(d => d.version !== v.version)
|
prev.filter(d => d.version !== v.version)
|
||||||
)
|
)
|
||||||
if (v.type != 1) {
|
if (v.type != 1) {
|
||||||
setDownloadedVersionsConfig(prev => {
|
if (v.type == 2) {
|
||||||
if (!prev) return prev
|
versions?.set('mods', {
|
||||||
|
...modsList,
|
||||||
const updated =
|
|
||||||
v.type == 2
|
|
||||||
? {
|
|
||||||
...prev,
|
|
||||||
mods: {
|
|
||||||
...prev.mods,
|
|
||||||
[v.modGame! + '-' + v.modId!]: {
|
[v.modGame! + '-' + v.modId!]: {
|
||||||
[v.modVersion!]: Date.now()
|
[v.modVersion!]: Date.now()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
...prev,
|
|
||||||
list: {
|
|
||||||
...prev.list,
|
|
||||||
[v.version]: Date.now()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeVersionsConfig(updated)
|
|
||||||
return updated
|
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
versions?.set('list', {
|
||||||
|
...versionsList,
|
||||||
|
[v.version]: Date.now()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (res == '0') {
|
} else if (res == '0') {
|
||||||
setDownloadProgress(prev => {
|
setDownloadProgress(prev => {
|
||||||
@@ -127,7 +116,9 @@ export default function DownloadsPopup () {
|
|||||||
await notifyUser(
|
await notifyUser(
|
||||||
'Download Failed',
|
'Download Failed',
|
||||||
`The download for version ${
|
`The download for version ${
|
||||||
getVersionInfo(v.version)?.displayName
|
serverVersionList?.versions.find(
|
||||||
|
vf => vf.id == v.version
|
||||||
|
)?.displayName
|
||||||
} has failed.`
|
} has failed.`
|
||||||
)
|
)
|
||||||
await getCurrentWindow().requestUserAttention(
|
await getCurrentWindow().requestUserAttention(
|
||||||
@@ -186,11 +177,14 @@ export default function DownloadsPopup () {
|
|||||||
</div>
|
</div>
|
||||||
<p className='text-2xl text-center'>
|
<p className='text-2xl text-center'>
|
||||||
{v.type == 1
|
{v.type == 1
|
||||||
? 'Mod Manager for '
|
? 'Mod loader for '
|
||||||
: v.type == 2
|
: v.type == 2
|
||||||
? 'Mod for '
|
? 'Mod for '
|
||||||
: null}{' '}
|
: null}{' '}
|
||||||
{getVersionInfo(v.version)?.displayName}
|
{
|
||||||
|
serverVersionList?.versions.find(vf => vf.id == v.version)
|
||||||
|
?.displayName
|
||||||
|
}
|
||||||
</p>
|
</p>
|
||||||
<div className='mt-6.25 flex items-center justify-between'>
|
<div className='mt-6.25 flex items-center justify-between'>
|
||||||
{v.failed || v.queued ? (
|
{v.failed || v.queued ? (
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import {
|
import {
|
||||||
faCheck,
|
faCheck,
|
||||||
faCode,
|
faCode,
|
||||||
@@ -9,18 +9,18 @@ import {
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
export default function GamesDownloadPopup () {
|
export default function GamesDownloadPopup () {
|
||||||
const { serverVersionList, getVersionsAmountData, setSelectedGame } =
|
const { serverVersionList, setSelectedGame, versionsList } = useGlobal()
|
||||||
useGlobal()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className='text-xl text-center'>Select a game to download</p>
|
<p className='text-xl text-center'>Select a game to download</p>
|
||||||
<div className='popup-content'>
|
<div className='popup-content'>
|
||||||
{serverVersionList?.games
|
{serverVersionList?.games
|
||||||
.filter(v => {
|
.filter(i => {
|
||||||
const data = getVersionsAmountData(v.id)
|
const gameVersions = serverVersionList.versions.filter(
|
||||||
if (!data) return false
|
vf => vf.game === i.id
|
||||||
if (data.total > 0) return true
|
)
|
||||||
|
if (gameVersions.length > 0) return true
|
||||||
})
|
})
|
||||||
.map((v, i) => (
|
.map((v, i) => (
|
||||||
<div key={i} className='popup-entry'>
|
<div key={i} className='popup-entry'>
|
||||||
@@ -32,9 +32,15 @@ export default function GamesDownloadPopup () {
|
|||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{(() => {
|
{(() => {
|
||||||
const data = getVersionsAmountData(v.id)
|
const gameVersions = serverVersionList.versions.filter(
|
||||||
if (!data) return 'N/A'
|
vf => vf.game === v.id
|
||||||
return `${data.installed}/${data.total}`
|
)
|
||||||
|
const installed = gameVersions.filter(v =>
|
||||||
|
Object.keys(versionsList).includes(v.id)
|
||||||
|
).length
|
||||||
|
return gameVersions.length
|
||||||
|
? `${installed}/${gameVersions.length}`
|
||||||
|
: 'N/A'
|
||||||
})()}{' '}
|
})()}{' '}
|
||||||
versions installed
|
versions installed
|
||||||
</p>
|
</p>
|
||||||
@@ -74,11 +80,7 @@ export default function GamesDownloadPopup () {
|
|||||||
<button
|
<button
|
||||||
className='button btntheme3 right-2 bottom-2'
|
className='button btntheme3 right-2 bottom-2'
|
||||||
onClick={() => setSelectedGame(v.id)}
|
onClick={() => setSelectedGame(v.id)}
|
||||||
title={`Click to download specific versions of the game. You have ${(() => {
|
title='Click to download more versions of the game.'
|
||||||
const data = getVersionsAmountData(v.id)
|
|
||||||
if (!data) return 'N/A'
|
|
||||||
return `${data.installed} of ${data.total}`
|
|
||||||
})()} versions downloaded.`}
|
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<FontAwesomeIcon icon={faDownload} /> Download
|
<FontAwesomeIcon icon={faDownload} /> Download
|
||||||
@@ -9,28 +9,25 @@ import {
|
|||||||
faWarning
|
faWarning
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import prettyBytes from 'pretty-bytes'
|
||||||
import { message } from '@tauri-apps/plugin-dialog'
|
|
||||||
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
import { openFolder } from '@/lib/util'
|
||||||
import { openFolder } from '@/lib/Util'
|
|
||||||
|
|
||||||
export default function ManageVersionPopup () {
|
export default function ManageVersionPopup () {
|
||||||
const {
|
const {
|
||||||
getGameInfo,
|
versionsList,
|
||||||
getVersionInfo,
|
serverVersionList,
|
||||||
managingVersion,
|
managingVersion,
|
||||||
downloadedVersionsConfig,
|
|
||||||
viewingInfoFromDownloads,
|
viewingInfoFromDownloads,
|
||||||
setManagingVersion,
|
setManagingVersion,
|
||||||
closePopup,
|
closePopup,
|
||||||
setDownloadedVersionsConfig,
|
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
setSelectedVersionList,
|
setSelectedVersionList,
|
||||||
downloadVersions
|
downloadVersions,
|
||||||
|
versions
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
const [versionSize, setVersionSize] = useState<number>(0)
|
const [versionSize, setVersionSize] = useState<number>(0)
|
||||||
|
|
||||||
@@ -43,10 +40,14 @@ export default function ManageVersionPopup () {
|
|||||||
})
|
})
|
||||||
}, [managingVersion, setVersionSize, viewingInfoFromDownloads])
|
}, [managingVersion, setVersionSize, viewingInfoFromDownloads])
|
||||||
|
|
||||||
if (!managingVersion || !downloadedVersionsConfig) return <></>
|
if (!managingVersion) return <></>
|
||||||
|
|
||||||
const versionInfo = getVersionInfo(managingVersion)
|
const versionInfo = serverVersionList?.versions.find(
|
||||||
const gameInfo = getGameInfo(versionInfo?.game)
|
vf => vf.id == managingVersion
|
||||||
|
)
|
||||||
|
const gameInfo = serverVersionList?.games.find(
|
||||||
|
vf => vf.id == versionInfo?.game
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -59,7 +60,7 @@ export default function ManageVersionPopup () {
|
|||||||
<p>
|
<p>
|
||||||
Installed{' '}
|
Installed{' '}
|
||||||
{new Intl.DateTimeFormat(undefined).format(
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
downloadedVersionsConfig.list[managingVersion] ?? 0
|
versionsList[managingVersion] ?? 0
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,13 +110,7 @@ export default function ManageVersionPopup () {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className='entry-info-item btntheme2'
|
className='entry-info-item btntheme2'
|
||||||
onClick={async () => {
|
onClick={() => setPopupMode(4)}
|
||||||
if (!versionInfo) return
|
|
||||||
await message(atob(versionInfo.changelog), {
|
|
||||||
title: 'Changelog for ' + versionInfo.displayName,
|
|
||||||
kind: 'info'
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
hidden={!versionInfo?.changelog}
|
hidden={!versionInfo?.changelog}
|
||||||
>
|
>
|
||||||
<p>View Changelog</p>
|
<p>View Changelog</p>
|
||||||
@@ -135,18 +130,14 @@ export default function ManageVersionPopup () {
|
|||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
closePopup()
|
closePopup()
|
||||||
|
|
||||||
setDownloadedVersionsConfig(prev => {
|
versions?.set(
|
||||||
if (!prev) return prev
|
'list',
|
||||||
const updatedList = Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev.list).filter(([k]) => k !== managingVersion)
|
Object.entries(versionsList).filter(
|
||||||
|
([k]) => k !== managingVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
const updatedConfig = {
|
|
||||||
...prev,
|
|
||||||
list: updatedList
|
|
||||||
}
|
|
||||||
writeVersionsConfig(updatedConfig)
|
|
||||||
return updatedConfig
|
|
||||||
})
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
await exists('game/' + managingVersion, {
|
await exists('game/' + managingVersion, {
|
||||||
@@ -171,18 +162,14 @@ export default function ManageVersionPopup () {
|
|||||||
setPopupMode(1)
|
setPopupMode(1)
|
||||||
|
|
||||||
//uninstall
|
//uninstall
|
||||||
setDownloadedVersionsConfig(prev => {
|
versions?.set(
|
||||||
if (!prev) return prev
|
'list',
|
||||||
const updatedList = Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev.list).filter(([k]) => k !== managingVersion)
|
Object.entries(versionsList).filter(
|
||||||
|
([k]) => k !== managingVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
const updatedConfig = {
|
|
||||||
...prev,
|
|
||||||
list: updatedList
|
|
||||||
}
|
|
||||||
writeVersionsConfig(updatedConfig)
|
|
||||||
return updatedConfig
|
|
||||||
})
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
await exists('game/' + managingVersion, {
|
await exists('game/' + managingVersion, {
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
import { verifySignature } from '@/lib/util'
|
||||||
import { verifySignature } from '@/lib/Util'
|
|
||||||
import { Mod } from '@/types/Mod'
|
import { Mod } from '@/types/Mod'
|
||||||
import {
|
import {
|
||||||
faArrowUpRightFromSquare,
|
faArrowUpRightFromSquare,
|
||||||
@@ -23,14 +22,14 @@ import { useEffect, useState } from 'react'
|
|||||||
|
|
||||||
export default function ModDownloadsPopup () {
|
export default function ModDownloadsPopup () {
|
||||||
const {
|
const {
|
||||||
getVersionInfo,
|
modsList,
|
||||||
|
serverVersionList,
|
||||||
managingVersion,
|
managingVersion,
|
||||||
downloadedVersionsConfig,
|
|
||||||
showModInfo,
|
showModInfo,
|
||||||
setShowModInfo,
|
setShowModInfo,
|
||||||
downloadVersions,
|
downloadVersions,
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
setDownloadedVersionsConfig
|
versions
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
const [mods, setMods] = useState<Mod[] | 0 | 1>(0)
|
const [mods, setMods] = useState<Mod[] | 0 | 1>(0)
|
||||||
@@ -52,9 +51,11 @@ export default function ModDownloadsPopup () {
|
|||||||
})()
|
})()
|
||||||
}, [managingVersion])
|
}, [managingVersion])
|
||||||
|
|
||||||
if (!managingVersion) return <></>
|
if (!managingVersion || !serverVersionList) return <></>
|
||||||
|
|
||||||
const versionInfo = getVersionInfo(managingVersion)
|
const versionInfo = serverVersionList.versions.find(
|
||||||
|
v => v.id == managingVersion
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -110,10 +111,10 @@ export default function ModDownloadsPopup () {
|
|||||||
(!showModInfo &&
|
(!showModInfo &&
|
||||||
mods.filter(v =>
|
mods.filter(v =>
|
||||||
tab == 0
|
tab == 0
|
||||||
? Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
? Object.keys(modsList).includes(
|
||||||
String(versionInfo?.game + '-' + v.id)
|
String(versionInfo?.game + '-' + v.id)
|
||||||
)
|
)
|
||||||
: !Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
: !Object.keys(modsList).includes(
|
||||||
String(versionInfo?.game + '-' + v.id)
|
String(versionInfo?.game + '-' + v.id)
|
||||||
)
|
)
|
||||||
).length == 0) ? (
|
).length == 0) ? (
|
||||||
@@ -131,10 +132,10 @@ export default function ModDownloadsPopup () {
|
|||||||
{mods
|
{mods
|
||||||
.filter(v =>
|
.filter(v =>
|
||||||
tab == 0
|
tab == 0
|
||||||
? Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
? Object.keys(modsList).includes(
|
||||||
String(versionInfo?.game + '-' + v.id)
|
String(versionInfo?.game + '-' + v.id)
|
||||||
)
|
)
|
||||||
: !Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
: !Object.keys(modsList).includes(
|
||||||
String(versionInfo?.game + '-' + v.id)
|
String(versionInfo?.game + '-' + v.id)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -142,9 +143,7 @@ export default function ModDownloadsPopup () {
|
|||||||
const localVersion =
|
const localVersion =
|
||||||
tab == 0
|
tab == 0
|
||||||
? Object.keys(
|
? Object.keys(
|
||||||
downloadedVersionsConfig?.mods?.[
|
modsList[versionInfo?.game + '-' + v.id] ?? {}
|
||||||
versionInfo?.game + '-' + v.id
|
|
||||||
] ?? {}
|
|
||||||
)[0]
|
)[0]
|
||||||
: null
|
: null
|
||||||
return (
|
return (
|
||||||
@@ -201,20 +200,14 @@ export default function ModDownloadsPopup () {
|
|||||||
baseDir: BaseDirectory.AppLocalData,
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
recursive: true
|
recursive: true
|
||||||
})
|
})
|
||||||
setDownloadedVersionsConfig(prev => {
|
versions?.set(
|
||||||
if (!prev) return prev
|
'mods',
|
||||||
const updatedMods = Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev.mods).filter(
|
Object.entries(modsList).filter(
|
||||||
([k]) => k !== versionInfo?.game + '-' + v.id
|
([k]) => k !== versionInfo?.game + '-' + v.id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
const updatedConfig = {
|
)
|
||||||
...prev,
|
|
||||||
mods: updatedMods
|
|
||||||
}
|
|
||||||
writeVersionsConfig(updatedConfig)
|
|
||||||
return updatedConfig
|
|
||||||
})
|
|
||||||
|
|
||||||
downloadVersions([
|
downloadVersions([
|
||||||
{
|
{
|
||||||
@@ -273,7 +266,7 @@ export default function ModDownloadsPopup () {
|
|||||||
: '(No description added)'}
|
: '(No description added)'}
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-row h-fit w-full gap-2 justify-center my-2'>
|
<div className='flex flex-row h-fit w-full gap-2 justify-center my-2'>
|
||||||
{Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
{Object.keys(modsList).includes(
|
||||||
String(versionInfo?.game + '-' + showModInfo.id)
|
String(versionInfo?.game + '-' + showModInfo.id)
|
||||||
) ? (
|
) ? (
|
||||||
<button
|
<button
|
||||||
@@ -294,21 +287,15 @@ export default function ModDownloadsPopup () {
|
|||||||
baseDir: BaseDirectory.AppLocalData,
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
recursive: true
|
recursive: true
|
||||||
})
|
})
|
||||||
setDownloadedVersionsConfig(prev => {
|
versions?.set(
|
||||||
if (!prev) return prev
|
'mods',
|
||||||
const updatedMods = Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(prev.mods).filter(
|
Object.entries(modsList).filter(
|
||||||
([k]) =>
|
([k]) =>
|
||||||
k !== versionInfo?.game + '-' + showModInfo.id
|
k !== versionInfo?.game + '-' + showModInfo.id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
const updatedConfig = {
|
)
|
||||||
...prev,
|
|
||||||
mods: updatedMods
|
|
||||||
}
|
|
||||||
writeVersionsConfig(updatedConfig)
|
|
||||||
return updatedConfig
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faTrash} className='text-red-400' />{' '}
|
<FontAwesomeIcon icon={faTrash} className='text-red-400' />{' '}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
|
import DOMPurify from 'dompurify'
|
||||||
|
|
||||||
|
export default function VersionChangelogPopup () {
|
||||||
|
const { serverVersionList, managingVersion } = useGlobal()
|
||||||
|
|
||||||
|
if (!managingVersion) return <></>
|
||||||
|
|
||||||
|
const versionInfo = serverVersionList?.versions.find(
|
||||||
|
vf => vf.id == managingVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>
|
||||||
|
Viewing changelog {versionInfo?.displayName}
|
||||||
|
</p>
|
||||||
|
<div className='popup-content h-full w-full p-2'>
|
||||||
|
<p
|
||||||
|
className='whitespace-pre-line'
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: DOMPurify.sanitize(
|
||||||
|
atob(versionInfo?.changelog ?? '')
|
||||||
|
.replaceAll('- ', '• ')
|
||||||
|
.replaceAll(/`([^`]+)`/g, '<code>$1</code>')
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
></p>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
import { useGlobal } from '@/app/GlobalProvider'
|
import { useGlobal } from '@/providers/GlobalProvider'
|
||||||
import { faAdd, faInfo, faRemove } from '@fortawesome/free-solid-svg-icons'
|
import { faAdd, faInfo, faRemove } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
export default function VersionsDownloadPopup () {
|
export default function VersionsDownloadPopup () {
|
||||||
const {
|
const {
|
||||||
|
serverVersionList,
|
||||||
|
getSpecialVersionsList,
|
||||||
selectedVersionList,
|
selectedVersionList,
|
||||||
setSelectedVersionList,
|
setSelectedVersionList,
|
||||||
setManagingVersion,
|
setManagingVersion,
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
getSpecialVersionsList,
|
|
||||||
selectedGame,
|
selectedGame,
|
||||||
setViewingInfoFromDownloads,
|
setViewingInfoFromDownloads,
|
||||||
downloadedVersionsConfig,
|
downloadVersions
|
||||||
downloadVersions,
|
|
||||||
getGameInfo
|
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
if (!selectedGame) return <></>
|
const game = serverVersionList?.games.find(g => g.id === selectedGame)
|
||||||
|
|
||||||
|
if (!selectedGame || !game) return <></>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -78,7 +79,6 @@ export default function VersionsDownloadPopup () {
|
|||||||
<button
|
<button
|
||||||
className='button btntheme1 w-fit mt-2 -mb-4'
|
className='button btntheme1 w-fit mt-2 -mb-4'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (downloadedVersionsConfig) {
|
|
||||||
downloadVersions(
|
downloadVersions(
|
||||||
selectedVersionList.map(versionId => ({
|
selectedVersionList.map(versionId => ({
|
||||||
id: versionId,
|
id: versionId,
|
||||||
@@ -86,16 +86,11 @@ export default function VersionsDownloadPopup () {
|
|||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
setPopupMode(1)
|
setPopupMode(1)
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
disabled={selectedVersionList.length == 0}
|
disabled={selectedVersionList.length == 0}
|
||||||
title={
|
title={`Download ${selectedVersionList.length} version${
|
||||||
selectedVersionList.length == 0
|
|
||||||
? 'Select at least one version to download'
|
|
||||||
: `Download ${selectedVersionList.length} version${
|
|
||||||
selectedVersionList.length == 1 ? '' : 's'
|
selectedVersionList.length == 1 ? '' : 's'
|
||||||
} of ${getGameInfo(selectedGame)?.name}`
|
} of ${game.name}`}
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Download {selectedVersionList.length} version
|
Download {selectedVersionList.length} version
|
||||||
{selectedVersionList.length == 1 ? '' : 's'}
|
{selectedVersionList.length == 1 ? '' : 's'}
|
||||||
@@ -8,12 +8,10 @@ import {
|
|||||||
SetStateAction
|
SetStateAction
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { DownloadProgress } from '@/types/DownloadProgress'
|
import { DownloadProgress } from '@/types/DownloadProgress'
|
||||||
import { VersionsConfig } from '@/types/VersionsConfig'
|
|
||||||
import { ServerVersionsResponse } from '@/types/ServerVersionsResponse'
|
import { ServerVersionsResponse } from '@/types/ServerVersionsResponse'
|
||||||
import { GameVersion } from '@/types/GameVersion'
|
|
||||||
import { Game } from '@/types/Game'
|
|
||||||
import { Mod } from '@/types/Mod'
|
import { Mod } from '@/types/Mod'
|
||||||
import { Store } from '@tauri-apps/plugin-store'
|
import { Store } from '@tauri-apps/plugin-store'
|
||||||
|
import { GameVersion } from '@/types/GameVersion'
|
||||||
|
|
||||||
type GlobalCtxType = {
|
type GlobalCtxType = {
|
||||||
serverVersionList: ServerVersionsResponse | null
|
serverVersionList: ServerVersionsResponse | null
|
||||||
@@ -27,18 +25,9 @@ type GlobalCtxType = {
|
|||||||
setPopupMode: Dispatch<SetStateAction<number | null>>
|
setPopupMode: Dispatch<SetStateAction<number | null>>
|
||||||
fadeOut: boolean
|
fadeOut: boolean
|
||||||
setFadeOut: Dispatch<SetStateAction<boolean>>
|
setFadeOut: Dispatch<SetStateAction<boolean>>
|
||||||
downloadedVersionsConfig: VersionsConfig | null
|
|
||||||
setDownloadedVersionsConfig: Dispatch<SetStateAction<VersionsConfig | null>>
|
|
||||||
managingVersion: string | null
|
managingVersion: string | null
|
||||||
setManagingVersion: Dispatch<SetStateAction<string | null>>
|
setManagingVersion: Dispatch<SetStateAction<string | null>>
|
||||||
setSelectedGame: Dispatch<SetStateAction<number | null>>
|
setSelectedGame: Dispatch<SetStateAction<number | null>>
|
||||||
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
|
||||||
getGameInfo: (game: number | undefined) => Game | undefined
|
|
||||||
getListOfGames(): Game[]
|
|
||||||
getVersionsAmountData: (gameId: number) => {
|
|
||||||
installed: number
|
|
||||||
total: number
|
|
||||||
} | null
|
|
||||||
viewingInfoFromDownloads: boolean
|
viewingInfoFromDownloads: boolean
|
||||||
version: string | null
|
version: string | null
|
||||||
downloadVersions: (
|
downloadVersions: (
|
||||||
@@ -56,17 +45,20 @@ type GlobalCtxType = {
|
|||||||
downloadQueue: string[]
|
downloadQueue: string[]
|
||||||
setDownloadQueue: Dispatch<SetStateAction<string[]>>
|
setDownloadQueue: Dispatch<SetStateAction<string[]>>
|
||||||
closePopup: () => void
|
closePopup: () => void
|
||||||
getSpecialVersionsList(game?: number | undefined): GameVersion[]
|
|
||||||
selectedGame: number | null
|
selectedGame: number | null
|
||||||
setViewingInfoFromDownloads: Dispatch<SetStateAction<boolean>>
|
setViewingInfoFromDownloads: Dispatch<SetStateAction<boolean>>
|
||||||
showModInfo: Mod | null
|
showModInfo: Mod | null
|
||||||
setShowModInfo: Dispatch<SetStateAction<Mod | null>>
|
setShowModInfo: Dispatch<SetStateAction<Mod | null>>
|
||||||
|
getSpecialVersionsList: (game?: number) => GameVersion[]
|
||||||
settings: Store | null
|
settings: Store | null
|
||||||
|
versions: Store | null
|
||||||
notificationsAllowed: boolean
|
notificationsAllowed: boolean
|
||||||
sidebarAlwaysShowGames: boolean
|
sidebarAlwaysShowGames: boolean
|
||||||
linuxUseWine: boolean
|
linuxUseWine: boolean
|
||||||
linuxWineCommand: string
|
linuxWineCommand: string
|
||||||
theme: string
|
theme: string
|
||||||
|
versionsList: Record<string, number>
|
||||||
|
modsList: Record<string, Record<string, number>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
||||||
@@ -149,3 +149,7 @@ body {
|
|||||||
.entry-info-item {
|
.entry-info-item {
|
||||||
@apply flex flex-row items-center gap-1 border text-gray-300 py-1 px-2 rounded-md w-fit text-[16px] transition-colors cursor-pointer;
|
@apply flex flex-row items-center gap-1 border text-gray-300 py-1 px-2 rounded-md w-fit text-[16px] transition-colors cursor-pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply bg-(--col4) border border-(--col6) rounded-lg px-1 py-0.5 text-sm;
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
@@ -1,20 +0,0 @@
|
|||||||
export type VersionsConfigData = {
|
|
||||||
version: string
|
|
||||||
list: Record<string, number>
|
|
||||||
mods: Record<string, Record<string, number>>
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VersionsConfig {
|
|
||||||
constructor (
|
|
||||||
public version: string,
|
|
||||||
public list: Record<string, number> = {},
|
|
||||||
public mods: Record<string, Record<string, number>> = {}
|
|
||||||
) {}
|
|
||||||
|
|
||||||
static import (data: VersionsConfigData) {
|
|
||||||
const cfg = new VersionsConfig(data.version)
|
|
||||||
cfg.list = { ...data.list }
|
|
||||||
cfg.mods = { ...data.mods }
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user