Skip to content

Commit a191c5b

Browse files
committed
feat: animate manual refresh button
1 parent e307051 commit a191c5b

1 file changed

Lines changed: 48 additions & 2 deletions

File tree

extension.js

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class CodexUsageIndicator extends PanelMenu.Button {
4343
this._extension = extension;
4444
this._settings = extension.getSettings();
4545
this._refreshId = 0;
46+
this._refreshSpinId = 0;
4647
this._refreshInFlight = false;
4748
this._snapshot = null;
4849
this._errorMessage = null;
@@ -70,6 +71,11 @@ class CodexUsageIndicator extends PanelMenu.Button {
7071
this._refreshId = 0;
7172
}
7273

74+
if (this._refreshSpinId) {
75+
GLib.source_remove(this._refreshSpinId);
76+
this._refreshSpinId = 0;
77+
}
78+
7379
if (this._settingsChangedId) {
7480
this._settings.disconnect(this._settingsChangedId);
7581
this._settingsChangedId = 0;
@@ -211,8 +217,10 @@ class CodexUsageIndicator extends PanelMenu.Button {
211217
x_align: Clutter.ActorAlign.END,
212218
y_align: Clutter.ActorAlign.CENTER,
213219
});
220+
const refreshIcon = refreshButton.child;
221+
refreshIcon.set_pivot_point(0.5, 0.5);
214222
refreshButton.connect('clicked', () => {
215-
void this._refreshUsage();
223+
void this._refreshUsage({manual: true});
216224
});
217225

218226
const datetimeLabel = new St.Label({
@@ -227,6 +235,7 @@ class CodexUsageIndicator extends PanelMenu.Button {
227235
box.add_child(datetimeLabel);
228236
item.add_child(box);
229237
item.datetimeLabel = datetimeLabel;
238+
item.refreshIcon = refreshIcon;
230239
item.refreshButton = refreshButton;
231240

232241
return item;
@@ -309,18 +318,23 @@ class CodexUsageIndicator extends PanelMenu.Button {
309318
);
310319
}
311320

312-
async _refreshUsage() {
321+
async _refreshUsage({manual = false} = {}) {
313322
if (this._refreshInFlight)
314323
return;
315324

316325
this._refreshInFlight = true;
317326

327+
if (manual)
328+
this._startRefreshSpin();
329+
318330
try {
319331
this._snapshot = await fetchCodexUsageSnapshot();
320332
this._errorMessage = null;
321333
} catch (error) {
322334
this._errorMessage = error?.message ?? 'Unable to load Codex usage.';
323335
} finally {
336+
if (manual)
337+
this._stopRefreshSpin();
324338
this._refreshInFlight = false;
325339
this._syncLabel();
326340
this._syncMenu();
@@ -344,6 +358,38 @@ class CodexUsageIndicator extends PanelMenu.Button {
344358
return safeMinutes * 60;
345359
}
346360

361+
_startRefreshSpin() {
362+
if (!this._headerItem?.refreshIcon || this._refreshSpinId)
363+
return;
364+
365+
this._headerItem.refreshButton.reactive = false;
366+
this._headerItem.refreshButton.can_focus = false;
367+
368+
this._refreshSpinId = GLib.timeout_add(
369+
GLib.PRIORITY_DEFAULT,
370+
30,
371+
() => {
372+
this._headerItem.refreshIcon.rotation_angle_z =
373+
(this._headerItem.refreshIcon.rotation_angle_z + 18) % 360;
374+
return GLib.SOURCE_CONTINUE;
375+
}
376+
);
377+
}
378+
379+
_stopRefreshSpin() {
380+
if (this._refreshSpinId) {
381+
GLib.source_remove(this._refreshSpinId);
382+
this._refreshSpinId = 0;
383+
}
384+
385+
if (!this._headerItem?.refreshIcon)
386+
return;
387+
388+
this._headerItem.refreshIcon.rotation_angle_z = 0;
389+
this._headerItem.refreshButton.reactive = true;
390+
this._headerItem.refreshButton.can_focus = true;
391+
}
392+
347393
_syncLabel() {
348394
if (!this._snapshot) {
349395
this._label.text = this._errorMessage ? 'CX !' : 'CX --';

0 commit comments

Comments
 (0)