Files
buzz/desktop
ef2ecaf873 fix(desktop): defer channel visibility change to Save (#5203)
## Problem

In the **Edit channel** dialog, flipping visibility (Public <> Private)
persisted **immediately on selection**, bypassing the **Save changes**
button — while every other field (name, description, temporary, TTL)
waited for an explicit save. This surprised users and gave no chance to
cancel a flip, e.g. a private->public change that instantly exposes
channel history.

Reported in the Buzz "Welcome" channel by Kevin Chung.

## Root cause

The visibility dropdown was wired to `handleConvertVisibility()`, which
called the update mutation on selection. This was intentional at the
time (there was even an e2e test named `02 — visibility updates
immediately` and an "Updating…" spinner), but it is inconsistent with
the rest of the dialog and is the surprising behavior reported.

## Change (defer to Save)

- Visibility becomes a **deferred draft** like the other fields:
selecting a value updates local `isPrivateDraft` and marks the draft
dirty. The change commits via `handleSaveChannelEdits` (which already
handled visibility) on **Save**, and is discarded on **Cancel**.
- The dialog title now reflects the **pending draft**
(`nextVisibility`), so the pending choice is visible before saving.
- The edit-dialog reset restores `isPrivateDraft` from server state.
- Removed the now-dead `handleConvertVisibility` handler,
`isConvertingVisibility` state, the `channelIdRef` race guard it needed,
and the unused `isPending`/"Updating…" spinner path in
`ChannelPermissionsSettings` (no caller passes `isPending` anymore).

## Tests

- Rewrote e2e `02` -> **`visibility defers to Save`**: select -> Save
enabled -> title reflects draft -> Save -> persists; toggling back to
the original value clears the draft and disables Save.
- Extended `09` (cancel discards drafts) to also cover a visibility
change.
- Repurposed `10`: the stale-update race it guarded is architecturally
gone, so it now asserts an **unsaved visibility draft does not leak
across a channel switch**.

## Validation

- `pnpm typecheck` — clean
- `biome check` (changed files) — clean
- `pnpm test` — **4497 passed / 0 failed**
- `playwright test --project=smoke channel-controls` — **10 passed**

Signed-off-by: Kevin Chung <chung@squareup.com>
Co-authored-by: Fizz <e3f95089179cc1bcc68d70c334b9bdf670d0470496db90bcdbb20386963432da@buzz.block.builderlab.xyz>
2026-08-07 17:25:13 +00:00
..
2026-08-03 21:51:17 -04:00

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition