Commit Graph
13 Commits
Author SHA1 Message Date
ZacharyZhang-NYandClaude Opus 5.5 48d02c4903 Messaging · Calls: controls, tiles, a grid, a shared screen, a bar, a ringing dialog, a huddle
CallControls holds the microphone, camera and a shared screen as
toggles, then Leave. ParticipantTile shows a camera's frame from the
host or the person's initials, their name with a mark when muted, and a
ring while they speak. VideoCallGrid lays tiles in even rows as far as
they fit across its measured width; a short last row centers at the
full rows' width. ScreenShareView names who presents and offers Stop
presenting for your own share, the call's tiles beside or below.
VoiceCallBar tells where a call is, how long it has run and who is in
it, with the microphone and Leave. IncomingCallDialog rings with the
caller's picture; Accept or Decline answers each ring once, and Escape
declines. HuddleIndicator rings while a huddle is live; a press joins.

The recorder's device toggle and the camera's name chip now have one
home in media. People: member names sort whatever their case, a
status's words save trimmed, and a profile card's local time ticks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:33:54 -04:00
ZacharyZhang-NYandClaude Opus 5.5 ebad5328ed Files · Items: one icon map, file icon, file row and file grid
The crate had two maps from a file's name to its icon, in chat and in the
file tree, and they disagreed. One map now lives in primitives, over the
Lucide file-* icons, and chat, agent, the file tree and the directory
listing use it. FileIcon draws it for a file or a folder. FileItem is a
file's row, a ListItem with its size and when it changed. FileList is the
directory listing. FileGrid lays tiles in the order given, with a cursor
seeded from the owner's pick: arrows by tile and by row, Home, End, Enter
and a double press to open. The count of what fits a width has one home,
layout's columns_for, and fit builds on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:40:10 -04:00
ZacharyZhang-NYandClaude Opus 5.5 9872adc5e9 Forms: an option list stays inside the window; media ratios are checked in one place
The floating list under a Select, Combobox or MultiSelect was at least its
trigger's width with no ceiling, so a long choice ran it past the window
and its rows never ellipsized. It now stops at the window's width less the
window margin on each side, so gpui snaps it inside. The camera preview
and the model viewer check their ratio through primitives::checked_ratio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:17:52 -04:00
ZacharyZhang-NYandClaude Opus 5.5 7f1cfe8c3d Media · Capture and devices: recorder, camera, mic meter, device choice and 3D model viewer
ScreenRecorderControls holds a recording in one pill: Record, then a live
dot and the time it has run beside pause or resume and stop, with mic and
camera toggles. CameraPreview shows host frames in the camera's shape, or
the camera off. MicLevelMeter lights segments up to the level, amber and
red near the top, with tones shared from data_display. DeviceSelector
picks a microphone, camera or speaker through Select, which may now be
empty while shut. ModelViewer shows the host's frame for an orbit that a
drag, the arrows, Command-scroll, + and - and a reset move; the orbit is
seeded from the host so fast drags add up. The gallery draws a stone
torus per orbit and frees each replaced frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:05:23 -04:00
ZacharyZhang-NYandClaude Opus 5.5 235f059c8e Lists: a selectable list's cursor starts on the owner's pick; the waveform's fit is tested
SelectableList keeps the owner's last selection and the one it last
sent. A selection the owner makes, on first paint or later, moves the
cursor to its first row; the echo of the list's own pick leaves the
cursor where the pick put it. The playlist's keys start from the song
under way. The waveform's bar count and inset move into `fit`, tested
beside `resample`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:44:38 -04:00
ZacharyZhang-NYandClaude Opus 5.5 4b86283d69 Media · Audio and controls: player, waveform, spectrum, volume, speed, transport and playlist
AudioPlayer sets a song's cover, title and artist over a scrubber with
the time played and left, the transport and the volume. AudioWaveform
draws peaks gathered to the bars that fit, dark as far as it has played,
and seeks by press, drag and keys, with the time tip the scrubber shares.
AudioSpectrum shows levels by pitch. VolumeControl mutes from its speaker,
and moving its slider while muted unmutes. PlaybackSpeedControl picks from
a menu. MediaControls holds shuffle, back, play, forward and repeat.
Playlist builds on SelectableList: the song under way is lit with moving
bars, and Enter or a double press plays another.

The video player's bar now rests while the stage itself holds focus, a
key it takes wakes the bar, and a press on a resting bar only wakes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:32:45 -04:00
ZacharyZhang-NYandClaude Opus 5.5 fcb1b2d9df Media: the player's bar fades by elapsed time, so its scrubber and buttons keep their state
The fade restarted an animation id at each rest and wake, and gpui hands
that id to every descendant: the scrubber's drag, hover and focus handle
and the buttons' focus were rebuilt under it. The bar's opacity now reads
the time since the last change through motion::since_change. The stage
tracks focus even without key handlers, so a focused bar button keeps
the bar up. The player's tests move to their own file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:14:06 -04:00
ZacharyZhang-NYandClaude Opus 5.5 fbf99ed4f7 Media: the caption outlasts the bar; one Space per press; narrow boxes hold
Only the bar fades now, so the caption stays while the controls rest, and
the caption chip can shrink, so a long line wraps inside a narrow player.
A focused media button keeps Space to itself, since gpui presses it on
the release. The player and the strip let Command and Control letters
pass. The scrubber's tip splits the free width by the pointer's share and
stays over the track at both ends. An inline edit's label gives way with
an ellipsis beside fixed parts.

The player is a Tab stop only when a key does something, logs its
captions, keys its fade by its own id, and logs a failed wake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:52:27 -04:00
ZacharyZhang-NYandClaude Opus 5.5 d0175edb7b T26c Media: video
Scrubber shows what has loaded, what has played and its chapters, names
the time under the pointer, seeks by press and gpui's drag, and steps by
the slider's keys; over_media lights it for a dark layer. VideoPlayer
shows the host's frame in its shape with a caption and a control bar over
it: the scrubber, play, the time, speed, captions, picture in picture and
full screen, each only with its handler; the bar rests after a still
pointer while it plays, on one wake from the executor's timer. Keys:
Space and K, J and L, the arrows, C and F. VideoThumbnailStrip lays frames
along the length under a playhead with a trim whose handles drag and whose
ends I and O set. SubtitleEditor edits cues in place: times as mm:ss.mmm,
kept in order, a time that does not read kept out with the reason shown.

InlineEdit is a Tab stop with the ring; it hands focus back after Enter or
Escape and keeps its text on Enter's release. overlays::media_button is
shared by the lightbox and the player's bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:07:26 -04:00
ZacharyZhang-NYandClaude Opus 5.5 cb28c0e305 Media: a shaped corner follows the pointer up and down; the fitted crop is told once
With an aspect, a corner drag sizes the crop by whichever side the pointer
moved further, so a drag straight up or down resizes it too. The upload
tells the host the fitted crop once per file, whether the host keeps it or
not; a host that dropped it had set off a loop of reports. The annotator's
Escape stops only when it lets a chosen mark go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 16:38:22 -04:00
ZacharyZhang-NYandClaude Opus 5.5 7d86c804d7 T26b Media: crop and annotate
ImageCropper crops a picture by a box in shares of it: a press holds a
corner, a side or the body (crop::grip_at), a drag through gpui's drag
moves them (crop::dragged), kept inside the picture with a least side;
with an aspect only the corners size it and the box keeps its shape; the
arrows move it. The picture sits inset by half a handle, the focus border
outside it, so handles on its edge stay whole and it keeps its shape.
ImageUpload (T06e) takes pictures only, from a drop or the dialog
(forms::taken, DropZone::kinds), decodes the file for its shape, and with
no crop yet reports the largest centered box of its aspect once. The
annotator draws boxes, arrows, lines and numbered pins in chart colors
through forms::pen; Select chooses a mark, Delete removes it, and Cmd-Z
and Shift-Cmd-Z undo and redo through forms::History. theme.media() holds
their sizes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 16:16:29 -04:00
ZacharyZhang-NYandClaude Opus 5.5 12f0baab15 Media: the viewer's picture moves; a viewer with no picture takes no Tab
The stage's picture carries an id, so gpui keeps its frame and asks for
the next: an animated picture plays, turned or not. A viewer whose picture
has not loaded or cannot open is no Tab stop. AGENTS.md: img() moves an
animated picture's frames only with an id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:51:03 -04:00
ZacharyZhang-NYandClaude Opus 5.5 f8a51a5352 T26a Media: images
A new chapter, src/media. ImageViewer fits a picture to its stage and
zooms by the document steps, by keys, buttons and Cmd-scroll about the
pointer; a drag through gpui's drag, a scroll or the arrows pan it once it
overhangs; R turns it a quarter at a time. gpui paints pictures without a
transform, so media::turn turns the decoded frames off the main thread,
an asset keyed by the picture and the turn; `image` 0.25, which gpui
already decodes with, is now a dependency. ImageThumbnail shows a picture
in its own shape with a corner label and a ring when chosen, and is a Tab
stop only with a handler. Lightbox / Gallery Viewer points to
overlays::Lightbox, which the gallery opens from the thumbnails.

T26 splits into T26a–e. AGENTS.md: the drag rule says drags that pan,
turn or slide go through gpui's drag; pictures turn by their pixels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:34:45 -04:00