Skip to content

Add conversation visibility toggle (Private/Shared)#5268

Merged
beastoin merged 1 commit intoBasedHardware:mainfrom
dmfilipenko:feat/conversation-visibility-toggle
Mar 2, 2026
Merged

Add conversation visibility toggle (Private/Shared)#5268
beastoin merged 1 commit intoBasedHardware:mainfrom
dmfilipenko:feat/conversation-visibility-toggle

Conversation

@dmfilipenko
Copy link
Contributor

@dmfilipenko dmfilipenko commented Mar 1, 2026

Problem

When a user shares a conversation (making it public via the share button), there is no way to make it private again from the app. The backend already supports PATCH /v1/conversations/{id}/visibility, but the app never exposes a "make private" action.

Screenshot 2026-03-01 at 21 47 37 Screenshot 2026-03-01 at 21 46 26

Solution

Add a visibility chip to the conversation detail page that toggles between Private and Shared:

  • Private (lock icon, grey) — only you can see the conversation
  • Shared (globe icon, green) — anyone with the link can view

Tapping the chip opens a bottom sheet (matching the existing folder chip pattern) where the user can switch visibility. When switching to Shared for the first time, the native share sheet opens automatically.

Screenshots

Screenshots will be added in a comment below.

Changes

  • conversation.dart — Add ConversationVisibility enum with private_/shared values
  • conversation_detail_provider.dart — Add updateVisibilityLocally() for optimistic updates
  • widgets.dart — Add visibility chip + bottom sheet UI
  • page.dart — Sync app bar share button with visibility state
  • mixpanel.dart — Add conversationVisibilityChanged analytics event
  • l10n/ — Add translations for all 34 locales

Test plan

  • All existing tests pass
  • Open a conversation → verify "Private" chip appears (lock icon, grey)
  • Tap chip → bottom sheet opens with Private/Shared options
  • Select Shared → chip updates to green, share sheet opens
  • Select Private → chip updates back to grey
  • Tapping already-selected option just closes the sheet
  • Share button in app bar also updates the chip

🤖 Generated with Claude Code

@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch 2 times, most recently from 38825b6 to e4890c9 Compare March 1, 2026 21:00
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0592dfc5b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch from e4890c9 to 44f097a Compare March 1, 2026 21:00
@dmfilipenko
Copy link
Contributor Author

@codex review

@greptile-apps
Copy link

greptile-apps bot commented Mar 1, 2026

Greptile Summary

This PR adds a visibility toggle feature that allows users to switch conversations between Private (only visible to the user) and Shared (publicly accessible via link). The implementation includes a new ConversationVisibility enum, a chip UI component, and a bottom sheet for toggling visibility.

Key changes:

  • Schema: Added ConversationVisibility enum and visibility field to ServerConversation
  • UI: Added visibility chip with lock/globe icons and bottom sheet for toggling
  • State management: Implemented optimistic updates with rollback on API failure
  • Integration: Share button now updates visibility to Shared when used
  • Localization: Added translations for 34 locales (3 new keys)
  • Analytics: Added conversationVisibilityChanged event tracking

Critical issue found:
The analytics tracking in widgets.dart has a bug where events fire even when API calls fail and visibility is reverted (lines 335-347 and 362-376). The return statement should come before the analytics call, not after the revert.

Confidence Score: 3/5

  • This PR is mostly safe to merge but has a critical analytics bug that should be fixed first
  • Score reflects solid core implementation (schema, state management, UI) but critical analytics bugs where events fire even when API calls fail. The visibility toggling logic itself works correctly with proper optimistic updates and rollbacks, but the analytics tracking is misleading.
  • Pay close attention to app/lib/pages/conversation_detail/widgets.dart - the analytics calls on lines 335-347 and 362-376 need to be moved after the error handling

Important Files Changed

Filename Overview
app/lib/backend/schema/conversation.dart Added ConversationVisibility enum and visibility field to ServerConversation - clean schema change with backward compatibility
app/lib/pages/conversation_detail/conversation_detail_provider.dart Added updateVisibilityLocally() method for optimistic updates - simple and correct
app/lib/pages/conversation_detail/widgets.dart Added visibility chip and bottom sheet UI - has critical analytics bugs where events fire even when API calls fail
app/lib/pages/conversation_detail/page.dart Syncs share button with visibility chip - correctly updates visibility only after successful API call
app/lib/utils/analytics/mixpanel.dart Added conversationVisibilityChanged analytics event - clean implementation

Last reviewed commit: 579df70

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

74 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 579df7073c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

nice, pls mention me (beastoin) when the pr is ready

@dmfilipenko
Copy link
Contributor Author

