Commit Graph
17934 Commits
Author SHA1 Message Date
Claude 89aea073ed fix: bound the context shown around a highlight to a window
A kind:9802 highlight can carry a huge `context` tag — a quote pulled from
the middle of a long article may ship several paragraphs of surrounding
text. Rendered whole, that fills the feed card with paragraphs around a
one-sentence highlight.

Trim the context in `HighlightQuote.of` to at most ~160 characters on each
side of the marked quote, snapping the cut to a whole-word boundary and
marking it with an ellipsis. The quote itself is always kept in full and
the marked range is re-based onto the trimmed text, so the in-context
marker still lands exactly on the highlighted passage. Short contexts are
left untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApuEseGcFjUFqYoLhCuR91
2026-07-28 21:03:56 +00:00
Claude 4d24e2b09c fix: collapse scraped whitespace when reconstructing highlight context
A kind:9802 highlight with no `context` tag falls back to reconstructing
the surrounding passage from the W3C `textquoteselector` prefix/suffix.
Those fragments are scraped from the source web page, so they carry the
page's block-boundary whitespace (runs of newlines/spaces between DOM
nodes). Glued in verbatim as `prefix + content + suffix`, they render as a
stack of blank lines above the marked quote.

Collapse each whitespace run in the prefix/suffix to a single space (and
trim the outer edges) in `HighlightEvent.contextOrReconstructed()`. The
highlight's own `content` is left verbatim so its offsets inside the
reconstructed context stay exact for the in-context marker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApuEseGcFjUFqYoLhCuR91
2026-07-28 20:47:53 +00:00
Vitor PamplonaandGitHub af04267f9a Merge pull request #3778 from vitorpamplona/claude/back-arrow-responsiveness-sz40m9
Fix back arrow visibility during predictive back-swipe animations
2026-07-28 16:09:35 -04:00
Claude 88ee46df05 fix: keep back arrow visible until the exiting screen finishes leaving
canPop() read the globally-current back-stack entry via
currentBackStackEntryAsState(). A pop commits the instant it is accepted
— most visibly during a predictive back-swipe, whose exit animation is
long and finger-driven — so controller.currentBackStackEntry flips to the
destination while the screen being dismissed is still on screen, sliding
out and still composing its top bar. Evaluating canPop against the
incoming destination there dropped the back arrow (and re-showed the
bottom bar) before the outgoing screen had finished leaving, which is
exactly the flicker seen when back-swiping to Home or a bottom-nav root.

Evaluate poppability against the screen's own NavBackStackEntry — the one
the NavHost provides to each destination via LocalViewModelStoreOwner —
which is intrinsic to that screen and never changes for the life of its
composition. The arrow now stays put until the screen itself is gone.
Callers outside a NavHost destination (shell chrome, drawer) see the
account-scoped owner instead of an entry and fall back to the previous
globally-current behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011matx1mGJ6ZyS5dS77EQUo
2026-07-28 20:03:43 +00:00
Vitor PamplonaandGitHub ab5a59a106 Merge pull request #3776 from vitorpamplona/claude/amethyst-lint-translation-hvu5pz
Remove unused buzz_dm_hide string resource
2026-07-28 15:55:03 -04:00
Claude c49e2d3390 fix: remove orphaned buzz_dm_hide translations
The `buzz_dm_hide` string key exists only in translation files but has no
entry in the default `values/strings.xml` and is not referenced anywhere in
code. This triggered the lint ExtraTranslation error and failed the
`:amethyst:lintFdroidBenchmark` build. Removed the orphaned key from all 7
locale files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ksnCb8x45HnL7nFPzxh4B
2026-07-28 19:45:48 +00:00
Vitor PamplonaandGitHub f3db2c73dc Merge pull request #3773 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-07-28 15:41:40 -04:00
vitorpamplonaandgithub-actions[bot] 456684edb1 chore: sync Crowdin translations and seed translator npub placeholders 2026-07-28 19:22:32 +00:00
Vitor PamplonaandGitHub 31582320f2 Merge pull request #3775 from vitorpamplona/claude/resource-consumption-trigger-709n5v
Relax resource usage alert thresholds
2026-07-28 15:19:30 -04:00
Vitor PamplonaandGitHub 68664bfac1 Merge pull request #3774 from vitorpamplona/claude/buzz-community-channel-style-l2l63v
Simplify ConcordAuthorFacepile to use ClickableUserPicture
2026-07-28 15:10:44 -04:00
Claude d9d02110dd fix(resource-usage): raise the background mobile data trigger to 500 MB
Bump BG_MOBILE_BYTES_PER_DAY from 100 MB to 500 MB/day so the report
prompt only flags genuinely excessive background cellular traffic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R2efhyiQHKFoNjQo6WnGRH
2026-07-28 19:10:43 +00:00
Claude 8a41129dfc fix(resource-usage): double the report-prompt trigger thresholds
Raise every ResourceUsageAlerts threshold to 2x so the "this app is
consuming too much" report prompt only fires at twice the previous
consumption levels, cutting false positives on heavy-but-normal days:

