Files
llink/js/mobile/src/features/stream-view/EditParticleSheet.tsx
T
Arjun PatelandGitHub a8a0b7db1b infra: add linting and formatting for js projects (#230)
* wip

* wip

* wip

* format

* wip(mobile): lint and format

* cleanup

* nits

* nits

* idiomatic react

* nit

* format all root files
2026-06-02 07:44:24 -07:00

94 lines
2.7 KiB
TypeScript

import { 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);
// Reset the editor each time the sheet opens fresh.
const [prevOpen, setPrevOpen] = useState(open);
if (open !== prevOpen) {
setPrevOpen(open);
if (open) {
setContent(currentContent);
setSaving(false);
}
}
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>
);
}