From f17e069156c81f521bfb875739c2fd9b0cfca50f Mon Sep 17 00:00:00 2001 From: ZickZenni Date: Thu, 5 Sep 2024 16:14:22 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Added=20relationships=20and=20home?= =?UTF-8?q?=20screen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/discord/core/client.ts | 41 ++++++++++--- src/discord/managers/UserManager.ts | 18 ++++++ src/discord/structures/Relationship.ts | 10 ++++ src/discord/ws/types.ts | 11 ++++ src/main/app.ts | 8 ++- src/main/ipc.ts | 3 +- src/renderer/components/Serverbar/index.tsx | 5 ++ src/renderer/pages/Guild/Guild.css | 6 +- src/renderer/pages/Guild/index.tsx | 2 +- src/renderer/pages/Home/Home.css | 62 +++++++++++++++++++ src/renderer/pages/Home/index.tsx | 66 ++++++++++++++++++++- src/renderer/styles/vars.css | 7 ++- 12 files changed, 218 insertions(+), 21 deletions(-) create mode 100644 src/discord/managers/UserManager.ts create mode 100644 src/discord/structures/Relationship.ts diff --git a/src/discord/core/client.ts b/src/discord/core/client.ts index 8dcefd4..7f914de 100644 --- a/src/discord/core/client.ts +++ b/src/discord/core/client.ts @@ -6,13 +6,16 @@ import { GatewayReadyDispatchData, GatewaySocketEvent, } from '../ws/types'; -import { debug, setDebugging } from './logger'; +import { setDebugging } from './logger'; import { GuildManager } from '../managers/GuildManager'; import { ChannelManager } from '../managers/ChannelManager'; import MainGuild from '../structures/guild/MainGuild'; import MainChannel from '../structures/channel/MainChannel'; import MainUser from '../structures/user/MainUser'; import { Message } from '../structures/Message'; +import { Relationship } from '../structures/Relationship'; +import { registerHandler } from '../../main/ipc'; +import UserManager from '../managers/UserManager'; export interface ClientEvents { ready: () => void; @@ -33,7 +36,9 @@ export class Client extends TypedEmitter { public readonly channels: ChannelManager; - public user: MainUser | null; + public readonly users: UserManager; + + public relationships: Relationship[]; private token: string; @@ -67,12 +72,14 @@ export class Client extends TypedEmitter { }); } }); - this.user = new MainUser(data.user); - debug( - 'Client', - "Client received 'Ready' dispatch event and is now ready to use!", - ); + data.users.forEach((userData) => { + this.users.cache.set(userData.id, new MainUser(userData)); + }); + + this.relationships = data.relationships; + + this.users.clientUser = new MainUser(data.user); this.emit('ready'); } @@ -88,8 +95,10 @@ export class Client extends TypedEmitter { }); this.guilds = new GuildManager(this); this.channels = new ChannelManager(this); - this.user = null; + this.users = new UserManager(this); + this.relationships = []; this.token = ''; + this.registerIpcs(); } /** @@ -156,4 +165,20 @@ export class Client extends TypedEmitter { this.gateway.socket.readyState === WebSocket.OPEN ); } + + private registerIpcs() { + registerHandler('discord:relationships', () => { + return { + relationships: this.relationships, + users: this.users.cache + .values() + .filter((v) => { + return ( + this.relationships.find((r) => r.user_id === v.id) !== undefined + ); + }) + .map((v) => v.toRaw()), + }; + }); + } } diff --git a/src/discord/managers/UserManager.ts b/src/discord/managers/UserManager.ts new file mode 100644 index 0000000..30865c2 --- /dev/null +++ b/src/discord/managers/UserManager.ts @@ -0,0 +1,18 @@ +import { CacheHolder } from '../core/cache'; +import { Client } from '../core/client'; +import { Snowflake } from '../structures/Snowflake'; +import MainUser from '../structures/user/MainUser'; + +export default class UserManager { + public readonly client: Client; + + public readonly cache: CacheHolder; + + public clientUser: MainUser | null; + + constructor(client: Client) { + this.client = client; + this.cache = new CacheHolder(); + this.clientUser = null; + } +} diff --git a/src/discord/structures/Relationship.ts b/src/discord/structures/Relationship.ts new file mode 100644 index 0000000..7f510c1 --- /dev/null +++ b/src/discord/structures/Relationship.ts @@ -0,0 +1,10 @@ +import { Snowflake } from './Snowflake'; + +export interface Relationship { + user_id: Snowflake; + type: number; + since: string; + nickname: any; + is_spam_request: boolean; + id: Snowflake; +} diff --git a/src/discord/ws/types.ts b/src/discord/ws/types.ts index 9cd6dbb..e8f7cb6 100644 --- a/src/discord/ws/types.ts +++ b/src/discord/ws/types.ts @@ -1,6 +1,7 @@ /* eslint-disable no-unused-vars */ import { IGuildData } from '../structures/guild/BaseGuild'; +import { Relationship } from '../structures/Relationship'; import { IUserData } from '../structures/user/BaseUser'; export enum GatewayOpcodes { @@ -114,6 +115,11 @@ export interface GatewayReadyDispatchData { */ user: IUserData; + /** + * Other users + */ + users: IUserData[]; + /** * Guilds you are in */ @@ -128,4 +134,9 @@ export interface GatewayReadyDispatchData { * The url you'll use when reconnecting */ resume_gateway_url: string; + + /** + * Your relationships with other users + */ + relationships: Relationship[]; } diff --git a/src/main/app.ts b/src/main/app.ts index d82b130..9d7d36f 100644 --- a/src/main/app.ts +++ b/src/main/app.ts @@ -58,6 +58,12 @@ export default class WaveCordApp { this.discord.on('dispatch', (event: GatewaySocketEvent) => { logger.info('Received event: ', event.event); + if (event.event === GatewayDispatchEvents.Ready) + fs.writeFileSync( + '/home/rohloff/Documents/discord_ready_output.txt', + JSON.stringify(event.data ?? {}), + ); + if (event.event === GatewayDispatchEvents.MessageCreate) { const message = event.data as Message; sendToRenderer(this.window!, 'discord:gateway:message-create', message); @@ -198,7 +204,7 @@ export default class WaveCordApp { }); registerHandler('discord:user', (userId: string | undefined) => { - if (userId === undefined) return this.discord.user?.toRaw(); + if (userId === undefined) return this.discord.users.clientUser?.toRaw(); return null; }); diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 40fbfa1..9d03a26 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -19,7 +19,8 @@ export type IpcChannels = | 'discord:get-last-visited-channel' | 'discord:set-last-visited-channel' | 'discord:create-message' - | 'discord:gateway:message-create'; + | 'discord:gateway:message-create' + | 'discord:relationships'; export function registerHandler( channel: IpcChannels, diff --git a/src/renderer/components/Serverbar/index.tsx b/src/renderer/components/Serverbar/index.tsx index eeae060..7ebf494 100644 --- a/src/renderer/components/Serverbar/index.tsx +++ b/src/renderer/components/Serverbar/index.tsx @@ -37,6 +37,11 @@ export default function Serverbar() { return (
+ +
+

WC

+
+ {guilds.map((guild) => { const selected = location.pathname.startsWith(`/guild/${guild.id}`); diff --git a/src/renderer/pages/Guild/Guild.css b/src/renderer/pages/Guild/Guild.css index a515e04..6beda4d 100644 --- a/src/renderer/pages/Guild/Guild.css +++ b/src/renderer/pages/Guild/Guild.css @@ -1,7 +1,3 @@ -:root { - --guild-page--sidebar-width: 300px; -} - .guild_page { width: 100%; height: 100%; @@ -17,7 +13,7 @@ .guild_page__channel_list { display: flex; flex-direction: column; - width: var(--guild-page--sidebar-width); + width: var(--sidebar-width); overflow: hidden; height: calc(100% - var(--topbar-height) - 80px); background: var(--background); diff --git a/src/renderer/pages/Guild/index.tsx b/src/renderer/pages/Guild/index.tsx index fbecc30..5219996 100644 --- a/src/renderer/pages/Guild/index.tsx +++ b/src/renderer/pages/Guild/index.tsx @@ -175,7 +175,7 @@ export default function GuildPage() {
diff --git a/src/renderer/pages/Home/Home.css b/src/renderer/pages/Home/Home.css index bbb85e4..0da96dd 100644 --- a/src/renderer/pages/Home/Home.css +++ b/src/renderer/pages/Home/Home.css @@ -1,2 +1,64 @@ +.home_page { + width: 100%; + height: 100%; +} + .home_page__container { + width: 100%; + height: 100%; + display: flex; +} + +.home_page__content { + margin-top: var(--topbar-height); + background: var(--background2); + width: 100%; + height: 100%; +} + +.home_page__sidebar { + z-index: 100; + flex-shrink: 0; + display: flex; + flex-direction: column; + width: var(--sidebar-width); + overflow: hidden; + height: 100%; + background: var(--background); + overflow-y: auto; + border-right: var(--border) var(--border-size) solid; +} + +.home_page__sidebar_list { + padding-top: calc(var(--titlebar-height) + 20px); + display: flex; + flex-direction: column; + width: var(--sidebar-width); + overflow: hidden; + height: calc(100% - 80px); + background: var(--background); + overflow-y: auto; + border-right: var(--border) var(--border-size) solid; +} + +.home_page__relationship { + display: flex; + width: calc(100% - 18px - 18px); + height: 28px; + padding: 12px 18px; + gap: 18px; + user-select: none; + text-decoration: none; + align-items: center; + color: var(--unselected-text); + flex-shrink: 0; +} + +.home_page__relationship:hover { + background: color-mix(in srgb, var(--background), #ffffff1d); +} + +.home_page__avatar { + width: 48px; + border-radius: 50%; } diff --git a/src/renderer/pages/Home/index.tsx b/src/renderer/pages/Home/index.tsx index ce47191..03579a5 100644 --- a/src/renderer/pages/Home/index.tsx +++ b/src/renderer/pages/Home/index.tsx @@ -1,12 +1,74 @@ +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; import Topbar from '../../components/Topbar'; +import UserPanel from '../../components/UserPanel'; import './Home.css'; +import { Relationship } from '../../../discord/structures/Relationship'; +import RendererUser from '../../../discord/structures/user/RendererUser'; +import { IUserData } from '../../../discord/structures/user/BaseUser'; export default function HomePage() { + const [relationships, setRelationships] = useState([]); + const [users, setUsers] = useState([]); + + useEffect(() => { + const fetchRelationships = async () => { + const ready = await window.electron.ipcRenderer + .invoke('discord:ready') + .catch((err) => window.logger.error(err)); + + if (!ready) return false; + + const data: any = await window.electron.ipcRenderer + .invoke('discord:relationships') + .catch((err) => window.logger.error(err)); + + const ships: Relationship[] = data.relationships; + const usrs: IUserData[] = data.users; + + window.logger.info('Received relationships:', data); + setRelationships(ships); + setUsers(usrs.map((v) => new RendererUser(v))); + return true; + }; + + const interval = setInterval(async () => { + if (await fetchRelationships()) clearInterval(interval); + }, 10); + + return () => { + clearInterval(interval); + }; + }, []); + return ( -
+
-
+
+
+ {relationships.map((relationship) => { + const user = users.find((v) => v.id === relationship.user_id); + if (user === undefined) return null; + + return ( + + {`UserAvatarRelationship:${user.id}`} +

{user.globalName}

+ + ); + })} +
+ +
diff --git a/src/renderer/styles/vars.css b/src/renderer/styles/vars.css index 5753ff5..c94a561 100644 --- a/src/renderer/styles/vars.css +++ b/src/renderer/styles/vars.css @@ -1,9 +1,9 @@ :root { --text: #e4edf6; - --unselected-text: #949BA4; + --unselected-text: #949ba4; - --background: #171B1D; - --background2: #0A0E0F; + --background: #171b1d; + --background2: #0a0e0f; --border: #212328; --primary: #85b9ea; @@ -14,4 +14,5 @@ --titlebar-height: 24px; --topbar-height: 150px; --serverbar-width: 75px; + --sidebar-width: 300px; }