Commit Graph

2339 Commits

Author SHA1 Message Date
mkfain 9fd585ebdd Moderator-curated featured organizations
Replace the hardcoded FEATURED_ORGANIZATION_AUTHORS allowlist with the
same NIP-32 label flow that curates featured campaigns: Team Soapbox
pack members publish kind 1985 labels in the agora.moderation namespace
tagging an organization's 34550:<pubkey>:<d> coordinate as featured,
hidden, or approved, and useFeaturedOrganizations folds those labels
into the /communities Featured shelf.

The campaign and organization label streams share a single namespace
and a single moderator pack — they're separated purely by which kind
prefix the 'a' tag carries. To keep that contract enforced in one
place, the constants, types, and folding logic are now in
src/lib/agoraModeration.ts; useCampaignModeration and the new
useOrganizationModeration both call foldModerationLabels with their
respective kind. The campaign hook's external surface
(AGORA_MODERATION_NAMESPACE, ModerationLabel, CampaignModerationData)
is preserved via re-exports so existing call sites don't move.

Moderators see a CommunityModerationMenu kebab overlaid on every
CommunityMiniCard exposing approve/unapprove, hide/unhide, and
feature/unfeature. Mounting reads moderation state once per page from
the shared TanStack cache, mirroring CampaignCard. Non-moderators see
no overlay (the menu returns null) and no card affordances change.

The 'My organizations' shelf intentionally ignores moderation — a
user's own founded, moderated, or followed organizations always render
regardless of label state. Only the Featured shelf consumes the
curation rollup.

The Featured grid is uncapped: moderators control how many orgs
surface by labeling, and ordering follows the recency of each
'featured' label so re-publishing bumps an org to the top.

NIP.md's 'Campaign Moderation Labels' section is renamed to 'Agora
Moderation Labels' and documents the kind-34550 coord form and the
'My organizations ignores moderation' rule.

Note: existing surfaced organizations will disappear from the shelf
until a moderator publishes featured labels for them.
2026-05-21 21:12:33 -05:00
mkfain c2fee23582 Let founders delete their organization
Add a 'Delete organization' item to the banner-overlay dropdown on the
community detail page, gated by the existing isFounder check. Clicking
it opens an AlertDialog that publishes a NIP-09 (kind 5) deletion
request referencing the community definition by both 'e' and 'a' tags
via the shared useDeleteEvent hook.

On success we invalidate every org-related query key the hook doesn't
touch — addr-event for this community, community-definition,
manageable-organizations, featured-organizations, and the
followed-organizations sub-queries — then navigate back to
/communities so the user lands on a list that already reflects the
deletion. Errors surface as a destructive toast.

The confirmation copy is explicit about NIP-09's advisory nature
(well-behaved relays will honor it; campaigns and pledges published
under the organization stay on-chain) and points users toward 'Edit
organization' as the non-destructive alternative.
2026-05-21 20:57:14 -05:00
mkfain 0a7388ac2f Replace organizations horizontal scroll with responsive grid
The /communities page previously rendered both 'My organizations' and
'Featured organizations' as horizontally-scrolling shelves of 256px
cards, which hid most content off-screen and made it tedious to browse.

Now both shelves use a new responsive CommunityGrid (1/2/3/4 columns by
breakpoint) inside the existing max-w-5xl content column. Card visuals
stay identical at the desktop breakpoint (~232-256px wide); the only
difference is that cards now wrap onto subsequent rows.

'My organizations' starts collapsed at the first 4 entries with a
'Show N more' / 'Show less' toggle, replacing the prior 18-card cap so
power users can see everything in one place when they want to.
Featured stays a full grid (the curated list is intentionally short)
and its loading skeleton count is bumped from 4 to 8 to fill two rows.
2026-05-21 20:52:12 -05:00
mkfain fed1bb9ce0 Render kind 33863 campaigns as rich cards in the activity feed
Campaign-launch events (kind 33863) previously fell through to the
generic text-note path in NoteCard, rendering as just the author row
plus the campaign's raw markdown story. No banner, no title, no
progress, no donor count, no goal, no deadline, no link to the
campaign page.

Wire campaigns through the same polished CampaignCard component the
campaign directory already uses:

- New CampaignNoteCardContent component — thin wrapper that parses the
  event and renders a CampaignCard. Malformed events silently drop.
- NoteCard: add isCampaign flag, exclude from isTextNote, add the
  dispatch branch, and import HandHeart for the action header.
