Skip to content

feat(sharing): choose what a view's links unfurl into - #82

Merged
fullynocturnal merged 3 commits into
mainfrom
feat/sharing-link-previews
Sep 19, 2026
Merged

fullynocturnal merged 3 commits into
mainfrom
feat/sharing-link-previews

Conversation

@fullynocturnal

Copy link
Copy Markdown
Collaborator

Stacked on #78, which adds the share view screen this builds on. Merge that first; this PR's diff is against it. It is independent of #79.

The app side of per-view link previews (backend sheaf-project/sheaf#295). Each share view now chooses what a pasted link unfurls into:

Setting Rich card shows
Show the system in link previews the system's name, avatar and a snippet of its description, on the public profile link
Show members in link previews one member's name and avatar, on that member's permalink

They are independent, because naming the system and naming one member are different disclosures. Both default to the generic card, and both live in a new Link previews section on a view.

Same doors as the flags

Turning a card on is an exposure, so it goes through what the six flags already do: re-auth when the view is shared and the safety category is armed, a server bounce reopening the sheet if the local check drifts, and staging under the same flags_activate_at when there is a grace period. The existing "share view showing more" pending exposure already covers a staged card, so nothing new was needed there.

Turning a card off is immediate. It also stays available when what it would need to turn back on is gone (publishing switched off, permalinks off), so going dark is never blocked. That is one deliberate difference from web, which disables the member switch outright once permalinks are off.

Saying why a card is still generic

The server reports what each URL really unfurls as (link_preview_effective, member_link_preview_effective). When a card is on but the link still previews generically, a note under the switch names the cause:

  • the raise is still waiting out the grace period;
  • member permalinks are off (member card only);
  • otherwise the view is only reachable by share link, whose address is the secret and never gets a rich card.

A staged raise counts as on for the note. The live mode stays generic while a raise waits, so a note keyed on the live mode alone would hide in exactly the case it is for.

Checked

  • Unit tests for every branch of the note, including the staged case and the ordering between staged and permalinks-off, and for parsing: a staged raise with its live, pending and effective values, and an older instance that sends none of the new fields reading as generic.
  • Full unit suite and assembleOpenDebug on this branch.

The backend now lets each share view decide what a pasted link previews as:
the generic card, or one naming the system (name, avatar and a snippet of the
description). A second, independent setting does the same for member
permalinks, with only that member's name and avatar. They are separate
because naming a system and naming one member are different disclosures.

Both sit in a new Link previews section on a view. Turning one on is an
exposure like the six flags: it asks for re-auth when the view is shared and
the safety category is armed, and a grace period stages it under the same
flags_activate_at. Turning one off is immediate, and stays available even
when what it would need to turn back on (publishing, permalinks) is gone, so
going dark is never blocked.

**Saying why a card is still generic.** The server reports what each URL
really unfurls as. When a card is switched on but the link still previews
generically, a note under the switch names the cause: the raise is waiting
out the grace period, member permalinks are off, or the view is only
reachable by share link, whose address is the secret and never gets a rich
card. A staged raise counts as on for the note, because the live mode stays
generic while it waits and a note keyed on the live mode would hide in the
one case it exists for.

The new fields default to generic, so an instance without the feature still
parses.
Base automatically changed from feat/sharing-owner-controls to main September 19, 2026 04:55
@fullynocturnal
fullynocturnal merged commit 9647dbe into main Sep 19, 2026
1 check passed
@fullynocturnal
fullynocturnal deleted the feat/sharing-link-previews branch September 19, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant