Skip to content

Commit cb8445c

Browse files
committed
chat: various sanity improvements with chat being a full application, e.g., don't also have side chat at the same time.
1 parent f5fbc39 commit cb8445c

File tree

5 files changed

+97
-83
lines changed

5 files changed

+97
-83
lines changed

src/packages/frontend/frame-editors/frame-tree/commands/generic-commands.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ addCommands({
107107
title: defineMessage({
108108
id: "command.generic.close.title",
109109
defaultMessage:
110-
"Close this frame. To restore the default layout, select the application menu entry 'Default Layout'.",
110+
"Close this frame. To restore the default layout, select the application menu entry 'Default Layout' or close all frames.",
111111
}),
112112
onClick: ({ props }) => {
113113
props.actions.close_frame(props.id);
@@ -1071,13 +1071,15 @@ addCommands({
10711071
redux.getStore("projects").hasLanguageModelEnabled(props.project_id),
10721072
},
10731073
chat: {
1074-
alwaysShow: true,
1074+
// we have a side chat menu item... except for in a chatroom or side chat.
1075+
isVisible: ({ props }) =>
1076+
!props.path?.endsWith(".sage-chat") && props.type != "chat",
10751077
pos: 5,
10761078
group: "help-link",
10771079
icon: "comment",
10781080
label: defineMessage({
10791081
id: "command.generic.chat.label",
1080-
defaultMessage: "Chat with Collaborators or AI",
1082+
defaultMessage: "Side Chat with Collaborators or AI",
10811083
description:
10821084
"Opens a chatroom next to the document to chat with other users (collaborators) or an AI chatbot",
10831085
}),

src/packages/frontend/frame-editors/frame-tree/commands/manage.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ export class ManageCommands {
7070
if (cmd == null) {
7171
cmd = COMMANDS[name];
7272
}
73-
// some buttons are always visible, e.g., for controlling the frame.
73+
if (this.props.spec.commands?.[`-${name}`]) {
74+
// explicitly hidden by the spec
75+
return false;
76+
}
77+
// some buttons are always visible, e.g., for controlling the frame, unless of course they are explicitly
78+
// hidden by the spec (above)
7479
if (cmd?.alwaysShow) {
7580
return true;
7681
}
@@ -81,10 +86,6 @@ export class ManageCommands {
8186
if (cmd?.disable && this.studentProjectFunctionality[cmd.disable]) {
8287
return false;
8388
}
84-
if (this.props.spec.commands?.[`-${name}`]) {
85-
// explicitly hidden by the spec
86-
return false;
87-
}
8889
if (cmd?.isVisible != null) {
8990
const { isVisible } = cmd;
9091
if (typeof isVisible === "string") {

src/packages/frontend/frame-editors/frame-tree/editor.tsx

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

66
import { Map, Set } from "immutable";
77
import { clone } from "lodash";
8-
98
import {
109
CSS,
1110
React,
@@ -243,7 +242,11 @@ export function createEditor(opts: Options): React.FC<EditorProps> {
243242
project_id={project_id}
244243
format_bar={!!opts.format_bar}
245244
format_bar_exclude={opts.format_bar_exclude}
246-
editor_spec={{ ...opts.editor_spec, chat }}
245+
editor_spec={
246+
path.endsWith(".sage-chat")
247+
? opts.editor_spec
248+
: { ...opts.editor_spec, chat }
249+
}
247250
tab_is_visible={is_visible}
248251
/>
249252
);

src/packages/frontend/frame-editors/frame-tree/title-bar.tsx

Lines changed: 79 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { Button, Input, InputNumber, Popover, Tooltip } from "antd";
1212
import { List } from "immutable";
1313
import { useMemo, useRef } from "react";
1414
import { useIntl } from "react-intl";
15-
1615
import { ButtonGroup } from "@cocalc/frontend/antd-bootstrap";
1716
import {
1817
CSS,
@@ -325,19 +324,18 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
325324

326325
function render_x(): Rendered {
327326
return (
328-
<Button
327+
<Tooltip
329328
title={intl.formatMessage({
330329
id: "frame_editors.frame_tree.title_bar.close",
331-
defaultMessage: "Close this frame",
330+
defaultMessage:
331+
"Close this frame. To restore the default layout, close all frames.",
332332
description: "Click this X button to close the frame",
333333
})}
334-
key={"close"}
335-
size="small"
336-
type="text"
337-
onClick={click_close}
338334
>
339-
<Icon name={"times"} />
340-
</Button>
335+
<Button key={"close"} size="small" type="text" onClick={click_close}>
336+
<Icon name={"times"} />
337+
</Button>
338+
</Tooltip>
341339
);
342340
}
343341

@@ -374,94 +372,104 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
374372
function render_full(): Rendered {
375373
if (props.is_full) {
376374
return (
377-
<Button
378-
disabled={props.is_only}
375+
<Tooltip
379376
title={intl.formatMessage({
380377
id: "frame_editors.frame_tree.title_bar.minimize",
381378
defaultMessage: "Show all frames",
382379
description: "Minimize this frame to show all frames",
383380
})}
384-
key={"full-screen-button"}
385-
size="small"
386-
type="text"
387-
onClick={() => {
388-
track("unset-full");
389-
props.actions.unset_frame_full();
390-
}}
391-
style={{
392-
color: darkMode ? "orange" : undefined,
393-
background: !darkMode ? "orange" : undefined,
394-
}}
395381
>
396-
<Icon name={"compress"} />
397-
</Button>
382+
<Button
383+
disabled={props.is_only}
384+
key={"full-screen-button"}
385+
size="small"
386+
type="text"
387+
onClick={() => {
388+
track("unset-full");
389+
props.actions.unset_frame_full();
390+
}}
391+
style={{
392+
color: darkMode ? "orange" : undefined,
393+
background: !darkMode ? "orange" : undefined,
394+
}}
395+
>
396+
<Icon name={"compress"} />
397+
</Button>
398+
</Tooltip>
398399
);
399400
} else {
400401
return (
401-
<Button
402-
disabled={props.is_only}
403-
key={"full-screen-button"}
402+
<Tooltip
404403
title={intl.formatMessage({
405404
id: "frame_editors.frame_tree.title_bar.maximize",
406405
defaultMessage: "Show only this frame",
407406
description: "Maximize this frame to show only this one",
408407
})}
409-
size="small"
410-
type="text"
411-
onClick={() => {
412-
track("set-full");
413-
props.actions.set_frame_full(props.id);
414-
}}
415408
>
416-
<Icon name={"expand"} />
417-
</Button>
409+
<Button
410+
disabled={props.is_only}
411+
key={"full-screen-button"}
412+
size="small"
413+
type="text"
414+
onClick={() => {
415+
track("set-full");
416+
props.actions.set_frame_full(props.id);
417+
}}
418+
>
419+
<Icon name={"expand"} />
420+
</Button>
421+
</Tooltip>
418422
);
419423
}
420424
}
421425

422426
function render_split_row(): Rendered {
423427
return (
424-
<Button
425-
key={"split-row-button"}
428+
<Tooltip
426429
title={intl.formatMessage(labels.split_frame_horizontally_title)}
427-
size="small"
428-
type="text"
429-
onClick={(e) => {
430-
e.stopPropagation();
431-
if (props.is_full) {
432-
track("unset-full");
433-
return props.actions.unset_frame_full();
434-
} else {
435-
track("split-row");
436-
return props.actions.split_frame("row", props.id);
437-
}
438-
}}
439430
>
440-
<Icon name="horizontal-split" />
441-
</Button>
431+
<Button
432+
key={"split-row-button"}
433+
size="small"
434+
type="text"
435+
onClick={(e) => {
436+
e.stopPropagation();
437+
if (props.is_full) {
438+
track("unset-full");
439+
return props.actions.unset_frame_full();
440+
} else {
441+
track("split-row");
442+
return props.actions.split_frame("row", props.id);
443+
}
444+
}}
445+
>
446+
<Icon name="horizontal-split" />
447+
</Button>
448+
</Tooltip>
442449
);
443450
}
444451

445452
function render_split_col(): Rendered {
446453
return (
447-
<Button
448-
key={"split-col-button"}
449-
title={intl.formatMessage(labels.split_frame_vertically_title)}
450-
size="small"
451-
type="text"
452-
onClick={(e) => {
453-
e.stopPropagation();
454-
if (props.is_full) {
455-
track("unset-full");
456-
return props.actions.unset_frame_full();
457-
} else {
458-
track("split-col");
459-
return props.actions.split_frame("col", props.id);
460-
}
461-
}}
462-
>
463-
<Icon name="vertical-split" />
464-
</Button>
454+
<Tooltip title={intl.formatMessage(labels.split_frame_vertically_title)}>
455+
<Button
456+
key={"split-col-button"}
457+
size="small"
458+
type="text"
459+
onClick={(e) => {
460+
e.stopPropagation();
461+
if (props.is_full) {
462+
track("unset-full");
463+
return props.actions.unset_frame_full();
464+
} else {
465+
track("split-col");
466+
return props.actions.split_frame("col", props.id);
467+
}
468+
}}
469+
>
470+
<Icon name="vertical-split" />
471+
</Button>
472+
</Tooltip>
465473
);
466474
}
467475

@@ -698,8 +706,8 @@ export function FrameTitleBar(props: FrameTitleBarProps) {
698706
label === APPLICATION_MENU
699707
? manageCommands.applicationMenuTitle()
700708
: isIntlMessage(label)
701-
? intl.formatMessage(label)
702-
: label
709+
? intl.formatMessage(label)
710+
: label
703711
}
704712
items={v}
705713
/>

src/packages/frontend/i18n/common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ export const labels = defineMessages({
204204
},
205205
split_frame_horizontally_title: {
206206
id: "labels.split_frame_horizontally.title",
207-
defaultMessage: "Split Down",
208-
description: "Split a frame horizontally",
207+
defaultMessage: "Split frame horizontally into two rows",
208+
description: "Split frame horizontally",
209209
},
210210
assistant: {
211211
id: "labels.assistant",

0 commit comments

Comments
 (0)