Skip to content

Commit 257aaa7

Browse files
committed
fix #7662, hopefully -- chat replies reappear
- I was using two different conflicting definitions of the date field for drafts, which caused predictable problems. Now we only use the negative of the root of the thread in all cases. I deleted *all* the hacky code (set timeouts, deleting negatives, etc.), and wrote things to use this clearer definition, hopefully
1 parent 7f57fe3 commit 257aaa7

File tree

4 files changed

+46
-36
lines changed

4 files changed

+46
-36
lines changed

src/packages/frontend/chat/actions.ts

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const MAX_CHATSTREAM = 10;
5858

5959
export class ChatActions extends Actions<ChatState> {
6060
public syncdb?: SyncDB;
61-
private store?: ChatStore;
61+
public store?: ChatStore;
6262
// We use this to ensure at most once chatgpt output is streaming
6363
// at a time in a given chatroom. I saw a bug where hundreds started
6464
// at once and it really did send them all to openai at once, and
@@ -424,56 +424,40 @@ export class ChatActions extends Actions<ChatState> {
424424
noNotification?: boolean;
425425
reply_to?: Date;
426426
}): string {
427+
const store = this.store;
428+
if (store == null) {
429+
return "";
430+
}
427431
// the reply_to field of the message is *always* the root.
428432
// the order of the replies is by timestamp. This is meant
429433
// to make sure chat is just 1 layer deep, rather than a
430434
// full tree structure, which is powerful but too confusing.
431-
reply_to ??= getReplyToRoot(
432-
message,
433-
this.store?.get("messages") ?? (fromJS({}) as ChatMessages),
434-
);
435-
const time = reply_to?.valueOf() ?? 0;
435+
const reply_to_value =
436+
reply_to != null
437+
? reply_to.valueOf()
438+
: store.getThreadRootDate(new Date(message.date).valueOf());
436439
const time_stamp_str = this.send_chat({
437440
input: reply,
438441
sender_id: from ?? this.redux.getStore("account").get_account_id(),
439-
reply_to,
442+
reply_to: new Date(reply_to_value),
440443
noNotification,
441444
});
442-
this.delete_draft(-time);
443-
// it's conceivable that for some clients they recreate the draft
444-
// message right as the editor for that message is being removed.
445-
// Thus we do an extra delete a moment after send (after successfully
446-
// sending the message) to be sure the draft is really gone.
447-
// See https://github.com/sagemathinc/cocalc/issues/7662
448-
// and note that I'm not able to reproduce this, so it might not
449-
// be the right solution.
450-
setTimeout(() => {
451-
this.delete_draft(-time);
452-
}, 500);
445+
// negative date of reply_to root is used for replies.
446+
this.delete_draft(-reply_to_value);
453447
return time_stamp_str;
454448
}
455449

