Commit 82f033d7 authored by Grant's avatar Grant
Browse files

draft: impl new unified ctx

parent c68ea0ea
Loading
Loading
Loading
Loading
Loading
+60 −6
Original line number Diff line number Diff line
import type { MXUserID } from "@/lib/const";
import type { MXRoomID, MXUserID } from "@/lib/const";
import { MXClient } from "@/lib/MXClient";
import type React from "react";
import { createContext, useContext, useMemo, useReducer } from "react";
import {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useReducer,
} from "react";

type State = {
  stage: "INIT";
@@ -9,15 +15,28 @@ type State = {
};
type Actions = ["login"] | ["ready"];

const context = createContext<{
type InternalAPI = {
  state: State;
  dispatch: React.ActionDispatch<[Actions]>;
}>(
};

type PublicAPI = {
  ready: () => unknown;
  doLogin: () => unknown;
  openChat: (withWho: MXUserID | MXRoomID) => unknown;
  setSystem: (handler: (mxid: MXUserID) => boolean) => unknown;
};

const context = createContext<InternalAPI & PublicAPI>(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  null as any,
);

export const useYap = () => useContext(context);
// eslint-disable-next-line react-refresh/only-export-components
export const useYap: <
  Mode extends "Internal" | "" = "",
>() => Mode extends "Internal" ? InternalAPI & PublicAPI : PublicAPI = () =>
  useContext(context);

export const YapContext = ({ children }: React.PropsWithChildren) => {
  // @ts-expect-error ignore
@@ -39,6 +58,37 @@ export const YapContext = ({ children }: React.PropsWithChildren) => {
    },
  );

  const doLogin = useCallback(() => {
    window.open(client.getLoginUrl(window.location.href), "_self");
  }, [client]);

  const openChat = useCallback((withWho: MXUserID | MXRoomID) => {}, []);

  const setSystem = useCallback(
    (handler: (mxid: MXUserID) => boolean) => {},
    [],
  );

  const ready = useCallback(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.has("loginToken")) {
      console.debug(
        "YapContext: Attempting to login with loginToken query parameter...",
      );
      client
        .login()
        .then((success) => {
          console.debug(
            "YapContext: Finished processing loginToken",
            success ? "and logged in" : "",
          );
        })
        .catch((e) => {
          console.error("YapContext: Failed to process loginToken", e);
        });
    }
  }, [client]);

  // todo:
  // - migrate to new, public, context
  // - ready state to trigger url parsing for login
@@ -46,6 +96,10 @@ export const YapContext = ({ children }: React.PropsWithChildren) => {
  // - replacement definitions & handlers in props

  return (
    <context.Provider value={{ state, dispatch }}>{children}</context.Provider>
    <context.Provider
      value={{ state, dispatch, doLogin, openChat, setSystem, ready }}
    >
      {children}
    </context.Provider>
  );
};
+3 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ export class MXClient extends EventEmitter<MXEvents> {
    const params = new URLSearchParams(window.location.search);
    if (!params.has("loginToken")) {
      console.warn("MXClient#login called but no loginToken found");
      return;
      return false;
    }
    const loginToken = params.get("loginToken")!;
    params.delete("loginToken");
@@ -76,6 +76,8 @@ export class MXClient extends EventEmitter<MXEvents> {
      accessToken: loginReq.access_token,
      userId: loginReq.user_id,
    });

    return true;
  }

  private setupListeners() {
+1 −0
Original line number Diff line number Diff line
export { MatrixChat } from "./components/MatrixChat";
export { Yapper } from "./components/Yapper";
export { YapContext } from "./components/YapContext";
export type { MXEventID, MXRoomID, MXUserID } from "./lib/const";
+7 −5
Original line number Diff line number Diff line
@@ -17,15 +17,17 @@ function App() {
    document.querySelector("html")?.classList[!dark ? "remove" : "add"]("dark");
  }, [dark]);

  useEffect(() => {
    yap.ready();
  }, [yap]);

  return (
    <>
      <div>hello this is the demo app</div>
      <button onClick={() => setDark((d) => !d)}>toggle dark</button>
      <details>
        <summary>hi</summary>
        abc
      </details>
      <button onClick={() => yap.dispatch(["login"])}>try login</button>
      <button onClick={() => yap.doLogin()}>try login</button>
      <button onClick={() => alert("not impl")}>open chat with (...)</button>
      <button onClick={() => alert("not impl")}>open room (...)</button>
      <Sidebar>
        <MatrixChat />
      </Sidebar>