e3461dd5cd
* 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
119 lines
2.8 KiB
TypeScript
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>
|
|
);
|
|
}
|