CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/collaborators/handle-project-invite.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { QueryParams } from "../misc/query-params";
7
import { webapp_client } from "../webapp-client";
8
import { alert_message } from "../alerts";
9
import { redux } from "../app-framework";
10
import { delay } from "awaiting";
11
12
export const PROJECT_INVITE_QUERY_PARAM = "project-invite";
13
14
async function handle_project_invite() {
15
webapp_client.removeListener("signed_in", handle_project_invite); // only try at most once the first time.
16
const token_id = QueryParams.get(PROJECT_INVITE_QUERY_PARAM);
17
if (!token_id) return;
18
QueryParams.remove(PROJECT_INVITE_QUERY_PARAM);
19
const account_id = webapp_client.account_id;
20
if (!account_id) return;
21
add_self_to_project_using_token(token_id);
22
}
23
24
async function init() {
25
await delay(0); // has to be after page loads...
26
webapp_client.on("signed_in", handle_project_invite);
27
}
28
init();
29
30
export async function add_self_to_project_using_token(token_id) {
31
if (webapp_client.account_id == null) return;
32
33
const actions = redux.getActions("page");
34
if (
35
!(await actions.popconfirm({
36
title: "Would you like to accept this project invitation?",
37
description:
38
"If you are visiting a link from somebody you trust, click 'Yes, accept invitation'. If this seems suspicious, click 'No'. You can always open the invite link again if you change your mind.",
39
okText: "Yes, accept invitation",
40
}))
41
) {
42
return;
43
}
44
try {
45
const resp = await webapp_client.project_collaborators.add_collaborator({
46
account_id: webapp_client.account_id,
47
token_id,
48
});
49
const project_id = resp.project_id;
50
if (typeof project_id == "string") {
51
alert_message({
52
type: "info",
53
message: "You have been successfully added to the project!",
54
timeout: 10,
55
});
56
// Wait until the project is available in the store:
57
const store = redux.getStore("projects");
58
await store.async_wait({
59
until: () => store.getIn(["project_map", project_id]),
60
timeout: 120,
61
});
62
// Now actually open it.
63
redux.getActions("projects").open_project({ project_id });
64
} else {
65
throw Error("something went wrong (this shouldn't happen)"); // should never happen.
66
}
67
} catch (err) {
68
alert_message({ type: "error", message: err.toString(), timeout: 30 });
69
}
70
}
71
72