Files
llink/js/mobile/src/features/stream-view/StreamActionsSheet.tsx
T
Arjun Patel e3461dd5cd 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
2026-04-29 17:39:11 -07:00

119 lines
2.8 KiB
TypeScript

import { Pressable, Text, View } from "react-native";
import {
CircleCheckBig,
CircleDot,
Pencil,
Trash2,
Users,
} from "lucide-react-native";
import { cn } from "@/lib/utils";
import { BottomSheet } from "@/components/BottomSheet";
export type StreamActionId =
| "toggle-status"
| "rename"
| "members"
| "delete-particle";
interface StreamActionsSheetProps {
open: boolean;
onClose: () => void;
onSelect: (action: StreamActionId) => void;
streamStatus: "open" | "closed";
isCreator: boolean;
/** True when the *current* particle is one this user can soft-delete. */
canDeleteParticle: boolean;
}
export function StreamActionsSheet({
open,
onClose,
onSelect,
streamStatus,
isCreator,
canDeleteParticle,
}: StreamActionsSheetProps) {
const choose = (id: StreamActionId) => {
onClose();
onSelect(id);
};
return (
<BottomSheet open={open} onClose={onClose}>
<View className="py-2">
<ActionRow
icon={
streamStatus === "open" ? (
<CircleCheckBig color="white" size={20} />
) : (
<CircleDot color="#22c55e" size={20} />
)
}
label={
streamStatus === "open" ? "Close stream" : "Reopen stream"
}
onPress={() => choose("toggle-status")}
/>
<ActionRow
icon={<Users color="white" size={20} />}
label="Members"
onPress={() => choose("members")}
/>
{isCreator ? (
<ActionRow
icon={<Pencil color="white" size={20} />}
label="Rename stream"
onPress={() => choose("rename")}
/>
) : null}
{canDeleteParticle ? (
<ActionRow
icon={<Trash2 color="#ef4444" size={20} />}
label="Delete particle"
tone="destructive"
onPress={() => choose("delete-particle")}
/>
) : null}
</View>
<View className="px-5 pt-2 pb-2">
<Pressable
onPress={onClose}
className="bg-white/10 active:bg-white/15 rounded-xl py-3 items-center"
>
<Text className="text-white text-base font-semibold">Cancel</Text>
</Pressable>
</View>
</BottomSheet>
);
}
function ActionRow({
icon,
label,
onPress,
tone = "default",
}: {
icon: React.ReactNode;
label: string;
onPress: () => void;
tone?: "default" | "destructive";
}) {
return (
<Pressable
onPress={onPress}
className="px-5 py-3.5 flex-row items-center gap-3 active:bg-white/5"
>
<View className="w-6 items-center">{icon}</View>
<Text
className={cn(
"text-base",
tone === "destructive" ? "text-red-400" : "text-white",
)}
>
{label}
</Text>
</Pressable>
);
}