Skip to content

Commit ca3feb9

Browse files
committed
frontend/chat: add a "fold all LLM threads" button
1 parent 1d0b67b commit ca3feb9

File tree

6 files changed

+60
-8
lines changed

6 files changed

+60
-8
lines changed

src/packages/frontend/chat/actions.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ export class ChatActions extends Actions<ChatState> {
9090
};
9191

9292
toggleFoldThread = (reply_to: Date, messageIndex?: number) => {
93-
if (this.syncdb == null) {
94-
return;
95-
}
93+
if (this.syncdb == null) return;
9694
const account_id = this.redux.getStore("account").get_account_id();
9795
const cur = this.syncdb.get_one({ event: "chat", date: reply_to });
9896
const folding = cur?.get("folding") ?? List([]);
@@ -113,6 +111,29 @@ export class ChatActions extends Actions<ChatState> {
113111
}
114112
};
115113

114+
foldAllThreads = (onlyLLM = true) => {
115+
if (this.syncdb == null || this.store == null) return;
116+
const messages = this.store.get("messages");
117+
if (messages == null) return;
118+
const account_id = this.redux.getStore("account").get_account_id();
119+
for (const [_timestamp, message] of messages) {
120+
// ignore replies
121+
if (message.get("reply_to") != null) continue;
122+
const date = message.get("date");
123+
if (!(date instanceof Date)) continue;
124+
const isLLMThread = this.isLanguageModelThread(date) !== false;
125+
if (onlyLLM && !isLLMThread) continue;
126+
const folding = message?.get("folding") ?? List([]);
127+
const folded = folding.includes(account_id);
128+
if (!folded) {
129+
this.syncdb.set({
130+
folding: folding.push(account_id),
131+
date,
132+
});
133+
}
134+
}
135+
};
136+
116137
feedback = (message: ChatMessageTyped, feedback: Feedback | null) => {
117138
if (this.syncdb == null) return;
118139
const date = message.get("date");
@@ -479,6 +500,7 @@ export class ChatActions extends Actions<ChatState> {
479500
scrollToDate: null,
480501
});
481502
};
503+
482504
scrollToIndex = (index: number = -1) => {
483505
if (this.syncdb == null) return;
484506
// we first clear, then set it, since scroll to needs to

src/packages/frontend/chat/chatroom.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { hoursToTimeIntervalHuman } from "@cocalc/util/misc";
2323
import type { ChatActions } from "./actions";
2424
import { ChatLog } from "./chat-log";
2525
import Filter from "./filter";
26+
import { FoldAllThreads } from "./fold-threads";
2627
import ChatInput from "./input";
2728
import { LLMCostEstimationChat } from "./llm-cost-estimation";
2829
import type { ChatState } from "./store";
@@ -262,6 +263,7 @@ export function ChatRoom({
262263
<ButtonGroup style={{ marginLeft: "5px" }}>
263264
{render_video_chat_button()}
264265
</ButtonGroup>
266+
<FoldAllThreads actions={actions} shortLabel={false} />
265267
</Space>
266268
);
267269
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Button } from "antd";
2+
3+
import { ChatActions } from "@cocalc/frontend/chat/actions";
4+
import { Icon, Tip } from "@cocalc/frontend/components";
5+
6+
export function FoldAllThreads({
7+
actions,
8+
shortLabel,
9+
}: {
10+
actions: ChatActions;
11+
shortLabel: boolean;
12+
}) {
13+
return (
14+
<Tip placement="top" title="Fold all language model threads">
15+
<Button
16+
onClick={() => {
17+
actions.foldAllThreads(true);
18+
}}
19+
>
20+
<Icon name="to-top-outlined" />{" "}
21+
{shortLabel ? "LLM" : "Fold LLM threads"}
22+
</Button>
23+
</Tip>
24+
);
25+
}

src/packages/frontend/chat/message.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ export default function Message({
964964
);
965965

966966
return (
967-
<Col xs={24} style={{}}>
967+
<Col xs={24}>
968968
<Tip title={"Click to unfold this thread to show all messages."}>
969969
<Button
970970
onClick={() =>

src/packages/frontend/chat/side-chat.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Button, Flex, Space, Tooltip } from "antd";
22
import { CSSProperties, useCallback, useEffect, useRef, useState } from "react";
3+
34
import {
45
redux,
56
useActions,
@@ -11,15 +12,16 @@ import { A, Icon, Loading } from "@cocalc/frontend/components";
1112
import { IS_MOBILE } from "@cocalc/frontend/feature";
1213
import { ProjectUsers } from "@cocalc/frontend/projects/project-users";
1314
import { user_activity } from "@cocalc/frontend/tracker";
15+
import { COLORS } from "@cocalc/util/theme";
1416
import type { ChatActions } from "./actions";
1517
import { ChatLog } from "./chat-log";
18+
import Filter from "./filter";
19+
import { FoldAllThreads } from "./fold-threads";
1620
import ChatInput from "./input";
1721
import { LLMCostEstimationChat } from "./llm-cost-estimation";
1822
import { SubmitMentionsFn } from "./types";
1923
import { INPUT_HEIGHT, markChatAsReadIfUnseen } from "./utils";
2024
import VideoChatButton from "./video/launch-button";
21-
import { COLORS } from "@cocalc/util/theme";
22-
import Filter from "./filter";
2325

2426
interface Props {
2527
project_id: string;
@@ -104,7 +106,7 @@ export default function SideChat({
104106
onMouseMove={markAsRead}
105107
onFocus={() => {
106108
// Remove any active key handler that is next to this side chat.
107-
// E.g, this is critical for taks lists...
109+
// E.g, this is critical for tasks lists...
108110
redux.getActions("page").erase_active_key_handler();
109111
}}
110112
>
@@ -134,6 +136,7 @@ export default function SideChat({
134136
<Icon name="history" />
135137
</Button>
136138
</Tooltip>
139+
<FoldAllThreads actions={actions} shortLabel={true} />
137140
</Space.Compact>
138141
<CollabList
139142
addCollab={addCollab}

src/packages/frontend/frame-editors/frame-tree/commands/editor-menus.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export function addEditorMenus({
135135
const { children } = COMMANDS[name];
136136
const cmdName = `${prefix}-${name}`;
137137
if (children == null) {
138-
// everthing based entirely on spec object.
138+
// everything based entirely on spec object.
139139
C[cmdName] = {
140140
...cmd(name),
141141
...COMMANDS[name],

0 commit comments

Comments
 (0)