- KIND_HEADER_MAP: 33863 entry gives 'Alice launched a campaign'
  header above the rich card (uses publishedAtAction so edits read
  'updated a' instead of 'launched a'). nounRoute points at
  /campaigns/all so the bold 'campaign' word is clickable.
- CommentContext: register 33863 in KIND_LABELS ('a campaign'),
  KIND_SUFFIXES ('campaign'), and KIND_ICONS (HandHeart) so comments
  on campaigns render with proper context labels instead of falling
  back to 'an unsupported event'.

The whole feed card now links to the campaign's naddr-based detail
route via CampaignCard's existing <Link> wrapper.

Embedded quote-preview rendering for kind 33863 and notification-stack
integration are deferred — out of scope for the activity-feed card.
2026-05-21 20:36:04 -05:00
mkfain b864a73573 Rename TopNav 'Feed' to 'Activity' 2026-05-21 20:26:01 -05:00
mkfain 4188e926a4 Post to any country, white Post button text
The post-to-country picker previously only listed countries the user
followed, so a user following VE couldn't post about Iran without
following Iran first. Two changes fix this:

- New "Choose another country…" item at the bottom of the destination
  dropdown opens a searchable CommandDialog over the full COUNTRY_LIST.
  Search matches both name and ISO code ("iran" and "IR" both work).
- The dropdown's quick-pick list now also includes any ad-hoc country
  the user has selected via the picker, even if not in their follow
  list, so they have a one-tap way back to it.
- canChooseDestination no longer requires followedCountries.length > 0;
  any logged-in user composing a top-level kind 1 can now pick a country.
- Snap-back guard now only fires when the selected code is invalid
  (deleted from the country directory), not just because it isn't in
  the follow list.

Also: the orange Post! / Publish poll button text is now forced white
via a className override. Previously it relied on the theme's
--primary-foreground token which was producing low-contrast text on
the orange background.
2026-05-21 20:26:01 -05:00
mkfain f4688137bc Persistent default country, drop weather + organize feed, simplify mode switcher
Five small UX improvements bundled together.

Default post-to-country with localStorage persistence
- New `useDefaultPostCountry` hook (localStorage-backed) hydrates the
  composer's destination from a saved preference on every fresh compose.
- ComposeBox's country-destination picker (formerly a shadcn Select)
  becomes a DropdownMenu so it can mix country options with an action
  item.
- New "Set as default" item appears at the bottom of the dropdown
  when the current selection is not already the saved default; clicking
  it persists the choice and shows a toast.
- A passive "Country X is your default" label replaces the action
  item when the current selection already is the default.
- resetComposeState now resets to the saved default instead of
  hardcoded 'world', so the next compose lands where the user expects.
- The existing snap-back-to-world guard now also clears the saved
  default if it points at a country the user has just unfollowed.

Remove weather from country feed pages
- Drop `WeatherVitalsRow`'s weather panel — the row keeps the
  population / languages / currency vitals but no longer renders
  temperature, sky description, or icon.
- Remove the live day/night sky-overlay flip on the country hero;
  default to the warm daytime gradient.
- Remove the `PrecipitationEffect` overlay (animated rain/snow) from
  country pages.
- Delete the now-orphan `useWeather` hook and
  `PrecipitationEffect` component.

Remove organization activity feed from /communities
- Drop the `OrganizationActivityFeed` section and its helpers.
- /communities is now a directory page: hero + My organizations shelf
  + Featured organizations shelf.
- Delete the now-orphan `useOrganizationHomeActivityFeed` and
  `useOrganizationMembersOnlyFilter` hooks.

