feat: ship a web app (#218)

* feat(orion): add endpoint for link metadata

* refactor: cleanup comments

* wip: plumbing for building a web app

* setup deployment materials for web app

* fix(web): favicon
This commit was merged in pull request #218.
This commit is contained in:
Arjun Patel
2026-05-26 15:37:35 -07:00
committed by GitHub
parent 173c63508a
commit 64f02d1c3b
51 changed files with 1260 additions and 238 deletions
@@ -10,6 +10,7 @@ import {
getAttachmentHandler,
type AttachmentItem,
} from "@/features/attachments/attachment-lightbox";
import { platform } from "@/lib/platform";
type FileParticle = Extract<Particle, { type: "file" }>;
@@ -46,7 +47,7 @@ function openParticle(
if (getAttachmentHandler(particle.properties.mime_type) === "lightbox") {
onPreview(index);
} else if (url) {
window.electronLink.openExternal(url);
platform.link.openExternal(url);
}
}
@@ -65,7 +66,7 @@ function ImageAttachment({
const handleDownload = (e: React.MouseEvent) => {
e.stopPropagation();
window.electronAttachment.download(url, particle.properties.filename);
platform.attachment.download(url, particle.properties.filename);
};
return (
@@ -113,7 +114,7 @@ function FileAttachment({
const handleDownload = (e: React.MouseEvent) => {
e.stopPropagation();
if (!url) return;
window.electronAttachment.download(url, particle.properties.filename);
platform.attachment.download(url, particle.properties.filename);
};
return (
@@ -25,6 +25,8 @@ import { WindowControls } from "@/components/window-controls";
import { RelativeTimestamp } from "@/components/relative-timestamp";
import { useStreamPresence } from "@/features/particles/stream-presence-context";
import { resolveHumanDisplay } from "@/lib/humans";
import { platform } from "@/lib/platform";
import { requireDesktop } from "@/lib/platform/desktop-only";
function getParticleDisplayName(particle: Particle): string {
switch (particle.type) {
@@ -71,8 +73,9 @@ export function TopBar({ networkId, particle, streamParticle }: TopBarProps) {
const hasActiveHuddle = huddleParticipants.length > 0;
const handleJoinHuddle = () => {
if (!requireDesktop("Huddle")) return;
apiClient.getLivekitToken(networkId, streamParticle.id).then(({ token, server_url }) => {
window.electronWindow.openHuddle({ token, serverUrl: server_url });
platform.huddle.open({ token, serverUrl: server_url });
});
};
@@ -30,7 +30,8 @@ import { usePlaybackPauseStore, selectIsPaused } from "@/stores/playback-pause-s
import { usePlaybackKeys } from "@/hooks/use-playback-keys";
import { useStreamNavigationKeys } from "@/hooks/use-stream-navigation-keys";
import { useStreamActionKeys } from "@/hooks/use-stream-action-keys";
import { c } from "vite/dist/node/types.d-aGj9QkWt";
import { platform } from "@/lib/platform";
import { requireDesktop } from "@/lib/platform/desktop-only";
function getReactions(particle: Particle): Record<string, string[]> | undefined {
if (isParticleDeleted(particle)) return undefined;
@@ -150,7 +151,7 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
const navigate = useNavigate();
useMount(() => {
window.electronAutoplay.dismiss();
platform.autoplay.dismiss();
});
const {
@@ -220,8 +221,9 @@ function StreamViewInner({ path, streamParticle }: StreamViewProps) {
});
const handleOpenHuddle = useCallback(() => {
if (!requireDesktop("Huddle")) return;
apiClient.getLivekitToken(networkId, streamParticle.id).then(({ token, server_url }) => {
window.electronWindow.openHuddle({ token, serverUrl: server_url });
platform.huddle.open({ token, serverUrl: server_url });
});
navigate(`/${networkId}`);
}, [networkId, streamParticle.id, navigate]);