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 { useParams } from "next/navigation";
import useApp from "@/hooks/use-app";
import { useEffect, useRef } from "react";
import auth from "@/lib/auth";
export default function DMs() {
const { id } = useParams<{ id: string }>();
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 (
<AppSidebar app={app}>
+19 -44
View File
@@ -56,6 +56,7 @@ export default function AppSidebar({
const [newServer, setNewServer] = useState({ name: "", ip: "" });
const [query, setQuery] = useState("");
const router = useRouter();
const [filteredDms, setFilteredDms] = useState<UserProfile[]>([]);
const dms = Array.from(
new Set(
@@ -65,14 +66,20 @@ export default function AppSidebar({
)
);
const filteredDms = dms.filter((id) => {
const user = getUser(id, app.profiles, app.setProfiles);
const name = user?.display_name || "";
return (
name.toLowerCase().includes(query.toLowerCase()) ||
id.toLowerCase().includes(query.toLowerCase())
useEffect(() => {
const load = async () => {
const users = await Promise.all(dms.map((id) => app.getUserById(id)));
setFilteredDms(
users.filter(
(user) =>
user !== null &&
(user?.username.toLowerCase().includes(query.toLowerCase()) ||
user?.id.toLowerCase().includes(query.toLowerCase()))
) as UserProfile[]
);
});
};
load();
}, [dms]);
useEffect(() => {
const s = Cookies.get("servers")?.split(",");
@@ -246,19 +253,13 @@ export default function AppSidebar({
</>
) : (
<>
{filteredDms.map((id) => (
{filteredDms.map((user) => (
<DMItem
name={
getUser(id, app.profiles, app.setProfiles)
?.display_name || id
}
id={id}
name={user.display_name}
id={user.id}
status="online"
avatar={
getUser(id, app.profiles, app.setProfiles)
?.avatar_url || ""
}
key={id}
avatar={user.avatar_url}
key={user.id}
app={app}
/>
))}
@@ -368,29 +369,3 @@ function ChannelIcon({ kind }: { kind: "text" | "voice" }) {
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 () => {
localStorage.removeItem("chat-messages");
localStorage.removeItem("server-messages");
setFeedback(undefined);
const validationError = validateInput();
if (validationError) {
+2
View File
@@ -18,6 +18,8 @@ export default function Login() {
const router = useRouter();
const login = async () => {
localStorage.removeItem("chat-messages");
localStorage.removeItem("server-messages");
setFeedback(undefined);
try {
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 useUser, { UserProfile } from "./get-user";
import { useClientSettings } from "./use-settings";
import { get, Response } from "@/lib/request";
export default function useApp(): App {
const node = useRef<WebSocket | null>(null);
@@ -24,5 +25,23 @@ export default function useApp(): App {
addMessage,
sidebarOpen,
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() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
return !!isMobile
return !!isMobile;
}
+2
View File
@@ -21,4 +21,6 @@ export default interface App {
sidebarOpen: boolean;
setSidebarOpen: SetState<boolean>;
getUserById: (userId: string) => Promise<UserProfile | null>;
}