+24
-21
@@ -1,12 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { StatusCodes } from "http-status-codes";
|
import { StatusCodes } from "http-status-codes";
|
||||||
import { supabase } from "../supa";
|
import { supabase } from "../supa";
|
||||||
|
|
||||||
const SERVER_AUTH_TOKENS = new Map<
|
|
||||||
string,
|
|
||||||
{ user_id: string; server_id: string }
|
|
||||||
>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/auth?token=<relayToken>?key=<serverKey>
|
* GET /api/auth?token=<relayToken>?key=<serverKey>
|
||||||
* Called by a (DM node / Server) to verify a temporary relay token.
|
* Called by a (DM node / Server) to verify a temporary relay token.
|
||||||
@@ -16,31 +10,36 @@ export async function GET(req: NextRequest) {
|
|||||||
const token = url.searchParams.get("token");
|
const token = url.searchParams.get("token");
|
||||||
const key = url.searchParams.get("key");
|
const key = url.searchParams.get("key");
|
||||||
|
|
||||||
if (!token || !key) {
|
if (!token || !key)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ message: "There should be a token and a key parameter" },
|
{ message: "There should be a token and a key parameter" },
|
||||||
{ status: StatusCodes.BAD_REQUEST }
|
{ status: StatusCodes.BAD_REQUEST }
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
const { data: server } = await supabase
|
const { data: server } = await supabase
|
||||||
.from("servers")
|
.from("servers")
|
||||||
.select("id, created_at, owner, address")
|
.select("id, created_at, owner, address")
|
||||||
.eq("key", key)
|
.eq("key", key)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
if (!server)
|
if (!server)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ message: "Key unauthorized" },
|
{ message: "Key unauthorized" },
|
||||||
{ status: StatusCodes.UNAUTHORIZED }
|
{ status: StatusCodes.UNAUTHORIZED }
|
||||||
);
|
);
|
||||||
|
|
||||||
const auth = SERVER_AUTH_TOKENS.get(token);
|
const { data: auth } = await supabase
|
||||||
if (!auth) {
|
.from("server_auth")
|
||||||
|
.delete()
|
||||||
|
.eq("key", token)
|
||||||
|
.select()
|
||||||
|
.maybeSingle();
|
||||||
|
|
||||||
|
if (!auth)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ message: "Invalid or expired token" },
|
{ message: "Invalid or expired token" },
|
||||||
{ status: StatusCodes.NOT_FOUND }
|
{ status: StatusCodes.NOT_FOUND }
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (auth.server_id !== server.id)
|
if (auth.server_id !== server.id)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -48,8 +47,6 @@ export async function GET(req: NextRequest) {
|
|||||||
{ status: StatusCodes.UNAUTHORIZED }
|
{ status: StatusCodes.UNAUTHORIZED }
|
||||||
);
|
);
|
||||||
|
|
||||||
SERVER_AUTH_TOKENS.delete(token);
|
|
||||||
|
|
||||||
return NextResponse.json({ message: "ok", ...auth });
|
return NextResponse.json({ message: "ok", ...auth });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +73,10 @@ export async function POST(req: NextRequest) {
|
|||||||
{ status: StatusCodes.BAD_REQUEST }
|
{ status: StatusCodes.BAD_REQUEST }
|
||||||
);
|
);
|
||||||
|
|
||||||
const supabaseToken = authHeader.value;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: { user },
|
data: { user },
|
||||||
error,
|
error,
|
||||||
} = await supabase.auth.getUser(supabaseToken);
|
} = await supabase.auth.getUser(authHeader.value);
|
||||||
|
|
||||||
if (error || !user) {
|
if (error || !user) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -90,12 +85,20 @@ export async function POST(req: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const relayToken = crypto.randomUUID();
|
const { data: relayToken, error: errorRelay } = await supabase
|
||||||
|
.from("server_auth")
|
||||||
SERVER_AUTH_TOKENS.set(relayToken, {
|
.insert({
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
server_id,
|
server_id,
|
||||||
});
|
})
|
||||||
|
.select()
|
||||||
|
.maybeSingle();
|
||||||
|
|
||||||
return NextResponse.json({ message: "ok", token: relayToken });
|
if (!relayToken || errorRelay)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Failed to create relay token" },
|
||||||
|
{ status: StatusCodes.INTERNAL_SERVER_ERROR }
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({ message: "ok", token: relayToken.key });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,14 +84,26 @@ export async function GET(req: NextRequest) {
|
|||||||
if (!user_id)
|
if (!user_id)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ message: "Invalid token" },
|
{ message: "Invalid token" },
|
||||||
{ status: StatusCodes.NOT_FOUND }
|
{ status: StatusCodes.BAD_REQUEST }
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: profile } = await supabase
|
const { data: profile, error } = await supabase
|
||||||
.from("profiles")
|
.from("profiles")
|
||||||
.select("id, username, display_name, avatar_url, node_address")
|
.select("id, username, display_name, avatar_url, node_address")
|
||||||
.eq("id", user_id)
|
.eq("id", user_id)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: error.message },
|
||||||
|
{ status: StatusCodes.INTERNAL_SERVER_ERROR }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!profile)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Profile not found" },
|
||||||
|
{ status: StatusCodes.NOT_FOUND }
|
||||||
|
);
|
||||||
|
|
||||||
return NextResponse.json({ message: "ok", ...profile });
|
return NextResponse.json({ message: "ok", ...profile });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ import { StringMap } from "@/types/typeUtils";
|
|||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import { useMessages } from "@/hooks/use-messages";
|
import { useMessages } from "@/hooks/use-messages";
|
||||||
|
|
||||||
// In this testing instance we are assuming that the target's node is localhost
|
|
||||||
// To make this functional we need to add a settings feature to the api
|
|
||||||
|
|
||||||
export default function DMs() {
|
export default function DMs() {
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<{ id: string }>();
|
||||||
const wsRef = useRef<WebSocket | null>(null);
|
const wsRef = useRef<WebSocket | null>(null);
|
||||||
@@ -19,9 +16,12 @@ export default function DMs() {
|
|||||||
const addMessage = useMessages((s) => s.addMessage);
|
const addMessage = useMessages((s) => s.addMessage);
|
||||||
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
||||||
const [user, setUser] = useState<UserProfile | undefined>();
|
const [user, setUser] = useState<UserProfile | undefined>();
|
||||||
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppSidebar
|
<AppSidebar
|
||||||
|
open={sidebarOpen}
|
||||||
|
setOpen={setSidebarOpen}
|
||||||
addMessage={addMessage}
|
addMessage={addMessage}
|
||||||
wsRef={wsRef}
|
wsRef={wsRef}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
@@ -31,6 +31,7 @@ export default function DMs() {
|
|||||||
messages={messages}
|
messages={messages}
|
||||||
>
|
>
|
||||||
<MessageBox
|
<MessageBox
|
||||||
|
toggleSidebar={() => setSidebarOpen(true)}
|
||||||
channelName={userList[id]?.display_name || id}
|
channelName={userList[id]?.display_name || id}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
setUserList={setUserList}
|
setUserList={setUserList}
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ export default function Chat() {
|
|||||||
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
||||||
const messages = useMessages((s) => s.messages);
|
const messages = useMessages((s) => s.messages);
|
||||||
const addMessage = useMessages((s) => s.addMessage);
|
const addMessage = useMessages((s) => s.addMessage);
|
||||||
|
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppSidebar
|
<AppSidebar
|
||||||
|
open={sidebarOpen}
|
||||||
|
setOpen={setSidebarOpen}
|
||||||
wsRef={wsRef}
|
wsRef={wsRef}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
setUserList={setUserList}
|
setUserList={setUserList}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default function Server() {
|
|||||||
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
||||||
const messages = useMessages((s) => s.messages);
|
const messages = useMessages((s) => s.messages);
|
||||||
const addMessage = useMessages((s) => s.addMessage);
|
const addMessage = useMessages((s) => s.addMessage);
|
||||||
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ip) return;
|
if (!ip) return;
|
||||||
@@ -26,6 +27,8 @@ export default function Server() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppSidebar
|
<AppSidebar
|
||||||
|
open={sidebarOpen}
|
||||||
|
setOpen={setSidebarOpen}
|
||||||
wsRef={wsNodeRef}
|
wsRef={wsNodeRef}
|
||||||
addMessage={() => {}}
|
addMessage={() => {}}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
@@ -33,6 +36,7 @@ export default function Server() {
|
|||||||
server={server}
|
server={server}
|
||||||
>
|
>
|
||||||
<MessageBox
|
<MessageBox
|
||||||
|
toggleSidebar={() => setSidebarOpen(true)}
|
||||||
channelName="General"
|
channelName="General"
|
||||||
userList={userList}
|
userList={userList}
|
||||||
setUserList={setUserList}
|
setUserList={setUserList}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "./ui/dropdown-menu";
|
} from "./ui/dropdown-menu";
|
||||||
import { SmilePlusIcon } from "lucide-react";
|
import { ChevronLeft, ChevronLeftIcon, SmilePlusIcon } from "lucide-react";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { format, isToday, isYesterday } from "date-fns";
|
import { format, isToday, isYesterday } from "date-fns";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
@@ -38,7 +38,7 @@ function MessageContainer({
|
|||||||
[message.from]: res.data as UserProfile,
|
[message.from]: res.data as UserProfile,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
.catch(console.error);
|
.catch(() => {});
|
||||||
}, [message.from, setUserList]);
|
}, [message.from, setUserList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -144,23 +144,28 @@ export default function MessageBox({
|
|||||||
setUserList,
|
setUserList,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
channelName,
|
channelName,
|
||||||
|
toggleSidebar,
|
||||||
}: {
|
}: {
|
||||||
messages: Message[];
|
messages: Message[];
|
||||||
userList: NumberMap<UserProfile>;
|
userList: NumberMap<UserProfile>;
|
||||||
setUserList: React.Dispatch<React.SetStateAction<NumberMap<UserProfile>>>;
|
setUserList: React.Dispatch<React.SetStateAction<NumberMap<UserProfile>>>;
|
||||||
sendMessage: (m: string) => void;
|
sendMessage: (m: string) => void;
|
||||||
channelName?: string;
|
channelName?: string;
|
||||||
|
toggleSidebar: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [text, setText] = useState("");
|
const [text, setText] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen w-full flex flex-col pb-5 pl-5 gap-5">
|
<div className="h-full w-full flex flex-col pb-5 pl-5 gap-5">
|
||||||
{channelName && (
|
{channelName && (
|
||||||
<header className="h-12 py-4 flex items-center border-b text-sm font-semibold">
|
<header className="h-12 py-4 flex items-center border-b text-sm font-semibold">
|
||||||
|
<span onClick={toggleSidebar} className="cursor-pointer flex">
|
||||||
|
<ChevronLeftIcon className="w-5 h-5" />
|
||||||
{channelName}
|
{channelName}
|
||||||
|
</span>
|
||||||
</header>
|
</header>
|
||||||
)}
|
)}
|
||||||
<div className="w-full flex-1 overflow-y-scroll flex gap-2 flex-col-reverse pr-5">
|
<div className="w-full h-max flex-1 overflow-y-scroll flex gap-2 flex-col-reverse pr-5">
|
||||||
{messages.map((msg) => (
|
{messages.map((msg) => (
|
||||||
<MessageContainer
|
<MessageContainer
|
||||||
key={msg.id}
|
key={msg.id}
|
||||||
@@ -170,7 +175,7 @@ export default function MessageBox({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex gap-3 pr-5">
|
<footer className="w-full flex gap-3 pr-5 mt-auto">
|
||||||
<Input
|
<Input
|
||||||
className=""
|
className=""
|
||||||
placeholder="Type a message..."
|
placeholder="Type a message..."
|
||||||
@@ -197,7 +202,7 @@ export default function MessageBox({
|
|||||||
/>
|
/>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</div>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-12
@@ -35,6 +35,7 @@ import SettingsDialog from "./settings/SettingsDialog";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { get, Response } from "@/lib/request";
|
import { get, Response } from "@/lib/request";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export default function AppSidebar({
|
export default function AppSidebar({
|
||||||
children,
|
children,
|
||||||
@@ -45,6 +46,8 @@ export default function AppSidebar({
|
|||||||
server,
|
server,
|
||||||
messages,
|
messages,
|
||||||
addMessage,
|
addMessage,
|
||||||
|
open,
|
||||||
|
setOpen,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
wsRef: React.RefObject<WebSocket | null>;
|
wsRef: React.RefObject<WebSocket | null>;
|
||||||
addMessage: (msg: Message) => void;
|
addMessage: (msg: Message) => void;
|
||||||
@@ -56,6 +59,8 @@ export default function AppSidebar({
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
setUser?: React.Dispatch<React.SetStateAction<UserProfile | undefined>>;
|
setUser?: React.Dispatch<React.SetStateAction<UserProfile | undefined>>;
|
||||||
server?: Server | undefined;
|
server?: Server | undefined;
|
||||||
|
open: boolean;
|
||||||
|
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
}>) {
|
}>) {
|
||||||
const [servers, setServers] = useState<[string, string][]>([]);
|
const [servers, setServers] = useState<[string, string][]>([]);
|
||||||
const [newServer, setNewServer] = useState({ name: "", ip: "" });
|
const [newServer, setNewServer] = useState({ name: "", ip: "" });
|
||||||
@@ -64,7 +69,11 @@ export default function AppSidebar({
|
|||||||
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
const [userList, setUserList] = useState<StringMap<UserProfile>>({});
|
||||||
|
|
||||||
const dms = Array.from(
|
const dms = Array.from(
|
||||||
new Set(messages?.flatMap((item) => [item.from, item.channel_id]) || [])
|
new Set(
|
||||||
|
messages
|
||||||
|
?.flatMap((item) => [item.from, item.channel_id])
|
||||||
|
.filter((item) => item !== user?.id) || []
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -90,6 +99,7 @@ export default function AppSidebar({
|
|||||||
label: "View",
|
label: "View",
|
||||||
onClick: () => router.push(`/chat/${m.from}`),
|
onClick: () => router.push(`/chat/${m.from}`),
|
||||||
},
|
},
|
||||||
|
position: "top-right",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -118,8 +128,13 @@ export default function AppSidebar({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen">
|
<div className="flex h-svh md:h-screen">
|
||||||
<div className="h-screen flex border-r">
|
<div
|
||||||
|
className={cn(
|
||||||
|
"border-r transition-all duration-300 ease-in-out overflow-hidden flex",
|
||||||
|
open ? "w-5xl md:w-md" : "w-0 md:w-md"
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="w-16 flex flex-col items-center gap-4 py-4 bg-muted border-r">
|
<div className="w-16 flex flex-col items-center gap-4 py-4 bg-muted border-r">
|
||||||
<Button
|
<Button
|
||||||
onClick={() => router.push(`/chat`)}
|
onClick={() => router.push(`/chat`)}
|
||||||
@@ -208,7 +223,7 @@ export default function AppSidebar({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right column */}
|
{/* Right column */}
|
||||||
<div className="w-64 flex flex-col bg-card">
|
<div className="w-full flex flex-col bg-card">
|
||||||
{server ? (
|
{server ? (
|
||||||
<div className="p-3 border-b flex items-center gap-2">
|
<div className="p-3 border-b flex items-center gap-2">
|
||||||
<h2>{server.name}</h2>
|
<h2>{server.name}</h2>
|
||||||
@@ -261,9 +276,19 @@ export default function AppSidebar({
|
|||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{open ? (
|
||||||
|
<div
|
||||||
|
className="w-screen h-full overflow-x-hidden"
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
>
|
||||||
|
<div className="overflow-x-hidden w-screen min-w-max flex-shrink-0">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
children
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,12 +305,10 @@ function DMItem({
|
|||||||
status: string;
|
status: string;
|
||||||
settings?: boolean;
|
settings?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/chat/${id}`}
|
href={settings ? "" : `/chat/${id}`}
|
||||||
className="p-2 flex flex-row items-center gap-2 cursor-pointer hover:bg-accent"
|
className="p-2 flex flex-row items-center gap-2 cursor-pointer hover:bg-accent rounded-md"
|
||||||
>
|
>
|
||||||
<ProfilePicture name={name} url={avatar} />
|
<ProfilePicture name={name} url={avatar} />
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
@@ -338,7 +361,5 @@ function getUser(
|
|||||||
|
|
||||||
get(`/api/profile/?id=${id}`, onResponse)
|
get(`/api/profile/?id=${id}`, onResponse)
|
||||||
?.then(onResponse)
|
?.then(onResponse)
|
||||||
.catch((e) => {
|
.catch((e) => {});
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Cookies from "js-cookie";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { get } from "@/lib/request";
|
import { get } from "@/lib/request";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export interface UserProfile extends ProfileSettings {
|
export interface UserProfile extends ProfileSettings {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -24,8 +25,9 @@ export default function useUser() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setUser((await get("/api/profile")).data);
|
setUser((await get("/api/profile")).data);
|
||||||
} catch {
|
} catch (e: any) {
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
|
toast.error(`Error: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { defaultSettings, getClientSettings } from "@/lib/clientSettings";
|
import { defaultSettings, getClientSettings } from "@/lib/clientSettings";
|
||||||
import { ProfileSettings, ClientSettings } from "@/types/settings";
|
import { ProfileSettings, ClientSettings } from "@/types/settings";
|
||||||
|
import axios from "axios";
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||||
|
|
||||||
export function useClientSettings(): [
|
export function useClientSettings(): [
|
||||||
@@ -31,11 +32,8 @@ export function useProfileSettings(): [
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchProfileSettings() {
|
async function fetchProfileSettings() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch("/api/profile");
|
const res = await axios.get("/api/profile");
|
||||||
if (res.ok) {
|
setSettings(res.data as ProfileSettings);
|
||||||
const data = (await res.json()) as ProfileSettings;
|
|
||||||
setSettings(data);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch profile settings:", error);
|
console.error("Failed to fetch profile settings:", error);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -26,13 +26,6 @@ export default async function auth(
|
|||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log("Connected to WebSocket:", ip);
|
console.log("Connected to WebSocket:", ip);
|
||||||
ws.send(
|
|
||||||
JSON.stringify({
|
|
||||||
version: "0.0.1",
|
|
||||||
auth_token: server_auth,
|
|
||||||
last_message: lastMessage || 0,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = (m) => {
|
ws.onmessage = (m) => {
|
||||||
@@ -41,6 +34,13 @@ export default async function auth(
|
|||||||
|
|
||||||
if (data.version) {
|
if (data.version) {
|
||||||
setServer({ channels: [], ...data });
|
setServer({ channels: [], ...data });
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
version: "0.0.1",
|
||||||
|
auth_token: server_auth,
|
||||||
|
last_message: lastMessage || 0,
|
||||||
|
})
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user