Tailwind, dialog, filesystem, homedir & save finding, initial project work

This commit is contained in:
2024-11-27 04:30:43 -06:00
parent c6e6434cf6
commit 82589e555d
14 changed files with 1778 additions and 193 deletions

View File

@@ -1,23 +1,31 @@
{
"name": "factorio-achievements-fixer",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"preact": "^10.16.0",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-shell": "^2"
},
"devDependencies": {
"@preact/preset-vite": "^2.5.0",
"typescript": "^5.2.2",
"vite": "^5.3.1",
"@tauri-apps/cli": "^2"
}
}
{
"name": "factorio-achievements-fixer",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "~2",
"@tauri-apps/plugin-fs": "~2",
"@tauri-apps/plugin-shell": "^2",
"clsx": "^2.1.1",
"preact": "^10.16.0",
"tailwind-merge": "^2.5.5"
},
"devDependencies": {
"@preact/preset-vite": "^2.5.0",
"@tauri-apps/cli": "^2",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"typescript": "^5.2.2",
"vite": "^5.3.1"
}
}

850
pnpm-lock.yaml generated
View File

File diff suppressed because it is too large Load Diff

6
postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

560
src-tauri/Cargo.lock generated
View File

@@ -62,6 +62,61 @@ version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]]
name = "ashpd"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3"
dependencies = [
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.8.5",
"raw-window-handle",
"serde",
"serde_repr",
"tokio",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus",
]
[[package]]
name = "async-broadcast"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
dependencies = [
"event-listener",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "async-trait"
version = "0.1.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "atk"
version = "0.18.0"
@@ -373,6 +428,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "convert_case"
version = "0.4.0"
@@ -615,6 +679,15 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "dlib"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading",
]
[[package]]
name = "dlopen2"
version = "0.7.0"
@@ -638,6 +711,12 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "downcast-rs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "dpi"
version = "0.1.1"
@@ -703,6 +782,33 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "endi"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
[[package]]
name = "enumflags2"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
dependencies = [
"enumflags2_derive",
"serde",
]
[[package]]
name = "enumflags2_derive"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -719,17 +825,59 @@ dependencies = [
"typeid",
]
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "event-listener"
version = "5.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
dependencies = [
"event-listener",
"pin-project-lite",
]
[[package]]
name = "factorio-achievements-fixer"
version = "0.1.0"
dependencies = [
"human_bytes",
"serde",
"serde_json",
"simple-home-dir",
"tauri",
"tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-fs",
"tauri-plugin-shell",
"time",
]
[[package]]
name = "fastrand"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
[[package]]
name = "fdeflate"
version = "0.3.6"
@@ -1091,7 +1239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
dependencies = [
"heck 0.4.1",
"proc-macro-crate 2.0.2",
"proc-macro-crate 2.0.0",
"proc-macro-error",
"proc-macro2",
"quote",
@@ -1267,6 +1415,12 @@ version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
[[package]]
name = "human_bytes"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e"
[[package]]
name = "hyper"
version = "1.5.1"
@@ -1716,6 +1870,12 @@ dependencies = [
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "litemap"
version = "0.7.4"
@@ -1872,6 +2032,19 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@@ -1908,7 +2081,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate 2.0.2",
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.89",
@@ -2032,6 +2205,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.6.0",
"block2",
"dispatch",
"libc",
"objc2",
]
@@ -2173,6 +2347,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-stream"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
dependencies = [
"futures-core",
"pin-project-lite",
]
[[package]]
name = "os_pipe"
version = "1.2.1"
@@ -2208,6 +2392,12 @@ dependencies = [
"system-deps",
]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
version = "0.12.3"
@@ -2403,7 +2593,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64 0.22.1",
"indexmap 2.6.0",
"quick-xml",
"quick-xml 0.32.0",
"serde",
"time",
]
@@ -2454,14 +2644,22 @@ dependencies = [
[[package]]
name = "proc-macro-crate"
version = "2.0.2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [
"toml_datetime",
"toml_edit 0.20.2",
]
[[package]]
name = "proc-macro-crate"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
dependencies = [
"toml_edit 0.22.22",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@@ -2510,6 +2708,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.37"
@@ -2692,6 +2899,29 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "rfd"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f6f80a9b882647d9014673ca9925d30ffc9750f2eed2b4490e189eaebd01e8"
dependencies = [
"ashpd",
"block2",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"log",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"raw-window-handle",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.48.0",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@@ -2707,6 +2937,19 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "ryu"
version = "1.0.18"
@@ -2749,6 +2992,12 @@ dependencies = [
"syn 2.0.89",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -2959,12 +3208,30 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "simple-home-dir"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d80554cb5ec21f0163f142f4078427aaa5a93d40e87e9ad2b6b8392c26e20f8"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "siphasher"
version = "0.3.11"
@@ -3050,6 +3317,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "string_cache"
version = "0.8.7"
@@ -3334,6 +3607,45 @@ dependencies = [
"walkdir",
]
[[package]]
name = "tauri-plugin-dialog"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4307310e1d2c09ab110235834722e7c2b85099b683e1eb7342ab351b0be5ada3"
dependencies = [
"log",
"raw-window-handle",
"rfd",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-plugin-fs",
"thiserror 1.0.69",
"url",
]
[[package]]
name = "tauri-plugin-fs"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0"
dependencies = [
"anyhow",
"dunce",
"glob",
"percent-encoding",
"schemars",
"serde",
"serde_json",
"serde_repr",
"tauri",
"tauri-plugin",
"thiserror 1.0.69",
"url",
"uuid",
]
[[package]]
name = "tauri-plugin-shell"
version = "2.0.2"
@@ -3447,6 +3759,19 @@ dependencies = [
"toml 0.7.8",
]
[[package]]
name = "tempfile"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "tendril"
version = "0.4.3"
@@ -3556,7 +3881,9 @@ dependencies = [
"libc",
"mio",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tracing",
"windows-sys 0.52.0",
]
@@ -3599,9 +3926,9 @@ dependencies = [
[[package]]
name = "toml_datetime"
version = "0.6.3"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
@@ -3616,7 +3943,7 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
"winnow 0.5.40",
]
[[package]]
@@ -3629,7 +3956,18 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap 2.6.0",
"toml_datetime",
"winnow 0.6.20",
]
[[package]]
@@ -3645,9 +3983,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
@@ -3696,6 +4046,17 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "uds_windows"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
"memoffset",
"tempfile",
"winapi",
]
[[package]]
name = "unic-char-property"
version = "0.9.0"
@@ -3944,6 +4305,66 @@ dependencies = [
"web-sys",
]
[[package]]
name = "wayland-backend"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280"
dependencies = [
"bitflags 2.6.0",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols"
version = "0.32.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
dependencies = [
"proc-macro2",
"quick-xml 0.36.2",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09"
dependencies = [
"dlib",
"log",
"pkg-config",
]
[[package]]
name = "web-sys"
version = "0.3.72"
@@ -4395,6 +4816,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.52.0"
@@ -4481,6 +4911,16 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "xdg-home"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
dependencies = [
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "yoke"
version = "0.7.5"
@@ -4505,6 +4945,63 @@ dependencies = [
"synstructure",
]
[[package]]
name = "zbus"
version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1162094dc63b1629fcc44150bcceeaa80798cd28bcbe7fa987b65a034c258608"
dependencies = [
"async-broadcast",
"async-recursion",
"async-trait",
"enumflags2",
"event-listener",
"futures-core",
"futures-util",
"hex",
"nix",
"ordered-stream",
"serde",
"serde_repr",
"static_assertions",
"tokio",
"tracing",
"uds_windows",
"windows-sys 0.59.0",
"winnow 0.6.20",
"xdg-home",
"zbus_macros",
"zbus_names",
"zvariant",
]
[[package]]
name = "zbus_macros"
version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cd2dcdce3e2727f7d74b7e33b5a89539b3cc31049562137faf7ae4eb86cd16d"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.89",
"zbus_names",
"zvariant",
"zvariant_utils",
]
[[package]]
name = "zbus_names"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b"
dependencies = [
"serde",
"static_assertions",
"winnow 0.6.20",
"zvariant",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
@@ -4568,3 +5065,46 @@ dependencies = [
"quote",
"syn 2.0.89",
]
[[package]]
name = "zvariant"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f"
dependencies = [
"endi",
"enumflags2",
"serde",
"static_assertions",
"url",
"winnow 0.6.20",
"zvariant_derive",
"zvariant_utils",
]
[[package]]
name = "zvariant_derive"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.89",
"zvariant_utils",
]
[[package]]
name = "zvariant_utils"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6"
dependencies = [
"proc-macro2",
"quote",
"serde",
"static_assertions",
"syn 2.0.89",
"winnow 0.6.20",
]

View File

@@ -22,4 +22,9 @@ tauri = { version = "2", features = [] }
tauri-plugin-shell = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
simple-home-dir = "0.4.4"
human_bytes = "0.4.3"
time = "0.3.36"

View File

@@ -1,10 +1,14 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"shell:allow-open"
]
}
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": [
"main"
],
"permissions": [
"core:default",
"shell:allow-open",
"dialog:default",
"fs:default"
]
}

