Commit Graph
100 Commits
Author SHA1 Message Date
OneWay ff54287916 chore(deps): bump the dependency-versions plugin to 0.65.0 2026-10-10 01:58:43 +08:00
OneWay 318d05350e chore(deps): bump paging to 3.5.2
Patch release fixing an append() call made before the initial refresh.
2026-10-10 01:58:19 +08:00
OneWay 4aeaca4a98 chore(deps): bump Kotlin to 2.4.21 2026-10-10 01:57:43 +08:00
OneWay 01ef1dee2c perf(profile): cover startup, search and article-open paths
Cover the startup path, per-keystroke search with index reads and
ranking, the dictzip article read, block merge and text warm-up,
and dictionary indexing; they previously ran as JIT-warmed or
interpreted code.
2026-10-10 01:13:18 +08:00
OneWay 5ad184ba58 refactor(article): warm up the blocks that are actually rendered
The screen merges small parser blocks into larger render blocks,
while the warm-up measured the unmerged parser blocks. Merge once in
the view model and keep the merged blocks in the article state, so
the screen and the warm-up share exactly what will be drawn.
2026-10-10 01:13:03 +08:00
OneWay 381ce33017 fix(article): warm up large single-block articles
The warm-up ran only above a block-count threshold, so an article
that parses into one large block never qualified. Trigger on the
total character count as well.
2026-10-10 01:12:48 +08:00
OneWay f3ecc3086c fix(search): order numbered headwords by numeric value
The final ranking tie-break compared headwords lexicographically,
so entries numbered with digits or CJK numerals sorted by text
instead of by number. Compare runs of digits or numeral characters
by their numeric value, saturating on very long runs.
2026-10-10 01:12:33 +08:00
OneWay ad3d4f83fb fix(search): pad the bottom of the search history sheet 2026-10-09 13:03:59 +08:00
OneWay 4e75c7d865 Release 1.7.0
- Added search history
- The search bar can be placed at the top or bottom of the screen
- Fixed headwords with stress marks displaying truncated in search results
- Improved download, indexing and navigation stability
- The About screen opens faster
- Updated build tooling and code cleanup
2026-10-07 01:33:27 +08:00
OneWay 5a0426c864 fix(main): populate the search field and results on history click in wide mode
HistoryEntryClicked in wide mode only called SearchAndLoadArticle,
which never updates searchQuery, so the field stayed empty and the
results pager took the query.isBlank() branch with PagingData.empty().
Now dispatch onSearchQueryChanged first, then SearchAndLoadArticle.
2026-10-07 00:43:15 +08:00
OneWay 5b6bb08248 fix(article): align the back arrow with the title in compact mode
In the two-pane compact title bar the arrow sat slightly above
the first title line; offset it down to optically center it.
2026-10-07 00:43:15 +08:00
OneWay cea46c0955 fix(parser): keep the full headword in the display text
The display form was truncated at the first formatting tag, so headwords
with a mid-word stress mark displayed as their prefix only. Build the
display from the full text with tags stripped and render stress marks as
a combining acute accent. Bump the index version so existing indexes
rebuild.
2026-10-06 12:23:50 +08:00
OneWay 37127b7bc9 fix(about): correct the version display
Drop the v prefix so the version shows as a plain version name, and
align it by baseline with the app name instead of the bottom edge of
the headline line box.
2026-10-06 11:10:19 +08:00
OneWay 84fcd77f02 feat(settings): split pasted dictionary URLs into separate fields
Pasting several URLs separated by spaces, newlines or commas into one
field now distributes them across separate fields when every token is a
valid source template. Previously the joined text passed validation as a
single URL and failed at download time.
2026-10-06 11:08:37 +08:00
OneWay 3d83d04cea style: address IDE warnings
Remove unused imports and an unused spacing constant, drop redundant if
checks and redundant opt-in markers, replace loop variables with
destructuring, convert a string concatenation to a template, use
Configuration.screenHeightDp instead of LocalWindowInfo.containerSize, and
opt in to ExperimentalSerializationApi for decodeFromStream.
2026-10-06 09:42:54 +08:00
OneWay 4b627b4d05 fix(search): rebuild the results pager only when the dictionary set changes
Background metadata loading rewrote the dictionaries flow several times
after startup, and every emission recreated the Pager: the results list
visibly collapsed and refilled. Distinct on the index paths that paging
actually uses, and seed the state synchronously instead of an empty list.
2026-10-06 09:42:54 +08:00
OneWay 5c655e769c fix(settings): skip the startup scan when dictionaries are already loaded
A second activity instance (PROCESS_TEXT) ran the full directory scan
again, and the main screen stayed blank until the scan finished. The
repository is a process-wide singleton: when it already holds
dictionaries, mark them up to date and load preferences immediately.
2026-10-06 09:42:54 +08:00
OneWay 0c4ab6dad5 fix(search): keep PROCESS_TEXT on the results screen
handleExternalSearch auto-opened the article on an exact match, so the main
screen with the search bar flashed before the article covered it. Only set
the query; the article now opens from the results list.
2026-10-06 09:42:54 +08:00
OneWay 87dccb4993 fix(article): stabilize baseTextStyle across recompositions
TextStyle.copy() returned a new instance on every recomposition, so the
remember() cache for the rendered blocks never hit. A text selection re-ran
block merging and recreated all article text nodes, rebuilding their
StaticLayouts repeatedly. Hoist the theme values and remember the style.
2026-10-06 09:42:54 +08:00
OneWay 9de47c7f0f perf(about): parse the license catalog with decodeFromStream
Stream the bundled license catalog straight into the JSON decoder
instead of buffering the whole resource as a string first, halving
parse time and peak allocation when the About screen loads.
2026-10-05 05:18:57 +08:00
OneWay 9b6a34b607 fix(settings): write the no-dictionaries seed only after a completed scan
A racing SettingsViewModel whose scan short-circuits with an in-progress
error persisted hadNoDictionaries from a still-empty list, forcing the
Settings screen on the next cold start despite existing dictionaries.
2026-10-05 05:16:21 +08:00
OneWay d2c9dd7701 fix(settings): pin Add Source container to static insets
With many fields, the Add Source sheet could keep re-triggering its
settle animation: animated window insets reached the container while
its height followed the content. Keep only the static status bar
inset on the sheet container; the content already pads itself for
the navigation bar and IME.
2026-10-04 12:36:00 +00:00
OneWay f227546111 fix(search): remove result row fade-in when the query changes
Remove the fade-in animation from result rows so that items render
directly when the query changes.
2026-10-04 12:33:00 +00:00
OneWay cec914ed00 feat(search): search history bottom sheet
Record queries on explicit search and keep up to 100 entries.
Show them in a bottom sheet opened from the search bar, with
per-entry removal and clear-all.
2026-10-04 12:30:00 +00:00
OneWay 73384bc0eb feat(settings): place the search bar at the top or the bottom
Add a search bar position setting and render the bar above the
results or below them, with window insets applied to match.
2026-10-04 12:24:00 +00:00
OneWay c4e4664542 feat(article): adaptive compact top bar
Top-align the title row in compact layouts, align the back button
with the first title line using the shared back button, make the
title start padding depend on whether the back button is shown,
and drop the spacing constant the old arrow buttons used.
2026-10-04 12:21:00 +00:00
OneWay 59dfb53756 fix(ui): align back arrows with the search bar leading icon
Use one shared back button with a matching icon size, touch target
and start padding on the settings and about screens.
2026-10-04 12:18:00 +00:00
OneWay e423bd6c58 refactor(main): expose cold-start preferences as an InitialLaunch flow
Read the theme, locale, empty-library seed and section expansion
once in the application and collect them as state, instead of
blocking the UI thread with synchronous reads before setContent.
2026-10-04 12:15:00 +00:00
OneWay 0bae625c01 feat(settings): enter multiple dictionary source URLs in one sheet
Allow adding and removing URL fields in the Add Source sheet,
validate the whole form at once, and sanitize entered URLs.
2026-10-04 12:12:00 +00:00
OneWay 344852a871 fix(download): verify payload freshness before restoring the update state
On restart the update-available state was restored purely from the
saved date. Also compare the installed payload file names against
dated sources, and re-check when they no longer match.
2026-10-04 12:09:00 +00:00
OneWay 6146c0ebfe fix(article): cancel link press only after touch slop
An already-consumed down change is part of another gesture, not a
reason to cancel the link press. Only treat movement past touch
slop as cancellation.
2026-10-04 12:06:00 +00:00
OneWay 1202662afe fix(storage): retry index file creation while the target is busy
A just-deleted index file can still be held by the system, so
createNewFile() may fail right after deletion. Retry a few times
with a short delay, waiting for the old file to disappear first.
2026-10-04 12:03:00 +00:00
OneWay c90f658bfe fix(settings): accept dictionary source URLs over https only
The platform blocks cleartext traffic by default, so an http:// source
passed validation but could never download and failed with a misleading
network error. The validator now rejects http:// upfront.
2026-09-27 12:30:00 +08:00
OneWay cd589b30a4 fix(download): don't show the update card for current dictionaries
areDictionariesUpToDate() mapped every exception to NeedsUpdate, and
the post-update recheck ran after the first indexed source of a batch,
before later sources finished downloading; the interim NeedsUpdate
persisted for the day. Treat unexpected errors as up to date, rethrow
cancellation, and recheck once when the download batch completes.
2026-09-27 11:00:00 +08:00
OneWay 65684b291d build: bump Gradle wrapper to 9.8.0 2026-09-26 08:27:45 +08:00
OneWay 35f2ded634 refactor: clean up redundant calls and replace deprecated APIs
Unnecessary safe call on a non-null File receiver; unused catch parameters renamed to _; constructor parameter used only in init no longer held as a property; deprecated Configuration.screenHeightDp replaced with LocalWindowInfo.containerSize; redundant filterNotNull on Paging items; deprecated invisibleToUser() replaced with hideFromAccessibility(); redundant alias variable inlined; redundant else in an exhaustive when removed; paging snapshot read moved into the SideEffect that consumes it.
2026-09-26 08:17:09 +08:00
OneWay c7f658dd94 fix(navigation): keep article content during exit animation
On back navigation the article state was cleared before the exit animation ran, so the panel animated out empty except for the back arrow. The overlay now retains the last shown article state until the exit transition completes.
2026-09-26 00:38:57 +08:00
OneWay ed4a4436b8 fix(navigation): keep Home composed while article is open
Article was an AnimatedContent target: opening it disposed Home, and returning from it recreated the whole results list in a single frame. The article screen now renders as a full-screen AnimatedVisibility overlay above Home, which stays composed for the whole article session.
2026-09-25 23:59:45 +08:00
OneWay c7c080939c Release 1.6.0
- The app starts faster
- Smooth screen transition animations
- Articles render DSL line breaks, indentation and named colors correctly
- Tabs and extra spaces inside articles no longer break the layout
- The article title can be copied, tapping the article clears the selection
- Source URLs accept host:port addresses
- Dictionary downloads retry automatically when the network switches
- Download progress notifications are more reliable
- Search results clear instantly when the query is erased
- Leftover files from cancelled downloads are now removed automatically
- Improved app stability
- Faster dictionary indexing
- Updated build tooling and documentation
- Long link-heavy articles no longer freeze while scrolling
- Large search result lists render faster
- Dark article colors are readable in the dark theme
2026-09-24 13:00:00 +08:00
OneWay 2c8668dab3 build: update core to 1.19.1 2026-09-24 12:00:00 +08:00
OneWay e4e50db08e fix(ui): clear article title selection on any tap
The title SelectionContainer covered only the text, so a tap on the empty bar area or the article body never cleared the highlight. A tap anywhere on the article screen now recreates the container and drops the selection.
2026-09-24 10:00:00 +08:00
OneWay 98ec38f272 fix(ui): remap dark article colors in dark theme
Colors set by dictionaries such as navy, dark red and brown are nearly invisible on the dark background. Swap the dark named colors for lighter tones when rendering in the dark theme; the light theme keeps the original colors.
2026-09-24 09:00:00 +08:00
OneWay 6040ca8db5 fix(ui): merge article blocks to fix scroll jank
Link-heavy articles split every line into its own list item, so a
fast fling composed a dozen items in one frame and froze. Merge small
blocks into multi-paragraph items: indent via em space and a uniform
line pitch via LineHeightStyle(Proportional, Trim.Both).
2026-09-23 09:30:00 +08:00
OneWay 71fea4472b fix(ui): read paging snapshot directly
Replace the per-index peek loop with the item snapshot list;
the loop walked the whole result set on every recomposition.
2026-09-23 09:00:00 +08:00
OneWay b5fc7e7246 fix(ui): keep previous search results while reloading
Keep showing the last results while a new search generation loads,
and guard list access: the paging snapshot can shrink mid-layout,
which threw and crashed on an empty result set.
2026-09-22 00:37:48 +08:00
OneWay 447d086cdf fix(dsl): close margin blocks at the closing tag
Blocks stayed open until the next character arrived, so following text
merged into them and trailing escapes dropped. Close each block right
at its tag and append escaped characters unconditionally.
2026-09-21 22:08:45 +08:00
OneWay ac9a22dbe1 fix(dsl): render [p] labels in italics
Style and grammar labels printed upright while sources mark the same
words in different ways, so identical labels rendered inconsistently.

