forked from akai/readest
93abca8960
Make the dictionary import path usable on large bundles and bring the multi-device flow up to par. Import perf - Skip `MDX.create()` at import time. The factory triggers full init — decompresses every key block and sorts millions of keys with localeCompare just to expose the header. Replace with a tiny `readMdxHeader()` that only reads the small XML header for Title / Encoding / Encrypted (saves ~17 s on a 250 MB MDX on web). - `partialMD5`: read the 9 sample slices in parallel rather than sequentially. Each freshly-picked-File slice round-trip on Chrome costs ~100 ms cold; parallelisation collapses 9 of them into one. - Native fast-path in `nativeAppService.writeFile`: when the source is a `NativeFile`, delegate to Tauri's `copyFile` rather than streaming the file through `NativeFile.stream()`. Streaming a 250 MB body through 1 MB IPC chunks on Android took ~100 s; native copy is bound by disk throughput instead. Exposes `NativeFile.getNativeLocation()` for the FS layer to use the underlying path + baseDir directly. Lazy lookup - Pass `lazy: true` to `MDX.create` / `MDD.create`. The js-mdict change in this PR skips the upfront decompress-every-block + sort during init (~80 s on the same 250 MB bundle) and decodes only the relevant key block on demand per lookup. First-lookup main-thread block drops from ~81 s to ~230 ms. (Closes #4228.) Raw .dict - Drop the import-time gate that flagged non-gzip dict bodies as `unsupported`. The runtime body loader (`loadDictBody`) already probes the gzip header and falls through to a passthrough buffer for raw files, so the gate was the only thing preventing raw `.dict` bundles from importing on devices that received them via cloud sync. (Closes #4179, partially addresses #4248.) Import-flow UX - `handleImport` now always surfaces a toast for every non-cancelled attempt: picker errors, missing app service, no-op imports, and unsupported-but-imported bundles each get their own message instead of failing silently. - Call `markAvailableByContentId(newDict.contentId)` after add/replace so the "Bundle is missing on this device" warning clears immediately — no need to close-and-reopen the panel. System Dictionary - Drop the cascading toggle behavior in `setEnabled`. Each provider's enabled flag persists independently; exclusivity is enforced at lookup time. Toggling System on/off no longer wipes the user's preferred set of in-app providers. - Render non-system rows as read-only when System is on (toggle still shows what's queued to restore; tooltip explains the lock). - `isSystemDictionaryEnabled` short-circuits to `false` on platforms where the handoff isn't implemented. `providerEnabled` is whole- field synced across devices, so a flag set on macOS would otherwise leak to a Windows device with no way to look up a word. js-mdict - Submodule bump to e6dbc99 which adds the opt-in `lazy: true` `MDictOptions` flag (skip `_readKeyBlocks` + post-init sort; new `lookupKeyBlockByWordLazy` path on `MDX` and `MDD`). Eager mode is unchanged and every existing js-mdict test still passes. i18n - 208 new translations across 33 locales for the new UX strings. Closes #4228 Closes #4248 Closes #4179 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>