@beastoin is ready, not sure about this regenerated language files

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

@dmfilipenko Your editor reformatted all 34 ARB files from 4-space to 2-space indent, blowing the diff to ~98K lines for what's actually ~102 lines of changes. Run this to fix: for f in app/lib/l10n/*.arb; do jq --indent 4 '.' "$f" > tmp && mv tmp "$f"; done

We also added a pre-commit guard in #5273 so this won't happen again.


by AI for @beastoin

@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch 2 times, most recently from f895a79 to d54be6d Compare March 2, 2026 09:04
@dmfilipenko
Copy link
Contributor Author

@beastoin All 3 items from your review are fixed:

1. ARB indentation — Restored all 34 ARB files to 4-space indent using jq --indent 4. Diff is now clean. (commit 9c2d197)

2. Duplicate URL params — Removed redundant &visibility=$visibility from conversations.dart:241. Now sends only ?value=$visibility matching the backend's value query param. (commit 58f1c71)

3. Rollback logic — Changed from hardcoded opposite state to captured previousVisibility enum. Both private and shared handlers now store final previousVisibility = conversation.visibility; before the optimistic update and restore it on failure with provider.updateVisibilityLocally(previousVisibility);. (commit f895a79)

4. Share flows — Verified both page.dart and share_to_contacts_sheet.dart already call setConversationVisibility() API before updating local state. The API call happens first, failure returns early without touching local state, and updateVisibilityLocally() only runs on success. No changes needed here.

Branch is rebased on latest main and force-pushed.

@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch 2 times, most recently from 5459541 to 914946c Compare March 2, 2026 09:10
@dmfilipenko
Copy link
Contributor Author

Extracted shareConversationLink into share.dart as a shared utility. Both page.dart (app bar share button) and widgets.dart (visibility chip share flow) now reuse the same function instead of duplicating the share link + render box positioning logic.

@dmfilipenko
Copy link
Contributor Author

@codex review

@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch 2 times, most recently from 084bb02 to e3fd9d3 Compare March 2, 2026 09:13
});
return;
}
String content = 'https://h.omi.me/memories/${provider.conversation.id}';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beastoin is it an old link for sharing? I guess now it's /conversation>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Redirect: /memories/:path* → /conversations/:path* (permanent 301)
    It's safe

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 914946c5a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Allow users to toggle conversation visibility between Private and Shared
from the conversation detail page. Adds a visibility chip that opens a
bottom sheet for switching states, with optimistic UI updates and rollback
on API failure. Share flows sync visibility state across all entry points.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dmfilipenko dmfilipenko force-pushed the feat/conversation-visibility-toggle branch 2 times, most recently from 4f55618 to 94fef30 Compare March 2, 2026 09:19
@dmfilipenko
Copy link
Contributor Author

@beastoin all comments in review fixed

@dmfilipenko
Copy link
Contributor Author

#5268 (comment) This is not relevant to my changes.

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

no worries, this is the end-to-end test of my agents so we can cover all the feature changes. since the set-private visibility affected the shared feature via web.

to keep our prod high quality.

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

Test results:

  • PATCH visibility private→shared — pass
  • PATCH visibility shared→private — pass
  • PATCH idempotent (same value) — pass
  • PATCH invalid conversation ID — pass (404)
  • PATCH invalid visibility value — pass (422)
  • Web share page (shared) — pass
  • Web share page (private) — pass (404, no content leaked)

Shared — renders title, date, tabs:

shared

Private — blank 404:

private

One bug: widgets.dart:334,362 — if the PATCH fails, rollback hardcodes the opposite state instead of restoring previousVisibility. Would break if a third value is added (backend already accepts public). Small fix: use ConversationVisibility.fromString(previousVisibility) instead.


by AI for @beastoin

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

@dmfilipenko Opened #5276 for a few follow-up improvements (API persistence in share flows, error feedback, loading state). No rush — happy to have you pick it up after this PR lands if you're interested.


by AI for @beastoin

@dmfilipenko
Copy link
Contributor Author

dmfilipenko commented Mar 2, 2026 via email

@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

@dmfilipenko Reviewed the updated commit — rollback logic and duplicate URL param both fixed, ARB indent cleaned up. Looks good to merge.

@beastoin ready for your final call.


by AI for @beastoin

Copy link
Collaborator

@beastoin beastoin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@beastoin beastoin merged commit 720d8a8 into BasedHardware:main Mar 2, 2026
@beastoin
Copy link
Collaborator

beastoin commented Mar 2, 2026

thanks, @dmfilipenko

@dmfilipenko dmfilipenko deleted the feat/conversation-visibility-toggle branch March 2, 2026 12:02
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.

2 participants