mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-06 17:11:55 +00:00
Feature: Add message links.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" });
|
||||
}
|
||||
|
||||
@@ -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<void>;
|
||||
|
||||
|
||||
@@ -90,9 +90,14 @@ export default function App() {
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/channel/:channel/message/:message"
|
||||
path="/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/server/:server/channel/:channel"
|
||||
component={Channel}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { RenderState, ScrollState } from "../../../lib/renderer/types";
|
||||
import { IntermediateContext } from "../../../context/intermediate/Intermediate";
|
||||
import RequiresOnline from "../../../context/revoltjs/RequiresOnline";
|
||||
import {
|
||||
AppContext,
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
@@ -27,6 +28,7 @@ import Preloader from "../../../components/ui/Preloader";
|
||||
|
||||
import ConversationStart from "./ConversationStart";
|
||||
import MessageRenderer from "./MessageRenderer";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
|
||||
const Area = styled.div`
|
||||
height: 100%;
|
||||
@@ -53,9 +55,13 @@ export const MessageAreaWidthContext = createContext(0);
|
||||
export const MESSAGE_AREA_PADDING = 82;
|
||||
|
||||
export function MessageArea({ id }: Props) {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const status = useContext(StatusContext);
|
||||
const { focusTaken } = useContext(IntermediateContext);
|
||||
|
||||
const { message } = useParams<{ message: string }>();
|
||||
|
||||
// ? This is the scroll container.
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const { width, height } = useResizeObserver<HTMLDivElement>({ 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) {
|
||||
|
||||
Reference in New Issue
Block a user