One discovery subscription over the shared connection for the user's
current zone; matches each incoming offer against saved searches and
fires a text-free OS alert on the new 'alerts' channel for fresh matches.
Skips own/blocked/hidden/non-active offers and dedups via seen keys. The
replay-on-connect doubles as the catch-up scan. Notification payloads are
now prefixed so taps route to chat or the saved search.
Keystore-backed, account-scoped store mirroring SavedOffersStore. Tracks
per-search seen keys (dedup, capped 500) and unread match keys (badge
source), with markMatched/markViewed/newMatchCount and a changes stream.
Extract the market's query/type/category/organic filter chain into
SavedSearch.matchesFilters so live results and saved-search alerts can
never disagree. OffersState.visibleOffers now delegates to it.
Add a features section to the landing home (EN/ES) that describes what
Tane does by intent, not mechanism: inventory, care & calendar, labels &
backup, and the neighbourly sharing layer (offers, chat, trust, plantaré,
sync). Follows the existing pillars/values pattern (front-matter data +
template + CSS, RTL-safe). Reframe the beta status copy so the sharing
layer reads as 'arriving, in beta' rather than 'being built'.
Bumps to 0.1.1+3 (versionCode 3). Adds CHANGELOG [0.1.1], fastlane
changelogs (en-US, es-ES) for versionCode 3, and a 0.1.1 build entry in
the F-Droid recipe (commit v0.1.1, CurrentVersion/Code 3).
Removes the geolocator dependency, which transitively embedded
com.google.android.gms.* (play-services-location) — proprietary classes
that F-Droid's scanner rejects. The optional coarse-location button now
talks to Android's own LocationManager over a small platform channel
(org.comunes.tane/coarse_location): permission prompt, single coarse fix
with a 12s timeout, last-known fallback, null on any failure. Behavior
is unchanged and the CoarseLocationProvider interface is preserved, so
the UI, i18n and widget tests need no changes.
Also sets dependenciesInfo.includeInApk/Bundle = false so the AGP
dependency-metadata block (also flagged by F-Droid) is not embedded.
Neither change affects the Google Play build.
- chown /opt/flutter to vagrant (build runs as non-root; fixes cache write)
- AutoUpdateMode: Version (drop invalid 'v%v' per schema)
- UpdateCheckMode: Tags v[\d.]+ + UpdateCheckData reading version from
apps/app_seeds/pubspec.yaml (Flutter versionCode isn't a literal in gradle)
Validated locally: schema, lint, checkupdates (exit 0), and flutter build as vagrant.
Categories now Inventory + Market & Price + Science & Education (F-Droid has no
'Tools'; these match the app). Build entry and CurrentVersionCode bumped to 2 to
match the shipped 0.1.0 release. Description/screenshots come from the fastlane
metadata tree, not this recipe.
aaron routes to groucho via ada (ens18 down); the groucho->aaron data path drops
packets so the SSH banner never returns (TCP+ICMP ok). Left workflow_dispatch-only
until the network is fixed; deploy meanwhile via ansible tane-landing.yml.
Format: repo predates Dart 3.11's tall formatter (~128 files would need a
dedicated reformat commit); disable --set-exit-if-changed for now, keep
flutter analyze as the real gate.
Test: 'drawer Settings opens the settings screen' asserted find.text('Español'),
which only holds when the resolved locale is Spanish. Under AppLocale.en (as
set in the test) the tile reads 'English', so it failed under CI's non-Spanish
host locale. Assert by the language selector's Key + icon instead (locale-robust).
The cirruslabs/flutter job image has no Node.js, so JS-based actions fail with
'exec: node: not found'. Check out with plain git over the internal forgejo:3000
URL + job token, keeping the workflows Node-free.
aaron runs forgejo + jenkins but no act_runner, so workflows queue until a runner
is registered (or CI moves to Jenkins). Record that the keystore alias is tane-upload.
git.comunes.org is Forgejo. Replicates the analyze + commons_core/app_seeds test
gate in .forgejo/workflows/ci.yml (per-push + PR). Dropped the GitLab-only Windows
job (no Forgejo Windows runner).
git.comunes.org runs Forgejo Actions, not GitLab CI, so the tag-triggered
signed-AAB build + fastlane Play upload now lives in .forgejo/workflows/release.yml
(single job, no cross-job artifact passing). Removed the equivalent GitLab jobs;
.gitlab-ci.yml keeps only the analyze/test gate. Play service account is reused
from Ğ1nkgo. docs/release.md updated (Forgejo secrets).
Noto Sans wordmark on brand green (#2F7D34), white sprout, and the official
value tagline ('keep and share traditional seeds' / 'guarda y comparte...').
Generated by tool/gen_feature_graphic.py for en-US and es-ES.
- fastlane: Appfile/Fastfile/Gemfile with deploy_play lane (AAB -> Play internal track)
- CI: tag-gated build:android (signed AAB/APK from CI secrets) + deploy:play jobs
- F-Droid: fdroiddata build recipe at docs/fdroid/org.comunes.tane.yml
- Play compliance: Data Safety / content-rating answer sheet (docs/legal/internal)
- docs/release.md: automated tag-triggered flow, dedicated tane-upload keystore
- pubspec: description now mentions the market, not just the inventory
The Cancel / Save-and-add-another / Save actions were a fixed Row that
could not shrink, so on narrow phones and long locales (es/pt/de/fr) the
buttons overflowed the right edge (the clipped 'Guardar'). Replace it with
an OverflowBar that wraps onto stacked, end-aligned lines when they don't
fit; move the added-count onto its own line above.
Guard it in small_screen_overflow_test.dart across the long locales.
The object-form go-i18n JSON ({"key":{"other":...}}) is parsed by Weblate's
go-i18n-json-v2 format, not go-i18n-json (which expects a top-level array).
Weblate has no native Hugo-TOML format. The strings are already the go-i18n
structure ([key]/other=), so convert site/i18n/{en,es}.toml -> {en,es}.json
({"key":{"other":"..."}}) — Hugo 0.140 reads it identically (verified with the
pinned hugomods/hugo:exts-0.140.2 image). Enables a 'site' Weblate component.
Update TRANSLATIONS.md: site is now a component (go-i18n-json), not deferred.
Beta-tester feedback triage. The data model already had LotType.seedling as
first class; the gaps were copy and UX.
- Seedlings/plantones: broaden landing hero (EN/ES), in-app legal notice, and
all legal texts (site + docs masters) from seeds-only to "seeds and
seedlings", with a live-plant phytosanitary/transport caveat. Seeds stay the
hero — targeted, not a blanket rename.
- Backups: settings line now states the 7-day cadence explicitly; cadence lives
in AutoBackupService.backupInterval as the single source for text and schedule.
- Community servers: replace the manual wss:// text box with a checklist of the
known servers (defaults visible/toggleable) plus an "add server" affordance
with basic validation. No jargon in the UI.
i18n across en/es/pt/fr/de/ast (ja falls back). Tests updated + a new
server-picker widget test.
- Hugo site (site/): EN/ES intro + legal (generated from docs/legal), an
ES/EN About page from docs/{que-es-tane,what-is-tane}.md, seed-green theme,
responsive header, store-badge placeholders, multi-stage Hugo->nginx image.
- Golden screenshot harness (test/screenshots/): en,es,fr,de,pt,ja + RTL demo,
real fonts via DejaVu Sans + FontManifest; skip-by-default tag so CI stays
green. collect_screenshots.sh feeds site/ and fastlane phoneScreenshots.
- Drop editorial notes from the public explainer.
The propose sheet used a free-text seed name, unlinked from the
inventory. Now the seed is picked from your catalogued varieties so the
Plantaré is always tied to a real Variety (tap-through to its detail, and
it shows in that seed's commitments):
- Seed field is an Autocomplete over the inventory; on send the typed name
resolves to the matching Variety, or creates a quick one if it's new —
so varietyId is never null. Sheet takes the VarietyRepository; chat
passes it.
- New repo one-shot `varietyLabels()` (id + label, no joins) feeds the
picker. Deliberately a Future, not `watchInventory()` — a transient
sheet must not hold a live Drift subscription (that hung the widget test
~36 min). Tests use it too and now run in ~2s with bounded pumps + a
tall surface, no pumpAndSettle.
Tests: a new name creates & links a Variety; a matching name links the
existing one without duplicating. ui/services/data plantare suites green.
Flip plantare-bilateral.md from "design, not yet built" to "v1 shipped",
summarize what landed (transport / schema v12 / service / UI), resolve
the open questions inline with the decisions made, and list the honest
follow-ups (durable outbox, accept-after-restart, rating anchor,
provenance DAG, paper/group/forgiveness sync).
The viral loop, made usable end-to-end:
- Propose sheet (plantare_propose_sheet.dart): from a chat with a peer
(their key already in hand), pick your side, name the seed, choose what
comes back (similar · non-GMO organic / work hours / other) and an
optional return-by, then sign and send. Reached from the chat overflow
menu; confirms "waiting for them to sign".
- Plantares screen: incoming proposals show Accept & sign / Decline right
on the tile; every bilateral row wears a handshake badge — awaiting
signature, signed by both, or declined. Accept falls back to a gentle
"offline" nudge if the proposal isn't in hand yet.
- i18n: full en + es for the bilateral flow; other locales fall back to
base per slang config.
Wire-up only touches human copy (no jargon) and stays behind the
optional PlantareService, so inventory-only builds are unaffected.
Tests: propose sheet drives a real sign+send; the ledger renders the
signed/awaiting badges. Fake SocialSession in your_people test gains the
new transport getter. Widget tests targeted + timed. All green.