feat: add structured search with visual filter builder #469

Merged
guettlibot merged 5 commits from issue-466-structured-search into main 2026-06-07 02:38:29 +00:00
guettlibot commented 2026-06-06 08:47:40 +00:00 (Migrated from codeberg.org)

Closes #466

Summary

  • FilterGroup / FilterLeaf tree model (lib/core/filter/filter_expression.dart) — sealed hierarchy with FilterField (from, to, cc, subject, size), FilterComparison (contains, is, matches, over, under), and FilterOperator (AND / OR).
  • SieveSerializer (lib/core/sieve/sieve_serializer.dart) — converts a FilterGroup + List<SieveAction> to a valid RFC 5228 Sieve script.
  • FilterSieveConverter (lib/core/filter/filter_sieve_converter.dart) — parses a Sieve script back into a FilterGroup tree; returns null for unsupported scripts.
  • FilterBuilderWidget (lib/ui/widgets/filter_builder.dart) — interactive filter editor with AND/OR toggle, nested group support (depth ≤ 1).
  • Search screen gains an Advanced Search mode (Icons.tune toggle).
  • Sieve script editor gains Visual / Script tabs with round-trip serialization. _ActionEditor covers keep, discard, mark-as-read, file-into.
  • 25 unit tests covering all new model/logic classes including round-trip.
  • Fix: SieveSerializer now emits \\Seen so the IMAP flag survives quoted-string parsing.

Test plan

  • flutter analyze — No issues found
  • flutter test test/unit/filter_and_sieve_test.dart — all 25 tests pass
  • All pre-commit hooks pass (format, check-fast, coverage gate)

🤖 Generated with Claude Code

Closes #466 ## Summary - **`FilterGroup` / `FilterLeaf` tree model** (`lib/core/filter/filter_expression.dart`) — sealed hierarchy with `FilterField` (from, to, cc, subject, size), `FilterComparison` (contains, is, matches, over, under), and `FilterOperator` (AND / OR). - **`SieveSerializer`** (`lib/core/sieve/sieve_serializer.dart`) — converts a `FilterGroup` + `List<SieveAction>` to a valid RFC 5228 Sieve script. - **`FilterSieveConverter`** (`lib/core/filter/filter_sieve_converter.dart`) — parses a Sieve script back into a `FilterGroup` tree; returns `null` for unsupported scripts. - **`FilterBuilderWidget`** (`lib/ui/widgets/filter_builder.dart`) — interactive filter editor with AND/OR toggle, nested group support (depth ≤ 1). - **Search screen** gains an Advanced Search mode (`Icons.tune` toggle). - **Sieve script editor** gains Visual / Script tabs with round-trip serialization. `_ActionEditor` covers keep, discard, mark-as-read, file-into. - **25 unit tests** covering all new model/logic classes including round-trip. - Fix: `SieveSerializer` now emits `\\Seen` so the IMAP flag survives quoted-string parsing. ## Test plan - [x] `flutter analyze` — No issues found - [x] `flutter test test/unit/filter_and_sieve_test.dart` — all 25 tests pass - [x] All pre-commit hooks pass (format, check-fast, coverage gate) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.