DM typing indicator, and bug fix sending messages on connect

This commit is contained in:
2025-12-23 14:06:39 +01:00
parent d75d286dee
commit 4899943cfc
4 changed files with 59 additions and 35 deletions
+9 -1
View File
@@ -4,10 +4,11 @@ import MessageBox from "@/components/channel/MessageBox";
import AppLayout from "@/components/app/AppLayout"; import AppLayout from "@/components/app/AppLayout";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import useApp from "@/hooks/use-app"; import useApp from "@/hooks/use-app";
import { useEffect, useRef } from "react"; import { useEffect, useRef, useState } from "react";
import auth from "@/lib/auth"; import auth from "@/lib/auth";
import useAsync from "@/hooks/use-async"; import useAsync from "@/hooks/use-async";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import useIndicators from "@/hooks/use-indicators";
export default function DMs() { export default function DMs() {
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
@@ -15,6 +16,7 @@ export default function DMs() {
const targetNode = useRef<WebSocket | null>(null); const targetNode = useRef<WebSocket | null>(null);
const { value: target, loading } = useAsync(() => app.getUserById(id)); const { value: target, loading } = useAsync(() => app.getUserById(id));
const router = useRouter(); const router = useRouter();
const { indicators, addIndicator } = useIndicators();
useEffect(() => { useEffect(() => {
async function connectTargetNode() { async function connectTargetNode() {
@@ -23,6 +25,7 @@ export default function DMs() {
id: target.node_address, id: target.node_address,
wsRef: targetNode, wsRef: targetNode,
messageStore: app.privateMessages, messageStore: app.privateMessages,
onIndicator: addIndicator,
}); });
} }
@@ -48,6 +51,10 @@ export default function DMs() {
)} )}
sendRequest={(req) => { sendRequest={(req) => {
console.log("Sending request: ", req); console.log("Sending request: ", req);
while (
targetNode.current?.CONNECTING ||
app.node.current?.CONNECTING
) {}
switch (req.type) { switch (req.type) {
case "send_message": case "send_message":
targetNode.current?.send(JSON.stringify(req)); targetNode.current?.send(JSON.stringify(req));
@@ -61,6 +68,7 @@ export default function DMs() {
break; break;
} }
}} }}
indicators={indicators}
/> />
</AppLayout> </AppLayout>
) : ( ) : (
+3 -33
View File
@@ -9,6 +9,7 @@ import useApp from "@/hooks/use-app";
import { useEffectOnceWhenReady } from "@/hooks/use-once"; import { useEffectOnceWhenReady } from "@/hooks/use-once";
import ChannelView from "@/components/channel/ChannelView"; import ChannelView from "@/components/channel/ChannelView";
import { IndicatorContext } from "@/types/protocol"; import { IndicatorContext } from "@/types/protocol";
import useIndicators from "@/hooks/use-indicators";
export default function Server() { export default function Server() {
const { ip } = useParams<{ ip: string }>(); const { ip } = useParams<{ ip: string }>();
@@ -16,7 +17,7 @@ export default function Server() {
const serverRef = useRef<WebSocket | null>(null); const serverRef = useRef<WebSocket | null>(null);
const app = useApp(); const app = useApp();
const messageStore = useMessages(); const messageStore = useMessages();
const [indicators, setIndicators] = useState<IndicatorContext[]>([]); const { indicators, addIndicator } = useIndicators();
useEffectOnceWhenReady( useEffectOnceWhenReady(
() => { () => {
@@ -26,44 +27,13 @@ export default function Server() {
wsRef: serverRef, wsRef: serverRef,
setServer: app.setServer, setServer: app.setServer,
messageStore: messageStore, messageStore: messageStore,
onIndicator: (i) => { onIndicator: addIndicator,
setIndicators((prev) => {
const combined = [...prev, { ...i }];
const uniqueByUser = combined.reduce<Record<string, typeof i>>(
(acc, curr) => {
const userId = curr.indicator.params.user_id;
if (!acc[userId] || curr.expires > acc[userId].expires) {
acc[userId] = curr;
}
return acc;
},
{}
);
return Object.values(uniqueByUser);
});
},
}); });
}, },
[ip, messageStore.messages], [ip, messageStore.messages],
[undefined, (v) => v] [undefined, (v) => v]
); );
useEffect(() => {
const interval = setInterval(() => {
setIndicators((prev) =>
prev
.map((item) => ({
...item,
expires: item.expires - 1,
}))
.filter((item) => item.expires > 0)
);
}, 1000);
return () => clearInterval(interval);
}, []);
useEffect(() => { useEffect(() => {
const channelId = searchParams.get("ch"); const channelId = searchParams.get("ch");
if (channelId) { if (channelId) {
+4 -1
View File
@@ -29,7 +29,10 @@ export default function ChannelView({
app={app} app={app}
channelName={app.currentChannel.name} channelName={app.currentChannel.name}
messages={messages} messages={messages}
sendRequest={(req) => serverRef.current?.send(JSON.stringify(req))} sendRequest={(req) => {
while (serverRef.current?.CONNECTING) {}
serverRef.current?.send(JSON.stringify(req));
}}
indicators={indicators} indicators={indicators}
/> />
); );
+43
View File
@@ -0,0 +1,43 @@
import { IndicatorContext } from "@/types/protocol";
import { useEffect, useState } from "react";
export default function useIndicators() {
const [indicators, setIndicators] = useState<IndicatorContext[]>([]);
useEffect(() => {
const interval = setInterval(() => {
setIndicators((prev) =>
prev
.map((item) => ({
...item,
expires: item.expires - 1,
}))
.filter((item) => item.expires > 0)
);
}, 1000);
return () => clearInterval(interval);
}, []);
return {
indicators,
setIndicators,
addIndicator: (i: IndicatorContext) => {
setIndicators((prev) => {
const combined = [...prev, { ...i }];
const uniqueByUser = combined.reduce<Record<string, typeof i>>(
(acc, curr) => {
const userId = curr.indicator.params.user_id;
if (!acc[userId] || curr.expires > acc[userId].expires) {
acc[userId] = curr;
}
return acc;
},
{}
);
return Object.values(uniqueByUser);
});
},
};
}