diff --git a/ts/form.ts b/ts/form.ts
index b3dbc25..01b8d87 100644
--- a/ts/form.ts
+++ b/ts/form.ts
@@ -1,8 +1,9 @@
import { Modal } from "./modules/modal.js";
import { notificationBox, whichAnimationEvent } from "./modules/common.js";
-import { _get, _post, toggleLoader, addLoader, removeLoader, toDateString, DiscordInvite } from "./modules/common.js";
+import { _get, _post, toggleLoader, addLoader, removeLoader, toDateString } from "./modules/common.js";
import { loadLangSelector } from "./modules/lang.js";
import { initValidator } from "./modules/validator.js";
+import { Discord, DiscordConfiguration } from "./modules/account-linking.js";
interface formWindow extends Window {
invalidPassword: string;
@@ -95,61 +96,32 @@ var discordVerified = false;
if (window.discordEnabled) {
window.discordModal = new Modal(document.getElementById("modal-discord"), window.discordRequired);
const discordButton = document.getElementById("link-discord") as HTMLSpanElement;
- if (window.discordInviteLink) {
- _get("/invite/" + window.code + "/discord/invite", null, (req: XMLHttpRequest) => {
- if (req.readyState == 4) {
- if (req.status != 200) {
- return;
- }
- const inv = req.response as DiscordInvite;
- const link = document.getElementById("discord-invite") as HTMLAnchorElement;
- link.classList.add("subheading", "link-center");
- link.href = inv.invite;
- link.target = "_blank";
- link.innerHTML = `${window.discordServerName}`;
+
+ const discordConf: DiscordConfiguration = {
+ modal: window.discordModal as Modal,
+ pin: window.discordPIN,
+ inviteURL: window.discordInviteLink ? ("/invite/" + window.code + "/discord/invite") : "",
+ pinURL: "",
+ verifiedURL: "/invite/" + window.code + "/discord/verified/",
+ invalidCodeError: window.messages["errorInvalidCode"],
+ accountLinkedError: window.messages["errorAccountLinked"],
+ successError: window.messages["verified"],
+ successFunc: (modalClosed: boolean) => {
+ if (!modalClosed) {
+ discordButton.classList.add("unfocused");
+ document.getElementById("contact-via").classList.remove("unfocused");
+ document.getElementById("contact-via-email").parentElement.classList.remove("unfocused");
+ const radio = document.getElementById("contact-via-discord") as HTMLInputElement;
+ radio.parentElement.classList.remove("unfocused")
+ radio.checked = true;
+ validatorFunc();
}
- });
- }
- discordButton.onclick = () => {
- const waiting = document.getElementById("discord-waiting") as HTMLSpanElement;
- toggleLoader(waiting);
- window.discordModal.show();
- let modalClosed = false;
- window.discordModal.onclose = () => {
- modalClosed = true;
- toggleLoader(waiting);
}
- const checkVerified = () => _get("/invite/" + window.code + "/discord/verified/" + window.discordPIN, null, (req: XMLHttpRequest) => {
- if (req.readyState == 4) {
- if (req.status == 401) {
- window.discordModal.close();
- window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
- return;
- } else if (req.status == 400) {
- window.discordModal.close();
- window.notifications.customError("accountLinkedError", window.messages["errorAccountLinked"]);
- } else if (req.status == 200) {
- if (req.response["success"] as boolean) {
- discordVerified = true;
- waiting.classList.add("~positive");
- waiting.classList.remove("~info");
- window.notifications.customPositive("discordVerified", "", window.messages["verified"]);
- setTimeout(window.discordModal.close, 2000);
- discordButton.classList.add("unfocused");
- document.getElementById("contact-via").classList.remove("unfocused");
- document.getElementById("contact-via-email").parentElement.classList.remove("unfocused");
- const radio = document.getElementById("contact-via-discord") as HTMLInputElement;
- radio.parentElement.classList.remove("unfocused")
- radio.checked = true;
- validatorFunc();
- } else if (!modalClosed) {
- setTimeout(checkVerified, 1500);
- }
- }
- }
- });
- checkVerified();
};
+
+ const discord = new Discord(discordConf);
+
+ discordButton.onclick = discord.onclick;
}
var matrixVerified = false;
diff --git a/ts/modules/account-linking.ts b/ts/modules/account-linking.ts
new file mode 100644
index 0000000..fce2ec8
--- /dev/null
+++ b/ts/modules/account-linking.ts
@@ -0,0 +1,144 @@
+import { Modal } from "../modules/modal.js";
+import { _get, _post, toggleLoader } from "../modules/common.js";
+
+interface formWindow extends Window {
+ invalidPassword: string;
+ successModal: Modal;
+ telegramModal: Modal;
+ discordModal: Modal;
+ matrixModal: Modal;
+ confirmationModal: Modal;
+ redirectToJellyfin: boolean;
+ code: string;
+ messages: { [key: string]: string };
+ confirmation: boolean;
+ telegramRequired: boolean;
+ telegramPIN: string;
+ discordRequired: boolean;
+ discordPIN: string;
+ discordStartCommand: string;
+ discordInviteLink: boolean;
+ discordServerName: string;
+ matrixRequired: boolean;
+ matrixUserID: string;
+ userExpiryEnabled: boolean;
+ userExpiryMonths: number;
+ userExpiryDays: number;
+ userExpiryHours: number;
+ userExpiryMinutes: number;
+ userExpiryMessage: string;
+ emailRequired: boolean;
+ captcha: boolean;
+ reCAPTCHA: boolean;
+ reCAPTCHASiteKey: string;
+}
+
+declare var window: formWindow;
+
+export interface DiscordConfiguration {
+ modal: Modal;
+ pin: string;
+ inviteURL: string;
+ pinURL: string;
+ verifiedURL: string;
+ invalidCodeError: string;
+ accountLinkedError: string;
+ successError: string;
+ successFunc: (modalClosed: boolean) => void;
+};
+
+export interface DiscordInvite {
+ invite: string;
+ icon: string;
+}
+
+export class Discord {
+ private _conf: DiscordConfiguration;
+ private _pinAcquired = false;
+ private _modalClosed = false;
+ private _waiting = document.getElementById("discord-waiting") as HTMLSpanElement;
+ private _verified = false;
+
+ get verified(): boolean { return this._verified; }
+
+ constructor(conf: DiscordConfiguration) {
+ this._conf = conf;
+ this._conf.modal.onclose = () => {
+ this._modalClosed = true;
+ toggleLoader(this._waiting);
+ };
+ }
+
+ private _getInviteURL = () => _get(this._conf.inviteURL, null, (req: XMLHttpRequest) => {
+ if (req.readyState != 4) return;
+ const inv = req.response as DiscordInvite;
+ const link = document.getElementById("discord-invite") as HTMLAnchorElement;
+ link.href = inv.invite;
+ link.target = "_blank";
+ link.innerHTML = `${window.discordServerName}`;
+ });
+
+ private _checkVerified = () => {
+ if (this._modalClosed) return;
+ if (!this._pinAcquired) {
+ setTimeout(this._checkVerified, 1500);
+ return;
+ }
+ _get(this._conf.verifiedURL + this._conf.pin, null, (req: XMLHttpRequest) => {
+ if (req.readyState != 4) return;
+ if (req.status == 401) {
+ this._conf.modal.close();
+ window.notifications.customError("invalidCodeError", this._conf.invalidCodeError);
+ } else if (req.status == 400) {
+ this._conf.modal.close();
+ window.notifications.customError("accountLinkedError", this._conf.accountLinkedError);
+ } else if (req.status == 200) {
+ if (req.response["success"] as boolean) {
+ this._verified = true;
+ this._waiting.classList.add("~positive");
+ this._waiting.classList.remove("~info");
+ window.notifications.customPositive("discordVerified", "", this._conf.successError);
+ if (this._conf.successFunc) {
+ this._conf.successFunc(false);
+ }
+ setTimeout(() => {
+ this._conf.modal.close();
+ if (this._conf.successFunc) {
+ this._conf.successFunc(true);
+ }
+ }, 2000);
+
+ } else if (!this._modalClosed) {
+ setTimeout(this._checkVerified, 1500);
+ }
+ }
+ });
+ };
+
+ onclick = () => {
+ if (this._conf.inviteURL != "") {
+ this._getInviteURL();
+ }
+
+ toggleLoader(this._waiting);
+
+ this._pinAcquired = false;
+ if (this._conf.pin) {
+ this._pinAcquired = true;
+ this._conf.modal.modal.querySelector(".pin").textContent = this._conf.pin;
+ } else {
+ _get(this._conf.pinURL, null, (req: XMLHttpRequest) => {
+ if (req.readyState == 4 && req.status == 200) {
+ this._conf.pin = req.response["pin"];
+ this._conf.modal.modal.querySelector(".pin").textContent = this._conf.pin;
+ this._pinAcquired = true;
+ }
+ });
+ }
+
+ this._modalClosed = false;
+ this._conf.modal.show();
+
+ this._checkVerified();
+ }
+}
diff --git a/ts/modules/common.ts b/ts/modules/common.ts
index 6ae320d..4687cc8 100644
--- a/ts/modules/common.ts
+++ b/ts/modules/common.ts
@@ -221,8 +221,3 @@ export function insertText(textarea: HTMLTextAreaElement, text: string) {
textarea.focus();
}
}
-
-export interface DiscordInvite {
- invite: string;
- icon: string;
-}
diff --git a/ts/user.ts b/ts/user.ts
index ac34517..465dfd9 100644
--- a/ts/user.ts
+++ b/ts/user.ts
@@ -1,8 +1,9 @@
import { ThemeManager } from "./modules/theme.js";
import { lang, LangFile, loadLangSelector } from "./modules/lang.js";
import { Modal } from "./modules/modal.js";
-import { _get, _post, notificationBox, whichAnimationEvent, toDateString, toggleLoader, DiscordInvite } from "./modules/common.js";
+import { _get, _post, notificationBox, whichAnimationEvent, toDateString, toggleLoader } from "./modules/common.js";
import { Login } from "./modules/login.js";
+import { Discord, DiscordConfiguration } from "./modules/account-linking.js";
interface userWindow extends Window {
jellyfinID: string;
@@ -278,70 +279,22 @@ const addEditEmail = (add: boolean): void => {
window.modals.email.show();
}
-let discordModalClosed = false;
-let discordPIN = "";
-const addEditDiscord = (add: boolean): void => {
- if (window.discordInviteLink) {
- _get("/my/discord/invite", null, (req: XMLHttpRequest) => {
- if (req.readyState == 4) {
- if (req.status != 200) return;
- const inv = req.response as DiscordInvite;
- const link = document.getElementById("discord-invite") as HTMLAnchorElement;
- link.href = inv.invite;
- link.target = "_blank";
- link.innerHTML = `${window.discordServerName}`;
- }
- });
+const discordConf: DiscordConfiguration = {
+ modal: window.modals.discord as Modal,
+ pin: "",
+ inviteURL: window.discordInviteLink ? "/my/discord/invite" : "",
+ pinURL: "/my/pin/discord",
+ verifiedURL: "/my/discord/verified/",
+ invalidCodeError: window.lang.notif("errorInvalidCode"),
+ accountLinkedError: window.lang.notif("errorAccountLinked"),
+ successError: window.lang.notif("verified"),
+ successFunc: (modalClosed: boolean) => {
+ if (modalClosed) window.location.reload();
}
-
- _get("/my/pin/discord", null, (req: XMLHttpRequest) => {
- if (req.readyState == 4 && req.status == 200) {
- discordPIN = req.response["pin"];
- window.modals.discord.modal.querySelector(".pin").textContent = discordPIN;
- }
- });
-
- const waiting = document.getElementById("discord-waiting") as HTMLSpanElement;
- toggleLoader(waiting);
- window.modals.discord.show();
- discordModalClosed = false;
- window.modals.discord.onclose = () => {
- discordModalClosed = true;
- toggleLoader(waiting);
- }
- const checkVerified = () => {
- if (discordPIN == "") {
- setTimeout(checkVerified, 1500);
- }
- if (discordModalClosed) return;
- _get("/my/discord/verified/" + discordPIN, null, (req: XMLHttpRequest) => {
- if (req.readyState != 4) return;
- if (req.status == 401) {
- window.modals.discord.close();
- window.notifications.customError("invalidCodeError", window.lang.notif("errorInvalidCode"));
- return;
- } else if (req.status == 400) {
- window.modals.discord.close();
- window.notifications.customError("accountLinkedError", window.lang.notif("errorAccountLinked"));
- } else if (req.status == 200) {
- if (req.response["success"] as boolean) {
- waiting.classList.add("~positive");
- waiting.classList.remove("~info");
- window.notifications.customPositive("discordVerified", "", window.lang.notif("verified"));
- setTimeout(() => {
- window.modals.discord.close;
- window.location.reload();
- }, 2000);
- } else if (!discordModalClosed) {
- setTimeout(checkVerified, 1500);
- }
- }
- });
- };
-
- checkVerified();
};
+let discord = new Discord(discordConf);
+
document.addEventListener("details-reload", () => {
_get("/my/details", null, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
@@ -368,7 +321,7 @@ document.addEventListener("details-reload", () => {
const contactMethods: { name: string, icon: string, f: (add: boolean) => void }[] = [
{name: "email", icon: ``, f: addEditEmail},
- {name: "discord", icon: ``, f: addEditDiscord},
+ {name: "discord", icon: ``, f: discord.onclick},
{name: "telegram", icon: ``, f: null},
{name: "matrix", icon: `[m]`, f: null}
];