Add spinner to indicate profile application

d99dfb91682a07e9fbc4d14ffd140161d83805ef

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

3 files changed, +61 -3Ignore whitespace
public/scripts/extensions/connection-manager/index.js+54 -1
@@ -49,6 +49,48 @@ const FANCY_NAMES = {
49 'tokenizer': 'Tokenizer',49 'tokenizer': 'Tokenizer',
50};50};
5151
52/**
53 * A wrapper for the connection manager spinner.
54 */
55class 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
52/** @type {() => SlashCommandEnumValue[]} */94/** @type {() => SlashCommandEnumValue[]} */
53const profilesProvider = () => [95const profilesProvider = () => [
54 new SlashCommandEnumValue(NONE),96 new SlashCommandEnumValue(NONE),
@@ -214,10 +256,19 @@ async function applyConnectionProfile(profile) {
214 return;256 return;
215 }257 }
216258
259 // Abort any ongoing profile application
260 ConnectionManagerSpinner.abort();
261
217 const mode = profile.mode;262 const mode = profile.mode;
218 const commands = mode === 'cc' ? CC_COMMANDS : TC_COMMANDS;263 const commands = mode === 'cc' ? CC_COMMANDS : TC_COMMANDS;
264 const spinner = new ConnectionManagerSpinner();
265 spinner.start();
219266
220 for (const command of commands) {267 for (const command of commands) {
268 if (spinner.isAborted()) {
269 throw new Error('Profile application aborted');
270 }
271
221 const argument = profile[command];272 const argument = profile[command];
222 if (!argument) {273 if (!argument) {
223 continue;274 continue;
@@ -226,9 +277,11 @@ async function applyConnectionProfile(profile) {
226 try {277 try {
227 await executeSlashCommandsWithOptions(commandText, { handleParserErrors: false, handleExecutionErrors: false });278 await executeSlashCommandsWithOptions(commandText, { handleParserErrors: false, handleExecutionErrors: false });
228 } catch (error) {279 } catch (error) {
229 console.warn(`Failed to execute command: ${commandText}`, error);280 console.error(`Failed to execute command: ${commandText}`, error);
230 }281 }
231 }282 }
283
284 spinner.stop();
232}285}
233286
234/**287/**
public/scripts/extensions/connection-manager/settings.html+3 -2
@@ -13,8 +13,9 @@
13 <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>13 <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>
14 </div>14 </div>
15 <details id="connection_profile_details" class="marginBot10">15 <details id="connection_profile_details" class="marginBot10">
16 <summary data-i18n="Profile Details">16 <summary>
17 Profile Details17 <span data-i18n="Profile Details">Profile Details</span>
18 <i id="connection_profile_spinner" class="fa-solid fa-spinner fa-spin hidden"></i>
18 </summary>19 </summary>
19 <div id="connection_profile_details_content" class="marginTop5"></div>20 <div id="connection_profile_details_content" class="marginTop5"></div>
20 </details>21 </details>
public/scripts/extensions/connection-manager/style.css+4 -0
@@ -7,3 +7,7 @@
7#connection_profile_details ul {7#connection_profile_details ul {
8 margin: 5px 0;8 margin: 5px 0;
9}9}
10
11#connection_profile_spinner {
12 margin-lefT: 5px;
13}