* wip * wip * wip * format * wip(mobile): lint and format * cleanup * nits * nits * idiomatic react * nit * format all root files
62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import { Text, View } from 'react-native';
|
|
import type { Network, Particle } from '@/api/types';
|
|
import { resolveHumanDisplay } from '@/lib/humans';
|
|
import { RelativeTimestamp } from '@/components/RelativeTimestamp';
|
|
import { Avatar } from '@/components/Avatar';
|
|
import { useStreamPresence } from './stream-presence-context';
|
|
|
|
interface StreamMetadataHeaderProps {
|
|
particle: Particle | null;
|
|
network: Network | null;
|
|
}
|
|
|
|
/**
|
|
* Avatar + display name + relative time. Sits below the segmented bar so the
|
|
* "who/when" answer is always one glance away — Snapchat-style.
|
|
*/
|
|
export function StreamMetadataHeader({
|
|
particle,
|
|
network,
|
|
}: StreamMetadataHeaderProps) {
|
|
const { onlineHumanIds } = useStreamPresence();
|
|
if (!particle) return null;
|
|
const display = resolveHumanDisplay(
|
|
particle.created_by_human_id,
|
|
network?.humans,
|
|
);
|
|
|
|
const editedAt =
|
|
particle.type === 'text' ? particle.properties.edited_at : undefined;
|
|
const isOnline = particle.created_by_human_id
|
|
? onlineHumanIds.has(particle.created_by_human_id)
|
|
: false;
|
|
|
|
return (
|
|
<View className="flex-row items-center gap-3">
|
|
<Avatar
|
|
humanId={particle.created_by_human_id}
|
|
humans={network?.humans}
|
|
size="sm"
|
|
online={isOnline}
|
|
/>
|
|
<View className="flex-1">
|
|
<Text className="text-white text-sm font-semibold" numberOfLines={1}>
|
|
{display.displayName}
|
|
</Text>
|
|
<View className="flex-row items-center gap-2">
|
|
<RelativeTimestamp
|
|
date={particle.created_at}
|
|
className="text-white/60 text-xs"
|
|
/>
|
|
{editedAt ? (
|
|
<Text className="text-white/40 text-xs">
|
|
· edited{' '}
|
|
<RelativeTimestamp date={editedAt} className="text-white/40" />
|
|
</Text>
|
|
) : null}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|