feat(mobile): edit text messages
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Pressable, Text, TextInput, View } from "react-native";
|
||||
import { toast } from "sonner-native";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { toUserMessage } from "@/lib/errors";
|
||||
import { editTextParticleContent } from "@/lib/firestore-particles";
|
||||
import { particlePath, toFirestoreDocPath } from "@/lib/particle-path";
|
||||
import { useSuspendPlayback } from "@/hooks/use-suspend-playback";
|
||||
import { BottomSheet } from "@/components/BottomSheet";
|
||||
|
||||
interface EditParticleSheetProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
networkId: string;
|
||||
streamId: string;
|
||||
particleId: string;
|
||||
currentContent: string;
|
||||
}
|
||||
|
||||
export function EditParticleSheet({
|
||||
open,
|
||||
onClose,
|
||||
networkId,
|
||||
streamId,
|
||||
particleId,
|
||||
currentContent,
|
||||
}: EditParticleSheetProps) {
|
||||
useSuspendPlayback(open, "edit-particle");
|
||||
|
||||
const [content, setContent] = useState(currentContent);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setContent(currentContent);
|
||||
setSaving(false);
|
||||
}
|
||||
}, [open, currentContent]);
|
||||
|
||||
const trimmed = content.trim();
|
||||
const canSave = !saving && trimmed.length > 0 && trimmed !== currentContent;
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!canSave) return;
|
||||
setSaving(true);
|
||||
try {
|
||||
const docPath = toFirestoreDocPath(
|
||||
particlePath(networkId, [streamId, particleId]),
|
||||
);
|
||||
await editTextParticleContent(docPath, trimmed);
|
||||
onClose();
|
||||
} catch (err) {
|
||||
toast.error(toUserMessage(err));
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BottomSheet open={open} onClose={onClose} avoidKeyboard>
|
||||
<View className="flex-row items-center justify-between px-5 pb-3">
|
||||
<Pressable onPress={onClose} hitSlop={12}>
|
||||
<Text className="text-white/70 text-base">Cancel</Text>
|
||||
</Pressable>
|
||||
<Text className="text-white text-base font-semibold">Edit</Text>
|
||||
<Pressable onPress={handleSave} disabled={!canSave} hitSlop={12}>
|
||||
<Text
|
||||
className={cn(
|
||||
"text-base font-semibold",
|
||||
canSave ? "text-white" : "text-white/30",
|
||||
)}
|
||||
>
|
||||
{saving ? "Saving..." : "Save"}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<View className="px-5 pb-6">
|
||||
<TextInput
|
||||
value={content}
|
||||
onChangeText={setContent}
|
||||
autoFocus
|
||||
multiline
|
||||
placeholder="Message"
|
||||
placeholderTextColor="rgba(255,255,255,0.3)"
|
||||
className="bg-white/10 rounded-xl px-4 py-3 text-white text-lg min-h-[120px]"
|
||||
textAlignVertical="top"
|
||||
/>
|
||||
</View>
|
||||
</BottomSheet>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user