diff --git a/src-tauri/src/commands/accounts.rs b/src-tauri/src/commands/accounts.rs index 8124468..fa8461d 100644 --- a/src-tauri/src/commands/accounts.rs +++ b/src-tauri/src/commands/accounts.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use std::fs; use tauri::{AppHandle, Manager}; -use crate::protocol::ClientMeta; +use crate::types::ClientMeta; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/src-tauri/src/commands/server_list.rs b/src-tauri/src/commands/server_list.rs index e66e0ab..b084088 100644 --- a/src-tauri/src/commands/server_list.rs +++ b/src-tauri/src/commands/server_list.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fs}; use tauri::{AppHandle, Manager}; -use crate::protocol::ServerMeta; +use crate::types::ServerMeta; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 51cbccc..6a7af70 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,5 +1,5 @@ pub mod commands; -pub mod protocol; +pub mod types; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { diff --git a/src-tauri/src/protocol.rs b/src-tauri/src/protocol.rs deleted file mode 100644 index 163e0eb..0000000 --- a/src-tauri/src/protocol.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::borrow::Cow; - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ClientMeta { - pub display_name: String, - pub avatar: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ServerMeta { - pub name: String, - pub description: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "method")] -pub enum ClientMethod { - Initialized { - public_key: String, - signature: String, - - timestamp: u64, - hostname: String, - }, - - Error { - error: Cow<'static, str>, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "method")] -pub enum ServerMethod { - Initialize { - public_key: String, - signature: String, - - timestamp: u64, - hostname: String, - }, - - Meta(ClientMeta), - - Error { - error: String, - }, -} diff --git a/src-tauri/src/types.rs b/src-tauri/src/types.rs new file mode 100644 index 0000000..46497db --- /dev/null +++ b/src-tauri/src/types.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ClientMeta { + pub display_name: String, + pub avatar: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ServerMeta { + pub name: String, + pub description: String, +} diff --git a/src/app/app.ts b/src/app/app.ts index a103451..58a752c 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -7,6 +7,7 @@ import { base58 } from "@scure/base"; import axios from "axios"; import { Account, AccountsFile, getAccounts } from "@/lib/accounts"; import { Page } from "@/components/page/PageView"; +import { ClientMethod } from "./protocol"; ed.hashes.sha512 = sha512; @@ -124,7 +125,12 @@ export default class Enclave

{ return; } - this.server.websocket?.send({ method: "Meta", ...account.meta }); + if (this.server.websocket) { + this.server.websocket.send({ method: "Meta", ...account.meta }); + this.server.websocket.websocket.onmessage = (msg) => { + this.onMessage(JSON.parse(msg.data)); + }; + } const metaResponse = await axios.get( getHTTPUrl(hostname, isSecure, "/meta"), @@ -140,4 +146,37 @@ export default class Enclave

{ this.forceRender(); } + + public async onMessage(msg: ClientMethod) { + const server = this.server; + + if (!server) { + console.error("Unable to get server for message, MSG:", msg); + return; + } + + switch (msg.method) { + case "Initialized": + console.error("Already initialized"); + return; + + case "Error": + console.error("Server error:", msg.error); + return; + + case "Messages": + console.log("msg", msg.messages); + Object.entries(msg.messages).forEach(([channelId, messages]) => { + if (!server.messages[channelId]) { + server.messages[channelId] = []; + } + + messages.forEach((message) => { + server.messages[channelId].push(message); + }); + }); + + return; + } + } } diff --git a/src/app/protocol.ts b/src/app/protocol.ts index b509425..ed48003 100644 --- a/src/app/protocol.ts +++ b/src/app/protocol.ts @@ -1,4 +1,4 @@ -import { ClientMeta, MessageData } from "@/lib/types"; +import { ClientMeta, MessageData, StoredMessage } from "@/lib/types"; export type ClientMethod = | { @@ -11,6 +11,10 @@ export type ClientMethod = | { method: "Error"; error: string; + } + | { + method: "Messages"; + messages: Record; }; export type ServerMethod = @@ -21,6 +25,10 @@ export type ServerMethod = timestamp: number; hostname: string; } + | { + method: "Error"; + error: string; + } | ({ method: "Meta"; } & ClientMeta) @@ -30,6 +38,7 @@ export type ServerMethod = data: MessageData; } | { - method: "Error"; - error: string; + method: "GetMessages"; + channel_id: string; + chunk: number; }; diff --git a/src/app/server.ts b/src/app/server.ts index 0ebfcd4..c54efd1 100644 --- a/src/app/server.ts +++ b/src/app/server.ts @@ -3,7 +3,7 @@ import * as ed from "@noble/ed25519"; import EnclaveWebSocket from "./ws"; import { sha512 } from "@noble/hashes/sha2.js"; import { getWSUrl } from "@/lib/serverList"; -import { ServerMeta } from "@/lib/types"; +import { ServerMeta, StoredMessage } from "@/lib/types"; ed.hashes.sha512 = sha512; @@ -29,10 +29,12 @@ export default class EnclaveServer { public isSecure: boolean; public websocket?: EnclaveWebSocket; public meta?: ServerMeta; + public messages: Record; public constructor(hostname: string, isSecure: boolean) { this.hostname = hostname; this.isSecure = isSecure; + this.messages = {}; } public disconnect() { diff --git a/src/components/page/channel/TextChannel.tsx b/src/components/page/channel/TextChannel.tsx index b584951..166b90f 100644 --- a/src/components/page/channel/TextChannel.tsx +++ b/src/components/page/channel/TextChannel.tsx @@ -1,5 +1,6 @@ import Enclave from "@/app/app"; import { ChannelPageProps } from "@/components/page/PageView"; +import { useEffect } from "react"; export default function TextChannel({ appRef, @@ -10,13 +11,17 @@ export default function TextChannel({ if (!channel) return null; + useEffect(() => { + appRef.current?.server?.websocket?.send({ + method: "GetMessages", + channel_id: channel.id, + chunk: 0, + }); + + appRef.current?.forceRender(); + }, []); + return ( -

{ - appRef.current?.sendMessage("Hello, World", channel.id); - }} - > - {channel.name} -
+
{JSON.stringify(appRef.current?.server?.messages[channel.id])}
); }