Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/chat/sync.ts
Views: 687
import { Map as iMap, fromJS } from "immutable";1import type { ChatMessage } from "./types";23export function initFromSyncDB({ syncdb, store }) {4const v = {};5for (let x of syncdb.get().toJS()) {6x = processSyncDBObj(x);7if (x != null) {8v[x.date.valueOf()] = x;9}10}11store.setState({12messages: fromJS(v),13});14}1516export function handleSyncDBChange({ syncdb, store, changes }) {17if (syncdb == null || store == null || changes == null) {18console.warn("handleSyncDBChange: inputs should not be null");19return;20}21changes.map((obj) => {22obj = obj.toJS();23switch (obj.event) {24case "draft": {25let drafts = store.get("drafts") ?? (fromJS({}) as any);26// used to show that another user is editing a message.27const record = syncdb.get_one(obj);28if (record == null) {29drafts = drafts.delete(obj.sender_id);30} else {31const sender_id = record.get("sender_id");32drafts = drafts.set(sender_id, record);33}34store.setState({ drafts });35return;36}3738case "chat": {39let changed: boolean = false;40let messages = store.get("messages") ?? iMap();41obj.date = new Date(obj.date);42const record = syncdb.get_one(obj);43let x = record?.toJS();44if (x == null) {45// delete46messages = messages.delete(`${obj.date.valueOf()}`);47changed = true;48} else {49x = processSyncDBObj(x);50if (x != null) {51messages = messages.set(`${x.date.valueOf()}`, fromJS(x));52changed = true;53}54}55if (changed) {56store.setState({ messages });57}58return;59}6061default:62console.warn("unknown chat event: ", obj.event);63}64});65}6667// NOTE: x must be already a plain JS object (.toJS()).68// This function mutates x.69export function processSyncDBObj(x: ChatMessage): ChatMessage | undefined {70if (x.event !== "chat") {71// Event used to be used for video chat, etc...; but we have a better approach now, so72// all events we care about are chat.73return;74}75if ((x as any).video_chat?.is_video_chat) {76// discard/ignore anything else related to the old old video chat approach77return;78}79x.date = new Date(x.date);80if ((x.history?.length ?? 0) > 0) {81// nontrivial history -- nothing to do82} else if ((x as any).payload != null) {83// for old chats with payload: content (2014-2016)... plus the script @hsy wrote in the work project ;-(84x.history = [];85x.history.push({86content: (x as any).payload.content,87author_id: x.sender_id,88date: new Date(x.date).toISOString(),89});90delete (x as any).payload;91} else if ((x as any).mesg != null) {92// for old chats with mesg: content (up to 2014)93x.history = [];94x.history.push({95content: (x as any).mesg.content,96author_id: x.sender_id,97date: new Date(x.date).toISOString(),98});99delete (x as any).mesg;100}101if (x.history == null) {102x.history = [];103}104if (!x.editing) {105x.editing = {};106}107x.folding ??= [];108x.feedback ??= {};109return x;110}111112113