Skip to content

Commit 86c72cf

Browse files
committed
Merge remote-tracking branch 'origin/master' into sso-exclusive-all
2 parents 647477c + f1f5ff5 commit 86c72cf

File tree

92 files changed

+883
-16935
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+883
-16935
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,8 @@ src/go
151151

152152
# Python virtual environment
153153
venv
154+
155+
# frontend/i18n files, which are created during build or updating the languages
156+
src/packages/frontend/i18n/extracted.json
157+
src/packages/frontend/i18n/*.compiled.json
158+

src/packages/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@cocalc/backend": "workspace:*",
3434
"@cocalc/util": "workspace:*",
3535
"@types/debug": "^4.1.12",
36+
"@types/watchpack": "^2.4.4",
3637
"awaiting": "^3.0.0",
3738
"chokidar": "^3.6.0",
3839
"debug": "^4.3.2",

src/packages/backend/path-watcher.ts

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*/
55

66
/*
7-
Watch A DIRECTORY for changes. Use ./watcher.ts for a single file.
8-
7+
Watch A DIRECTORY for changes of the files in *that* directory only (not recursive).
8+
Use ./watcher.ts for a single file.
99
1010
Slightly generalized fs.watch that works even when the directory doesn't exist,
1111
but also doesn't provide any information about what changed.
@@ -54,7 +54,7 @@ const logger = getLogger("backend:path-watcher");
5454
const POLLING = true;
5555

5656
const DEFAULT_POLL_MS = parseInt(
57-
process.env.COCALC_FS_WATCHER_POLL_INTERVAL_MS ?? "1500",
57+
process.env.COCALC_FS_WATCHER_POLL_INTERVAL_MS ?? "3000",
5858
);
5959

6060
const ChokidarOpts: WatchOptions = {
@@ -79,17 +79,13 @@ export class Watcher extends EventEmitter {
7979
private exists: boolean;
8080
private watchContents?: FSWatcher;
8181
private watchExistence?: FSWatcher;
82-
private interval_ms: number;
8382
private debounce_ms: number;
8483
private debouncedChange: any;
8584
private log: Function;
8685

8786
constructor(
8887
path: string,
89-
{
90-
debounce: debounce_ms = 0,
91-
interval: interval_ms,
92-
}: { debounce?: number; interval?: number } = {},
88+
{ debounce: debounce_ms = DEFAULT_POLL_MS }: { debounce?: number } = {},
9389
) {
9490
super();
9591
this.log = logger.extend(path).debug;
@@ -99,7 +95,6 @@ export class Watcher extends EventEmitter {
9995
}
10096
this.path = path.startsWith("/") ? path : join(process.env.HOME, path);
10197
this.debounce_ms = debounce_ms;
102-
this.interval_ms = interval_ms ?? DEFAULT_POLL_MS;
10398
this.debouncedChange = this.debounce_ms
10499
? debounce(this.change, this.debounce_ms, {
105100
leading: true,
@@ -122,16 +117,8 @@ export class Watcher extends EventEmitter {
122117
}
123118
}
124119

125-
private chokidarOptions = () => {
126-
return {
127-
...ChokidarOpts,
128-
interval: this.interval_ms,
129-
binaryInterval: this.interval_ms,
130-
};
131-
};
132-
133120
private initWatchContents(): void {
134-
this.watchContents = watch(this.path, this.chokidarOptions());
121+
this.watchContents = watch(this.path, ChokidarOpts);
135122
this.watchContents.on("all", this.debouncedChange);
136123
this.watchContents.on("error", (err) => {
137124
this.log(`error watching listings -- ${err}`);
@@ -140,7 +127,7 @@ export class Watcher extends EventEmitter {
140127

141128
private async initWatchExistence(): Promise<void> {
142129
const containing_path = path_split(this.path).head;
143-
this.watchExistence = watch(containing_path, this.chokidarOptions());
130+
this.watchExistence = watch(containing_path, ChokidarOpts);
144131
this.watchExistence.on("all", this.watchExistenceChange(containing_path));
145132
this.watchExistence.on("error", (err) => {
146133
this.log(`error watching for existence of ${this.path} -- ${err}`);

src/packages/backend/watcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class Watcher extends EventEmitter {
4040

4141
constructor(
4242
path: string,
43-
{ debounce, interval = 300 }: { debounce?: number; interval?: number } = {},
43+
{ debounce, interval = 750 }: { debounce?: number; interval?: number } = {},
4444
) {
4545
super();
4646
this.path = path;

src/packages/frontend/account/account-page.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ for different account related information
1010
and configuration.
1111
*/
1212

