CI / Build & Quality Checks (pull_request) Successful in 1m52s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 8s
CI / Playwright smoke (e2e) (pull_request) Successful in 10m59s
DND was sent as presence unavailable with the literal status text "dnd": it replaced your status, and other clients showed "dnd". Where the server supports MSC3026 (busy_presence), DND now sends presence org.matrix.msc3026.busy and leaves the status alone (Synapse keeps busy across /sync set_presence=online). Busy renders as red "Do Not Disturb" with the real status line; the legacy unavailable + "dnd" encoding is still recognised and still used on servers without it. Status saves / clears no longer downgrade busy. The SDK rejects non-spec presences, so busy goes through a direct authed PUT. Fixes #283 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import React, { CSSProperties } from 'react';
|
|
import { color } from 'folds';
|
|
import { Presence, useUserPresence } from '../../hooks/useUserPresence';
|
|
|
|
function presenceRingColor(presence: Presence | undefined, status?: string): string | null {
|
|
if (!presence || presence === Presence.Offline) return null;
|
|
if (presence === Presence.Busy) return color.Critical.Main; // [Gitea #283] DND
|
|
if (presence === Presence.Unavailable) {
|
|
return status === 'dnd' ? color.Critical.Main : color.Warning.Main;
|
|
}
|
|
return color.Success.Main;
|
|
}
|
|
|
|
type PresenceRingAvatarProps = {
|
|
userId: string;
|
|
children: React.ReactElement<{ style?: CSSProperties }>;
|
|
};
|
|
|
|
export function PresenceRingAvatar({ userId, children }: PresenceRingAvatarProps) {
|
|
const presence = useUserPresence(userId);
|
|
const ringColor = presenceRingColor(presence?.presence, presence?.status);
|
|
|
|
if (!ringColor) return <>{children}</>;
|
|
|
|
// Apply outline directly to the child so it follows the child's actual border-radius.
|
|
// outline follows border-radius in Chrome 94+, Firefox 88+, Safari 16.4+.
|
|
// This avoids the mismatch of a circular wrapper around a rounded-square avatar.
|
|
return React.cloneElement(children, {
|
|
style: {
|
|
...children.props.style,
|
|
outline: `2px solid ${ringColor}`,
|
|
outlineOffset: '2px',
|
|
},
|
|
});
|
|
}
|