Compact FeedModeSwitcher
- Strip the per-item descriptions ("Campaigns, pledges, donations,
  and Agora posts", etc.) from the home-feed mode dropdown.
- Each menu item is now a single line: icon + label + optional check.
- Shrink menu width from w-72 to w-56 to match the new content density.
- Keep the disabled-Following tooltip — that's a state explanation,
  not help text.
2026-05-21 20:26:01 -05:00
mkfain 7ee35644e3 Strict t:agora tagging for all Agora-created content
The Agora activity feed now filters strictly to Agora-created content via
the relay-indexed single-letter `t:agora` tag. Multi-letter tags like
NIP-89 `client` are not indexed by relays and cannot serve this purpose.

Every event Agora publishes that represents first-class Agora content
now carries `["t", "agora"]`, added via a new `withAgoraTag` helper
in `src/lib/agoraNoteTags.ts` that dedupes against any user-supplied
`t:agora` tag.

Tagged at publish time:
- Communities (kind 34550) — CreateCommunityPage
- Campaigns (kind 30223) — CreateCampaignPage, useArchiveCampaign
- Pledges (kind 36639) — CreateActionPage (alongside agora-action)
- Calendar events (kinds 31922 / 31923) — CreateEventPage and
  CreateCommunityEventDialog
- Onchain zaps (kind 8333) — useOnchainZap, useDonateCampaign,
  SendBitcoinDialog
- Zap goals (kind 9041) — CreateGoalDialog
- NIP-22 comments (kind 1111) — usePostComment, covering every comment
  authored from within the app regardless of root kind
- Kind 1 notes — already covered by ComposeBox default tags

Intentionally not tagged: reactions, reposts, follows, profile metadata,
lists, settings, badges, vanish requests, encrypted DMs, live chat.

useAgoraFeed tightened:
- Entity kinds and Agora-comment kinds now require `#t=agora` at the
  relay layer (server-side filter).
- World layer (kind 1111 / 1068 with `#k=iso3166|geo`) remains
  unfiltered — intentionally cross-client.
- `#Agora`-tagged kind 1 notes still surface from any author (preserves
  viral / opt-in discovery via user-typed hashtags).
- Donation enrichment now requires the Agora marker on zap receipts.
- `isRelevantAgoraEvent` rewritten as a strict checker that demands
  the marker for everything outside the world layer.

Legacy content without the marker disappears from the feed. It remains
reachable by direct link and via kind-specific directories (e.g.
`/campaigns/all`). Authors who edit a legacy event through the Agora UI
will automatically add the marker via the helper.

NIP.md updated with a new "Agora Content Marker" section under "Agora
Protocols" — documents the tagged-kind table, the untagged-kind list,
the canonical query shape, and the backward-compatibility behavior.
2026-05-21 20:25:01 -05:00
mkfain b83d35fc75 Remove flag backdrop behind world posts, keep corner flag pill
The CountryFlagBackdrop rendered a faded full-width Wikipedia flag image
across the top of every country-rooted (kind 1111, iso3166-rooted) post.
It cluttered the feed and competed with post content. Drop it.

The CountryCommentPill in the upper-right of the card header is retained
— it remains the sole country chrome for world posts.

Removed:
- CountryFlagBackdrop component from CommentContext.tsx
- Both NoteCard render sites (threaded + normal layouts)
- The CountryFlagBackdrop import in NoteCard
- Dead imports in CommentContext: useState, getWikipediaTitle,
  customFlagAsset, useFlagPalette, useWikipediaSummary

Updated jsdoc on useIsCountryRooted to reflect that country chrome
is now just the pill, not pill+backdrop.
2026-05-21 20:22:36 -05:00
mkfain f08e3d6226 Add three-mode home feed with Agora / All Nostr / Following
The home /feed page now offers a top-left dropdown to switch between three
chronological streams:

- Agora: campaigns, pledges, donations, communities, comments on Agora
  entities, and #Agora-tagged kind 1 notes (the existing useAgoraFeed mix,
  widened for NIP-72 communities).
- All Nostr: the global kind 1 stream interleaved with the full Agora mix.
- Following: same content scoped to authors in the logged-in user's
  follow list (gracefully gated when the follow list is loading or empty).

Implementation:

- useMixedFeed orchestrates the three modes, paginating the Agora and
  kind 1 layers in lockstep and merging chronologically.
- useAgoraFeed now accepts an optional authors filter (server-side) so
  Following mode doesn't fetch and discard the global Agora mix. It also
  includes new community definitions (34550) and community-scoped
  comments (1111 with A=34550:...).
- FeedModeSwitcher is the new top-left picker: large text2xl trigger,
  shadcn DropdownMenu with iconified options and active checkmark.
  Following is disabled (with tooltip) for logged-out users.
- AGORA_DEFAULT_NOTE_TAGS moved to src/lib/agoraNoteTags.ts; ComposeBox
  now auto-attaches t:agora to every top-level kind 1 from anywhere in
  the app (replies, quotes-as-replies, polls, and comments are unaffected).
- Feed mode persistence upgraded from sessionStorage to localStorage so
  preference sticks across sessions.
- Feed entry added to TopNav as the first item.

