Compare commits

...

4 Commits

Author SHA1 Message Date
Guido D'Orsi
b0ea8eecb2 fix: hack a solution for the chat rooms sync 2024-11-11 22:52:33 +01:00
Trisha Lim
c9200e0a77 pass user 2024-11-11 18:21:31 +00:00
Trisha Lim
5a5a5f0fc0 simplify 2024-11-11 17:21:38 +00:00
Trisha Lim
402c0373bd remove listener 2024-11-11 16:38:05 +00:00
5 changed files with 94 additions and 114 deletions

View File

@@ -10,11 +10,19 @@ export function App() {
const router = useIframeHashRouter();
const createChat = () => {
console.log("createChat", window.location.href);
if (!me) return;
const group = Group.create({ owner: me });
group.addMember("everyone", "writer");
const chat = Chat.create([], { owner: group });
router.navigate("/#/chat/" + chat.id);
if (window.parent) {
window.parent.postMessage(
{ type: "chat-load", id: "/chat/" + chat.id },
"*",
);
}
};
return (

View File

@@ -9,8 +9,13 @@ export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = useDemoAuth();
const url = new URL(window.location.href);
const user = url.searchParams.get("user") || undefined;
return (
<>
{window.location.href}
<Jazz.Provider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@gcmp.io"
@@ -18,7 +23,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
{children}
</Jazz.Provider>
{state.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
<DemoAuthBasicUI appName="Jazz Chat" state={state} user={user} />
)}
</>
);

View File

@@ -1,97 +1,94 @@
"use client";
import { CopyIcon } from "lucide-react";
import { IframeHTMLAttributes, useLayoutEffect, useRef, useState } from "react";
import {
IframeHTMLAttributes,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
const dimensions = {
width: 200,
height: 800,
};
function Iframe(props: IframeHTMLAttributes<HTMLIFrameElement>) {
const { src } = props;
return (
<iframe
{...props}
src={src}
className="dark:bg-black w-full"
{...dimensions}
allowFullScreen
/>
);
}
export function ResponsiveIframe(
props: IframeHTMLAttributes<HTMLIFrameElement> & { localsrc: string },
) {
const containerRef = useRef<HTMLDivElement>(null);
const [chatId, setChatId] = useState<string | undefined>();
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
const [url, setUrl] = useState<string | undefined>();
const [src, setSrc] = useState<string | undefined>();
const user1 = "A";
const user2 = "B";
const isLocal = window.location.hostname === "localhost";
// const isLocal = false;
const server1 = isLocal
? "http://localhost:5173"
: "https://chat.jazz.tools" + `?user=${user1}`;
const server2 = isLocal
? "http://localhost:5174"
: "https://jazz-chat-2.vercel.app" + `?user=${user2}`;
useLayoutEffect(() => {
if (chatId) return; // Once the chatId is set, we don't need to listen for messages anymore
const server1Url = new URL(server1);
const server2Url = new URL(server2);
const listener = (e: MessageEvent) => {
console.log(e);
if (e.data.type === "navigate" && src?.startsWith(e.origin)) {
setUrl(e.data.url);
const isValidOrigin =
e.origin === server1Url.origin || e.origin === server2Url.origin;
if (e.data.type === "chat-load" && isValidOrigin && e.data.id) {
setChatId(e.data.id);
}
};
window.addEventListener("message", listener);
return () => {
window.removeEventListener("message", listener);
};
}, [src]);
}, [chatId]);
useLayoutEffect(() => {
if (!containerRef.current) return;
const observer = new ResizeObserver(() => {
if (!containerRef.current) return;
setDimensions({
width: containerRef.current.offsetWidth,
height: containerRef.current.offsetHeight,
});
});
observer.observe(containerRef.current);
return () => {
observer.disconnect();
};
}, [containerRef]);
useLayoutEffect(() => {
setSrc(
window.location.hostname === "localhost" ? props.localsrc : props.src,
);
setUrl(
window.location.hostname === "localhost" ? props.localsrc : props.src,
);
}, [props.src, props.localsrc]);
const copyUrl = () => {
if (url) {
navigator.clipboard.writeText(url);
const src1 = useMemo(() => {
if (chatId) {
const server1Url = new URL(server1);
server1Url.hash = chatId;
return server1Url.toString();
}
};
return server1;
}, [chatId, server1]);
const src2 = useMemo(() => {
if (chatId) {
const server2Url = new URL(server2);
server2Url.hash = chatId;
return server2Url.toString();
}
return server2;
}, [chatId, server2]);
return (
<>
<div className="bg-white flex gap-3 border-b text-xs dark:bg-stone-925">
<input
className="flex-1 font-mono bg-transparent overflow-hidden text-ellipsis py-2 px-3"
value={url?.replace("http://", "").replace("https://", "")}
onClick={(e) => e.currentTarget.select()}
onBlur={(e) => e.currentTarget.setSelectionRange(0, 0)}
readOnly
/>
{url?.includes("/#/chat/") && (
<button
type="button"
className="text-blue-600 flex items-center gap-1.5 py-2 px-3"
onClick={copyUrl}
>
<CopyIcon className="hidden sm:inline" size={12} />
<span>
Copy URL{" "}
<span className="hidden sm:inline">to invite others</span>
</span>
</button>
)}
</div>
<div className="flex-1 bg-stone-100 flex items-stretch justify-center p-2 sm:p-6 dark:bg-stone-925">
<div className="border rounded-lg overflow-hidden shadow-2xl w-[20rem] min-h-[30rem]">
<div className="h-full" ref={containerRef}>
<iframe
{...props}
src={src}
className="dark:bg-black w-full"
{...dimensions}
allowFullScreen
/>
</div>
</div>
</div>
</>
<div className="grid grid-cols-2 justify-center gap-8">
<Iframe src={src1} />
<Iframe src={src2} />
</div>
);
}

View File

@@ -15,44 +15,12 @@ export function CodeExampleSection() {
title="See it for yourself"
slogan="A chat app in 174 lines of code."
/>
<div className="flex flex-col md:grid md:grid-cols-2 md:divide-x border rounded-sm overflow-hidden shadow-sm dark:divide-stone-900">
<CodeExampleTabs
tabs={[
{
name: "main.tsx",
content: <Main_tsx />,
},
{
name: "app.tsx",
content: <App_tsx />,
},
{
name: "schema.ts",
content: <Schema_ts />,
},
{
name: "chatScreen.tsx",
content: <ChatScreen_tsx />,
},
{
name: "ui.tsx",
content: <Ui_tsx />,
},
]}
/>
<div className="border-b order-first md:order-last flex flex-col md:border-b-0">
<div className="flex border-b overflow-x-auto overflow-y-hidden bg-white dark:bg-stone-900">
<p className="items-center -mb-px transition-colors px-3 pb-1.5 pt-2 block text-xs border-b-2 border-blue-700 text-stone-700 dark:bg-stone-925 dark:text-blue-500 dark:border-blue-500">
result
</p>
</div>
<ResponsiveIframe
src="https://chat.jazz.tools"
localsrc="http://localhost:5173"
/>
</div>
</div>
<ResponsiveIframe
src="https://chat.jazz.tools"
src2="https://jazz-chat-2.vercel.app/"
localsrc="http://localhost:5173"
localsrc2="http://localhost:5174"
/>
</div>
);
}

View File

@@ -81,6 +81,8 @@ export const DemoAuthBasicUI = ({
? window.matchMedia("(prefers-color-scheme: dark)").matches
: false;
console.log("log in as", user);
if (user && state.state === "ready") {
if (state.existingUsers.includes(user)) {
state.logInAs(user);