File size: 3,781 Bytes
e26a977
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
114
115
import { api } from "../api.js";
import { $el } from "../ui.js";
import { addStylesheet } from "../utils.js";
import { createSpinner } from "./spinner.js";

export class UserSelectionScreen {
	async show(users, user) {
		// This will rarely be hit so move the loading to on demand
		await addStylesheet(import.meta.url);
		const userSelection = document.getElementById("comfy-user-selection");
		userSelection.style.display = "";
		return new Promise((resolve) => {
			const input = userSelection.getElementsByTagName("input")[0];
			const select = userSelection.getElementsByTagName("select")[0];
			const inputSection = input.closest("section");
			const selectSection = select.closest("section");
			const form = userSelection.getElementsByTagName("form")[0];
			const error = userSelection.getElementsByClassName("comfy-user-error")[0];
			const button = userSelection.getElementsByClassName("comfy-user-button-next")[0];

			let inputActive = null;
			input.addEventListener("focus", () => {
				inputSection.classList.add("selected");
				selectSection.classList.remove("selected");
				inputActive = true;
			});
			select.addEventListener("focus", () => {
				inputSection.classList.remove("selected");
				selectSection.classList.add("selected");
				inputActive = false;
				select.style.color = "";
			});
			select.addEventListener("blur", () => {
				if (!select.value) {
					select.style.color = "var(--descrip-text)";
				}
			});

			form.addEventListener("submit", async (e) => {
				e.preventDefault();
				if (inputActive == null) {
					error.textContent = "Please enter a username or select an existing user.";
				} else if (inputActive) {
					const username = input.value.trim();
					if (!username) {
						error.textContent = "Please enter a username.";
						return;
					}

					// Create new user
					input.disabled = select.disabled = input.readonly = select.readonly = true;
					const spinner = createSpinner();
					button.prepend(spinner);
					try {
						const resp = await api.createUser(username);
						if (resp.status >= 300) {
							let message = "Error creating user: " + resp.status + " " + resp.statusText;
							try {
								const res = await resp.json();								
								if(res.error) {
									message = res.error;
								}
							} catch (error) {
							}
							throw new Error(message);
						}

						resolve({ username, userId: await resp.json(), created: true });
					} catch (err) {
						spinner.remove();
						error.textContent = err.message ?? err.statusText ?? err ?? "An unknown error occurred.";
						input.disabled = select.disabled = input.readonly = select.readonly = false;
						return;
					}
				} else if (!select.value) {
					error.textContent = "Please select an existing user.";
					return;
				} else {
					resolve({ username: users[select.value], userId: select.value, created: false });
				}
			});

			if (user) {
				const name = localStorage["Comfy.userName"];
				if (name) {
					input.value = name;
				}
			}
			if (input.value) {
				// Focus the input, do this separately as sometimes browsers like to fill in the value
				input.focus();
			}

			const userIds = Object.keys(users ?? {});
			if (userIds.length) {
				for (const u of userIds) {
					$el("option", { textContent: users[u], value: u, parent: select });
				}
				select.style.color = "var(--descrip-text)";

				if (select.value) {
					// Focus the select, do this separately as sometimes browsers like to fill in the value
					select.focus();
				}
			} else {
				userSelection.classList.add("no-users");
				input.focus();
			}
		}).then((r) => {
			userSelection.remove();
			return r;
		});
	}
}