This repository has been archived by the owner on Nov 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
kubePopupMenuItem.js
126 lines (112 loc) · 4.42 KB
/
kubePopupMenuItem.js
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
116
117
118
119
120
121
122
123
124
125
126
import Clutter from 'gi://Clutter';
import GObject from 'gi://GObject';
import GLib from 'gi://GLib';
import St from 'gi://St';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import { Kubectl } from './kubectl.js';
import { throttle } from './utils.js';
export const KubePopupMenuItem = GObject.registerClass(
{
GTypeName: 'KubePopupMenuItem'
},
class extends PopupMenu.PopupMenuItem {
/**
* @param {Extension} extensionObject
* @param {String} text
* @param {boolean} selected
* @param {Object} params : PopupBaseMenuItem additional item properties (https://gjs.guide/extensions/topics/popup-menu.html#popupbasemenuitem)
*/
constructor(extensionObject, text, selected, params) {
super(text.trim(), params);
this._extensionObject = extensionObject;
this._settings = this._extensionObject.getSettings();
// TODO: How to know if item is already destroyed?
this._destroyed = false;
// current context ornament
if (selected === true) {
this.setOrnament(PopupMenu.Ornament.DOT);
//this.setOrnament(PopupMenu.Ornament.CHECK);
} else {
this.setOrnament(PopupMenu.Ornament.NONE);
}
// connect signals
this.connect("activate", (_item, _event) => {
Kubectl.useContext(this.label.get_text());
});
this.connect('destroy', this._onDestroy.bind(this));
// initialize cluster status icon
this._clusterStatusIcon = null;
this._setClusterStatusIcon('network-error-symbolic');
// bind settings and start cluster polling
this._timerid = null;
this._bindSettingsChanges();
// initial update because GLib.timeout_add_seconds call first time
// after interval, not immediately
this._updateClusterStatus().catch(e => console.error(`${this._extensionObject.uuid}: ${e}`));
this._restartClusterPoll();
}
_bindSettingsChanges() {
// limit too frequent updates
const throttledClusterPoll = throttle(this._restartClusterPoll.bind(this), 500);
this._settings.connect('changed::cluster-poll-interval-seconds', () => {
throttledClusterPoll();
});
}
_restartClusterPoll() {
this._stopClusterPoll();
this._timerid = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT,
this._settings.get_int('cluster-poll-interval-seconds'),
() => this._updateClusterStatus().catch(e => console.error(`${this._extensionObject.uuid}: ${e}`))
);
}
_stopClusterPoll() {
if (this._timerid !== null) {
if (GLib.source_remove(this._timerid)) {
this._timerid = null;
} else {
console.error(`${this._extensionObject.uuid}: cannot remove timer ${this._timerid}`);
}
}
}
async _updateClusterStatus() {
if (this._destroyed) {
return;
}
const status = await Kubectl.clusterIsReachable(this.label.get_text());
if (this._destroyed) {
return;
}
if (status) {
this._setClusterStatusIcon('network-transmit-receive-symbolic');
} else {
this._setClusterStatusIcon('network-error-symbolic');
}
}
/**
* Set cluster status icon.
*
* @param {String} iconName
*/
_setClusterStatusIcon(iconName) {
if (this._destroyed) {
return;
}
if (this._clusterStatusIcon === null) {
this._clusterStatusIcon = new St.Icon({
icon_name: iconName,
style_class: 'popup-menu-icon',
x_align: Clutter.ActorAlign.END,
x_expand: true,
y_expand: true,
});
this.add_child(this._clusterStatusIcon);
} else {
this._clusterStatusIcon.set_icon_name(iconName);
}
}
_onDestroy() {
this._destroyed = true;
this._stopClusterPoll();
}
});