Commit Graph
46 Commits
Author SHA1 Message Date
OneWay 30aa86f39f fix(search): drop the open article when the query is cleared 2026-09-19 15:20:16 +08:00
OneWay 8a506763a5 feat(ui): always use two-pane layout in landscape 2026-09-18 02:15:00 +08:00
OneWay 4ce39d0e4f feat(ui): smooth screen transitions and list entrances 2026-09-18 02:11:00 +08:00
OneWay 058330dd34 fix(ui): align article title bar with first search result 2026-09-18 02:05:00 +08:00
OneWay f39aa2a341 fix(ui): align content start offset between search list and article 2026-09-18 02:02:00 +08:00
OneWay f51684367a fix(dsl): render articles faithfully
Split lines on LF, CRLF and lone CR like the indexer, strip leading whitespace from body lines, break the paragraph after a closing margin tag, and apply named colors from [c] tags.
2026-09-18 01:50:00 +08:00
OneWay bddcb99177 fix: drop "No article selected" flash on back from article
ClearArticle nulls state before exit transition ends, so the outgoing screen briefly rendered the null-branch fallback in the title bar. Render empty title/content for null state; remove article_no_selected.
2026-09-15 23:19:29 +08:00
OneWay 2394c7cf5e fix(settings): evaluate update availability on operations and startup
Re-evaluate after indexing completes, persist the last status with its check date, and restore it on startup. When the saved date is older than today the status is re-evaluated once, so new dictionary updates stay visible without a server request on every launch.
2026-09-15 16:55:00 +08:00
OneWay 830f99578a build(release): strip Log warnings/errors from release dex 2026-09-15 14:51:49 +08:00
OneWay 214b9f91e4 perf(about): eliminate all-row recomposition on library expand 2026-09-14 20:04:51 +08:00
OneWay edf6a6074e fix: clean up orphaned and partial files after cancelled downloads
Treat inactive download contexts as cancellation, delete the partial file, and
rethrow the cancellation so the pipeline does not retain an incomplete payload.
Also remove orphaned .dsl/.dz files left behind by cancelled downloads.
Run the partial/orphan deletions on NonCancellable: the cleanup is invoked from
already-cancelled coroutines, where withContext(Dispatchers.IO) aborts before
executing the block and silently leaves the files behind.
2026-09-14 07:50:30 +08:00
OneWay 8319973161 fix: restore boundary progress publishes and animate the bar at constant velocity 2026-09-11 16:37:23 +03:00
OneWay 1631e5384c chore: drop the unused indexing_label string 2026-09-11 16:28:23 +03:00
OneWay 1d4990e5b7 refactor: slim IndexingProgress to a producer-supplied [0,1] progress
perFileProgress was never populated and its progress branch was
unreachable; currentFile, currentIndex, currentFileProgress and label
were write-only (no consumer read them); progressPercent had no
callers; the -1f aggregate sentinel is gone along with the fallback
branches that only fired when the tracker was absent.
2026-09-11 16:28:23 +03:00
OneWay 8c6e43f3db fix: latch terminal notification state and post pipeline progress on one thread
A late ImportState Success snapshot collected after the success
notification overwrote it with an ongoing progress record. Post
progress on Main behind a volatile terminal latch; notifications go
through NotificationPort, the pipeline lives in the coordinator, and
the service finish is injected.
2026-09-06 15:32:35 +08:00
OneWay 2f22144d19 fix: defer import errors until the copy loop finishes
Errors and skips are collected while the copy loop runs and reported
once it ends. The final import state is exhaustive - success, already
added, invalid name, or nothing supported found - so every import run
reaches a terminal state and the pipeline notification always resolves
instead of lingering as an indeterminate progress bar.
2026-09-05 21:55:01 +08:00
OneWay 9807a0cf27 fix: tie back arrow to pipeline idle state
Computed from operation states in SettingsViewModel instead of a fixed
delay; cancel and error release the arrow immediately.
2026-09-05 05:55:56 +08:00
OneWay de27eecd9e fix: key search result rows by dictionary, offset and word
Paging result rows had no keys and were matched by position: appended
pages and query diffs could not reuse row state. Keys derived from
dictionaryPath+offset+word are stable per row, and the paging source
collapses duplicate entries for one dictionary card: case and diacritic
alias variants of a headword share the normalized word, so entries are
deduplicated by dictionaryPath+word+offset before emitting.
2026-09-05 03:00:44 +08:00
OneWay c4b3a57ccb perf(about): parse aboutlibraries.json off the main thread
Bump AboutLibraries plugin to 15.0.4 -> 15.2.0; parse
aboutlibraries.json on Dispatchers.IO via produceState (header renders
immediately, rows fill in); drop animateContentSize from rows.
2026-09-05 00:37:41 +08:00
OneWay d96fad9cab fix: open Settings immediately on cold start when no dictionaries
Seed and synchronously read hadNoDictionaries before setContent so
Settings shows from the first frame until the startup scan confirms.
2026-09-04 19:09:19 +08:00
OneWay e21a134d65 fix: hide dictionary rows from accessibility while mutations blocked
invisibleToUser() removes blocked content from the accessibility tree;
mergeDescendants only regrouped traversal order.
2026-09-04 18:04:32 +08:00
OneWay b9baf61264 fix: re-check mutation-block inside gesture coroutines
Stale drag-tick coroutines launched before the flip no-op at execution
time instead of moving the row after the reset.
2026-09-04 14:59:59 +08:00
OneWay 7b63ee4377 refactor: unify swipe reset to snap before clearing offset
Snap the Animatable first, clear rawOffset after - no frame with the
row still translated while the delete affordance is hidden.
2026-09-04 13:28:27 +08:00
OneWay d892427a3f fix: key dictionary list items by path
Swipe state follows its row instead of migrating to a neighbor on
delete or reorder.
2026-09-04 02:05:59 +08:00
OneWay 628813c3f6 refactor: isolate dictionary rows from mutation-block recomposition
Delete-block flag becomes a () -> Boolean provider read at state/gesture
time, so flipping it no longer recomposes the whole Dictionaries block.
2026-09-04 01:53:06 +08:00
OneWay 4f202f8c10 refactor: replace deprecated currentWindowAdaptiveInfo with V2 2026-09-02 16:18:39 +08:00
OneWay 44ebe68f75 refactor: expose state flows via asStateFlow
Drops the explicit getters and an unused import, and lets an emptyList
type argument be inferred.
2026-09-02 12:55:48 +08:00
OneWay 5de466792a chore: remove unused index comparison and decode helpers
IndexSearcher.compareEntryGroups / IndexComparisonSummary /
IndexComparisonException / readEntryOrNull and AboutLibrariesData.decode
have no call sites left in the app.
2026-09-02 11:30:51 +08:00
OneWay b6e6bd328c fix: reset dictionary progress bar between indexing operations
monotonicTargetProgress is held in remember and only ever grows via
maxOf, so when a new indexing starts after a previous one reached a
higher value the bar is left at the old level while the percent label
starts at 0. Snap it to the current target when the section becomes
visible so the bar follows the new operation from its first frame.
2026-09-02 10:56:32 +08:00
OneWay 5132ae66b9 fix: cancel stale progress notification on process start
Notifications belong to the package and outlive the process: after the
system kills the foreground service mid-download the frozen progress
notification stays in the shade forever. A fresh process means no
service is running, so any leftover notification is stale.
2026-09-02 08:37:43 +08:00
OneWay 5151665216 perf: mark Compose state types as @Immutable
Compose compiler reports showed DownloadState's sealed root as Uncertain
and DownloadProgressState/SettingsUiState as runtime stability, so
skippability checks were deferred to runtime. The annotations make them
compile-time stable and turn any future mutable field into an explicit
contract break.
2026-09-01 17:28:17 +08:00
OneWay 96461bd7cf fix: probe source availability before showing download progress
Probe the source URLs up front so the download flow only enters the
progress state when something is actually downloadable, and report
Idle instead of a fake Success when nothing is: the early return
skipped the terminal-state delay and reset, leaving a phantom 100%
Success (and a stuck "indexing" bar plus a success notification) for
downloads that never happened.
2026-09-01 11:45:41 +08:00
OneWay 98ef99ab53 fix: probe source availability before showing download progress
Instant server failures (404/HTML error page) no longer flash a 0%
progress bar; the check mirrors the downloader's previous-day fallback
and tolerates transient network errors, which still go through the
downloader's retry path.
2026-09-05 10:03:54 +08:00
OneWay 43823e3bfa Fix: clear search results instantly on query clear
Skipped the 300ms debounce for blank queries so the results list clears immediately; typed queries keep the debounce.
2026-08-30 03:36:27 +08:00
OneWay bab03b6c73 fix: retry dictionary downloads on network-switch errors
Downloads killed by WiFi/mobile transitions failed with the generic
"Dictionary download failed" message because UnknownHostException,
ConnectException, unexpected end of stream, and closed-socket errors
were not classified as network errors and were never retried.
Classify them by exception type and message so the retry loop
engages and exhaustion reports the network-specific message.