- background mobile data: 50 MB -> 100 MB / day
- background mobile relay-connection time: 12 h -> 24 h / day
- notification wakelock: 30 min -> 60 min / day
- app process starts: 75 -> 150 / day
- completed relay (re)connections: 5000 -> 10000 / day

Tests reference the constants symbolically, so the alert suite stays green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R2efhyiQHKFoNjQo6WnGRH
2026-07-28 18:57:30 +00:00
Claude baf5f37532 feat: render Buzz channel recent-poster facepile with the standard avatar
The recent-posters facepile in a Buzz community's channel rows drew each
poster with ObserveAndDrawInnerUserPicture — a bare cropped image wrapped
in a surface-coloured ring, overlapped into a deck. That omitted the
following badge and trust-score tag every other user avatar in the app
carries.

Draw each poster with ClickableUserPicture (the regular BaseUserPicture
path) instead, so the facepile shows the following icon (top-right) and
trust-score tag (bottom-centre). Lay the avatars out with a small gap
rather than an overlapping stack so those badges stay readable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013f3JZdoChYEEDtqTArFAxn
2026-07-28 18:54:23 +00:00
Vitor PamplonaandGitHub 3842ab14bb Merge pull request #3772 from vitorpamplona/claude/concord-buzz-messages-visibility-ye6ocz
Add long-press menu to relay group & Concord channels in Messages
2026-07-28 14:51:15 -04:00
Claude 49e4234f99 feat: align leave vs remove-from-messages actions across chat types
"Leave" meant three different things and the actions were scattered across
each channel's own screen, so they were hard to find from Messages. Make the
vocabulary consistent and reachable:

- "Leave" now always means "renounce membership / you're out" — the kind-9022
  LeaveRequestEvent for NIP-29/Buzz groups, and the kind-13302 self-list removal
  for Concord (its only exit).
- "Remove from Messages" is the single soft action: take it off my list but keep
  membership. For a joined relay group this drops the kind-10009 entry without a
  9022 (I stay in the roster) and dismisses the invite so a Buzz kind-44100
  re-announce can't bounce it back. The Buzz DM "Hide conversation" reuses the
  same label.

Surface both on the Messages rows via long-press (previously only reachable
inside each group/community screen):
- Relay-group row: "Remove from Messages" + "Leave".
- Concord row: "Leave" (reuses the existing confirm dialog; a community has no
  soft/hard split since the list entry is the whole membership).

Split the relay-group top-bar menu into the same two actions, thread an optional
onLongClick through ChannelName, and consolidate the buzz_dm_hide string into the
shared remove_from_messages string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NRifAJ75U4zWbg3V3Y3g8g
2026-07-28 18:40:16 +00:00
Vitor PamplonaandGitHub 48eea9a350 Merge pull request #3771 from vitorpamplona/claude/top-nav-font-sizes-vg4l9q
Remove unnecessary FontWeight.Bold styling from Text components
2026-07-28 14:34:12 -04:00
davotoula 7718e3ab19 fix: extract duplicated string literals 2026-07-28 20:29:21 +02:00
Claude 47be9909da fix: normalize bold top nav bar titles to default weight
The Buzz relay group (community) top bar and its sub-screens (members,
threads, browse, channel list), the Buzz canvas, geohash chat/new/teleport
screens, the single-URL and single-geohash viewers, and the Marmot group
chat all forced FontWeight.Bold (geohash chat also titleMedium) on their
top-bar titles, while every sibling channel header — DM rooms, public
chats, ephemeral chats, live activities — and the shared TopBar wrappers
render the Material3 titleLarge default at normal weight.

