style(lists): live pill left of a divider, actions right, like the notes

Tasks get the live pill too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-02 11:50:27 +01:00
1 parent 2b7356d043
commit ae1f799d9c
4 files changed
+82 -46

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
import React, { useEffect, useState } from 'react';
import { onRealtimeStatus, RealtimeTransport } from '../lib/api';
// Connection pill in the look of the notes' header (Doku/ui-patterns.md): whether changes of others
// arrive live, and how. Phones show the short label only.
export const LivePill: React.FC = () => {
const [status, setStatus] = useState<{ connected: boolean; transport: RealtimeTransport }>({
connected: false,
transport: 'none',
});
useEffect(() => onRealtimeStatus((connected, transport) => setStatus({ connected, transport })), []);
const { connected, transport } = status;
return (
<span
className="inline-flex items-center gap-1 h-7 px-2 rounded-btn text-[11px] bg-panel text-muted flex-shrink-0"
title={
!connected
? 'Keine Live-Verbindung – Änderungen anderer erscheinen nach dem Neuladen'
: transport === 'sse'
? 'Live-Verbindung über Server-Sent Events (WebSocket wird blockiert)'
: transport === 'poll'
? 'Live über Long-Polling (WebSocket und SSE werden blockiert)'
: 'Live-Verbindung über WebSocket'
}
>
<span className={`w-1.5 h-1.5 rounded-full ${connected ? 'bg-status-ok' : 'bg-status-warn'}`} />
{!connected ? (
'Offline'
) : (
<>
Live
{transport === 'poll' && <span className="hidden sm:inline">&nbsp;(Long-Polling)</span>}
</>
)}
</span>
);
};