From 115cb7b08ef55bc6abd014695daafee59283fe33 Mon Sep 17 00:00:00 2001 From: Claas Date: Wed, 19 Jun 2024 14:28:05 +0200 Subject: [PATCH] Improve chats list Allow sign out --- README.md | 6 +++ chat/src/components/TopAppBar.tsx | 21 ++++++++++ chat/src/context.tsx | 18 ++++++++ chat/src/routes/Chat.tsx | 40 +++++++++--------- chat/src/routes/Index.tsx | 70 ++++++++++++++++++++++--------- chat/src/routes/SetUp.tsx | 33 ++++++++++++++- 6 files changed, 148 insertions(+), 40 deletions(-) create mode 100644 chat/src/components/TopAppBar.tsx diff --git a/README.md b/README.md index 9303817..355e93b 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,9 @@ - Virtualization of chat message lists. Too many messages will currently have a performance impact - Possible solution: [TanStack Virtual](https://tanstack.com/virtual/latest/docs/introduction) - Message time is controlled by client and not server and client can write in it whatever they want + +# My Wishlist + +- Add data view for time send, time received in milliseconds to get information how long the message was possibly in travel +- Show time on tap if chat partner is in different time zone. Needs to save date in non-utc as ISO 8601 +- Notifications diff --git a/chat/src/components/TopAppBar.tsx b/chat/src/components/TopAppBar.tsx new file mode 100644 index 0000000..ad6f870 --- /dev/null +++ b/chat/src/components/TopAppBar.tsx @@ -0,0 +1,21 @@ +import { JSX, VoidProps } from "solid-js"; + +export default function TopAppBar({ + header, + leadingAction, + trailingAction, +}: VoidProps<{ + header: string; + leadingAction?: JSX.Element; + trailingAction?: JSX.Element; +}>) { + return ( +
+ {leadingAction} +

+ {header} +

+ {trailingAction} +
+ ); +} diff --git a/chat/src/context.tsx b/chat/src/context.tsx index 8557a40..b4d62bf 100644 --- a/chat/src/context.tsx +++ b/chat/src/context.tsx @@ -37,6 +37,23 @@ async function handleMessage(event: MessageEvent) { const state = { socket, name, setName, messagesByUser }; const Context = createContext(state); + +// Close socket if name goes to null. Meaningif the user signs out +createEffect>((previous) => { + const value = name(); + if (!(value === null && previous !== null)) return value; + + const currentSocket = socket(); + if (currentSocket === undefined) return value; + + console.debug("Closing socket"); + currentSocket.close(); + setSocket(undefined); + + return value; +}, name()); + +// Use new socket if name changes createEffect((previous) => { const id = name(); if (id === null) return previous; @@ -44,6 +61,7 @@ createEffect((previous) => { previous?.removeEventListener("message", handleMessage); previous?.close(); + console.debug("Opening socket"); const newSocket = new WebSocket(`ws://localhost:3000/messages/${id}`); newSocket.addEventListener("message", handleMessage); setSocket(newSocket); diff --git a/chat/src/routes/Chat.tsx b/chat/src/routes/Chat.tsx index 2d3bd13..6c0c05e 100644 --- a/chat/src/routes/Chat.tsx +++ b/chat/src/routes/Chat.tsx @@ -1,6 +1,7 @@ import { useNavigate, useParams } from "@solidjs/router"; import { useAppContext } from "../context"; import { For, Show, createEffect, createSignal } from "solid-js"; +import TopAppBar from "../components/TopAppBar"; /** * This type has to be kept in sync with the server-side types @@ -81,23 +82,24 @@ export default function Chat() { return ( <> -
- - go back - - - - -

- {contactName} -

-
+ + go back + + + } + />
{(message) => (
  • diff --git a/chat/src/routes/Index.tsx b/chat/src/routes/Index.tsx index f99eb36..2faf7e4 100644 --- a/chat/src/routes/Index.tsx +++ b/chat/src/routes/Index.tsx @@ -1,6 +1,7 @@ -import { For, Show, createResource } from "solid-js"; +import { For, Show, createEffect, createResource } from "solid-js"; import { useAppContext } from "../context"; -import { Navigate } from "@solidjs/router"; +import { Navigate, useNavigate } from "@solidjs/router"; +import TopAppBar from "../components/TopAppBar"; async function fetchUsers() { const response = await fetch("http://localhost:3000/users"); @@ -8,31 +9,60 @@ async function fetchUsers() { return data; } export default function Index() { - const { socket, name } = useAppContext(); + const { socket, name, setName } = useAppContext(); + const navigate = useNavigate(); - if (socket() === undefined || name() === undefined) + if (socket() === undefined || name() === null) return ; + createEffect(() => { + if (name() === null) navigate("/setup"); + }); + // Available chats const [users] = createResource(fetchUsers); + const usersWithoutSelf = () => users()?.filter((user) => user !== name()); + return ( - Loading...

    }> - 0} - fallback={

    No one available to chat

    } - > -
      - - {(user) => ( -
    • - {user} -
    • - )} -
      -
    -
    -
    + <> + setName(null)} class="p-3 text-slate-900"> + sign out + + + } + /> +
    + Loading...

    }> + 0} + fallback={

    No one available to chat

    } + > +
      + + {(user) => ( +
    • + {user} +
    • + )} +
      +
    +
    +
    +
    + ); } diff --git a/chat/src/routes/SetUp.tsx b/chat/src/routes/SetUp.tsx index 8bc9cc2..e185869 100644 --- a/chat/src/routes/SetUp.tsx +++ b/chat/src/routes/SetUp.tsx @@ -2,6 +2,37 @@ import { useNavigate } from "@solidjs/router"; import { useAppContext } from "../context"; import { createEffect } from "solid-js"; +function Alert() { + return ( +
    +
    +
    + +
    +
    +

    Attention needed

    +
    +

    + Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid + pariatur, ipsum similique veniam quo totam eius aperiam dolorum. +

    +
    +
    +
    +
    + ); +} + export default function SetUp() { const { name, setName } = useAppContext(); function handleSubmit(event: SubmitEvent) { @@ -19,7 +50,7 @@ export default function SetUp() { }); return ( -
    +
    {/* TODO use melt logo */}