View File

@@ -1,14 +1,149 @@
use human_bytes::human_bytes;
use serde::Serialize;
use simple_home_dir::home_dir;
use std::fs;
use std::fs::metadata;
use time::OffsetDateTime;
#[cfg(target_os = "windows")]
fn get_save_directories() -> Vec<String> {
let mut save_directories: Vec<String> = Vec::new();
if let Some(home_dir) = home_dir() {
let save_path = home_dir.join("AppData\\Roaming\\Factorio\\saves");
if save_path.exists() {
save_directories.push(save_path.to_str().unwrap().to_string());
}
}
save_directories
}
#[cfg(target_os = "linux")]
fn get_save_directories() -> Vec<String> {
let mut save_directories = Vec::new();
if let Some(home_dir) = home_dir() {
let normal_save_path = home_dir.join(".factorio/saves");
if normal_save_path.exists() {
save_directories.push(save_path.to_str().unwrap().to_string());
}
let flatpak_save_path = home_dir.join(".var/app/com.valvesoftware.Steam/.factorio/saves");
if flatpak_save_path.exists() {
save_directories.push(flatpak_save_path.to_str().unwrap().to_string());
}
}
save_directories
}
#[cfg(target_os = "macos")]
fn get_save_directories() -> Vec<String> {
let mut save_directories = Vec::new();
if let Some(home_dir) = home_dir() {
let save_path = home_dir.join("Library/Application Support/factorio/saves");
if save_path.exists() {
save_directories.push(save_path.to_str().unwrap().to_string());
}
}
save_directories
}
struct SaveFileInternal {
path: String,
last_modified: usize,
}
#[derive(Serialize, Debug)]
struct SaveFile {
name: String,
path: String,
size: String,
last_modified: String,
}
#[tauri::command]
fn choose_best_save_directory() -> Option<String> {
let save_directories = get_save_directories();
let mut best_directory: Option<String> = None;
let mut max_zip_files = 0;
for dir in save_directories {
if let Ok(entries) = fs::read_dir(&dir) {
let zip_file_count = entries
.filter_map(Result::ok)
.filter(|entry| {
entry
.file_name()
.to_str()
.map_or(false, |name| name.ends_with(".zip"))
})
.count();
if zip_file_count > max_zip_files {
max_zip_files = zip_file_count;
best_directory = Some(dir);
}
}
}
best_directory
}
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
fn find_save_files() -> Vec<SaveFile> {
let save_directories = get_save_directories();
let mut save_files = Vec::new();
for dir in save_directories {
println!("Save directory found: {}", dir);
if let Ok(entries) = fs::read_dir(dir) {
for entry in entries.flatten() {
if let Some(file_name) = entry.file_name().to_str() {
if !file_name.ends_with(".zip") {
continue;
}
let file_path = entry.path();
if let Ok(metadata) = metadata(&file_path) {
let size = human_bytes(metadata.len() as f64);
let last_modified =
Into::<OffsetDateTime>::into(metadata.modified().unwrap())
.format(
&time::format_description::parse(
"[year]-[month]-[day] [hour]:[minute]:[second]",
)
.unwrap(),
)
.unwrap();
save_files.push(SaveFile {
name: file_name.to_string(),
path: file_path.to_str().unwrap().to_string(),
size,
last_modified,
});
}
}
}
}
}
save_files
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![greet])
.invoke_handler(tauri::generate_handler![
find_save_files,
choose_best_save_directory
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@@ -12,7 +12,7 @@
"app": {
"windows": [
{
"title": "factorio-achievements-fixer",
"title": "Factorio Achievements Fixer",
"width": 800,
"height": 600
}

View File

@@ -1,116 +1,42 @@
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
@tailwind base;
@tailwind components;
@tailwind utilities;
html,
body {
@apply h-screen w-screen bg-zinc-600;
}
.logo.preact:hover {
filter: drop-shadow(0 0 2em #673ab8);
}
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
@layer base {
* {
/* @apply border-border; */
}
body {
/* @apply bg-background text-foreground; */
}
a:hover {
color: #24c8db;
ul,
ol {
list-style: revert;
}
/* NEW CODE */
/* width */
::-webkit-scrollbar {
@apply w-2 rounded-lg;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
/* Track */
::-webkit-scrollbar-track {
@apply bg-zinc-200 dark:bg-zinc-700 rounded-lg;
}
button:active {
background-color: #0f0f0f69;
/* Handle */
::-webkit-scrollbar-thumb {
@apply bg-zinc-400 dark:bg-zinc-500 rounded-xl;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
@apply bg-zinc-500 dark:bg-zinc-400 rounded-lg;
}
}

View File

@@ -1,49 +1,52 @@
import { useState } from "preact/hooks";
import preactLogo from "./assets/preact.svg";
import { invoke } from "@tauri-apps/api/core";
import "./App.css";
function App() {
const [greetMsg, setGreetMsg] = useState("");
const [name, setName] = useState("");
import DragAndDrop from "./components/DragAndDrop";
import { useEffect, useState } from "preact/hooks";
import { FolderIcon } from "@heroicons/react/20/solid";
async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
setGreetMsg(await invoke("greet", { name }));
}
type SaveFile = {
name: string;
path: string;
size: string;
};
function App() {
const [saveFiles, setSaveFiles] = useState<SaveFile[]>([]);
useEffect(() => {
// On startup, find all save files and list them for easy selection
invoke<SaveFile[]>("find_save_files").then((files) => {
setSaveFiles(files);
});
}, []);
return (
<main class="container">
<h1>Welcome to Tauri + Preact</h1>
<div class="row">
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
</a>
<a href="https://preactjs.com" target="_blank">
<img src={preactLogo} class="logo preact" alt="Preact logo" />
</a>
<main class="h-[100vh] w-[100vw] bg-zinc-800 p-4">
<DragAndDrop className="mr-1.5 bg-red-500!" onFile={() => {}} />
<div className="max-h-[50vh] mt-2.5 overflow-y-auto pr-1.5">
{saveFiles.map((file) => {
return (
<div
class="flex items-center justify-between p-1 bg-zinc-700 rounded-lg mb-2 hover:bg-zinc-600 group"
title={file.path}
>
<div class="flex items-center">
<FolderIcon class="w-6 h-6 text-zinc-400 ml-0.5 mt-0.5 mr-1.5" />
<div>
<p class="text-zinc-400">
<span class="text-sm font-semibold text-zinc-100">
{file.name}
</span>
{" "}
<span className="text-sm">({file.size})</span>
</p>
</div>
</div>
</div>
);
})}
</div>
<p>Click on the Tauri, Vite, and Preact logos to learn more.</p>
<form
class="row"
onSubmit={(e) => {
e.preventDefault();
greet();
}}
>
<input
id="greet-input"
onInput={(e) => setName(e.currentTarget.value)}
placeholder="Enter a name..."
/>
<button type="submit">Greet</button>
</form>
<p>{greetMsg}</p>
</main>
);
}

View File

@@ -0,0 +1,74 @@
import { useEffect, useState } from "preact/hooks";
import { listen } from "@tauri-apps/api/event";
import { open } from "@tauri-apps/plugin-dialog";
import { FolderArrowDownIcon } from "@heroicons/react/24/outline";
import { cn } from "../utils";
import { invoke } from "@tauri-apps/api/core";
import Monoblock from "./Monoblock";
interface DragAndDropProps {
className?: string;
onFile: (path: string) => void;
}
export default function DragAndDrop({ className, onFile }: DragAndDropProps) {
const [isHovering, setIsHovering] = useState(false);
useEffect(() => {
const unlistenEnter = listen("tauri://drag-enter", () => {
setIsHovering(true);
}).then((fn) => fn);
const unlistenLeave = listen("tauri://drag-leave", () => {
setIsHovering(false);
}).then((fn) => fn);
return () => {
unlistenEnter.then(() => {});
unlistenLeave.then(() => {});
};
});
async function onClick() {
const defaultPath = await invoke<string>("choose_best_save_directory");
const selectedFile = await open({
defaultPath: defaultPath ?? "",
multiple: false,
directory: false,
canCreateDirectories: false,
recursive: false,
title: "Select a save file",
filters: [
{
name: "ZIP Archive",
extensions: ["zip"],
},
],
});
if (selectedFile !== null) {
onFile(selectedFile);
}
}
return (
<div
onClick={onClick}
className={cn(className, "flex items-center justify-center w-full")}
>
<label className="flex flex-col items-center justify-center w-full h-64 border-2 border-zinc-300 border-dashed rounded-lg cursor-pointer bg-zinc-50 dark:hover:bg-zinc-800 dark:bg-zinc-700 hover:bg-zinc-100 dark:border-zinc-600 dark:hover:border-zinc-500 dark:hover:bg-zinc-600">
<div className="flex flex-col items-center justify-center pt-5 pb-6">
<FolderArrowDownIcon className="w-8 h-8 mb-4 text-zinc-500 dark:text-zinc-400" />
<p className="mb-2 text-sm text-zinc-500 dark:text-zinc-400">
<span className="font-semibold">Click to select</span> or drag and
drop a save file
</p>
<p className="text-xs text-zinc-500 dark:text-zinc-400">
<Monoblock>.zip</Monoblock> files only
</p>
</div>
</label>
</div>
);
}

View File

@@ -0,0 +1,20 @@
import { cn } from "../utils";
import { ComponentChildren } from "preact";
interface MonoblockProps {
className?: string;
children?: ComponentChildren;
}
export default function Monoblock({ className, children }: MonoblockProps) {
return (
<div
className={cn(
"inline-block border-zinc-500 px-0.5 border bg-zinc-800 rounded",
className
)}
>
{children}
</div>
);
}

6
src/utils.ts Normal file
View File

@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

8
tailwind.config.js Normal file
View File

@@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};