userpage: show and allow modification of contact methods
This commit is contained in:
+2
-8
@@ -177,12 +177,6 @@ login.onLogin = () => {
|
||||
}
|
||||
}
|
||||
|
||||
login.login("", "");
|
||||
login.bindLogout(document.getElementById("logout-button"));
|
||||
|
||||
(document.getElementById('logout-button') as HTMLButtonElement).onclick = () => _post("/logout", null, (req: XMLHttpRequest): boolean => {
|
||||
if (req.readyState == 4 && req.status == 200) {
|
||||
window.token = "";
|
||||
location.reload();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
login.login("", "");
|
||||
|
||||
+21
-4
@@ -1,17 +1,17 @@
|
||||
import { Modal } from "../modules/modal.js";
|
||||
import { toggleLoader } from "../modules/common.js";
|
||||
import { toggleLoader, _post } from "../modules/common.js";
|
||||
|
||||
export class Login {
|
||||
private _modal: Modal;
|
||||
private _form: HTMLFormElement;
|
||||
private _url: string;
|
||||
private _onLogin: (username: string, password: string) => void;
|
||||
private _logoutButton: HTMLElement = null;
|
||||
|
||||
constructor(modal: Modal, endpoint: string) {
|
||||
|
||||
this._url = window.URLBase + endpoint;
|
||||
if (this._url[this._url.length-1] != '/') this._url += "/";
|
||||
this._url += "token/";
|
||||
|
||||
this._modal = modal;
|
||||
this._form = this._modal.asElement().querySelector(".form-login") as HTMLFormElement;
|
||||
@@ -29,6 +29,18 @@ export class Login {
|
||||
};
|
||||
}
|
||||
|
||||
bindLogout = (button: HTMLElement) => {
|
||||
this._logoutButton = button;
|
||||
this._logoutButton.classList.add("unfocused");
|
||||
this._logoutButton.onclick = () => _post(this._url + "logout", null, (req: XMLHttpRequest): boolean => {
|
||||
if (req.readyState == 4 && req.status == 200) {
|
||||
window.token = "";
|
||||
location.reload();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
get onLogin() { return this._onLogin; }
|
||||
set onLogin(f: (username: string, password: string) => void) { this._onLogin = f; }
|
||||
|
||||
@@ -36,7 +48,7 @@ export class Login {
|
||||
const req = new XMLHttpRequest();
|
||||
req.responseType = 'json';
|
||||
const refresh = (username == "" && password == "");
|
||||
req.open("GET", this._url + (refresh ? "refresh" : "login"), true);
|
||||
req.open("GET", this._url + (refresh ? "token/refresh" : "token/login"), true);
|
||||
if (!refresh) {
|
||||
req.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
|
||||
}
|
||||
@@ -46,6 +58,10 @@ export class Login {
|
||||
let errorMsg = window.lang.notif("errorConnection");
|
||||
if (req.response) {
|
||||
errorMsg = req.response["error"];
|
||||
const langErrorMsg = window.lang.strings(errorMsg);
|
||||
if (langErrorMsg) {
|
||||
errorMsg = langErrorMsg;
|
||||
}
|
||||
}
|
||||
if (!errorMsg) {
|
||||
errorMsg = window.lang.notif("errorUnknown");
|
||||
@@ -62,7 +78,8 @@ export class Login {
|
||||
this._onLogin(username, password);
|
||||
}
|
||||
this._modal.close();
|
||||
document.getElementById("logout-button").classList.remove("unfocused");
|
||||
if (this._logoutButton != null)
|
||||
this._logoutButton.classList.remove("unfocused");
|
||||
}
|
||||
if (run) { run(+req.status); }
|
||||
}
|
||||
|
||||
+152
-6
@@ -30,21 +30,167 @@ window.modals = {} as Modals;
|
||||
window.notifications = new notificationBox(document.getElementById('notification-box') as HTMLDivElement, 5);
|
||||
|
||||
var rootCard = document.getElementById("card-user");
|
||||
var contactCard = document.getElementById("card-contact");
|
||||
|
||||
const login = new Login(window.modals.login as Modal, "/my/");
|
||||
login.onLogin = () => {
|
||||
console.log("Logged in.");
|
||||
interface MyDetailsContactMethod {
|
||||
value: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
interface MyDetails {
|
||||
id: string;
|
||||
username: string;
|
||||
expiry: number;
|
||||
admin: boolean;
|
||||
disabled: boolean;
|
||||
email?: MyDetailsContactMethod;
|
||||
discord?: MyDetailsContactMethod;
|
||||
telegram?: MyDetailsContactMethod;
|
||||
matrix?: MyDetailsContactMethod;
|
||||
}
|
||||
|
||||
interface ContactDTO {
|
||||
email?: boolean;
|
||||
discord?: boolean;
|
||||
telegram?: boolean;
|
||||
matrix?: boolean;
|
||||
}
|
||||
|
||||
class ContactMethods {
|
||||
private _card: HTMLElement;
|
||||
private _buttons: { [name: string]: { element: HTMLElement, details: MyDetailsContactMethod } };
|
||||
|
||||
constructor (card: HTMLElement) {
|
||||
this._card = card;
|
||||
this._buttons = {};
|
||||
}
|
||||
|
||||
clear = () => {
|
||||
this._card.textContent = "";
|
||||
this._buttons = {};
|
||||
}
|
||||
|
||||
append = (name: string, details: MyDetailsContactMethod, icon: string) => {
|
||||
const row = document.createElement("div");
|
||||
row.classList.add("row", "flex-expand", "my-2");
|
||||
row.innerHTML = `
|
||||
<div class="inline align-middle">
|
||||
<span class="shield ~info" alt="${name}">
|
||||
<span class="icon">
|
||||
${icon}
|
||||
</span>
|
||||
</span>
|
||||
<span class="ml-2 font-bold">${details.value}</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<button class="user-contact-enabled-disabled button ~neutral">
|
||||
<input type="checkbox" class="mr-2">
|
||||
<span>${window.lang.strings("enabled")}</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this._buttons[name] = {
|
||||
element: row,
|
||||
details: details
|
||||
};
|
||||
|
||||
const button = row.querySelector(".user-contact-enabled-disabled") as HTMLButtonElement;
|
||||
const checkbox = button.querySelector("input[type=checkbox]") as HTMLInputElement;
|
||||
const setButtonAppearance = () => {
|
||||
if (checkbox.checked) {
|
||||
button.classList.add("~info");
|
||||
button.classList.remove("~neutral");
|
||||
} else {
|
||||
button.classList.add("~neutral");
|
||||
button.classList.remove("~info");
|
||||
}
|
||||
};
|
||||
const onPress = () => {
|
||||
this._buttons[name].details.enabled = checkbox.checked;
|
||||
setButtonAppearance();
|
||||
this._save();
|
||||
};
|
||||
|
||||
checkbox.onchange = onPress;
|
||||
button.onclick = () => {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
onPress();
|
||||
};
|
||||
|
||||
checkbox.checked = details.enabled;
|
||||
setButtonAppearance();
|
||||
|
||||
this._card.appendChild(row);
|
||||
};
|
||||
|
||||
private _save = () => {
|
||||
let data: ContactDTO = {};
|
||||
for (let method of Object.keys(this._buttons)) {
|
||||
data[method] = this._buttons[method].details.enabled;
|
||||
}
|
||||
|
||||
_post("/my/contact", data, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200) {
|
||||
window.notifications.customError("errorSetNotify", window.lang.notif("errorSaveSettings"));
|
||||
document.dispatchEvent(new CustomEvent("details-reload"));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
var contactMethodList = new ContactMethods(contactCard);
|
||||
|
||||
document.addEventListener("details-reload", () => {
|
||||
_get("/my/details", null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200) {
|
||||
window.notifications.customError("myDetailsError", req.response["error"]);
|
||||
return;
|
||||
}
|
||||
window.jellyfinID = req.response["id"];
|
||||
window.username = req.response["username"];
|
||||
rootCard.querySelector(".heading").textContent = window.lang.strings("welcomeUser").replace("{user}", window.username);
|
||||
const details: MyDetails = req.response as MyDetails;
|
||||
window.jellyfinID = details.id;
|
||||
window.username = details.username;
|
||||
let innerHTML = `
|
||||
<span>${window.lang.strings("welcomeUser").replace("{user}", window.username)}</span>
|
||||
`;
|
||||
if (details.admin) {
|
||||
innerHTML += `<span class="chip ~info ml-4">${window.lang.strings("admin")}</span>`;
|
||||
}
|
||||
if (details.disabled) {
|
||||
innerHTML += `<span class="chip ~warning ml-4">${window.lang.strings("disabled")}</span>`;
|
||||
}
|
||||
|
||||
rootCard.querySelector(".heading").innerHTML = innerHTML;
|
||||
|
||||
contactMethodList.clear();
|
||||
|
||||
const contactMethods = [
|
||||
["email", `<i class="ri-mail-fill"></i>`],
|
||||
["discord", `<i class="ri-discord-fill"></i>`],
|
||||
["telegram", `<i class="ri-telegram-fill"></i>`],
|
||||
["matrix", `[m]`]
|
||||
];
|
||||
|
||||
for (let method of contactMethods) {
|
||||
if (method[0] in details) {
|
||||
contactMethodList.append(method[0], details[method[0]], method[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const login = new Login(window.modals.login as Modal, "/my/");
|
||||
login.onLogin = () => {
|
||||
console.log("Logged in.");
|
||||
document.dispatchEvent(new CustomEvent("details-reload"));
|
||||
};
|
||||
|
||||
|
||||
|
||||
login.bindLogout(document.getElementById("logout-button"));
|
||||
|
||||
login.login("", "");
|
||||
|
||||
Reference in New Issue
Block a user