Skip to content

feat(dictionary): flag unknown words with Add/Block + blocklist screen (#40)#59

Merged
AsafMah merged 1 commit into
devfrom
feat/c4-ui-flag-unknown-words
Jun 7, 2026
Merged

feat(dictionary): flag unknown words with Add/Block + blocklist screen (#40)#59
AsafMah merged 1 commit into
devfrom
feat/c4-ui-flag-unknown-words

Conversation

@AsafMah

@AsafMah AsafMah commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Implements #40 (C4-ui) — the clarity layer on top of the #43 blocklist backend.

What it does

  • Flag: suggestions that are only learned/typed (source dict = USER_HISTORY/USER_TYPED, i.e. not in a real dictionary) get a subtle underline in the strip. Gated by new pref PREF_FLAG_UNKNOWN_WORDS (default on; toggle in Settings → Dictionaries).
  • Add / Block: long-pressing a flagged word opens an AlertDialog with Add to dictionary / Block / Cancel. Curated words keep the existing bin affordance unchanged.
  • Blocklist screen: Settings → Dictionaries → Blocklist — per-locale view + remove of blocked words.

Backend (DictionaryFacilitator)

  • addToUserDictionary(word) — promote to the personal dictionary and un-blacklist. Resolves the user dict first, so a word is never un-blocked without actually being added.
  • blockWord(word) — delegates to removeWord, which (post-fix(dictionary): stop deleted/junk words from resurrecting (incl. via swipe) #43) already permanently blacklists in every group including history-only words; this just gives the UI a clear verb.

Why the source-dict heuristic for flagging

mSourceDict ∈ {USER_HISTORY, USER_TYPED} is cheap (no per-suggestion dict lookup in the view layer) and well-grounded: IMPROVEMENT_PLAN.md already uses mSourceDict != DICTIONARY_USER_TYPED to mean “real dictionary word” — so a valid typed word carries a real-dict source and is not flagged; only typed-but-unknown and learned words are. (#39 C4-smart is the algorithmic follow-up.)

Verification

  • Compiles (Java + Kotlin, offline flavor).
  • Full :app:testOfflineRunTestsUnitTest: 220 tests, 13 failed — all 13 are the exact dev baseline (4 Windows-only ParserTest + the 9 that PR ci: make unit-test gate green and blocking (#12) #57 quarantines, not yet merged to dev). New DictionaryGroupTest.removeFromBlacklist_unblocksWord passes. Zero new failures.
  • Cross-model review (rubber_duck) run; fixed the add-then-unblock ordering bug it surfaced.
  • Needs on-device verification (strip underline, dialog, blocklist screen rendering aren't JVM-coverable).

Known limitations (deliberate, for follow-up)

  • The flag heuristic can occasionally underline an over-learned word that's also in the main dict (history out-ranks main). The exact predicate (!isInNonHistoryDictionary) exists but needs the facilitator plumbed into the view; deferred to C4-smart: Graduated trust for non-dictionary learned words #39.
  • blockWord blocks across all loaded locales (matches the existing bin behavior).
  • Blocklist-screen edits write the per-locale file; they take effect on the next dictionary reload (the file is authoritative), not necessarily mid-session.

Implemented coordinator (backend + pref + strings + test) with two parallel subagents (strip UI; settings screen) on disjoint files. Base dev; leaving for review + merge.

#40)

C4-ui: when a suggestion is only learned/typed (not in a real dictionary),
underline it in the strip and offer Add-to-dictionary / Block on long-press.
Adds a per-locale Blocklist settings screen.

Backend (DictionaryFacilitator):
- addToUserDictionary(word): promote to personal dict + un-blacklist (only once the
  user dict is resolvable, so we never un-block without adding).
- blockWord(word): delegates to removeWord (which already permanently blacklists in
  every group, incl. history-only words) - gives the UI a clear verb.

UI:
- SuggestionStripLayoutHelper: underline suggestions whose mSourceDict is
  USER_HISTORY/USER_TYPED, gated by new pref PREF_FLAG_UNKNOWN_WORDS (default on).
- SuggestionStripView: long-press an uncurated word -> AlertDialog (Add/Block/Cancel);
  curated words keep the existing bin.
- BlocklistScreen: per-locale view/remove of blocked words (filesDir/blacklists/*.txt).

Test: removeFromBlacklist round-trip (the Add un-block path).
@AsafMah

AsafMah commented Jun 7, 2026

Copy link
Copy Markdown
Owner Author

On-device verified (S24+, standard debug build): unknown-word underline shows, long-press Add/Block dialog works, and the Blocklist settings screen lists/removes. ✅

@AsafMah
AsafMah merged commit 1adec40 into dev Jun 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant