import { mapMessage } from "../../../context/revoltjs/util"; import { SMOOTH_SCROLL_ON_RECEIVE } from "../Singleton"; import { RendererRoutines } from "../types"; export const SimpleRenderer: RendererRoutines = { init: async (renderer, id, 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 }, ); }); } else { renderer.setState(id, { type: "WAITING_FOR_NETWORK" }); } }, receive: async (renderer, message) => { if (message.channel !== renderer.channel) return; if (renderer.state.type !== "RENDER") return; if (renderer.state.messages.find((x) => x._id === message._id)) return; if (!renderer.state.atBottom) return; let messages = [...renderer.state.messages, mapMessage(message)]; let atTop = renderer.state.atTop; if (messages.length > 150) { messages = messages.slice(messages.length - 150); atTop = false; } renderer.setState( message.channel, { ...renderer.state, messages, atTop, }, { type: "StayAtBottom", smooth: SMOOTH_SCROLL_ON_RECEIVE }, ); }, edit: async (renderer, id, patch) => { const channel = renderer.channel; if (!channel) return; if (renderer.state.type !== "RENDER") return; let messages = [...renderer.state.messages]; let index = messages.findIndex((x) => x._id === id); if (index > -1) { let message = { ...messages[index], ...mapMessage(patch) }; messages.splice(index, 1, message); renderer.setState( channel, { ...renderer.state, messages, }, { type: "StayAtBottom" }, ); } }, delete: async (renderer, id) => { const channel = renderer.channel; if (!channel) return; if (renderer.state.type !== "RENDER") return; let messages = [...renderer.state.messages]; let index = messages.findIndex((x) => x._id === id); if (index > -1) { messages.splice(index, 1); renderer.setState( channel, { ...renderer.state, messages, }, { type: "StayAtBottom" }, ); } }, loadTop: async (renderer, generateScroll) => { const channel = renderer.channel; if (!channel) return; const state = renderer.state; if (state.type !== "RENDER") return; if (state.atTop) return; const { messages: data } = await renderer.client!.channels.fetchMessagesWithUsers( channel, { before: state.messages[0]._id, }, true, ); if (data.length === 0) { return renderer.setState(channel, { ...state, atTop: true, }); } data.reverse(); let messages = [...data.map((x) => mapMessage(x)), ...state.messages]; let atTop = false; if (data.length < 50) { atTop = true; } let atBottom = state.atBottom; if (messages.length > 150) { messages = messages.slice(0, 150); atBottom = false; } renderer.setState( channel, { ...state, atTop, atBottom, messages }, generateScroll(messages[messages.length - 1]._id), ); }, loadBottom: async (renderer, generateScroll) => { const channel = renderer.channel; if (!channel) return; const state = renderer.state; if (state.type !== "RENDER") return; if (state.atBottom) return; const { messages: data } = await renderer.client!.channels.fetchMessagesWithUsers( channel, { after: state.messages[state.messages.length - 1]._id, sort: "Oldest", }, true, ); if (data.length === 0) { return renderer.setState(channel, { ...state, atBottom: true, }); } let messages = [...state.messages, ...data.map((x) => mapMessage(x))]; let atBottom = false; if (data.length < 50) { atBottom = true; } let atTop = state.atTop; if (messages.length > 150) { messages = messages.slice(messages.length - 150); atTop = false; } renderer.setState( channel, { ...state, atTop, atBottom, messages }, generateScroll(messages[0]._id), ); }, };