Add spinner to indicate profile application

d99dfb91682a07e9fbc4d14ffd140161d83805ef

Cohee <18619528+Cohee1207@users.noreply.github.com>

3 files changed, +61 -3Showing whitespace changes
public/scripts/extensions/connection-manager/index.js+54 -1
@@ -49,6 +49,48 @@ const FANCY_NAMES = {
4949 'tokenizer': 'Tokenizer',
5050};
5151
52+/**
53+ * A wrapper for the connection manager spinner.
54+ */
55+class ConnectionManagerSpinner {
56+ /**
57+ * @type {AbortController[]}
58+ */
59+ static abortControllers = [];
60+
61+ /** @type {HTMLElement} */
62+ spinnerElement;
63+
64+ /** @type {AbortController} */
65+ abortController = new AbortController();
66+
67+ constructor() {
68+ // @ts-ignore
69+ this.spinnerElement = document.getElementById('connection_profile_spinner');
70+ this.abortController = new AbortController();
71+ }
72+
73+ start() {
74+ ConnectionManagerSpinner.abortControllers.push(this.abortController);
75+ this.spinnerElement.classList.remove('hidden');
76+ }
77+
78+ stop() {
79+ this.spinnerElement.classList.add('hidden');
80+ }
81+
82+ isAborted() {
83+ return this.abortController.signal.aborted;
84+ }
85+
86+ static abort() {
87+ for (const controller of ConnectionManagerSpinner.abortControllers) {
88+ controller.abort();
89+ }
90+ ConnectionManagerSpinner.abortControllers = [];
91+ }
92+}
93+
5294/** @type {() => SlashCommandEnumValue[]} */
5395const profilesProvider = () => [
5496 new SlashCommandEnumValue(NONE),
@@ -214,10 +256,19 @@ async function applyConnectionProfile(profile) {
214256 return;
215257 }
216258
259+ // Abort any ongoing profile application
260+ ConnectionManagerSpinner.abort();
261+
217262 const mode = profile.mode;
218263 const commands = mode === 'cc' ? CC_COMMANDS : TC_COMMANDS;
264+ const spinner = new ConnectionManagerSpinner();
265+ spinner.start();
219266
220267 for (const command of commands) {
268+ if (spinner.isAborted()) {
269+ throw new Error('Profile application aborted');
270+ }
271+
221272 const argument = profile[command];
222273 if (!argument) {
223274 continue;
@@ -226,9 +277,11 @@ async function applyConnectionProfile(profile) {
226277 try {
227278 await executeSlashCommandsWithOptions(commandText, { handleParserErrors: false, handleExecutionErrors: false });
228279 } catch (error) {
229280 console.warnerror(`Failed to execute command: ${commandText}`, error);
230281 }
231282 }
283+
284+ spinner.stop();
232285}
233286
234287/**
public/scripts/extensions/connection-manager/settings.html+3 -2
@@ -13,8 +13,9 @@
1313 <i id="delete_connection_profile" class="menu_button fa-solid fa-trash-can" title="Delete a connection profile" data-i18n="[title]Delete a connection profile"></i>
1414 </div>
1515 <details id="connection_profile_details" class="marginBot10">
16- <summary data-i18n="Profile Details">
16+ <summary>
17- Profile Details
17+ <span data-i18n="Profile Details">Profile Details</span>
18+ <i id="connection_profile_spinner" class="fa-solid fa-spinner fa-spin hidden"></i>
1819 </summary>
1920 <div id="connection_profile_details_content" class="marginTop5"></div>
2021 </details>
public/scripts/extensions/connection-manager/style.css+4 -0
@@ -7,3 +7,7 @@
77#connection_profile_details ul {
88 margin: 5px 0;
99}
10+
11+#connection_profile_spinner {
12+ margin-lefT: 5px;
13+}