13+
import { useState } from "react";
1314
import { DownOutlined } from "@ant-design/icons";
1415
import { Button, Dropdown, MenuProps, Modal, Space, Tooltip } from "antd";
1516
import { useIntl } from "react-intl";
16-
1717
import { SignOut } from "@cocalc/frontend/account/sign-out";
1818
import { AntdTabItem, Col, Row, Tabs } from "@cocalc/frontend/antd-bootstrap";
1919
import {
@@ -86,6 +86,7 @@ export const AccountPage: React.FC = () => {
8686
const is_commercial = useTypedRedux("customize", "is_commercial");
8787
const get_api_key = useTypedRedux("page", "get_api_key");
8888
const i18n_enabled = useTypedRedux("customize", "i18n");
89+
const [langOpen, setLangOpen] = useState<boolean>(false);
8990

9091
// for each exclusive domain, tell the user which strategy to use
9192
const exclusive_sso_domains = React.useMemo(() => {
@@ -351,13 +352,21 @@ Thank you for your patience and understanding as we work to make our application
351352
{cur}
352353
<br />
353354
{msg}
354-
<br />({labels.account_language_tooltip.defaultMessage})
355+
{labels.account_language_tooltip.defaultMessage != msg ? (
356+
<>
357+
<br />({labels.account_language_tooltip.defaultMessage})
358+
</>
359+
) : undefined}
355360
</>
356361
);
357362

358363
return (
359-
<Tooltip title={tooltip} trigger={["hover"]}>
360-
<Dropdown menu={menu} trigger={["click"]}>
364+
<Tooltip title={langOpen ? undefined : tooltip} trigger={["hover"]}>
365+
<Dropdown
366+
menu={menu}
367+
trigger={["click"]}
368+
onOpenChange={(open) => setLangOpen(open)}
369+
>
361370
<Button>
362371
<Space>
363372
{lang_icon}

src/packages/frontend/chat/actions.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,16 +297,16 @@ export class ChatActions extends Actions<ChatState> {
297297
search: "",
298298
});
299299
} else {
300-
// TODO: but until we fix search, do this:
300+
// TODO: but until we improve search to be by thread (instead of by message), do this:
301301
this.setState({
302302
search: "",
303303
});
304304
}
305305
this.ensureDraftStartsWithHashtags(false);
306306

307-
if (this.store) {
308-
const project_id = this.store.get("project_id");
309-
const path = this.store.get("path");
307+
if (this.store != null) {
308+
const project_id = this.store?.get("project_id");
309+
const path = this.store?.get("path");
310310
// set notification saying that we sent an actual chat
311311
let action;
312312
if (
@@ -570,7 +570,6 @@ export class ChatActions extends Actions<ChatState> {
570570
}
571571

572572
public set_uploading(is_uploading: boolean): void {
573-
console.log("set_uploading", is_uploading);
574573
this.setState({ is_uploading });
575574
}
576575

src/packages/frontend/chat/chatroom.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ export const ChatRoom: React.FC<Props> = ({ project_id, path, is_visible }) => {
509509
height={INPUT_HEIGHT}
510510
onChange={(value) => {
511511
actions.set_input(value);
512-
// submitMentionsRef will not acutally submit mentions, we're only interested in the reply value
512+
// submitMentionsRef will not actually submit mentions; we're only interested in the reply value
513513
const reply =
514514
submitMentionsRef.current?.(undefined, true) ?? value;
515515
actions?.llm_estimate_cost(reply, "room");

src/packages/frontend/chat/input.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ export default function ChatInput({
183183
sender_id,
184184
date,
185185
});
186-
const input = x?.get("input");
187-
if (input != null && input != lastSavedRef.current) {
186+
const input = x?.get("input") ?? "";
187+
if (input != lastSavedRef.current) {
188188
setInput(input);
189189
currentInputRef.current = input;
190190
lastSavedRef.current = input;
@@ -237,8 +237,8 @@ export default function ChatInput({
237237
saveChat(input);
238238
}}
239239
onShiftEnter={(input) => {
240-
setInput(input);
241-
saveChat(input);
240+
setInput("");
241+
saveChat("");
242242
on_send(input);
243243
}}
244244
height={height}

src/packages/frontend/client/project.ts

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ export class ProjectClient {
5050

5151
constructor(client: WebappClient) {
5252
this.client = client;
53-
this.ipywidgetsGetBuffer = reuseInFlight(
54-
this.ipywidgetsGetBuffer.bind(this),
55-
);
5653
}
5754

5855
private async call(message: object): Promise<any> {
@@ -380,16 +377,19 @@ export class ProjectClient {
380377
}
381378

382379
// This is async, so do "await smc_webapp.configuration(...project_id...)".
383-
public async configuration(
384-
project_id: string,
385-
aspect: ConfigurationAspect,
386-
no_cache: boolean,
387-
): Promise<Configuration> {
388-
if (!is_valid_uuid_string(project_id)) {
389-
throw Error("project_id must be a valid uuid");
390-
}
391-
return (await this.api(project_id)).configuration(aspect, no_cache);
392-
}
380+
// for reuseInFlight, see https://github.com/sagemathinc/cocalc/issues/7806
381+
public configuration = reuseInFlight(
382+
async (
383+
project_id: string,
384+
aspect: ConfigurationAspect,
385+
no_cache: boolean,
386+
): Promise<Configuration> => {
387+
if (!is_valid_uuid_string(project_id)) {
388+
throw Error("project_id must be a valid uuid");
389+
}
390+
return (await this.api(project_id)).configuration(aspect, no_cache);
391+
},
392+
);
393393

394394
// Remove all upgrades from all projects that this user collaborates on.
395395
public async remove_all_upgrades(projects?: string[]): Promise<void> {
@@ -543,29 +543,30 @@ export class ProjectClient {
543543
return get_usage_info(project_id);
544544
}
545545

546-
// NOTE: we reuseInFlight this in the constructor.
547-
public async ipywidgetsGetBuffer(
548-
project_id: string,
549-
path: string,
550-
model_id: string,
551-
buffer_path: string,
552-
useHttp?: boolean, // ONLY works for home base, NOT compute servers!
553-
): Promise<ArrayBuffer> {
554-
if (useHttp) {
555-
const url = ipywidgetsGetBufferUrl(
556-
project_id,
557-
path,
546+
public ipywidgetsGetBuffer = reuseInFlight(
547+
async (
548+
project_id: string,
549+
path: string,
550+
model_id: string,
551+
buffer_path: string,
552+
useHttp?: boolean, // ONLY works for home base, NOT compute servers!
553+
): Promise<ArrayBuffer> => {
554+
if (useHttp) {
555+
const url = ipywidgetsGetBufferUrl(
556+
project_id,
557+
path,
558+
model_id,
559+
buffer_path,
560+
);
561+
return await (await fetch(url)).arrayBuffer();
562+
}
563+
const actions = redux.getEditorActions(project_id, path);
564+
return await actions.jupyter_actions.ipywidgetsGetBuffer(
558565
model_id,
559566
buffer_path,
560567
);
561-
return await (await fetch(url)).arrayBuffer();
562-
}
563-
const actions = redux.getEditorActions(project_id, path);
564-
return await actions.jupyter_actions.ipywidgetsGetBuffer(
565-
model_id,
566-
buffer_path,
567-
);
568-
}
568+
},
569+
);
569570

570571
// getting, setting, editing, deleting, etc., the api keys for a project
571572
public async api_keys(opts: {

src/packages/frontend/course/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ export class CourseActions extends Actions<CourseState> {
246246

247247
// ACTIVITY ACTIONS
248248
public set_activity(
249-
opts: { id: number; desc?: string } | { id?: number; desc: string }
249+
opts: { id: number; desc?: string } | { id?: number; desc: string },
250250
): number {
251251
return this.activity.set_activity(opts);
252252
}
@@ -349,7 +349,7 @@ export class CourseActions extends Actions<CourseState> {
349349
| "peer_config"
350350
| "handout"
351351
| "skip_grading",
352-
item_id
352+
item_id,
353353
): void {
354354
let adjusted;
355355
const store = this.get_store();

0 commit comments

Comments
 (0)