Drop the bold (and size) overrides so all top nav bar titles share one
consistent treatment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019N7b8D4vBvafhG9eU7M9iJ
2026-07-28 18:27:16 +00:00
David KasparandGitHub 153d28b420 Merge pull request #3770 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-07-28 20:17:44 +02:00
davotoulaandgithub-actions[bot] 8ce93f3700 chore: sync Crowdin translations and seed translator npub placeholders 2026-07-28 18:15:15 +00:00
davotoula 14db81177f update cs,pt,de,sv 2026-07-28 20:06:18 +02:00
Claude d9ae9cbd37 fix: normalize top nav bar title font sizes
Three top nav bar titles overrode the Material3 titleLarge default with
titleMedium, rendering ~16sp while every other top bar title inherits
~22sp. Drop the titleMedium override so the Calendar event detail and Git
repository (home + sub-screen) titles match the rest of the app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019N7b8D4vBvafhG9eU7M9iJ
2026-07-28 17:42:37 +00:00
David KasparandGitHub a585fe3664 Merge pull request #3764 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-07-28 19:41:02 +02:00
Vitor PamplonaandGitHub b085c8cc37 Merge pull request #3767 from vitorpamplona/claude/corcord-read-only-communities-gu1x4k
Implement CORD-02 §9 community dissolution seal
2026-07-28 13:40:28 -04:00
vitorpamplonaandgithub-actions[bot] 8145bedd15 chore: sync Crowdin translations and seed translator npub placeholders 2026-07-28 17:36:46 +00:00
Vitor PamplonaandGitHub 6666637f9c Merge pull request #3766 from vitorpamplona/claude/lazygrid-duplicate-key-v4k7sj
Fix duplicate app entries in Discover Apps grid
2026-07-28 13:34:03 -04:00
Vitor PamplonaandGitHub 6086e48859 Merge pull request #3765 from vitorpamplona/claude/keyboard-ime-stuck-state-et3yfu
Fix keyboard state tracking and back handler races
2026-07-28 13:33:14 -04:00
Claude eeefacca9e fix(ime): union nav-bar and IME insets on the two remaining bare-Scaffold forms
Sweep of every imePadding() in the app for the same nav-bar-over-IME
double-count fixed for the chats. Two more bare Material3 Scaffold screens
applied the scaffold content padding (which carries the nav-bar inset) and
then imePadding() without consuming in between, so the nav bar stacked on top
of the IME while the keyboard was up:

- NewGeohashChatScreen (geohash create form)
- MarmotGroupInfoScreen (has the add-member search field)

Both now consumeWindowInsets(pad) before imePadding(), matching the idiom the
other forms already use. Every other imePadding() call was verified fine:
DisappearingScaffold-based screens are handled by the scaffold's own
reservation, dialogs/bottom sheets carry no nav-bar content padding, and the
rest either apply imePadding() alone at a root or already use the
navigationBarsPadding()/consumeWindowInsets union.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012dT2RLbPZzan2hULL2cmc6
2026-07-28 17:25:34 +00:00
Claude a569095e19 feat(concord): honor CORD-02 §9 read-only seal on dissolved communities
A dissolved community (owner-signed kind-3308 tombstone) is sealed
read-only per CORD-02 §9: held keys still open history, but nothing new
is honored. The `dissolved` flag was folded in quartz but ignored by the
write gates, so members — and the CLI — could still post to a dissolved
community.

- commons: ConcordChannel now tracks `dissolved` from the folded state
  and `canPost()` returns false when set, so the Android composer (which
  gates on it) is hidden. The self-delete carve-out is unaffected — it
  runs through the note context menu, not the composer.
- amethyst: show a read-only notice where the composer would be so the
  seal is explained rather than silent.
- cli: `amy concord send` folds the community and refuses with a
  `dissolved` error before building/publishing; `amy concord channels`
  surfaces the `dissolved` flag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HateTjrutJ23wAEttEwHQA
2026-07-28 17:22:24 +00:00
Claude 5174c8e5a3 fix: dedupe Discover apps by coordinate to avoid duplicate LazyGrid keys
The Browser home "Discover nsites/napplets" sections render each followed
manifest in a LazyVerticalGrid keyed by "ns:"/"np:" + coordinate. The
observed store (NoteListMatchingFilter, backed by a ConcurrentSkipListSet
ordered by created-at/id) can surface the same addressable note twice when a
replaceable manifest gets a new version — mutating the note's sort key inside
the set breaks dedup. Both copies map to the same coordinate, producing a
duplicate grid key and crashing with IllegalArgumentException.

Collapse the mapped list by coordinate so each app appears once and grid keys
stay unique.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9TomvuP9YnPUDCZuiQae6
2026-07-28 17:09:31 +00:00
Claude 39e272f478 fix(ime): stop nav-bar padding from stacking on top of the IME inset in chats
While the keyboard was up, the public / relay-group / live-activity /
ephemeral chats — and the Concord channel + minichat views — left an extra
navigation-bar-height gap between the composer and the keyboard. WindowInsets.ime
is measured from the bottom of the screen, so it already spans the nav-bar
band; reserving the nav bar again on top of it double-counts. NIP-17 DMs were
unaffected because their scaffold reserves the nav bar with the consuming
navigationBarsPadding(), which excludes the already-consumed IME inset (a
union), while the bottom-bar chats reserved it as a plain, non-excluding pad.

- DisappearingScaffold: when the bottom-bar slot renders empty it now reserves
  max(0, navigationBars - ime) instead of the full nav-bar inset, so the
  reservation drops to zero while the keyboard is up (the root imePadding has
  already lifted the scaffold above it). Covers every bottom-bar chat at once.
- ConcordChannelScreen / MinichatScreen: use the standard
  padding(padding).consumeWindowInsets(padding).imePadding() union instead of
  summing a plain padding(padding) with imePadding().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012dT2RLbPZzan2hULL2cmc6
2026-07-28 17:05:57 +00:00
Claude f734865a31 fix(ime): stop the soft keyboard state from getting stuck open
Leaving a chat with the keyboard up via a back gesture left a large IME
padding stranded at the bottom — and, because WindowInsets.ime is a single
app-wide holder, on every other screen too — until some later inset pass
happened to rebalance it. It only reproduced on release builds.

Root cause: the chat composers install a BackHandler that flushes the draft
and pops the screen. When that pop runs while the keyboard is still visible,
the predictive-back window animation races the IME's close animation. On an
optimized release build the window animation wins, and the IME
WindowInsetsAnimation is cancelled before its terminal (zero) frame reaches
Compose, so the shared insets holder stays "animating" and every
imePadding() in the app freezes at the keyboard height. Debug and benchmark
builds are slow enough that the IME animation completes first, which is why
they were unaffected.

Fixes:
- New KeyboardAwareBackHandler: while the keyboard is on screen it does not
  consume back, so the system dismisses the keyboard first (its animation
  completes cleanly); the next back runs the original handler. The top-bar
  back arrow remains an always-available exit. Adopted in the DM, public-chat
  and new-group-DM composers.
- Rederive keyboardAsState() from WindowInsets.ime instead of the
  pre-edge-to-edge getWindowVisibleDisplayFrame/OnGlobalLayout heuristic,
  which under enableEdgeToEdge() could itself latch Opened after the keyboard
  closed. Now it tracks the same inset that drives imePadding().
- Concord channel chat and the minichat thread view used a bare Material3
  Scaffold whose content insets ignore the IME; add imePadding() so the
  composer rides above the keyboard while typing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012dT2RLbPZzan2hULL2cmc6
2026-07-28 16:29:32 +00:00
Vitor PamplonaandGitHub 84a96f1f86 Merge pull request #3763 from vitorpamplona/claude/fix-localcache-dropdown-warnings-y4952o
Refactor parameter names for clarity and update Material3 API
2026-07-28 11:50:54 -04:00
Claude 3ffa259cff fix: resolve LocalCache override, dropdown deprecation, and shadowed extension warnings
- Rename LocalCache Dao overrides to match supertype parameter names
  (getOrCreateUser: pubkey->hex, getOrCreateNote: idHex->hex,
  getOrCreateAddressableNote: key->address) so named-argument calls stay safe.
