Commit graph

22 commits

Author SHA1 Message Date
de6938d5d7 feat(plantare): usable UI — commitments screen, add sheet, entry points
The reproduction-commitment (Plantare) UI, local-first and plain-spoken:
- A Plantares screen (drawer entry, /plantares) listing your commitments,
  grouped Open / Done, with a big 'mark returned', a menu (let it go / reopen
  / remove) and an empty-state that explains what a Plantare is.
- An add sheet (scrollable): a two-choice 'who reproduces & returns' (I return
  / owed to me), an optional 'with whom', an optional 'what comes back' in the
  grower's own words, and a note. No sale, no currency — a promise.
- Reachable from a seed too: an 'Add a commitment' action on the variety
  detail, pre-attached to that variety.
- i18n en/es/pt/ast (human words: 'Plantare' + a plain explanation).

Added the Plantares screen to the small-phone overflow guard (18 cases green).
2026-07-11 02:11:57 +02:00
0e41293de5 fix(ui): scroll the germination & condition-check sheets; extend overflow guard
Two save-button sheets wrapped their body in a bare Column (no scroll): the
germination sheet (which grows a list of past tests) and the condition-check
sheet. On a small phone — especially with the keyboard up — the Save button
was pushed off the bottom, unreachable. Both now wrap the body in a
SingleChildScrollView, like the other input sheets already do.

Also extends the small-phone overflow guard to the profile (identity card +
Save), about, intro carousel, and the market/chat screens in their offline
'set up sharing' state. 17 cases green at 320x568 across es/pt/ast.
2026-07-11 01:11:12 +02:00
913e058122 perf(ui): debounce species/name lookups in the edit sheet
Typing in the edit sheet ran heavy DB work on every keystroke: a SQL
LIKE search on the species field, and a full species-catalog load plus
O(n^2) label matching on the name field. That made typing laggy.

