From c54fe0f1bf449b24eca093f1fdd12664447cd2de Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 8 Jul 2021 22:47:56 +0100 Subject: [PATCH] Feature: Add message links. --- external/lang | 2 +- package.json | 2 +- src/lib/renderer/Singleton.ts | 6 +-- src/lib/renderer/simple/SimpleRenderer.ts | 52 +++++++++++++------- src/lib/renderer/types.ts | 2 + src/pages/RevoltApp.tsx | 7 ++- src/pages/channels/messaging/MessageArea.tsx | 26 ++++++++++ yarn.lock | 8 +-- 8 files changed, 78 insertions(+), 27 deletions(-) diff --git a/external/lang b/external/lang index b18d44b5..846a0e8a 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit b18d44b56037d09bd2fac68be04e42723e50a3d7 +Subproject commit 846a0e8a3a36e606d4d4249e495dc0daeee9c65d diff --git a/package.json b/package.json index 0ca7a34e..becf247e 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "react-router-dom": "^5.2.0", "react-scroll": "^1.8.2", "redux": "^4.1.0", - "revolt.js": "4.3.3-alpha.10", + "revolt.js": "4.3.3-alpha.11", "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", diff --git a/src/lib/renderer/Singleton.ts b/src/lib/renderer/Singleton.ts index f95e8df8..83bb2efe 100644 --- a/src/lib/renderer/Singleton.ts +++ b/src/lib/renderer/Singleton.ts @@ -72,11 +72,11 @@ export class SingletonRenderer extends EventEmitter3 { this.stale = true; } - async init(id: string) { + async init(id: string, message_id?: string) { this.channel = id; this.stale = false; this.setStateUnguarded({ type: "LOADING" }); - await this.currentRenderer.init(this, id); + await this.currentRenderer.init(this, id, message_id); } async reloadStale(id: string) { @@ -180,7 +180,7 @@ export class SingletonRenderer extends EventEmitter3 { if (this.state.type === "RENDER" && this.state.atBottom) { this.emit("scroll", { type: "ScrollToBottom", smooth }); } else { - await this.currentRenderer.init(this, id, true); + await this.currentRenderer.init(this, id, undefined, true); } } } diff --git a/src/lib/renderer/simple/SimpleRenderer.ts b/src/lib/renderer/simple/SimpleRenderer.ts index 05feadc8..00e91d63 100644 --- a/src/lib/renderer/simple/SimpleRenderer.ts +++ b/src/lib/renderer/simple/SimpleRenderer.ts @@ -4,24 +4,42 @@ import { SMOOTH_SCROLL_ON_RECEIVE } from "../Singleton"; import { RendererRoutines } from "../types"; export const SimpleRenderer: RendererRoutines = { - init: async (renderer, id, smooth) => { + init: async (renderer, id, nearby, smooth) => { if (renderer.client!.websocket.connected) { - renderer - .client!.channels.fetchMessagesWithUsers(id, {}, true) - .then(({ messages: data }) => { - data.reverse(); - let messages = data.map((x) => mapMessage(x)); - renderer.setState( - id, - { - type: "RENDER", - messages, - atTop: data.length < 50, - atBottom: true, - }, - { type: "ScrollToBottom", smooth }, - ); - }); + if (nearby) + renderer + .client!.channels.fetchMessagesWithUsers(id, { nearby, limit: 100 }, true) + .then(({ messages: data }) => { + data.sort((a, b) => a._id.localeCompare(b._id)); + let messages = data.map((x) => mapMessage(x)); + renderer.setState( + id, + { + type: "RENDER", + messages, + atTop: false, + atBottom: false, + }, + { type: "ScrollToView", id: nearby }, + ); + }); + else + renderer + .client!.channels.fetchMessagesWithUsers(id, {}, true) + .then(({ messages: data }) => { + data.reverse(); + let messages = data.map((x) => mapMessage(x)); + renderer.setState( + id, + { + type: "RENDER", + messages, + atTop: data.length < 50, + atBottom: true, + }, + { type: "ScrollToBottom", smooth }, + ); + }); } else { renderer.setState(id, { type: "WAITING_FOR_NETWORK" }); } diff --git a/src/lib/renderer/types.ts b/src/lib/renderer/types.ts index e0669250..66745368 100644 --- a/src/lib/renderer/types.ts +++ b/src/lib/renderer/types.ts @@ -8,6 +8,7 @@ export type ScrollState = | { type: "Free" } | { type: "Bottom"; scrollingUntil?: number } | { type: "ScrollToBottom" | "StayAtBottom"; smooth?: boolean } + | { type: "ScrollToView", id: string } | { type: "OffsetTop"; previousHeight: number } | { type: "ScrollTop"; y: number }; @@ -26,6 +27,7 @@ export interface RendererRoutines { init: ( renderer: SingletonRenderer, id: string, + message?: string, smooth?: boolean, ) => Promise; diff --git a/src/pages/RevoltApp.tsx b/src/pages/RevoltApp.tsx index d5137d88..446494d6 100644 --- a/src/pages/RevoltApp.tsx +++ b/src/pages/RevoltApp.tsx @@ -90,9 +90,14 @@ export default function App() { /> + + (); + // ? This is the scroll container. const ref = useRef(null); const { width, height } = useResizeObserver({ ref }); @@ -91,6 +97,11 @@ export function MessageArea({ id }: Props) { container: ref.current, duration: scrollState.current.smooth ? 150 : 0, }); + } else if (scrollState.current.type === "ScrollToView") { + document.getElementById(scrollState.current.id) + ?.scrollIntoView(); + + setScrollState({ type: "Free" }); } else if (scrollState.current.type === "OffsetTop") { animateScroll.scrollTo( Math.max( @@ -152,9 +163,24 @@ export function MessageArea({ id }: Props) { // ? Load channel initially. useEffect(() => { + if (message) return; SingletonMessageRenderer.init(id); }, [id]); + // ? If message present or changes, load it as well. + useEffect(() => { + if (message) { + SingletonMessageRenderer.init(id, message); + + let channel = client.channels.get(id); + if (channel?.channel_type === 'TextChannel') { + history.push(`/server/${channel.server}/channel/${id}`); + } else { + history.push(`/channel/${id}`); + } + } + }, [message]); + // ? If we are waiting for network, try again. useEffect(() => { switch (status) { diff --git a/yarn.lock b/yarn.lock index f1c01393..870786de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3563,10 +3563,10 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revolt.js@4.3.3-alpha.10: - version "4.3.3-alpha.10" - resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.10.tgz#3acbdd4f44c7f12be53faa0318396ce21694acde" - integrity sha512-s9VEJX1LBiHCl8mXyqD0+GnIQg6WJj7CV8vUAO6Rv35Jwy0gOjjOvma4csXeZTdiLpPoVFxutgBj8bXMnVL5Aw== +revolt.js@4.3.3-alpha.11: + version "4.3.3-alpha.11" + resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.11.tgz#d8499607cc3de48ab580c7da9bf2e8e0a1992ae9" + integrity sha512-//UB+VXKE4MziUoBm2RMDZNgxLmrar8FQ1hCewkdFbTdfkYey6joagNVF5DW+ImbffYbrnnjZhlJP7RRXZ5IeQ== dependencies: "@insertish/mutable" "1.1.0" axios "^0.19.2"