setup electron multi-window architecture (#102)

* prototype with two windows

* use deps in separate window render process

* enhance autoplay into desktop overlay

* fix: autoplay window not applying tailwind styles
This commit was merged in pull request #102.
This commit is contained in:
Arjun Patel
2026-03-31 15:05:59 -07:00
committed by GitHub
parent 7f490b4596
commit 3de3ca7cef
21 changed files with 428 additions and 133 deletions
+27 -2
View File
@@ -1,16 +1,21 @@
import { useEffect, useRef } from "react";
import beepSound from "../../assets/sound.wav";
import type { Particle, StreamProperties } from "@/api/types";
import type { Network, Particle, StreamProperties } from "@/api/types";
import { apiClient } from "@/api/client";
import { useAuthStore } from "@/stores/auth-store";
import { useAutoplayStore } from "@/stores/autoplay-store";
import { getInitials } from "@/lib/utils";
/**
* Triggers autoplay when a stream's latest child changes to a new media particle.
* Plays a beep sound for new text particles from other users.
* Sends autoplay data to the separate autoplay window via IPC.
*/
export function useStreamAutoplay(
latestChild: Particle | null,
streamParticle: Particle & { type: "stream"; properties: StreamProperties },
networkId: string,
network: Network | undefined,
) {
const userId = useAuthStore((s) => s.user?.id) ?? "";
const settledIdRef = useRef<string | undefined>(undefined);
@@ -36,6 +41,26 @@ export function useStreamAutoplay(
if (latestChild.type !== "media") return;
useAutoplayStore.getState().play(latestChild, streamParticle.id);
if (useAutoplayStore.getState().muted) return;
const particle = latestChild;
const creator = network?.humans?.find((h) => h.id === particle.created_by_human_id);
const senderName = creator?.email_prefix ?? particle.created_by_human_id;
const senderInitials = creator ? getInitials(creator.email) : particle.created_by_human_id.slice(0, 2).toUpperCase();
apiClient.getParticleDownloadUrl(particle.properties.object_id).then((downloadUrl) => {
window.electronAutoplay.play({
particleId: particle.id,
streamId: streamParticle.id,
networkId,
downloadUrl,
mimeType: particle.properties.mime_type,
durationMs: particle.properties.duration_ms,
senderName,
senderInitials,
});
}).catch(() => {
// Failed to get download URL — skip autoplay silently
});
}, [latestChild?.id]); // eslint-disable-line react-hooks/exhaustive-deps
}