Loading packages/chat/lib/components/ChatLog/ChatBubble.tsx +36 −29 Original line number Diff line number Diff line import { useYap } from "@/context/utils"; import type { MatrixEvent } from "matrix-js-sdk"; import { MessageFlag, type Message } from "@/lib/const"; import { useYap } from "@/lib/context"; import type React from "react"; export const ChatBubble = ({ event }: { event: MatrixEvent }) => { const { client } = useYap<"Internal">(); const isRight = event.getSender() === client.client.getUserId(); type MessageRole = "ME" | "OTHER" | "SYSTEM"; export const ChatBubble = ({ message }: { message: Message }) => { const { userId, isSystem } = useYap(); const role: MessageRole = isSystem(message.sender) ? "SYSTEM" : message.sender === userId ? "ME" : "OTHER"; const flags = message.flags; return ( <div className="flex flex-col w-full" style={{ alignItems: isRight ? "end" : "start", alignItems: role === "ME" ? "end" : role === "OTHER" ? "start" : "center", }} > {/* {role === "SYSTEM" ? ( <div className="self-center">{event.content}</div> ) : ( */} {role === "SYSTEM" ? ( <div className="self-center">{message.content}</div> ) : ( <> <div className="flex flex-row gap-1 *:text-xs"> <span>{event.getSender()}</span> </div> <div className="rounded-xl p-1" style={{ backgroundColor: isRight backgroundColor: role === "ME" ? "var(--color-gray-500)" : "var(--color-gray-300)", }} > {event.getContent().body} {message.content} </div> <div className="flex flex-row gap-1 *:text-xs"> {/* {flags & MessageFlag.SENDING ? <span>sending</span> : ""} {flags & MessageFlag.SENDING ? <span>sending</span> : ""} {flags & MessageFlag.SEEN ? <span>seen</span> : ""} {flags & MessageFlag.EDITED ? <span>edited</span> : ""} */} {flags & MessageFlag.EDITED ? <span>edited</span> : ""} </div> </> {/* )} */} )} </div> ); }; packages/chat/lib/components/ChatLog/ChatLog.tsx +4 −3 Original line number Diff line number Diff line import React, { useEffect, useRef } from "react"; import { ChatBubble } from "./ChatBubble"; import type { Message } from "@/lib/const"; export const ChatLog = ({ Loading @@ -24,9 +25,9 @@ export const ChatLog = ({ <button onClick={loadMore}>Load More {loading && "loading"}</button> )} <React.Fragment> {/* {messages.map((msg) => ( <ChatBubble key={msg.eventId} event={msg} /> ))} */} {messages.map((msg) => ( <ChatBubble key={msg.eventId} message={msg} /> ))} </React.Fragment> <div ref={bottom} /> </React.Fragment> Loading packages/chat/lib/components/MatrixChat.tsx 0 → 100644 +35 −0 Original line number Diff line number Diff line import * as sdk from "matrix-js-sdk"; import { memo, useEffect, useMemo } from "react"; import { MXClient } from "../lib/MXClient"; export const MatrixChat = memo(() => { // @ts-expect-error ignore const client = useMemo(() => new MXClient(), []); useEffect(() => { client.destroy(); }, []); return ( <div> hello from a library! cool abc{" "} <button onClick={() => { window.location.href = client.getLoginUrl(window.location.href); }} > login redirect </button>{" "} <button onClick={() => { client .login() .then(() => console.log("logged in")) .catch(console.error); }} > attempt login </button> </div> ); }); packages/chat/lib/components/Tab.tsx +2 −4 Original line number Diff line number Diff line Loading @@ -4,20 +4,18 @@ import { useState } from "react"; export const Tab = ({ name, isNagging, defaultOpen, className, onClose, onFocus, children, }: React.PropsWithChildren<{ name: string; isNagging?: boolean; defaultOpen?: boolean; isNagging: boolean; className?: string; onClose?: () => unknown; onFocus?: () => unknown; }>) => { const [open, setOpen] = useState(defaultOpen ?? false); const [open, setOpen] = useState(false); return ( <div Loading packages/chat/lib/components/Tab/Home.tsx +44 −48 Original line number Diff line number Diff line import { useYap } from "@/context/utils"; import { Tab } from "../Tab"; import { useRoom } from "@/hooks/useRoom"; import type { MXRoomID } from "@/main"; import { memo, useEffect, useState, type JSX } from "react"; import type { MatrixEvent } from "matrix-js-sdk"; import * as sdk from "matrix-js-sdk"; import { MXClient } from "@/lib/MXClient"; import { RoomListItem } from "../UI/RoomListItem"; import { List } from "../UI/List"; export const HomeTab = memo(() => { const { dispatch } = useYap<"Internal">(); const [invites, setInvites] = useState(0); const [subs, setSubs] = useState<{ roomId: MXRoomID }[]>([]); useEffect(() => { const { rooms } = MXClient.get(); const onSync = (rooms: sdk.Room[]) => { setSubs(rooms.map((r) => ({ roomId: r.roomId as MXRoomID }))); }; const onInvites = (rooms: sdk.Room[]) => { setInvites(rooms.length); }; setInvites(rooms.Invites.get().length); setSubs( rooms.Subscriptions.get().map((r) => ({ roomId: r.roomId as MXRoomID })), ); rooms.Subscriptions.on("sync", onSync); rooms.Invites.on("sync", onInvites); return () => { rooms.Subscriptions.off("sync", onSync); rooms.Invites.off("sync", onInvites); }; }, []); const TEST_ROOMS = [ "!room1:cool.chat", "!room2:bad.chat", "!room3:the.chat", ] as const; export const HomeTab = ({ openRoom, }: { openRoom: (roomId: `!${string}:${string}`) => unknown; }) => { return ( <Tab name="Chat" isNagging={false}> <List> {invites > 0 && ( <List.Item onClick={() => dispatch(["open", "invites"])}> invites {invites} </List.Item> )} {subs.map(({ roomId }) => ( <RoomListItem <ul> {TEST_ROOMS.map((roomId) => ( <ChatItem key={roomId} roomId={roomId} onClick={() => dispatch(["openChat", roomId])} onClick={() => openRoom(roomId)} /> ))} </List> </ul> </Tab> ); }); }; const ChatItem = ({ roomId, onClick, }: { roomId: string; onClick: () => unknown; }) => { return ( <li className="flex flex-row gap-1 p-1 relative"> <button className="absolute top-0 left-0 w-full h-full cursor-pointer" onClick={onClick} ></button> <div className="flex items-center justify-center p-0.5"> <div className="w-8 h-8 shrink-0 rounded-xl bg-gray-500"></div> </div> <div className="flex flex-col gap-px"> <span className="font-bold">{roomId}</span> <span className="text-xs text-gray-800 text-ellipsis max-w-full"> hey man you can't place therehey man you can't place therehey man you can't place therehey man you can't place therehey man you can't place there </span> </div> </li> ); }; Loading
packages/chat/lib/components/ChatLog/ChatBubble.tsx +36 −29 Original line number Diff line number Diff line import { useYap } from "@/context/utils"; import type { MatrixEvent } from "matrix-js-sdk"; import { MessageFlag, type Message } from "@/lib/const"; import { useYap } from "@/lib/context"; import type React from "react"; export const ChatBubble = ({ event }: { event: MatrixEvent }) => { const { client } = useYap<"Internal">(); const isRight = event.getSender() === client.client.getUserId(); type MessageRole = "ME" | "OTHER" | "SYSTEM"; export const ChatBubble = ({ message }: { message: Message }) => { const { userId, isSystem } = useYap(); const role: MessageRole = isSystem(message.sender) ? "SYSTEM" : message.sender === userId ? "ME" : "OTHER"; const flags = message.flags; return ( <div className="flex flex-col w-full" style={{ alignItems: isRight ? "end" : "start", alignItems: role === "ME" ? "end" : role === "OTHER" ? "start" : "center", }} > {/* {role === "SYSTEM" ? ( <div className="self-center">{event.content}</div> ) : ( */} {role === "SYSTEM" ? ( <div className="self-center">{message.content}</div> ) : ( <> <div className="flex flex-row gap-1 *:text-xs"> <span>{event.getSender()}</span> </div> <div className="rounded-xl p-1" style={{ backgroundColor: isRight backgroundColor: role === "ME" ? "var(--color-gray-500)" : "var(--color-gray-300)", }} > {event.getContent().body} {message.content} </div> <div className="flex flex-row gap-1 *:text-xs"> {/* {flags & MessageFlag.SENDING ? <span>sending</span> : ""} {flags & MessageFlag.SENDING ? <span>sending</span> : ""} {flags & MessageFlag.SEEN ? <span>seen</span> : ""} {flags & MessageFlag.EDITED ? <span>edited</span> : ""} */} {flags & MessageFlag.EDITED ? <span>edited</span> : ""} </div> </> {/* )} */} )} </div> ); };
packages/chat/lib/components/ChatLog/ChatLog.tsx +4 −3 Original line number Diff line number Diff line import React, { useEffect, useRef } from "react"; import { ChatBubble } from "./ChatBubble"; import type { Message } from "@/lib/const"; export const ChatLog = ({ Loading @@ -24,9 +25,9 @@ export const ChatLog = ({ <button onClick={loadMore}>Load More {loading && "loading"}</button> )} <React.Fragment> {/* {messages.map((msg) => ( <ChatBubble key={msg.eventId} event={msg} /> ))} */} {messages.map((msg) => ( <ChatBubble key={msg.eventId} message={msg} /> ))} </React.Fragment> <div ref={bottom} /> </React.Fragment> Loading
packages/chat/lib/components/MatrixChat.tsx 0 → 100644 +35 −0 Original line number Diff line number Diff line import * as sdk from "matrix-js-sdk"; import { memo, useEffect, useMemo } from "react"; import { MXClient } from "../lib/MXClient"; export const MatrixChat = memo(() => { // @ts-expect-error ignore const client = useMemo(() => new MXClient(), []); useEffect(() => { client.destroy(); }, []); return ( <div> hello from a library! cool abc{" "} <button onClick={() => { window.location.href = client.getLoginUrl(window.location.href); }} > login redirect </button>{" "} <button onClick={() => { client .login() .then(() => console.log("logged in")) .catch(console.error); }} > attempt login </button> </div> ); });
packages/chat/lib/components/Tab.tsx +2 −4 Original line number Diff line number Diff line Loading @@ -4,20 +4,18 @@ import { useState } from "react"; export const Tab = ({ name, isNagging, defaultOpen, className, onClose, onFocus, children, }: React.PropsWithChildren<{ name: string; isNagging?: boolean; defaultOpen?: boolean; isNagging: boolean; className?: string; onClose?: () => unknown; onFocus?: () => unknown; }>) => { const [open, setOpen] = useState(defaultOpen ?? false); const [open, setOpen] = useState(false); return ( <div Loading
packages/chat/lib/components/Tab/Home.tsx +44 −48 Original line number Diff line number Diff line import { useYap } from "@/context/utils"; import { Tab } from "../Tab"; import { useRoom } from "@/hooks/useRoom"; import type { MXRoomID } from "@/main"; import { memo, useEffect, useState, type JSX } from "react"; import type { MatrixEvent } from "matrix-js-sdk"; import * as sdk from "matrix-js-sdk"; import { MXClient } from "@/lib/MXClient"; import { RoomListItem } from "../UI/RoomListItem"; import { List } from "../UI/List"; export const HomeTab = memo(() => { const { dispatch } = useYap<"Internal">(); const [invites, setInvites] = useState(0); const [subs, setSubs] = useState<{ roomId: MXRoomID }[]>([]); useEffect(() => { const { rooms } = MXClient.get(); const onSync = (rooms: sdk.Room[]) => { setSubs(rooms.map((r) => ({ roomId: r.roomId as MXRoomID }))); }; const onInvites = (rooms: sdk.Room[]) => { setInvites(rooms.length); }; setInvites(rooms.Invites.get().length); setSubs( rooms.Subscriptions.get().map((r) => ({ roomId: r.roomId as MXRoomID })), ); rooms.Subscriptions.on("sync", onSync); rooms.Invites.on("sync", onInvites); return () => { rooms.Subscriptions.off("sync", onSync); rooms.Invites.off("sync", onInvites); }; }, []); const TEST_ROOMS = [ "!room1:cool.chat", "!room2:bad.chat", "!room3:the.chat", ] as const; export const HomeTab = ({ openRoom, }: { openRoom: (roomId: `!${string}:${string}`) => unknown; }) => { return ( <Tab name="Chat" isNagging={false}> <List> {invites > 0 && ( <List.Item onClick={() => dispatch(["open", "invites"])}> invites {invites} </List.Item> )} {subs.map(({ roomId }) => ( <RoomListItem <ul> {TEST_ROOMS.map((roomId) => ( <ChatItem key={roomId} roomId={roomId} onClick={() => dispatch(["openChat", roomId])} onClick={() => openRoom(roomId)} /> ))} </List> </ul> </Tab> ); }); }; const ChatItem = ({ roomId, onClick, }: { roomId: string; onClick: () => unknown; }) => { return ( <li className="flex flex-row gap-1 p-1 relative"> <button className="absolute top-0 left-0 w-full h-full cursor-pointer" onClick={onClick} ></button> <div className="flex items-center justify-center p-0.5"> <div className="w-8 h-8 shrink-0 rounded-xl bg-gray-500"></div> </div> <div className="flex flex-col gap-px"> <span className="font-bold">{roomId}</span> <span className="text-xs text-gray-800 text-ellipsis max-w-full"> hey man you can't place therehey man you can't place therehey man you can't place therehey man you can't place therehey man you can't place there </span> </div> </li> ); };