decrease clutter in stream-view

This commit is contained in:
talksik
2026-06-21 10:06:38 -07:00
parent 4a73ccad0b
commit a2a7fd4812
3 changed files with 67 additions and 26 deletions
+2 -2
View File
@@ -20,8 +20,8 @@ import (
"github.com/flowy-live/llink/internal"
"github.com/flowy-live/llink/internal/auth"
"github.com/flowy-live/llink/internal/billing"
"github.com/flowy-live/llink/internal/db"
"github.com/flowy-live/llink/internal/depot"
"github.com/flowy-live/llink/internal/db"
"github.com/flowy-live/llink/internal/depot"
"github.com/flowy-live/llink/internal/handler"
"github.com/flowy-live/llink/internal/human"
"github.com/flowy-live/llink/internal/human/pushnotify"
@@ -0,0 +1,50 @@
import { Text, View } from 'react-native';
import { Clock, Pause } from 'lucide-react-native';
interface StreamStatusPillsProps {
paused: boolean;
/** Null when no auto-exit is pending; ms remaining otherwise. */
exitRemainingMs: number | null;
}
/**
* Compact playback-state pills shown in the right chrome margin so they never
* overlay the particle canvas. "Paused" collapses to an icon-only badge; the
* exit countdown pairs a clock icon with tabular-number seconds so the digit
* tick doesn't reflow neighbors.
*/
export function StreamStatusPills({
paused,
exitRemainingMs,
}: StreamStatusPillsProps) {
if (!paused && exitRemainingMs === null) return null;
return (
<View className="flex-row items-center gap-1.5">
{paused ? (
<View
accessibilityLabel="Paused"
className="bg-white/15 h-6 w-6 items-center justify-center rounded-full"
>
<Pause color="white" size={11} fill="white" strokeWidth={0} />
</View>
) : null}
{exitRemainingMs !== null ? (
<View
accessibilityLabel={`Closing in ${Math.ceil(
exitRemainingMs / 1000,
)} seconds`}
className="bg-white/15 h-6 flex-row items-center gap-1 rounded-full px-2"
>
<Clock color="white" size={11} strokeWidth={2} />
<Text
className="text-white text-[11px] font-semibold"
style={{ fontVariant: ['tabular-nums'] }}
>
{Math.ceil(exitRemainingMs / 1000)}s
</Text>
</View>
) : null}
</View>
);
}
@@ -61,6 +61,7 @@ import { DeletedParticleView } from './DeletedParticleView';
import { FallbackParticleView } from './FallbackParticleView';
import { useExitCountdown } from './use-exit-countdown';
import { StreamTopActions } from './StreamTopActions';
import { StreamStatusPills } from './StreamStatusPills';
import { StreamActionsSheet, type StreamActionId } from './StreamActionsSheet';
import { StreamMembersSheet } from './StreamMembersSheet';
import { RenameStreamSheet } from './RenameStreamSheet';
@@ -579,30 +580,6 @@ function StreamViewInner({ streamParticle, path, onExit }: StreamViewProps) {
</View>
</View>
{/* Top status pills: paused + exit countdown. Anchored just below
the metadata row (avatar + name ≈ 40px tall, starts at
insets.top + 32) so they share the top chrome real estate
instead of competing with captions at the bottom. */}
<View
pointerEvents="none"
className="absolute inset-x-0 items-center"
style={{ top: insets.top + 88 }}
>
{paused ? (
<View className="bg-white/15 rounded-full px-3 py-1">
<Text className="text-white/90 text-xs font-medium">
Paused
</Text>
</View>
) : null}
{exitRemainingMs !== null ? (
<View className="bg-white/15 rounded-full px-3 py-1 mt-2">
<Text className="text-white/90 text-xs font-medium">
Closing in {Math.ceil(exitRemainingMs / 1000)}s
</Text>
</View>
) : null}
</View>
</View>
</GestureDetector>
@@ -658,6 +635,20 @@ function StreamViewInner({ streamParticle, path, onExit }: StreamViewProps) {
</View>
</View>
{/* Playback status pills — pinned to the right chrome margin just
below the top actions row so they live in the same band as the
chrome buttons instead of overlaying the particle canvas. */}
<View
pointerEvents="none"
className="absolute right-3"
style={{ top: insets.top + 72 }}
>
<StreamStatusPills
paused={paused}
exitRemainingMs={exitRemainingMs}
/>
</View>
{/* Right-edge reaction stack — mirrors desktop's ReactionBar. Vertically
centered on the canvas; outside the GestureDetector so each pill
tap toggles cleanly without competing with the stream advance/back