The globe backdrop, hue rotation, and translucent card treatment are
removed for a cleaner solid-background presentation. Specialized
feed pages (kind-specific, tag-filtered) keep the original Follows /
Global tab pair unchanged.
2026-05-21 20:22:36 -05:00
Chad Curtis d1c53df4d4 Style campaign donate CTAs with white text and white QR logo 2026-05-21 19:27:57 -05:00
Chad Curtis 6693f2c153 Render wallet QR in donate dialog when signer can't sign PSBTs 2026-05-21 19:16:50 -05:00
Chad Curtis 8436c7b787 Drop campaign title from SP donation disclaimer
The parenthetical '(<campaign title>)' after 'organizer' was awkward
and redundant -- the donor already knows which campaign they're on.
Strip it and remove the now-unused `campaignTitle` prop from
CampaignWalletDonatePanel.
2026-05-21 19:04:41 -05:00
Chad Curtis 935c121bab Implement Campaign kind 33863
Replaces every kind 30223 surface with kind 33863 -- the self-authored
fundraising campaign with a single `w` Bitcoin wallet endpoint. Hard
cutoff: no migration, no dual-read, no legacy support.

Schema (src/lib/campaign.ts):
- `CAMPAIGN_KIND` constant bumped 30223 -> 33863.
- New `CampaignWallet` type with `onchain` (`bc1q`/`bc1p`) and `sp`
  (`sp1`) modes, prefix-disambiguated. Bitcoin-mainnet only;
  testnet/regtest/lightning prefixes are rejected at parse time.
- New `parseCampaignWallet()` validates bech32 via bitcoinjs-lib for
  on-chain addresses and shape-checks silent-payment codes.
- `ParsedCampaign` drops `recipients`, `category`, `tags`,
  `location`, `archived`, `image` (-> `banner`), `goalSats` (->
  `goalUsd`). Adds `wallet` and `bannerImeta` (parsed NIP-92).
- `CAMPAIGN_CATEGORIES`, `CampaignCategory`,
  `LEGACY_CAMPAIGN_CATEGORY_ALIASES`, `getCampaignPrimaryTagLabel`,
  `splitDonation`, `minDonationForSplit`, `DonationSplit`,
  `CampaignRecipient` removed.

Publishing (useDonateCampaign):
- Single-output PSBT paying `campaign.wallet.value`.
- Kind 8333 receipt has NO `p` tags -- campaigns are not Nostr-identity
  recipients. `i`, `amount`, `a`, `K`, `alt` only.
- SP campaigns are refused with a clear error directing donors to
  external BIP-352-capable wallets via the on-page QR/copy panel.

Verification (useOnchainZaps.verifyOnchainZap):
- Two modes: identity-recipient (existing `p`-tag derivation) and
  campaign-wallet (match outputs against `campaign.w`). The branch is
  selected by whether the receipt has an `a` tag pointing at a kind
  33863 campaign. SP-targeted receipts are rejected.

Querying (useCampaigns, useAllCampaigns, useCampaignDonations):
- Drop `category`, `recipientPubkeys`, `includeArchived` options.
- `useCampaignDonations` now takes a `ParsedCampaign` and verifies
  every receipt on-chain against the campaign's `w` address before
  counting it. SP campaigns short-circuit to zeros.
- Search drops `location` and `t`-tag branches; title/summary/story
  only.

UI:
- `CampaignCard`, `HeroCampaignSpotlight`, `CampaignsPage`: drop
  recipient counts, archived/category badges, `location`; use
  `banner`. Silent-payment campaigns render a "Private -- totals not
  public" notice instead of progress.
- `CampaignDetailPage`: archive flow replaced with NIP-09 kind 5
  deletion. Drops the multi-beneficiary recipient column. Donate column
  shows the in-app PSBT donate button (on-chain) plus the always-
  available external-wallet QR/copy panel. SP campaigns show the panel
  only -- no in-app donate.
- `CreateCampaignPage`: drops Beneficiaries section, tag input, and
  USD-to-sats conversion. Adds a Wallet field with mode-aware
  validation hint. Goal is integer USD. Banner upload captures NIP-94
  tags and converts to NIP-92 `imeta` at publish.
- `DonateDialog`: collapses ~1200 LOC of split logic into a single-
  output flow. Form -> Confirm -> Success. Logged-out and signer-
  unsupported users are pointed at the external-wallet panel.
- New `CampaignWalletDonatePanel` component (replaces the
  pubkey-derived `BeneficiaryDonateDialog`). QR + copy + open-in-wallet
  for any `bc1`/`sp1` endpoint, with mode-appropriate privacy notice.