- Replace deprecated MenuAnchorType with ExposedDropdownMenuAnchorType in the
  Buzz dropdown composables.
- Remove the buzzChannelType() extension in BuzzChannelMetadata, now shadowed by
  the equivalent (stricter) member on GroupMetadataEvent, and drop its unused
  imports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VBP6HGj9M2kzA4WKAivjC
2026-07-28 15:37:01 +00:00
Vitor Pamplona 775c76621a v1.13.0 v1.13.0 2026-07-28 10:52:38 -04:00
Vitor Pamplona 9497510733 Merge branch 'main' of https://github.com/vitorpamplona/amethyst 2026-07-28 10:46:18 -04:00
Vitor Pamplona 5424a62f93 Fixes the order of settings 2026-07-28 10:41:49 -04:00
David KasparandGitHub 2cbf57fe79 Merge pull request #3761 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-07-28 16:41:30 +02:00
vitorpamplonaandgithub-actions[bot] b8a9c0242c chore: sync Crowdin translations and seed translator npub placeholders 2026-07-28 14:38:25 +00:00
Vitor PamplonaandGitHub 414d3fdda0 Merge pull request #3762 from vitorpamplona/claude/bottom-nav-settings-move-fsytta
Reorganize settings catalog: move UI settings to dedicated section
2026-07-28 10:35:31 -04:00
Claude a0202618c1 refactor: move per-account setting entries into Account Settings
Move the bottom navigation bar entry out of App Settings and into the
Account Settings section of the All Settings catalog, since its state is
stored per account (AccountNavigationPreferencesInternal.bottomBarItems in
the account-synced settings blob).

While auditing the App Settings section for other per-account entries, two
more were purely per-account and moved alongside it:

- Reactions settings (reaction row actions) writes account-synced
  reactionRowItems and now sits next to the existing "Reactions" entry.
- Messages settings writes account-scoped chat feed toggles and view modes
  (account.settings.enabledChatFeeds / relayGroupViewMode / concordViewMode).

The remaining App Settings entries stay put: UI preferences, Home tabs,
Profile UI, Calendar reminder, OTS, Namecoin and Resource usage are all
device-global, and Compose/Notification settings are mixed (they hold
genuine app-global preferences alongside a few per-account toggles).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SH88gCbbdTfdzp9wrr7buJ
2026-07-28 14:19:19 +00:00
Vitor PamplonaandGitHub 26a6cd37fb Merge pull request #3759 from davotoula/fix/playback-error-overlay-starves-browser-button
Keep the "open in browser" button alive in a short error box
2026-07-28 09:12:59 -04:00
David KasparandGitHub 93fd107ecf Merge pull request #3760 from davotoula/fix/workout-combined-sessions-plurals
Make the combined-sessions count a plurals resource
2026-07-28 10:33:11 +02:00
davotoula 416ac20f30 fix(workouts): make the combined-sessions count a plurals resource 2026-07-28 10:28:48 +02:00
David KasparandGitHub 58c88797f1 Merge pull request #3758 from vitorpamplona/l10n_crowdin_translations
New Crowdin Translations
2026-07-28 10:26:17 +02:00
davotoulaandgithub-actions[bot] e149f935e1 chore: sync Crowdin translations and seed translator npub placeholders 2026-07-28 08:08:23 +00:00
davotoula c89382f767 update cs,sv,de,pt 2026-07-28 09:54:50 +02:00
davotoula 0b1c4894a0 Code review:
- scale the icon threshold so it can't slice the title
- make the button's survival structural, not threshold-tuned
2026-07-28 09:47:11 +02:00
davotoula 86d0434628 fix(video): keep the "open in browser" button alive in a short error box 2026-07-28 09:46:45 +02:00
Vitor PamplonaandGitHub 011d5f2fa5 Merge pull request #3757 from vitorpamplona/claude/nip84-highlight-marker
feat(highlights): render NIP-84 quotes with a highlighter-pen marker
2026-07-27 22:48:01 -04:00