Debounce both lookups (250ms) so they only run once the grower pauses,
and drop stale results with a per-field query counter so an earlier
response can't flicker an outdated suggestion back in.
2026-07-10 02:32:02 +02:00
b840b83c42 feat(species): auto-classify variety species from its label
Infer the catalog species a free-text variety label names ("Maiz de la
abuela" -> Zea mays) and prefill the category from the species family.

- Pure, testable matcher (domain/species_autoclassify.dart): whole-word,
  accent/case-insensitive, Unicode-aware (any script), longest-name-wins,
  ambiguous names left unclassified, light plural fold.
- Quick-add and draft naming auto-link the species when the field is empty
  (non-destructive; an explicit category is kept).
- Edit sheet offers a one-tap suggestion from the typed name.

Tests: matcher unit, repository integration, SpeciesRepository.classifyLabel,
and an edit-sheet widget test.
2026-07-10 02:23:32 +02:00
0e6ef13d00 fix(ui): pin edit-sheet Save button as a fixed footer
The variety edit sheet grew with v8 fields (organic, needs-reproduction,
crop calendar) and its Save button, sitting at the bottom of the
SingleChildScrollView, dropped below the fold — the species-linking
widget test could not reach it (tap landed off-screen, species never
linked). Move the fields into a Flexible scroll area and pin the
Cancel/Save row as a fixed footer so Save is always visible and tappable.

Full suite green (233 tests).
2026-07-10 02:19:07 +02:00
fde0ea6eab feat(species): derived verified reference links (GBIF/Wikipedia/Wikispecies)
Add a read-only "Learn more" section on the variety detail that surfaces
verified external references for the linked species, built deterministically
from bundled identifiers — no titles bundled, no network, offline-first:

- GBIF taxon page from the backbone key
- Wikipedia via Wikidata Special:GoToLinkedPage (locale-aware, RTL-safe,
  falls back to the Wikidata item when a language lacks the article)
- Wikispecies from the scientific name

Enrich the bundled catalog (species.json v3) with gbif_key + wikidata_qid for
all 14 species, cross-checked (each QID carries GBIF ID P846 = the key).
Schema already had the columns; seedBundled now persists and backfills them.

The grower's own manual links stay but are demoted (progressive disclosure):
the section only shows when links exist and "Add link" is a low-emphasis
button, since hand-adding a link is the rarer power move.

Pure-Dart link builder is unit-tested; repo persistence/backfill and the
detail-screen section are covered too.
2026-07-09 22:44:12 +02:00
ba87bf2719 feat(inventory): local sharing — per-lot share terms, filter and printable catalog
The local half of the original Fase 2 (no network, no Offer entity yet):
- Lot sheet gains a 'do you share it?' choice (gift/swap first, sale last,
  never the default); declaring plenty of abundance reveals it with a nudge.
- Lot lines and list tiles badge shared batches; an 'I share' filter and
  a printable PDF catalog (paper bridge for fairs) round out the view.
- Catalog PDF embeds DejaVu (Latin-ext/Cyrillic/Greek); fonts are a
  per-locale resource like the OCR packs.
2026-07-09 22:19:55 +02:00
6809dc6143 feat(inventory): photo-first drafts + on-device OCR (digitization R2+R4)
Lower the bulk-digitization cliff with two more routes on top of the
already-landed CSV import and "save and add another":

- Photo-first drafts (capture now, catalogue later): burst-capture
  photos (camera or multi-gallery) into unnamed draft varieties, shown
  in a "to catalogue" tray, hidden from the main list until named.
  Adds Variety.isDraft (schema), addDraftVariety/watchDrafts/nameDraft,
  the triage sheet and the inventory banner.
- On-device OCR label suggestion (Tesseract, offline, no Google): a
  "Suggest name from photo" button in the naming dialog behind a
  LabelTextExtractor interface (Tesseract on Android/iOS, no-op
  elsewhere). Reads the largest print via hOCR bounding boxes, drops
  boilerplate/low-confidence noise, preprocesses (grayscale, contrast,
  upscale) and sweeps rotations (0-315 deg) so tilted packets still
  read. Bundles tessdata_fast eng+spa; validated on-device against real
  packets. The photo is written to a temp file deleted immediately in a
  finally block (the plugin needs a path) - a bounded, documented
  exception to no-plaintext-at-rest.

This commit also carries the co-developed schema evolution v5 to v8 that
shares these files (organic flag, species viability years, crop
calendar, lot provenance/abundance/preservation format, condition
checks) plus their exports/migrations and i18n.

Tests: CSV/draft/OCR unit + widget + migration green in isolation.
Note: the full widget suite currently hangs (>10 min) - under investigation.
2026-07-09 21:23:46 +02:00
42c16c0e3f feat(ui): Material 3 redesign, cover-photo viewer, About screen
Apply a Material 3 seed-green palette and rounded components across the
home, inventory, quick-add, quantity picker and variety-detail screens.
The full-screen photo viewer can now set any photo as the cover (via
attachment sort order) and delete after confirmation. Lot forms and
packaging surface as choice chips.

Extract About out of Settings into its own screen (app version via
package_info_plus, website link). Add es/en strings for the new lot
types, presentation, home tagline and About. Update Seedees v2 mockups.
2026-07-09 11:51:59 +02:00
c789cd1027 feat(photos): camera-or-gallery picker + swipeable full-screen viewer
- Adding a photo (quick-add and detail) now offers a Camera / Gallery chooser
  (shared pickPhoto helper); camera errors on desktop degrade gracefully.
- Full-screen viewer: pinch-to-zoom pans only while zoomed, so a plain
  horizontal swipe pages between photos again.

54 tests green; Linux runs.
2026-07-08 14:15:13 +02:00
46ef2c61cd fix(inventory): tappable photo dots + non-truncated quantity scale
- Photo carousel dots are now tappable (jump to that photo) with a larger hit
  area, so you can browse all images even when swiping the small thumbnail is
  awkward.
- The quantity unit scale is a Wrap instead of a horizontal scroll, so every
  unit stays visible instead of being cut off.
2026-07-08 13:59:21 +02:00
a69047326e feat(inventory): seed/plant clarity + full-screen photo viewer
- Each lot shows a Seeds/Plantel chip (green vs teal, with icon) so mixed
  seed-and-plant varieties read clearly at a glance.
- Germination is hidden on plant lots (it only applies to seeds).
- Tapping a photo in the detail carousel opens a full-screen, swipeable,
  pinch-to-zoom viewer.

Tests: plant lot shows the Plants chip and hides germination. 53 green; Linux runs.
2026-07-08 13:52:56 +02:00
b23f4f1c77 feat(inventory): external links on the variety detail
Add Wikipedia/forum-style URLs to a variety:
- Repository: addExternalLink/removeExternalLink (soft delete); watchVariety
  loads links and re-emits on external_links changes; ExternalLinkItem model
  (title preferred over URL for display).
- Cubit: addExternalLink/removeExternalLink.
- Detail: a "Links" section with tappable link chips (open via url_launcher,
  http(s):// prepended if missing), delete per chip, and an "Add link" dialog
  (URL + optional title).

Tests: repo add/remove + widget add/remove. 52 green; Linux runs.
2026-07-08 13:38:31 +02:00
5d4053157f feat(inventory): month/year harvest date picker (schema v3)
Replace the free-text harvest year with a themed month/year picker:
a tappable field opens a green-styled dialog with month and year grids
(navigable, paginated years), month optional. Lots now read e.g.
"September 2021" or just "Year 2021".

- schema v3: add nullable Lot.harvest_month (1..12) + migration + tests
- repo/cubit propagate harvestMonth; localized month names (en/es) via slang
2026-07-08 12:09:38 +02:00
9e5c82184b feat(inventory): editable vernacular (common) names
The "also known as" names were read-only; now they can be added and removed:
- Repository: addVernacularName + removeVernacularName (soft delete);
  VarietyDetail.vernacularNames carries ids (new VernacularName model).
- Cubit: addVernacularName / removeVernacularName.
- Detail: deletable name chips + an "Add name" chip opening a small dialog;
  the section is always visible so names can be added when empty.

Tests: repo add/remove + widget add/remove. 44 green.
2026-07-08 11:20:36 +02:00
f8d4d9a778 feat(inventory): edit and delete existing lots
Lots could only be created; now they can be edited and removed:
- Repository: updateLot (LWW) + softDeleteLot (tombstone).
- Cubit: updateLot / deleteLot.
- The add-lot sheet is now a shared add/edit sheet — tapping a lot opens it
  prefilled (type, year, quantity), with a trash action to delete. The reactive
  detail view refreshes on save/delete.

Tests: repo updateLot/softDeleteLot + widget edit-lot and delete-lot. 42 green.
2026-07-08 11:10:43 +02:00
7e92410728 refine(quantity): drop handful, reorder scale, potted-plant icon, year dropdown
Feedback from the running app:
- Remove "handful" from the scale (redundant with spoon); keep the enum value.
- Reorder so "packet" (sobre) follows "spoon" (cuchara).
- Use the Material Symbols potted-plant for the plant lot type and plant unit
  (adds material_symbols_icons).
- Harvest year is now a dropdown of recent years instead of free text.

38 tests green; Linux build runs with the new icon font bundled.
2026-07-08 11:03:57 +02:00
3942975dba feat(inventory): informal quantity scale (number + unit) + seed/plant lots
Rework quantities the way seeds are actually described — a number of an informal
unit — and let a lot hold seeds or plants (plantel).

Quantity model (commons_core):
- Quantity is now { kind, count?, label } — "3 cobs", "2 packets", "a few".
  Count is optional; uncountable vibes (a few, some, pinch) carry no number.
- QuantityKind reorganised into an ascending scale: vibes → containers
  (teaspoon/spoon/cup/jar/sack) → seed & fruit forms → plant units, each tagged
  countable/not. Stored by name; count reuses the existing numeric column.

Lot type (schema v2):
- Lots gain a `type` (seed | plant); germination stays meaningful for seeds.
  schemaVersion 2 with a from1To2 migration (adds the column), drift_schema_v2
  exported, migration test covers v1→v2.

UI:
- New QuantityPicker: a horizontal scale of large seed-glyph icons + a number
  stepper (shown only for countable units), plus a seed/plant SegmentedButton.
  Used in quick-add and add-lot. Lot lines render "3 cobs" / "a few".
- i18n: unit singular/plural (ES/EN, Weblate-friendly), lot-type labels.

Build: slang moved to its CLI (disabled in build_runner to avoid a multi-file
collision); CI runs `dart run slang` before build_runner. 38 tests green,
Linux migrates the existing v1 DB and runs.
2026-07-08 10:51:02 +02:00
48e9d15772 feat(ui): align inventory + detail with mockups (seed icons, green theme)
Visual pass toward docs/mockups (06 inventory, 07 item):
- Bundle the seedks icon font (chars a–k → seed pictograms: jar, packet, spoon…)
  and a SeedGlyph/QuantityKindIcon helper.
- Green app bar + pale-green canvas theme (buildTaneTheme).
- Inventory list: rounded-square photo thumbnail or green initial avatar, bold
  title, scientific-name subtitle, trailing edit pencil, styled category
  headers, rounded search field, seed-glyph empty state.
- Quantity selectors (quick-add + add-lot) show the seed pictogram + word;
  detail lot lines use the kind's glyph.
- Detail header restyled to mockup 07: category link + scientific name on the
  left, photo on the right.

watchInventory now also returns the linked species' scientific name (subtitle).
37 app tests green; seedks font verified in the Linux asset bundle.
2026-07-08 00:14:43 +02:00
37427fa738 feat(block1): germination tests per lot with derived rate
Record germination tests on a lot and surface the result.

- GerminationEntry model with a derived rate (germinated / sample). VarietyLot
  carries its tests (most-recent first) and exposes latestGerminationRate.
- VarietyRepository.addGerminationTest; watchVariety now also re-emits on
  germination-test changes, so the detail refreshes live.
- Detail UI: each lot shows a germination % badge and a grass action that opens
  a sheet listing past tests and adding a new one (germinated + sample size).
  i18n strings (ES/EN).

Tests: derived-rate + reactivity at the repository, and a widget test for the
record-test → badge flow. Full suite: 35 passing, 0 skipped.
2026-07-07 21:59:34 +02:00
4e8b8293e0 feat(block1): bundled species catalog + autocomplete link
Add a small curated catalog of Iberian horticultural species and let a variety
be linked to it from the edit sheet.

- assets/catalog/species.json: 14 species with botanical family and ES/EN
  common names (wikidata_qid/gbif_key deferred to the varilla enrichment).
- SpeciesRepository: idempotent seedBundled (is_bundled rows, keyed by
  scientific name) + search by scientific/common name with a locale-best label.
  Seeded on startup from DI.
- VarietyRepository.linkSpecies: sets species_id and prefills category from the
  species' family when empty (never overwrites an existing category).
  VarietyDetail now carries the scientific name.
- Edit sheet gains a live species-search field; the detail view shows the
  scientific name (italic). i18n strings added (ES/EN).

Tests: catalog parse, idempotent seeding, search by scientific/common name,
linkSpecies prefill semantics, and a widget test for the autocomplete → link →
scientific-name-shown flow. Full suite: 32 passing, 0 skipped.
2026-07-07 21:21:59 +02:00
7ff4e38a15 feat(block1): variety detail + edit screen with reactive lots
Tapping an inventory item now opens its detail (the /variety/:id route was a
placeholder). Read + edit one variety end-to-end:

- Detail view: photo, category, "also known as" names, notes and lots, driven
  by a reactive VarietyDetailCubit.
- Edit core fields (label/category/notes, LWW) via a bottom sheet.
- Add a lot (harvest year + quantity) — the list refreshes reactively.
- Soft-delete (tombstone) with a confirm dialog.

Repository:
- watchVariety(id): merges Drift table-change streams (variety, lots, names,
  attachments) via StreamGroup and reloads the full detail on any change, so a
  lot added to a *different* table still refreshes the view.
- updateVariety (LWW), addLot, softDeleteVariety.

i18n: detail/edit/addLot strings (ES/EN); switched slang to {param} braces
interpolation (translator- and Weblate-friendly).

Tests: repository (reactive watchVariety, update, soft-delete) and widget tests
(render, edit updates title, add-lot appears, delete shows not-found). Full
suite green: 23 passing, 1 skipped (SQLCipher-only encryption guard).
2026-07-07 15:56:03 +02:00