Every [p] block now uses the label color with italic posture, and the
text scan for specific label words is removed.
2026-09-21 21:53:32 +08:00
OneWay cf29f19511 fix(dsl): render tabs as a fixed-width gap
A literal tab advanced text to the next platform tab stop, which pushed
the rest of the line far enough to wrap it mid-phrase.

Replace each tab with an en space so the separator keeps a fixed, modest
width and the line breaks like ordinary text.
2026-09-21 20:11:40 +08:00
OneWay ed1e1db7f2 chore(dsl): drop stale cache comments 2026-09-21 17:43:15 +08:00
OneWay a5b54def51 fix(dsl): keep single spaces after opening tags
Dictionaries use a space right after an opening tag as a visible
separator, and dropping it glued words together.

Drop only space runs at the start of a block and collapse runs to one
space everywhere else; spaces after opening tags are now kept.
2026-09-21 16:35:08 +08:00
OneWay ee19f84f91 fix(ui): align article title with the first search result in two panes
In landscape the detail pane rendered the title inside a fixed 56.dp
bar and centered the text in it, so the headword sat about 14 dp lower
than the first search result next to it. Add a compact variant of the
title bar without the fixed height; the title line now shares the top
offset of the first list row.
2026-09-21 14:39:12 +08:00
OneWay 4e42a269a7 fix(ui): clear text selection on tap anywhere in the article
Every block of the dictionary article was wrapped in its own
SelectionContainer, so a tap in one block never cleared a highlight
held in another. A single container now wraps the article list — a tap
anywhere clears the selection and selection can span adjacent blocks.
2026-09-21 13:25:41 +08:00
OneWay 4caf3a534d fix(ui): make the article title selectable
The title Text sat outside any SelectionContainer, so the headword
could not be copied.
2026-09-21 13:24:41 +08:00
OneWay c0c9211b82 fix(dsl): render each margin on its own line
Each [m] block occupies its own line in the article. Blank paragraphs
and whitespace-only lines are dropped.
2026-09-21 10:27:34 +08:00
OneWay f5880d72ad feat(ui): animate dictionaries section expand and collapse 2026-09-21 09:01:12 +08:00
OneWay 95f4317eaf fix: honest indexing progress and preparing phase label 2026-09-21 09:00:12 +08:00
OneWay df96deb1fc fix: clear stale terminal notification when a new flow starts 2026-09-21 08:59:12 +08:00
OneWay 451267688a fix: clear import progress notification stuck at 100%
The progress notification was detached from the foreground
service on pipeline finish, so a process killed mid-import left an
ongoing notification orphaned in the shade until the next app launch.
Terminal notifications now use their own id, and finishing the
pipeline removes the bound progress notification; swiping the app
from recents cleans it up as well.
2026-09-21 00:05:48 +08:00
OneWay 1d84eaf9c0 fix: reject bare .dz source URLs and make extension validation case-insensitive
A bare .dz file (DictZip without the .dsl prefix) is treated by the
pipeline as an orphaned file and deleted right after the download, so
a .dz source URL passed validation but silently produced no
dictionary. Accept only DictZip-compressed DSL (.dsl.dz; .gz already
covers .dsl.gz) and compare extensions case-insensitively.
2026-09-20 23:14:54 +08:00
OneWay 59115ff9a3 fix: ignore dateless sources when checking dictionary freshness
A source URL without the {DATE} placeholder is date-invariant, so its
HEAD probe always answers 200. Including such sources in the freshness
check made the checker report "server has a newer version" regardless
of the dated sources' state.
2026-09-20 23:11:54 +08:00
OneWay eb918ca09f fix: accept host:port in dictionary source URLs
URL validation rejected any host containing a colon, so sources on
non-standard ports could not be added. Strip the optional :port from
the host before applying the domain checks and validate the port
range (1-65535); the port is kept intact through template
normalization and URL building.
2026-09-20 21:45:07 +08:00
OneWay 638e886498 chore(deps): bump Android Gradle Plugin to 9.4.1 and Kotlin to 2.4.20 2026-09-19 16:21:09 +08:00
OneWay c2b2bf1c8a chore(deps): bump Compose BOM to 2026.09.00
Measure-pass defect in compose ui 1.12.0: layoutChildrenBlock clobbered
the isPlacingForAlignment flag of child nodes during alignment
placement, so sheet anchors were recalculated from a stale content size.

compose ui 1.12.1 preserves and restores child placement flags, so the
anchor is computed from a consistent content size on the first frame.
2026-09-19 15:20:16 +08:00
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 2dadfa11e9 chore: add MIT license
Add the MIT LICENSE file (Copyright (c) 2026 OneWay), link it from the README, and draft the 1.6.0 changelog.
2026-09-15 18:39:00 +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 d4e6302274 docs: update README and Fastlane descriptions 2026-08-25 23:59:58 +08:00