Skip to content

Commit d981ab8

Browse files
committed
chat frame tree: got it mostly working with independent filter state per frame
1 parent daba41c commit d981ab8

File tree

9 files changed

+116
-56
lines changed

9 files changed

+116
-56
lines changed

src/packages/frontend/chat/actions.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export class ChatActions extends Actions<ChatState> {
6464
// at once and it really did send them all to openai at once, and
6565
// this prevents that at least.
6666
private chatStreams: Set<string> = new Set([]);
67+
public frameId: string = "";
68+
public frameTreeActions;
6769

6870
set_syncdb = (syncdb: SyncDB, store: ChatStore): void => {
6971
this.syncdb = syncdb;
@@ -527,13 +529,13 @@ export class ChatActions extends Actions<ChatState> {
527529
if (!this.store) return;
528530
// similar code in task list.
529531
let selectedHashtags: SelectedHashtags =
530-
this.store.get("selectedHashtags") ??
532+
this.frameTreeActions._get_frame_data(this.frameId, "selectedHashtags") ??
531533
immutableMap<string, HashtagState>();
532534
selectedHashtags =
533535
state == null
534536
? selectedHashtags.delete(tag)
535537
: selectedHashtags.set(tag, state);
536-
this.setState({ selectedHashtags });
538+
this.setSelectedHashtags(selectedHashtags);
537539
};
538540

539541
help = () => {
@@ -1028,10 +1030,27 @@ export class ChatActions extends Actions<ChatState> {
10281030
};
10291031

10301032
clearAllFilters = () => {
1031-
this.setState({
1032-
search: "",
1033-
selectedHashtags: immutableMap(),
1034-
filterRecentH: 0,
1033+
if (this.frameTreeActions == null) {
1034+
// crappy code just for sage worksheets -- will go away.
1035+
return;
1036+
}
1037+
this.setSearch("");
1038+
this.setFilterRecentH(0);
1039+
this.setSelectedHashtags({});
1040+
};
1041+
1042+
setSearch = (search) => {
1043+
this.frameTreeActions.set_frame_data({ id: this.frameId, search });
1044+
};
1045+
1046+
setFilterRecentH = (filterRecentH) => {
1047+
this.frameTreeActions.set_frame_data({ id: this.frameId, filterRecentH });
1048+
};
1049+
1050+
setSelectedHashtags = (selectedHashtags) => {
1051+
this.frameTreeActions.set_frame_data({
1052+
id: this.frameId,
1053+
selectedHashtags,
10351054
});
10361055
};
10371056
}

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ interface Props {
3939
setLastVisible?: (x: Date | null) => void;
4040
fontSize?: number;
4141
actions: ChatActions;
42+
search;
43+
filterRecentH?;
44+
selectedHashtags;
45+
disableFilters?: boolean;
4246
}
4347

4448
export function ChatLog({
@@ -49,6 +53,10 @@ export function ChatLog({
4953
setLastVisible,
5054
fontSize,
5155
actions,
56+
search: search0,
57+
filterRecentH,
58+
selectedHashtags: selectedHashtags0,
59+
disableFilters,
5260
}: Props) {
5361
const messages = useRedux(["messages"], project_id, path) as ChatMessages;
5462
const scrollToBottom = useRedux(["scrollToBottom"], project_id, path);
@@ -59,13 +67,10 @@ export function ChatLog({
5967
);
6068

6169
// see similar code in task list:
62-
const selectedHashtags0 = useRedux(["selectedHashtags"], project_id, path);
6370
const { selectedHashtags, selectedHashtagsSearch } = useMemo(() => {
6471
return getSelectedHashtagsSearch(selectedHashtags0);
6572
}, [selectedHashtags0]);
66-
67-
const search =
68-
useRedux(["search"], project_id, path) + selectedHashtagsSearch;
73+
const search = search0 + " " + selectedHashtagsSearch;
6974

7075
useEffect(() => {
7176
scrollToBottomRef?.current?.(true);
@@ -82,7 +87,6 @@ export function ChatLog({
8287
actions.setState({ scrollToBottom: undefined });
8388
}, [scrollToBottom]);
8489

85-
const filterRecentH = useRedux(["filterRecentH"], project_id, path);
8690
const user_map = useTypedRedux("users", "user_map");
8791
const account_id = useTypedRedux("account", "account_id");
8892
const { dates: sortedDates, numFolded } = useMemo<{
@@ -110,6 +114,9 @@ export function ChatLog({
110114

111115
const visibleHashtags = useMemo(() => {
112116
let X = immutableSet<string>([]);
117+
if (disableFilters) {
118+
return X;
119+
}
113120
for (const date of sortedDates) {
114121
const message = messages.get(date);
115122
const value = newest_content(message);

src/packages/frontend/chat/chatroom.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ interface Props {
7070
path: string;
7171
is_visible?: boolean;
7272
font_size: number;
73+
desc;
7374
}
7475

7576
export function ChatRoom({
@@ -78,16 +79,19 @@ export function ChatRoom({
7879
path,
7980
is_visible,
8081
font_size,
82+
desc,
8183
}: Props) {
8284
const useEditor = useEditorRedux<ChatState>({ project_id, path });
8385
const is_uploading = useEditor("is_uploading");
8486
const is_preview = useEditor("is_preview");
8587
const input: string = useEditor("input");
8688
const [preview] = useDebounce(input, 250);
8789

88-
const search = useEditor("search");
90+
const search = desc.get("data-search") ?? "";
91+
const filterRecentH: number = desc.get("data-filterRecentH") ?? 0;
92+
const selectedHashtags = desc.get("data-selectedHashtags");
93+
8994
const messages = useEditor("messages");
90-
const filterRecentH: number = useEditor("filterRecentH");
9195
const [filterRecentHCustom, setFilterRecentHCustom] = useState<string>("");
9296
const [filterRecentOpen, setFilterRecentOpen] = useState<boolean>(false);
9397
const llm_cost_room = useEditor("llm_cost_room");
@@ -205,12 +209,12 @@ export function ChatRoom({
205209
status={filterRecentH > 0 ? "warning" : undefined}
206210
allowClear
207211
onClear={() => {
208-
actions.setState({ filterRecentH: 0 });
212+
actions.setFilterRecentH(0);
209213
setFilterRecentHCustom("");
210214
}}
211215
style={{ width: 120 }}
212216
popupMatchSelectWidth={false}
213-
onSelect={(val: number) => actions.setState({ filterRecentH: val })}
217+
onSelect={(val: number) => actions.setFilterRecentH(val)}
214218
options={[
215219
FILTER_RECENT_NONE,
216220
...[1, 6, 12, 24, 48, 24 * 7, 14 * 24, 28 * 24].map((value) => {
@@ -258,11 +262,9 @@ export function ChatRoom({
258262
setFilterRecentHCustom(v);
259263
const val = parseFloat(v);
260264
if (isFinite(val) && val >= 0) {
261-
actions.setState({ filterRecentH: val });
265+
actions.setFilterRecentH(val);
262266
} else if (v == "") {
263-
actions.setState({
264-
filterRecentH: FILTER_RECENT_NONE.value,
265-
});
267+
actions.setFilterRecentH(FILTER_RECENT_NONE.value);
266268
}
267269
},
268270
150,
@@ -326,6 +328,9 @@ export function ChatRoom({
326328
scrollToBottomRef={scrollToBottomRef}
327329
mode={"standalone"}
328330
fontSize={font_size}
331+
search={search}
332+
filterRecentH={filterRecentH}
333+
selectedHashtags={selectedHashtags}
329334
/>
330335
{render_preview_message()}
331336
</div>

src/packages/frontend/chat/filter.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
import { Input, Tooltip } from "antd";
2-
import { useCallback, useEffect, useMemo, useState } from "react";
2+
import { useEffect, useMemo, useState } from "react";
33
import { debounce } from "lodash";
44

55
export default function Filter({ actions, search, style }) {
66
const [value, setValue] = useState<string>(search ?? "");
77
useEffect(() => {
88
setValue(search);
99
}, [search]);
10-
const doSearch = useCallback(
11-
(value: string) => {
12-
actions.setState({ search: value });
13-
},
14-
[actions],
15-
);
10+
1611
const debouncedSearch = useMemo(
1712
() =>
18-
debounce(doSearch, 200, {
13+
debounce(actions.setSearch, 200, {
1914
leading: false,
2015
trailing: true,
2116
}),
@@ -41,11 +36,11 @@ export default function Filter({ actions, search, style }) {
4136
}}
4237
onPressEnter={() => {
4338
debouncedSearch.cancel();
44-
doSearch(value);
39+
actions.setSearch(value);
4540
}}
4641
onSearch={() => {
4742
debouncedSearch.cancel();
48-
doSearch(value);
43+
actions.setSearch(value);
4944
}}
5045
/>
5146
</Tooltip>

src/packages/frontend/chat/message.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ export default function Message(props: Readonly<Props>) {
747747
}}
748748
type="primary"
749749
>
750-
<Icon name="paper-plane" /> Send Reply
750+
<Icon name="reply" /> Reply (shift+enter)
751751
</Button>
752752
<LLMCostEstimationChat
753753
llm_cost={llm_cost_reply}

src/packages/frontend/chat/register.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import { ChatActions } from "./actions";
1111
import { ChatStore } from "./store";
1212

1313
// it is fine to call this more than once.
14-
export function initChat(project_id: string, path: string): string {
14+
export function initChat(project_id: string, path: string): ChatActions {
1515
const name = redux_name(project_id, path);
1616
if (redux.getActions(name) != null) {
17-
return name; // already initialized
17+
return redux.getActions(name); // already initialized
1818
}
1919

2020
const actions = redux.createActions(name, ChatActions);
@@ -53,13 +53,13 @@ export function initChat(project_id: string, path: string): string {
5353
redux.getProjectActions(project_id)?.log_opened_time(path);
5454
});
5555

56-
return name;
56+
return actions;
5757
}
5858

5959
export function remove(path: string, redux, project_id: string): string {
6060
const name = redux_name(project_id, path);
6161
const actions = redux.getActions(name);
62-
actions?.syncdb.close();
62+
actions?.syncdb?.close();
6363
const store = redux.getStore(name);
6464
if (store == null) {
6565
return name;

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,28 @@ interface Props {
2626
path: string;
2727
style?: CSSProperties;
2828
fontSize?: number;
29+
actions?: ChatActions;
30+
desc?;
2931
}
3032

31-
export default function SideChat({ project_id, path, style, fontSize }: Props) {
32-
const actions: ChatActions = useActions(project_id, path);
33+
export default function SideChat({
34+
actions: actions0,
35+
project_id,
36+
path,
37+
style,
38+
fontSize,
39+
desc,
40+
}: Props) {
41+
// This actionsViaContext via useActions is ONLY needed for side chat for non-frame
42+
// editors, i.e., basically just Sage Worksheets!
43+
const actionsViaContext = useActions(project_id, path);
44+
const actions: ChatActions = actions0 ?? actionsViaContext;
45+
const disableFilters = actions0 == null;
3346
const messages = useRedux(["messages"], project_id, path);
3447
const [lastVisible, setLastVisible] = useState<Date | null>(null);
3548
const input: string = useRedux(["input"], project_id, path);
36-
const search: string = useRedux(["search"], project_id, path);
49+
const search = desc?.get("data-search") ?? "";
50+
const selectedHashtags = desc?.get("data-selectedHashtags");
3751
const addCollab: boolean = useRedux(["add_collab"], project_id, path);
3852
const is_uploading = useRedux(["is_uploading"], project_id, path);
3953
const project_map = useTypedRedux("projects", "project_map");
@@ -142,16 +156,18 @@ export default function SideChat({ project_id, path, style, fontSize }: Props) {
142156
<AddChatCollab addCollab={addCollab} project_id={project_id} />
143157
</div>
144158
)}
145-
<Filter
146-
actions={actions}
147-
search={search}
148-
style={{
149-
margin: 0,
150-
...(messages.size >= 2
151-
? undefined
152-
: { visibility: "hidden", height: 0 }),
153-
}}
154-
/>
159+
{!disableFilters && (
160+
<Filter
161+
actions={actions}
162+
search={search}
163+
style={{
164+
margin: 0,
165+
...(messages.size >= 2
166+
? undefined
167+
: { visibility: "hidden", height: 0 }),
168+
}}
169+
/>
170+
)}
155171
<div
156172
className="smc-vfill"
157173
style={{
@@ -169,6 +185,9 @@ export default function SideChat({ project_id, path, style, fontSize }: Props) {
169185
scrollToBottomRef={scrollToBottomRef}
170186
mode={"sidechat"}
171187
setLastVisible={setLastVisible}
188+
search={search}
189+
selectedHashtags={selectedHashtags}
190+
disableFilters={disableFilters}
172191
/>
173192
</div>
174193

@@ -184,7 +203,7 @@ export default function SideChat({ project_id, path, style, fontSize }: Props) {
184203
sendChat({ reply_to: new Date(lastVisible) });
185204
}}
186205
>
187-
Reply (shift+enter)
206+
<Icon name="reply" /> Reply (shift+enter)
188207
</Button>
189208
)}
190209
<Button
@@ -197,7 +216,7 @@ export default function SideChat({ project_id, path, style, fontSize }: Props) {
197216
disabled={!input?.trim() || is_uploading}
198217
>
199218
<Icon name="paper-plane" />
200-
Start New Conversation
219+
Start New Thread
201220
</Button>
202221
</Space>
203222
</Tooltip>

src/packages/frontend/frame-editors/chat-editor/actions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ export class Actions extends CodeEditorActions<ChatEditorState> {
6565
const actions = this.redux.createActions(reduxName, ChatActions);
6666
// our store is not exactly a ChatStore but it's close enough
6767
actions.set_syncdb(syncdb, this.store as ChatStore);
68+
actions.frameId = frameId;
69+
actions.frameTreeActions = this;
6870
this.chatActions[frameId] = actions;
6971
return actions;
7072
}

0 commit comments

Comments
 (0)