feat: jump to my newly created particle once created
This commit is contained in:
@@ -17,6 +17,7 @@ interface ComposeOverlayProps {
|
|||||||
// Optional target path for reply mode. If not provided, compose creates a new stream.
|
// Optional target path for reply mode. If not provided, compose creates a new stream.
|
||||||
targetPath?: ParticlePath;
|
targetPath?: ParticlePath;
|
||||||
onActiveChange?: (active: boolean) => void;
|
onActiveChange?: (active: boolean) => void;
|
||||||
|
onParticleCreated?: (particleId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ export function ComposeOverlay({
|
|||||||
networkId,
|
networkId,
|
||||||
targetPath,
|
targetPath,
|
||||||
onActiveChange,
|
onActiveChange,
|
||||||
|
onParticleCreated,
|
||||||
}: ComposeOverlayProps) {
|
}: ComposeOverlayProps) {
|
||||||
const [step, setStep] = useState<ComposeStep>("idle");
|
const [step, setStep] = useState<ComposeStep>("idle");
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@@ -113,8 +115,9 @@ export function ComposeOverlay({
|
|||||||
async (path: ParticlePath) => {
|
async (path: ParticlePath) => {
|
||||||
if (!userEmail) return;
|
if (!userEmail) return;
|
||||||
|
|
||||||
|
let particleId = '';
|
||||||
if (textContent.trim()) {
|
if (textContent.trim()) {
|
||||||
await createParticle.mutateAsync({
|
particleId = await createParticle.mutateAsync({
|
||||||
path,
|
path,
|
||||||
type: "text",
|
type: "text",
|
||||||
properties: { content: textContent },
|
properties: { content: textContent },
|
||||||
@@ -126,7 +129,7 @@ export function ComposeOverlay({
|
|||||||
reviewMimeType,
|
reviewMimeType,
|
||||||
);
|
);
|
||||||
|
|
||||||
await createParticle.mutateAsync({
|
particleId = await createParticle.mutateAsync({
|
||||||
path,
|
path,
|
||||||
type: "media",
|
type: "media",
|
||||||
properties: {
|
properties: {
|
||||||
@@ -138,6 +141,8 @@ export function ComposeOverlay({
|
|||||||
createdByEmail: userEmail,
|
createdByEmail: userEmail,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onParticleCreated?.(particleId);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
userEmail,
|
userEmail,
|
||||||
@@ -147,6 +152,7 @@ export function ComposeOverlay({
|
|||||||
reviewDurationMs,
|
reviewDurationMs,
|
||||||
createParticle,
|
createParticle,
|
||||||
uploadMedia,
|
uploadMedia,
|
||||||
|
onParticleCreated
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
next,
|
next,
|
||||||
prev,
|
prev,
|
||||||
goTo,
|
goTo,
|
||||||
|
goToParticle,
|
||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
} = useStreamPlayback(streamParticle, path);
|
} = useStreamPlayback(streamParticle, path);
|
||||||
@@ -188,6 +189,11 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
[prev, next],
|
[prev, next],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onLocalParticleCreated = useCallback(
|
||||||
|
(particleId: string) => {
|
||||||
|
goToParticle(particleId);
|
||||||
|
}, [goToParticle]);
|
||||||
|
|
||||||
if (children.length === 0) {
|
if (children.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col items-center justify-center gap-4 bg-black text-white">
|
<div className="flex h-full flex-col items-center justify-center gap-4 bg-black text-white">
|
||||||
@@ -264,6 +270,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
networkId={networkId!}
|
networkId={networkId!}
|
||||||
targetPath={path}
|
targetPath={path}
|
||||||
onActiveChange={setComposeActive}
|
onActiveChange={setComposeActive}
|
||||||
|
onParticleCreated={onLocalParticleCreated}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Bottom overlay: stream info + reply */}
|
{/* Bottom overlay: stream info + reply */}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ interface UseStreamPlaybackResult {
|
|||||||
next: () => void;
|
next: () => void;
|
||||||
prev: () => void;
|
prev: () => void;
|
||||||
goTo: (index: number) => void;
|
goTo: (index: number) => void;
|
||||||
|
goToParticle: (particleId: string) => void;
|
||||||
pause: () => void;
|
pause: () => void;
|
||||||
resume: () => void;
|
resume: () => void;
|
||||||
}
|
}
|
||||||
@@ -212,6 +213,14 @@ export function useStreamPlayback(
|
|||||||
[children],
|
[children],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// NOTE: if particle doesn't exist in children, this will lead to a brief moment where currentParticle is null
|
||||||
|
const goToParticle = useCallback(
|
||||||
|
(particleId: string) => {
|
||||||
|
// Dispatch directly by ID — if the particle isn't in children yet
|
||||||
|
// (e.g. just created), it will resolve once the live query delivers it.
|
||||||
|
dispatch({ type: "SET_PARTICLE", particleId });
|
||||||
|
}, []);
|
||||||
|
|
||||||
const pause = useCallback(() => dispatch({ type: "PAUSE" }), []);
|
const pause = useCallback(() => dispatch({ type: "PAUSE" }), []);
|
||||||
const resume = useCallback(() => dispatch({ type: "RESUME" }), []);
|
const resume = useCallback(() => dispatch({ type: "RESUME" }), []);
|
||||||
|
|
||||||
@@ -225,6 +234,7 @@ export function useStreamPlayback(
|
|||||||
next,
|
next,
|
||||||
prev,
|
prev,
|
||||||
goTo,
|
goTo,
|
||||||
|
goToParticle,
|
||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user