Bump OkHttp 5.4.0 to 5.5.0: a throwing system proxy selector now
falls back to a direct connection instead of failing the call,
complementing the download resilience fix.
2026-08-30 00:39:04 +08:00
OneWay bc3fa85b9d Release 1.5.0
- The dictionary update card now returns after a failed download
- Fixed headwords and articles with escaped characters being displayed incorrectly
- Fixed slow rendering of articles containing many bracket characters
2026-08-18 00:16:27 +03:00
OneWay 457bbe43b6 Unescape any escaped character in article text
Apply the general DSL rule \X -> X instead of unescaping only brackets
and parentheses, so sequences like \! no longer show the backslash.
2026-08-18 00:15:53 +03:00
OneWay f751ac0d36 Harden DSL parsing against escapes and malformed tags
Fixed escape-aware headword parsing for \{, \}, \[ and trailing backslash.
Fixed O(n^2) tag scan and nested bracket handling in article rendering.
2026-08-16 11:13:46 +03:00
OneWay 910bc8313c Release 1.4.0
- Fixed matching source URLs to installed dictionary files, so deleted dictionaries can be downloaded again from the same URL
2026-08-06 14:26:03 +03:00
OneWay 9d18d0c927 Release 1.3.0
- Blocked swipe-to-delete on dictionary rows while a download, extract,
  import or indexing pass is running. Deleting mid-update removed the
  dictionary's source from preferences while the pipeline kept its own
  snapshot, so the post-update rescan re-created the dictionary with its
  update source permanently lost.
- Fixed the dictionary icon leaving the row while swiping to delete: the
  item now clips to its bounds and the delete button is a static overlay
  instead of a counter-translated child of the sliding row.
2026-08-02 11:09:47 +03:00
OneWay 69bbb97b2a Release 1.2.1
- Fixed the dictionary update card taking too long to reappear after
  cancelling a download (DownloadManager).
- Bump agp 9.3.0 -> 9.3.1; migrate the release build type from
  isMinifyEnabled/isShrinkResources/proguardFiles to
  optimization { enable = true } with keep rules moved to
  app/src/release/keepRules/proguard-rules.keep.
2026-07-31 10:47:29 +03:00
OneWay 84612b26f2 Release 1.2.0
- Fixed a crash on broad queries (e.g. a single letter across several
  dictionaries): the results list keyed items by dictionary
  path/offset/word, and duplicate keys are illegal in a Compose list;
  drop the explicit key, let Paging identify items by position instead
  (SearchResultsList).
- Fixed a disabled dictionary reactivating itself on the next app
  launch: the active flag is now persisted through
  PreferencesManager/DataStore and reapplied whenever the dictionary
  list is rebuilt (LocalDictionaryRepository).
- Search results no longer stop at the first ~100-200 matches: the
  ranked head page hands back a cursor per unfinished prefix range,
  and IndexEntryPagingSource pages the rest straight from the index,
  merged alphabetically across dictionaries, until every match is
  surfaced (IndexSearcher, IndexEntryPagingSource).
- Added diacritic-insensitive search: folded index entries are merged
  into the primary index as aliases, so accented and plain spellings
  find each other (DslIndexer, IndexSearcher).
- Fixed indexing failures on dictionaries with dense non-Latin text: a
  truncated multi-byte sequence at a sample boundary was misread as
  invalid UTF-8 and the whole file fell back to UTF-16LE
  (DslCharsetDetector).
2026-07-22 16:29:16 +03:00
OneWay a5f3af83a4 Fix dictionary update flow and rebuild the search field on Material 3
Fixed the update card reappearing for a moment after tapping it: the tap
re-ran the status check and republished NeedsUpdate before the download
service reported Loading, so the card flashed back in that gap.

Fixed the update card never returning after cancelling a download: both the
Cancelled branch and cancelDownload() forced the status to UpToDate, and the
card's tap is the only thing that re-evaluates it. The status is now
re-derived on the Cancelled to Idle transition, once the partially downloaded
archive - which carries today's date and would otherwise be read as a current
dictionary - has been cleaned up.

Fixed the download progress bar staying at 0% far too long: progress was
published in 3-percentage-point buckets and then scaled by the download stage
weight, so the bar only moved after about 7% of the archive had transferred.

Rebuilt the search field on the Material 3 TextField instead of a hand-rolled
BasicTextField inside a Surface, so it picks up the standard container, cursor
and icon treatment. Dictionary entry titles in the search field, the results
list and the article bar now share a dictionaryTitleLarge style that keeps the
font padding, so their line height lines up with the Material 3 text field.
2026-07-13 19:20:25 +08:00
OneWay db0e8ba6ea Release 1.1.0
- Fixed handling of an HTML "not found" payload served with HTTP 200 for a
  missing daily build: DictionaryDownloader validates Content-Type and the
  gzip magic bytes and falls back to the previous day's build.
- Fixed the update check counting a text/html HEAD response as an available
  build (DictionaryChecker).
- Fixed dictionary source matching: sources are matched by normalized identity
  key and the normalized template is handed to the downloader in
  downloadSpecificSources (DictionaryRepository).
- Fixed the dictionary progress indicator animating backwards to 0% during its
  exit animation; it now stays frozen while it fades out
  (DictionaryProgressSection).
- Fixed slow first composition of every screen by extending the checked-in
  baseline profile to the settings/dictionary flow and the Compose framework:
  the Compose alpha AARs ship near-empty profiles, so every first composition
  ran interpreted.
2026-07-11 11:37:04 +08:00
OneWay 69a5ff6304 Disable fetchRemoteLicense for reproducible builds
AboutLibraries fetched license text over the network at build time, which is unavailable on F-Droid's isolated buildserver and produced different license identifiers (SPDX id vs. hash fallback) between environments, breaking APK reproducibility.
2026-07-07 06:23:05 +00:00
OneWay e8a49575c1 Initial ReSearch export 2026-07-06 09:29:50 +08:00