feat: F5.4 presence: who else is in the project
Over Yjs awareness each editor tells who it is (F names the person in the access message), the device it has chosen and the windows it has open, and nothing else: no pointer, nothing that changes without a cause, sent only when it changed. Others' states are read with care. A frame in their colour round a device they chose, a dot on a window they have open too, a circle with initials each beside the mode buttons; the bridge tells the dashboard who is there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,8 +46,12 @@ import { GnutellaPanel } from './GnutellaPanel.js';
|
||||
import { ImageViewerPanel, useImageViewer } from './ImageViewerPanel.js';
|
||||
import { WebServerPanel } from './WebServerPanel.js';
|
||||
import './desktop.css';
|
||||
import { WindowWatchers } from '../remote/PresenceMarks.js';
|
||||
import type { PresenceUser } from '../remote/presence.js';
|
||||
|
||||
export interface DesktopWindowProps {
|
||||
/** Who else in the project has this window open (plan §7.4). */
|
||||
readonly watchers?: readonly PresenceUser[] | undefined;
|
||||
readonly doc: Y.Doc;
|
||||
readonly id: string;
|
||||
/** The room: the computer's network as it runs, its programs' windows. */
|
||||
@@ -87,7 +91,7 @@ function useDesktopView(doc: Y.Doc, id: string) {
|
||||
return view;
|
||||
}
|
||||
|
||||
export function DesktopWindow({ doc, id, simulation, active, x, y, z, program: open, onProgram: setOpen, origin, onMove, onFront, onClose }: DesktopWindowProps) {
|
||||
export function DesktopWindow({ doc, id, simulation, active, x, y, z, program: open, onProgram: setOpen, origin, onMove, onFront, onClose, watchers }: DesktopWindowProps) {
|
||||
const t = useTranslate();
|
||||
const language = useLanguage();
|
||||
const view = useDesktopView(doc, id);
|
||||
@@ -134,6 +138,7 @@ export function DesktopWindow({ doc, id, simulation, active, x, y, z, program: o
|
||||
<header className="desktop-titlebar" onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={onPointerUp} onPointerCancel={onPointerUp}>
|
||||
<img src={ICON_URLS[view.kind === 'notebook' ? 'laptop' : 'server']} alt="" />
|
||||
<h2>{title}</h2>
|
||||
<WindowWatchers watchers={watchers} />
|
||||
<button type="button" className="desktop-close" aria-label={t('sheet.close')} title={t('sheet.close')} onClick={onClose}>
|
||||
×
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user