Removed:
- `useArchiveCampaign` hook (closure via NIP-09 deletion only).
- `ClaimPage` and its `/claim` route (claim-for-someone-else flow no
  longer applies -- campaigns are self-authored).
- `BeneficiaryDonateDialog.tsx` (replaced by
  `CampaignWalletDonatePanel.tsx`).
- Community-donate synthesis hack in `CommunityDetailPage` (no more
  fabricating a `ParsedCampaign` from community moderators).

NIP.md was updated separately to specify Kind 33863.
2026-05-21 19:04:41 -05:00
Alex Gleason b6f90a03c4 Merge branch 'main' of gitlab.com:soapbox-pub/agora 2026-05-21 17:46:47 -05:00
Chad Curtis 51d50e3b33 Remove "React" label from reaction button 2026-05-21 17:40:10 -05:00
Alex Gleason b53cb20d61 Replace Discover with Support nav link
Remove the Discover page and route entirely. In the top nav, swap the
Discover entry for a Support link pointing at /campaigns/all (the all
campaigns directory).

Also drops the now-orphaned DiscoverHero component and useDiscoverFeed
hook, and updates the NIP.md campaign moderation note that referenced
the deleted /discover route.
2026-05-21 17:39:15 -05:00
Chad Curtis 2b3a2e7daf Remove NIP-05 username from note card header 2026-05-21 17:38:44 -05:00
Chad Curtis 5c4cf3011e Merge remote-tracking branch 'origin/main' into fundraiser-detail-redesign
# Conflicts:
#	src/pages/CampaignDetailPage.tsx
2026-05-21 17:34:33 -05:00
Chad Curtis 81f1fd5d1f Use foreground token in soft Bitcoin disclaimer for light-mode contrast 2026-05-21 16:39:14 -05:00
lemon 48744aa13d Refine calendar event details 2026-05-21 14:08:11 -07:00
lemon b7d33577f1 Restore event RSVP detail card 2026-05-21 14:08:11 -07:00
lemon ffb9c93ee6 Add pins across detail comments 2026-05-21 14:08:11 -07:00
lemon 97ec528b50 Normalize organization activity cards 2026-05-21 14:08:11 -07:00
lemon 4dd913d3ca Redesign calendar event details 2026-05-21 14:08:11 -07:00
lemon e41e8396d7 Align detail comment widths 2026-05-21 14:08:11 -07:00
lemon 62517cc062 Join detail hero action bars 2026-05-21 14:08:11 -07:00
lemon b32ae751a2 Use megaphone for boost action 2026-05-21 14:08:11 -07:00
lemon 0f85584294 Reuse detail comment composer 2026-05-21 14:08:11 -07:00
lemon 1a53f3047d Add campaign activity composer 2026-05-21 14:08:11 -07:00
lemon 48794fa3b4 Pin campaign activity updates 2026-05-21 14:08:11 -07:00
Chad Curtis fe1061f81b Redesign beneficiary donate panel; align content edges; full-bleed at lg 2026-05-21 15:31:04 -05:00
Chad Curtis 421d4f366e Tighter campaign hero on desktop; align back button to content width; drop boxes 2026-05-21 15:09:48 -05:00
Chad Curtis 5920523b57 Flatten Home Feed settings; merge mutes inline; drop jargon
Reduce cognitive load on the Content settings page by collapsing the
two-section toggle layout, group sub-headers, sub-kind rows, kind
badges, and column headers into a single flat list of 14 toggles
ordered by importance: Posts, Replies, Reposts, Articles, Highlights,
Photos, Videos, Voice Messages, Events, Polls, Organizations, Badges,
Reactions, Zaps.

Each row is now a plain label + one-line description + switch. No
content-kind icons, no [1234] kind-number badges, no Media / Social /
Whimsy sub-headers, no Normal/Short video or Badge Definitions /
Profile Badges / Badge Awards sub-rows (the parent toggle now governs
all sub-kinds together).

Combine kind 6 (Reposted Notes) and kind 16 (Reposted Other Content)
into a single "Reposts" toggle via extraFeedKinds: [16]. The old
feedIncludeGenericReposts flag stays in the schema for backwards
compat but no longer surfaces in UI.

Rename "Comments" -> "Replies" — Nostr's NIP-22 threading is most
naturally called replies.

Strip NIP / kind-number references from all curated descriptions
(NIP-22, NIP-52, NIP-58, NIP-68, NIP-71, NIP-72, NIP-84, NIP-A0,
"kind 30009", etc.). Plain English only.

Merge the standalone /settings/content page (mutes + sensitive
content) into /settings/feed as inline sections under the toggle
list, since both are about "what you see in the feed." Delete
ContentPage.tsx and its route; remove the Content entry from the
settings index. Drop the giant ShieldAlert icon from the sensitive
content intro.

Rename "Home Feed Tabs" -> "Saved Feeds" in the page section heading.
2026-05-21 13:48:19 -05:00
Chad Curtis 4aa358d685 Limit content-type toggles in settings to Agora-curated kinds
The settings UI iterates EXTRA_KINDS and renders a toggle row per kind,
which exposed every Nostr content type the app understands (vines,
treasures, colors, decks, webxdc, birdstar, emoji packs, music,
podcasts, development, etc.) regardless of whether they fit Agora's
activist-utopian framing. The result was a wall of toggles with no
meaningful default.

Add an `agora` boolean to ExtraKindDef and mark only the curated set:
posts, comments, reposts, generic-reposts, reactions, zaps, articles,
highlights, photos, videos (with sub-toggles), voice messages, events,
polls, organizations (NIP-72 communities), and badges. Filter the
"Basic Home Feed Options" and "Show More Content Types" sections to
`def.agora === true`. Move badges from the "Whimsy" section into
"Social" so the Whimsy and Development groups vanish entirely after
filtering.

Enable zaps in the home feed by default (they're core engagement,
not noise) and drop "Disabled by default" from the zaps description.

Other pages (KindFeedPage deep-links, ExternalContentHeader quoted
events, etc.) still see the full EXTRA_KINDS registry, so external
content from non-curated kinds still renders correctly when linked.
2026-05-21 13:36:20 -05:00
Chad Curtis f811245f90 Make settings utilitarian and disable whimsical content types by default
Remove the spellbook-themed settings index: drop the "Codex of
Configuration" heading, the gradient ornaments with ✦/◆ dividers, the
sigil that appeared after two minutes of inactivity, and the IntroImage
illustration tiles on every section row and sub-page intro block. The
index is now a flat divider-separated list of labels and one-line
descriptions, with breathing room on both sides.

Delete the Magic settings page, its CursorFireEffect overlay, the
animate-sigil-glow / animate-pulse-slow keyframes, the magicMouse
AppConfig flag (schema, default, test fixture), and the /settings/magic
route. Delete the now-unreferenced IntroImage component and the ten
*-intro.png assets it masked.

Disable content types that don't fit an activist tool by default: vines,
treasures (geocaches + found logs), colors, decks, webxdc, birdstar
(detections / birdex / constellations), emoji packs, custom emojis, user
statuses, music, podcasts, and development. They remain available in
settings — just off out of the box. Highlights is bumped on by default
to pair with Articles. Posts, comments, reposts, articles, highlights,
events, polls, communities, people lists, badges, photos, videos, and
voice messages stay on.
2026-05-21 13:22:57 -05:00
sam a42522dda2 mid light/dark coloured gradient/shadows that thus contrast on light and dark mode 2026-05-21 01:02:56 -07:00
lemon fe43906cf1 Remove mobile FAB bottom-nav offset 2026-05-21 00:47:38 -07:00
lemon 0d1d782437 Refine feed composer and FAB placement 2026-05-21 00:43:25 -07:00
lemon 7f93dcb3af Make home feed Agora-only 2026-05-21 00:38:50 -07:00
lemon 3b9eef908f Tag default notes as Agora 2026-05-21 00:30:37 -07:00
lemon afe2bf1c28 Enlarge feed backdrop globe 2026-05-21 00:17:19 -07:00
lemon ae3daef072 Add Agora feed tab 2026-05-21 00:15:04 -07:00
lemon da6cab8784 Use Agora logo for compose FAB 2026-05-20 23:52:56 -07:00
lemon 2722ee1dcd Restore feed compose FAB 2026-05-20 23:48:26 -07:00
lemon 475843cd27 Add feed content filter layer 2026-05-20 23:37:45 -07:00
lemon fd97b76fbb Make feed surfaces transparent 2026-05-20 23:36:14 -07:00
lemon 587d7eb5ba Extend feed wash across viewport 2026-05-20 23:32:49 -07:00
lemon 5c6b9b3baf Soften feed backdrop transitions 2026-05-20 23:28:17 -07:00
lemon f6947aca9b Refine feed globe backdrop 2026-05-20 23:21:36 -07:00