456-
// negative date is used for replies.
457450
public delete_draft(
458451
date: number,
459452
commit: boolean = true,
460453
sender_id: string | undefined = undefined,
461454
) {
462455
if (!this.syncdb) return;
463456
sender_id = sender_id ?? this.redux.getStore("account").get_account_id();
464-
// date should always be negative for drafts (stupid, but that's the code),
465-
// so I'm just deleting both for now.
466-
if (date) {
467-
this.syncdb.delete({
468-
event: "draft",
469-
sender_id,
470-
date,
471-
});
472-
}
473457
this.syncdb.delete({
474458
event: "draft",
475459
sender_id,
476-
date: -date,
460+
date,
477461
});
478462
if (commit) {
479463
this.syncdb.commit();
@@ -1147,7 +1131,7 @@ export function getRootMessage(
11471131
}
11481132
}
11491133

1150-
function getReplyToRoot(
1134+
export function getReplyToRoot(
11511135
message: ChatMessage,
11521136
messages: ChatMessages,
11531137
): Date | undefined {

src/packages/frontend/chat/input.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ interface Props {
2323
on_send: (value: string) => void;
2424
onChange: (string) => void;
2525
syncdb: SyncDB | undefined;
26-
date: number; // ms since epoch of when this message was first sent; set to 0 for editing new message. set to -time (negative time) to respond to message at time!
26+
// date:
27+
// - ms since epoch of when this message was first sent
28+
// - set to 0 for editing new message
29+
// - set to -time (negative time) to respond to thread, where time is the time of ROOT message of the the thread.
30+
date: number;
2731
input?: string;
2832
on_paste?: (e) => void;
2933
height?: string;
@@ -93,6 +97,7 @@ export default function ChatInput({
9397
// but definitely don't save (thus updating active) if
9498
// the input didn't really change, since we use active for
9599
// showing that a user is writing to other users.
100+
console.log("saveChat", { date });
96101
const input0 = syncdb
97102
.get_one({
98103
event: "draft",

src/packages/frontend/chat/message.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
import { Button, Col, Popconfirm, Row, Space, Tooltip } from "antd";
77
import { Map } from "immutable";
8-
import { CSSProperties, useLayoutEffect } from "react";
9-
8+
import { CSSProperties, useEffect, useLayoutEffect } from "react";
109
import { Avatar } from "@cocalc/frontend/account/avatar/avatar";
1110
import {
1211
CSS,
@@ -187,10 +186,14 @@ export default function Message(props: Readonly<Props>) {
187186
const submitMentionsRef = useRef<SubmitMentionsFn>();
188187

189188
const [replying, setReplying] = useState<boolean>(() => {
189+
if (!props.allowReply) {
190+
return false;
191+
}
192+
const replyDate = -(props.actions?.store?.getThreadRootDate(date) ?? 0);
190193
const draft = props.actions?.syncdb?.get_one({
191194
event: "draft",
192195
sender_id: props.account_id,
193-
date: -date,
196+
date: replyDate,
194197
});
195198
if (draft == null) {
196199
return false;
@@ -202,6 +205,12 @@ export default function Message(props: Readonly<Props>) {
202205
}
203206
return true;
204207
});
208+
useEffect(() => {
209+
if (!props.allowReply) {
210+
setReplying(false);
211+
}
212+
}, [props.allowReply]);
213+
205214
const [autoFocusReply, setAutoFocusReply] = useState<boolean>(false);
206215
const [autoFocusEdit, setAutoFocusEdit] = useState<boolean>(false);
207216

@@ -640,6 +649,7 @@ export default function Message(props: Readonly<Props>) {
640649
// when null.
641650
return;
642651
}
652+
const replyDate = -(props.actions.store?.getThreadRootDate(date) ?? 0);
643653
return (
644654
<div style={{ marginLeft: mode === "standalone" ? "30px" : "0" }}>
645655
<ChatInput
@@ -654,7 +664,7 @@ export default function Message(props: Readonly<Props>) {
654664
on_send={sendReply}
655665
height={"auto"}
656666
syncdb={props.actions.syncdb}
657-
date={-date}
667+
date={replyDate}
658668
onChange={(value) => {
659669
replyMessageRef.current = value;
660670
// replyMentionsRef does not submit mentions, only gives us the value
@@ -668,7 +678,7 @@ export default function Message(props: Readonly<Props>) {
668678
style={{ marginRight: "5px" }}
669679
onClick={() => {
670680
setReplying(false);
671-
props.actions?.delete_draft(date);
681+
props.actions?.delete_draft(replyDate);
672682
}}
673683
>
674684
Cancel

src/packages/frontend/chat/store.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { List, fromJS, Map as immutableMap } from "immutable";
88
import { Store, redux } from "@cocalc/frontend/app-framework";
99
import type { HashtagState } from "@cocalc/frontend/editors/task-editor/types";
1010
import { ChatMessages, MentionList } from "./types";
11+
import { getReplyToRoot } from "./actions";
1112

1213
export interface ChatState {
1314
project_id?: string;
@@ -65,4 +66,14 @@ export class ChatStore extends Store<ChatState> {
6566
filterRecentH: 0,
6667
};
6768
};
69+
70+
getThreadRootDate = (date: number): number => {
71+
const messages = this.get("messages") ?? (fromJS({}) as ChatMessages);
72+
const message = messages.get(`${date}`)?.toJS();
73+
if (message == null) {
74+
return 0;
75+
}
76+
const d = getReplyToRoot(message, messages);
77+
return d?.valueOf() ?? 0;
78+
};
6879
}

0 commit comments

Comments
 (0)