1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
import { DiscordSDK } from "/static/discord-embedded-app-sdk/Discord.js";
const discordSdk = new DiscordSDK(DISCORD_CLIENT_ID);
const updateInstanceRoomInfo = () => {
const contentEl = document.getElementById("instance-room-info-content");
const defaultContents = document.createElement("i");
defaultContents.innerText = "none yet";
if (!contentEl.hasChildNodes()) {
contentEl.replaceChildren(defaultContents);
}
fetch(
`/.proxy/discord_activity/rooms_for_instance?discord_activity_inner&instance_id=${discordSdk.instanceId}`,
)
.then((response) => {
if (!response.ok) {
throw new Error(`Fetching instance room info failed with status code ${response.status}`);
}
return response.json();
})
.then((json) => {
let docFragment = new DocumentFragment();
if (json.length === 0) {
docFragment.appendChild(defaultContents);
} else {
const listEl = docFragment.appendChild(document.createElement("ul"));
for (const roomInfo of json) {
const item = listEl.appendChild(document.createElement("li"));
item.innerText = roomInfo["host_username"] + " ";
const form = item.appendChild(document.createElement("form"));
form.action = roomUrl(roomInfo["room_id"]);
form.target = "activity-inner-iframe";
form.style.display = "inline";
const hiddenInput = form.appendChild(document.createElement("input"));
hiddenInput.type = "hidden";
hiddenInput.name = "discord_activity_inner";
const submitInput = form.appendChild(document.createElement("input"));
submitInput.type = "submit";
submitInput.value = "join";
}
}
contentEl.replaceChildren(docFragment);
})
.catch((error) => {
console.error(error);
});
};
updateInstanceRoomInfo();
const INSTANCE_ROOM_INFO_INTERVAL = 3000;
let instanceRoomInfoIntervalId = setInterval(updateInstanceRoomInfo, INSTANCE_ROOM_INFO_INTERVAL);
const iframe = document.querySelector("iframe");
// It doesn't matter if the iframe's initial loading finishes before this is added
iframe.addEventListener("load", (_) => {
clearInterval(instanceRoomInfoIntervalId);
const locationURL = new URL(iframe.contentWindow.location);
const locationPath = locationURL.pathname + locationURL.search;
if (locationPath === HOME_URL) {
instanceRoomInfoIntervalId = setInterval(updateInstanceRoomInfo, INSTANCE_ROOM_INFO_INTERVAL);
iframe.className = "at-home";
} else {
iframe.className = "";
}
});
discordSdk
.ready()
.then(() => {
return discordSdk.commands.authorize({
client_id: DISCORD_CLIENT_ID,
response_type: "code",
state: "",
prompt: "none",
scope: ["identify"],
});
})
.then((result) => {
const { code } = result;
return fetch(ACCESS_TOKEN_URL, {
body: new URLSearchParams([["code", code]]),
headers: {
"content-type": "application/x-www-form-urlencoded",
"x-csrf-token": document.body.dataset.csrfToken,
},
method: "POST",
});
})
.then((response) => {
if (!response.ok) {
throw new Error(`Getting access token failed with status code ${response.status}`);
}
// Note: the access token should now be in the session cookie as well
return response.text();
})
.then((accessToken) => {
return discordSdk.commands.authenticate({ access_token: accessToken });
})
.then((authenticationResult) => {
if (authenticationResult === null) {
throw new Error("Authenticating with Discord client failed");
}
iframe.style.display = null;
})
.catch((error) => {
console.error(error);
const CLOSE_ABNORMAL = 1006;
discordSdk.close(CLOSE_ABNORMAL, "Could not obtain authorizations required to run this app.");
});
|