Commit d5b7ee1f authored by Grant's avatar Grant
Browse files

draft: chat

parent 2155bbc5
Loading
Loading
Loading
Loading
+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>
  );
};
+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 = ({
@@ -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>
+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>
  );
});
+2 −4
Original line number Diff line number Diff line
@@ -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
+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