mobile v0.1 with deployment for ios (#191)
* stage 1: project init * stage 2: skeleton with navigation * step 2.5: streams list * step 4: stream playback experience * step 5-6: compose experience * fix: broken record * transcode media particles to mp4 * build: reproducible go generate * build: rename skaffold module for particle processor worker * infra: increase particle processor worker resources Was dealing with OOM errors * tweaks to mobile * log transcode work * view on desktop placeholder * tweak padding * cap video resolution to save on memory * infra: bump memory limits as insurance * ux improvements * update bundle id for mobile * config for mobile
This commit was merged in pull request #191.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { Text, View } from "react-native";
|
||||
import type { Human } from "@/api/types";
|
||||
import { resolveHumanDisplay } from "@/lib/humans";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type Size = "xs" | "sm" | "md";
|
||||
|
||||
interface AvatarProps {
|
||||
humanId: string | null | undefined;
|
||||
humans: Human[] | undefined;
|
||||
size?: Size;
|
||||
/** True for online presence — adds a green ring (matches desktop). */
|
||||
online?: boolean;
|
||||
/** Background ring used to separate stacked avatars from the chrome. */
|
||||
stackBg?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const sizeMap: Record<Size, { box: string; text: string; ring: number }> = {
|
||||
xs: { box: "h-6 w-6", text: "text-[9px]", ring: 1.5 },
|
||||
sm: { box: "h-9 w-9", text: "text-xs", ring: 2 },
|
||||
md: { box: "h-10 w-10", text: "text-sm", ring: 2 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Initials avatar with optional online ring (green) and an optional outer
|
||||
* stack ring used to visually separate overlapping avatars on a busy chrome.
|
||||
* Matches desktop's avatar + presence pattern (`ring-2 ring-green-500`).
|
||||
*/
|
||||
export function Avatar({
|
||||
humanId,
|
||||
humans,
|
||||
size = "sm",
|
||||
online = false,
|
||||
stackBg,
|
||||
className,
|
||||
}: AvatarProps) {
|
||||
const { initials } = resolveHumanDisplay(humanId, humans);
|
||||
const dims = sizeMap[size];
|
||||
|
||||
return (
|
||||
<View
|
||||
className={cn(
|
||||
"bg-black/15 items-center justify-center rounded-full",
|
||||
dims.box,
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
// Online ring is the priority; if not online, show the stack
|
||||
// separator ring (if requested) so adjacent avatars stay distinct.
|
||||
borderWidth: online ? dims.ring : stackBg ? dims.ring : 0,
|
||||
borderColor: online ? "#22c55e" : stackBg ?? "transparent",
|
||||
}}
|
||||
>
|
||||
<Text className={cn("text-white font-semibold", dims.text)}>
|
||||
{initials}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user