Target node

This commit is contained in:
2025-10-17 16:04:33 +02:00
parent c784b80773
commit a4596270c8
7 changed files with 78 additions and 56 deletions
+20
View File
@@ -4,10 +4,30 @@ import MessageBox from "@/components/MessageBox";
import AppSidebar from "@/components/Sidebar"; import AppSidebar from "@/components/Sidebar";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import useApp from "@/hooks/use-app"; import useApp from "@/hooks/use-app";
import { useEffect, useRef } from "react";
import auth from "@/lib/auth";
export default function DMs() { export default function DMs() {
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
const app = useApp(); const app = useApp();
const targetNode = useRef<WebSocket | null>(null);
useEffect(() => {
async function connectTargetNode() {
const target = await app.getUserById(id);
if (target) {
auth(
target.node_address,
targetNode,
() => {},
app.addMessage,
() => {}
);
}
}
connectTargetNode().then(() => {});
}, [id]);
return ( return (
<AppSidebar app={app}> <AppSidebar app={app}>
+20 -45
View File
@@ -56,6 +56,7 @@ export default function AppSidebar({
const [newServer, setNewServer] = useState({ name: "", ip: "" }); const [newServer, setNewServer] = useState({ name: "", ip: "" });
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const router = useRouter(); const router = useRouter();
const [filteredDms, setFilteredDms] = useState<UserProfile[]>([]);
const dms = Array.from( const dms = Array.from(
new Set( new Set(
@@ -65,14 +66,20 @@ export default function AppSidebar({
) )
); );
const filteredDms = dms.filter((id) => { useEffect(() => {
const user = getUser(id, app.profiles, app.setProfiles); const load = async () => {
const name = user?.display_name || ""; const users = await Promise.all(dms.map((id) => app.getUserById(id)));
return ( setFilteredDms(
name.toLowerCase().includes(query.toLowerCase()) || users.filter(
id.toLowerCase().includes(query.toLowerCase()) (user) =>
); user !== null &&
}); (user?.username.toLowerCase().includes(query.toLowerCase()) ||
user?.id.toLowerCase().includes(query.toLowerCase()))
) as UserProfile[]
);
};
load();
}, [dms]);
useEffect(() => { useEffect(() => {
const s = Cookies.get("servers")?.split(","); const s = Cookies.get("servers")?.split(",");
@@ -246,19 +253,13 @@ export default function AppSidebar({
</> </>
) : ( ) : (
<> <>
{filteredDms.map((id) => ( {filteredDms.map((user) => (
<DMItem <DMItem
name={ name={user.display_name}
getUser(id, app.profiles, app.setProfiles) id={user.id}
?.display_name || id
}
id={id}
status="online" status="online"
avatar={ avatar={user.avatar_url}
getUser(id, app.profiles, app.setProfiles) key={user.id}
?.avatar_url || ""
}
key={id}
app={app} app={app}
/> />
))} ))}
@@ -368,29 +369,3 @@ function ChannelIcon({ kind }: { kind: "text" | "voice" }) {
return null; return null;
} }
} }
function getUser(
id: string,
userList: StringMap<UserProfile | null>,
setUserList: React.Dispatch<
React.SetStateAction<StringMap<UserProfile | null>>
>
) {
if (userList[id] !== undefined) return userList[id];
const onResponse = (res: Response<UserProfile>) => {
setUserList((prev) => {
prev[id] = res.data as UserProfile;
return prev;
});
};
get(`/api/profile/?id=${id}`, onResponse)
?.then(onResponse)
.catch((e) => {
setUserList((prev) => {
prev[id] = null;
return prev;
});
});
}
+2
View File
@@ -58,6 +58,8 @@ export default function CreateAccount() {
}; };
const signup = async () => { const signup = async () => {
localStorage.removeItem("chat-messages");
localStorage.removeItem("server-messages");
setFeedback(undefined); setFeedback(undefined);
const validationError = validateInput(); const validationError = validateInput();
if (validationError) { if (validationError) {
+2
View File
@@ -18,6 +18,8 @@ export default function Login() {
const router = useRouter(); const router = useRouter();
const login = async () => { const login = async () => {
localStorage.removeItem("chat-messages");
localStorage.removeItem("server-messages");
setFeedback(undefined); setFeedback(undefined);
try { try {
const res = await axios.get("/api/user", { const res = await axios.get("/api/user", {
+19
View File
@@ -4,6 +4,7 @@ import { useMessages } from "./use-messages";
import { StringMap } from "@/types/typeUtils"; import { StringMap } from "@/types/typeUtils";
import useUser, { UserProfile } from "./get-user"; import useUser, { UserProfile } from "./get-user";
import { useClientSettings } from "./use-settings"; import { useClientSettings } from "./use-settings";
import { get, Response } from "@/lib/request";
export default function useApp(): App { export default function useApp(): App {
const node = useRef<WebSocket | null>(null); const node = useRef<WebSocket | null>(null);
@@ -24,5 +25,23 @@ export default function useApp(): App {
addMessage, addMessage,
sidebarOpen, sidebarOpen,
setSidebarOpen, setSidebarOpen,
getUserById: async (id: string) => {
if (profiles[id] !== undefined) return profiles[id];
const onResponse = (res: Response<UserProfile>) => {
setProfiles((prev) => {
prev[id] = res.data as UserProfile;
return prev;
});
};
try {
const user = await get(`/api/profile/?id=${id}`, onResponse);
onResponse(user);
return user.data;
} catch {
return null;
}
},
}; };
} }
+13 -11
View File
@@ -1,19 +1,21 @@
import * as React from "react" import * as React from "react";
const MOBILE_BREAKPOINT = 768 const MOBILE_BREAKPOINT = 768;
export function useIsMobile() { export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined) const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined
);
React.useEffect(() => { React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => { const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
} };
mql.addEventListener("change", onChange) mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange) return () => mql.removeEventListener("change", onChange);
}, []) }, []);
return !!isMobile return !!isMobile;
} }
+2
View File
@@ -21,4 +21,6 @@ export default interface App {
sidebarOpen: boolean; sidebarOpen: boolean;
setSidebarOpen: SetState<boolean>; setSidebarOpen: SetState<boolean>;
getUserById: (userId: string) => Promise<UserProfile | null>;
} }