11import GObject from "gi://GObject" ;
22import GLib from "gi://GLib" ;
33import Gio from "gi://Gio" ;
4- import Soup from "gi://Soup?version=3.0 " ;
4+ import Soup from "gi://Soup" ;
55import St from "gi://St" ;
66import Clutter from "gi://Clutter" ;
77
@@ -13,6 +13,8 @@ import * as Main from "resource:///org/gnome/shell/ui/main.js";
1313const API_BASE = "https://forex.rabbitmonitor.com/v1" ;
1414const TROY_OUNCE_TO_GRAM = 31.1034768 ;
1515
16+ const CATEGORIES = [ "fiat" , "metals" , "crypto" , "stocks" ] ;
17+
1618const CATEGORY_ICONS = {
1719 fiat : "💱" ,
1820 metals : "🥇" ,
@@ -31,7 +33,6 @@ const RabbitForexIndicator = GObject.registerClass(
3133 this . _rates = { } ;
3234 this . _timestamps = { } ;
3335 this . _updateTimeout = null ;
34- this . _isDestroyed = false ;
3536
3637 // Create the panel button layout
3738 this . _box = new St . BoxLayout ( {
@@ -57,8 +58,6 @@ const RabbitForexIndicator = GObject.registerClass(
5758
5859 this . _fetchAllRates ( ) ;
5960 this . _startUpdateTimer ( ) ;
60-
61- console . log ( "Rabbit Forex: Extension initialized" ) ;
6261 }
6362
6463 _getEndpoints ( ) {
@@ -71,29 +70,25 @@ const RabbitForexIndicator = GObject.registerClass(
7170 } ;
7271 }
7372
74- _buildMenu ( ) {
75- // Header
76- /*
77- const headerItem = new PopupMenu.PopupMenuItem("🐰 Rabbit Forex", {
78- reactive: false,
79- });
80- this.menu.addMenuItem(headerItem);
73+ _getWatchedCategory ( category ) {
74+ if ( ! CATEGORIES . includes ( category ) ) return [ ] ;
8175
82- this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
83- */
76+ return this . _settings . get_strv ( `watched-${ category } ` ) ?? [ ] ;
77+ }
78+
79+ _getPanelCategory ( category ) {
80+ if ( ! CATEGORIES . includes ( category ) ) return [ ] ;
81+
82+ return this . _settings . get_strv ( `panel-${ category } ` ) ?? [ ] ;
83+ }
8484
85+ _buildMenu ( ) {
8586 // Rates section - will be populated dynamically
8687 this . _ratesSection = new PopupMenu . PopupMenuSection ( ) ;
8788 this . menu . addMenuItem ( this . _ratesSection ) ;
8889
8990 this . menu . addMenuItem ( new PopupMenu . PopupSeparatorMenuItem ( ) ) ;
9091
91- // Last updated timestamp
92- this . _timestampItem = new PopupMenu . PopupMenuItem ( "Last updated: --" , {
93- reactive : false ,
94- } ) ;
95- this . menu . addMenuItem ( this . _timestampItem ) ;
96-
9792 // Refresh button
9893 const refreshItem = new PopupMenu . PopupMenuItem ( "🔄 Refresh Now" ) ;
9994 refreshItem . connect ( "activate" , ( ) => {
@@ -107,6 +102,12 @@ const RabbitForexIndicator = GObject.registerClass(
107102 this . _extension . openPreferences ( ) ;
108103 } ) ;
109104 this . menu . addMenuItem ( settingsItem ) ;
105+
106+ // Last updated timestamp
107+ this . _timestampItem = new PopupMenu . PopupMenuItem ( "Last updated: --" , {
108+ reactive : false ,
109+ } ) ;
110+ this . menu . addMenuItem ( this . _timestampItem ) ;
110111 }
111112
112113 _startUpdateTimer ( ) {
@@ -117,46 +118,29 @@ const RabbitForexIndicator = GObject.registerClass(
117118
118119 const interval = this . _settings . get_int ( "update-interval" ) ;
119120 this . _updateTimeout = GLib . timeout_add_seconds ( GLib . PRIORITY_DEFAULT , interval , ( ) => {
120- if ( this . _isDestroyed ) {
121- return GLib . SOURCE_REMOVE ;
122- }
123121 this . _fetchAllRates ( ) ;
124122 return GLib . SOURCE_CONTINUE ;
125123 } ) ;
126124 }
127125
128126 _onSettingsChanged ( ) {
129- if ( this . _isDestroyed ) return ;
130127 this . _startUpdateTimer ( ) ;
131- // Re-fetch rates when settings change (especially primary currency)
132128 this . _fetchAllRates ( ) ;
133129 }
134130
135131 async _fetchAllRates ( ) {
136- if ( this . _isDestroyed ) return ;
137-
138- const categories = [ "fiat" , "metals" , "crypto" , "stocks" ] ;
139-
140- for ( const category of categories ) {
141- if ( this . _isDestroyed ) return ;
132+ for ( const category of CATEGORIES ) {
142133 if ( this . _hasWatchedItems ( category ) ) {
143134 await this . _fetchRates ( category ) ;
144135 }
145136 }
146137
147- if ( ! this . _isDestroyed ) {
148- this . _updateDisplay ( ) ;
149- }
138+ this . _updateDisplay ( ) ;
150139 }
151140
152141 _hasWatchedItems ( category ) {
153- try {
154- const watched = this . _settings . get_strv ( `watched-${ category } ` ) ;
155- return watched && watched . length > 0 ;
156- } catch ( e ) {
157- console . error ( `Rabbit Forex: Error checking watched-${ category } :` , e ) ;
158- return false ;
159- }
142+ const watched = this . _getWatchedCategory ( category ) ;
143+ return watched . length > 0 ;
160144 }
161145
162146 async _fetchRates ( category ) {
@@ -178,7 +162,6 @@ const RabbitForexIndicator = GObject.registerClass(
178162 } ) ;
179163
180164 if ( message . status_code !== 200 ) {
181- console . error ( `Rabbit Forex: Failed to fetch ${ category } rates: HTTP ${ message . status_code } ` ) ;
182165 return ;
183166 }
184167
@@ -189,40 +172,33 @@ const RabbitForexIndicator = GObject.registerClass(
189172 this . _rates [ category ] = data . rates ;
190173 this . _timestamps [ category ] = data . timestamps ;
191174 } catch ( error ) {
192- console . error ( `Rabbit Forex: Error fetching ${ category } rates:` , error . message ) ;
175+ // Silently fail - rates will show as N/A
193176 }
194177 }
195178
196179 _updateDisplay ( ) {
197- if ( this . _isDestroyed ) return ;
198180 this . _updatePanelLabel ( ) ;
199181 this . _updateMenuRates ( ) ;
200182 this . _updateTimestamp ( ) ;
201183 }
202184
203185 _updatePanelLabel ( ) {
204186 const panelItems = [ ] ;
205- const categories = [ "fiat" , "metals" , "crypto" , "stocks" ] ;
206187 const maxPanelItems = this . _settings . get_int ( "max-panel-items" ) ;
207- const primaryCurrency = this . _settings . get_string ( "primary-currency" ) ;
208188
209- for ( const category of categories ) {
189+ for ( const category of CATEGORIES ) {
210190 if ( ! this . _rates [ category ] ) continue ;
211191
212- try {
213- const showInPanel = this . _settings . get_strv ( `panel-${ category } ` ) ;
192+ const showInPanel = this . _getPanelCategory ( category ) ;
214193
215- for ( const symbol of showInPanel ) {
216- if ( panelItems . length >= maxPanelItems ) break ;
194+ for ( const symbol of showInPanel ) {
195+ if ( panelItems . length >= maxPanelItems ) break ;
217196
218- if ( this . _rates [ category ] [ symbol ] !== undefined ) {
219- const rate = this . _rates [ category ] [ symbol ] ;
220- const formattedRate = this . _formatPanelRate ( rate , category , symbol ) ;
221- panelItems . push ( `${ symbol } : ${ formattedRate } ` ) ;
222- }
197+ if ( this . _rates [ category ] [ symbol ] !== undefined ) {
198+ const rate = this . _rates [ category ] [ symbol ] ;
199+ const formattedRate = this . _formatPanelRate ( rate , category , symbol ) ;
200+ panelItems . push ( `${ symbol } : ${ formattedRate } ` ) ;
223201 }
224- } catch ( e ) {
225- console . error ( `Rabbit Forex: Error getting panel-${ category } :` , e ) ;
226202 }
227203 }
228204
@@ -236,7 +212,6 @@ const RabbitForexIndicator = GObject.registerClass(
236212 _updateMenuRates ( ) {
237213 this . _ratesSection . removeAll ( ) ;
238214
239- const categories = [ "fiat" , "metals" , "crypto" , "stocks" ] ;
240215 const categoryLabels = {
241216 fiat : "Fiat Currencies" ,
242217 metals : "Precious Metals" ,
@@ -250,19 +225,14 @@ const RabbitForexIndicator = GObject.registerClass(
250225 let hasAnyRates = false ;
251226
252227 // Determine which categories will actually be shown
253- const visibleCategories = categories . filter ( ( category ) => {
254- try {
255- const watched = this . _settings . get_strv ( `watched-${ category } ` ) ;
256- return watched && watched . length > 0 && this . _rates [ category ] ;
257- } catch ( e ) {
258- console . error ( `Rabbit Forex: Error getting watched-${ category } :` , e ) ;
259- return false ;
260- }
228+ const visibleCategories = CATEGORIES . filter ( ( category ) => {
229+ const watched = this . _getWatchedCategory ( category ) ;
230+ return watched . length > 0 && this . _rates [ category ] ;
261231 } ) ;
262232
263233 for ( let i = 0 ; i < visibleCategories . length ; i ++ ) {
264234 const category = visibleCategories [ i ] ;
265- const watched = this . _settings . get_strv ( `watched- ${ category } ` ) ;
235+ const watched = this . _getWatchedCategory ( category ) ;
266236
267237 hasAnyRates = true ;
268238
@@ -313,8 +283,6 @@ const RabbitForexIndicator = GObject.registerClass(
313283 }
314284
315285 _formatPanelRate ( rate , category , symbol ) {
316- const primaryCurrency = this . _settings . get_string ( "primary-currency" ) ;
317-
318286 if ( category === "metals" ) {
319287 let price = 1 / rate ;
320288 const metalsUnit = this . _settings . get_string ( "metals-unit" ) ;
@@ -386,8 +354,6 @@ const RabbitForexIndicator = GObject.registerClass(
386354 }
387355
388356 destroy ( ) {
389- this . _isDestroyed = true ;
390-
391357 if ( this . _updateTimeout ) {
392358 GLib . source_remove ( this . _updateTimeout ) ;
393359 this . _updateTimeout = null ;
@@ -398,9 +364,10 @@ const RabbitForexIndicator = GObject.registerClass(
398364 this . _settingsChangedId = null ;
399365 }
400366
401- this . _httpSession = null ;
402-
403- console . log ( "Rabbit Forex: Extension destroyed" ) ;
367+ if ( this . _httpSession ) {
368+ this . _httpSession . abort ( ) ;
369+ this . _httpSession = null ;
370+ }
404371
405372 super . destroy ( ) ;
406373 }
@@ -409,18 +376,14 @@ const RabbitForexIndicator = GObject.registerClass(
409376
410377export default class RabbitForexExtension extends Extension {
411378 enable ( ) {
412- console . log ( "Rabbit Forex: Enabling extension" ) ;
413379 this . _indicator = new RabbitForexIndicator ( this ) ;
414380 Main . panel . addToStatusArea ( this . uuid , this . _indicator ) ;
415- console . log ( "Rabbit Forex: Extension enabled" ) ;
416381 }
417382
418383 disable ( ) {
419- console . log ( "Rabbit Forex: Disabling extension" ) ;
420384 if ( this . _indicator ) {
421385 this . _indicator . destroy ( ) ;
422386 this . _indicator = null ;
423387 }
424- console . log ( "Rabbit Forex: Extension disabled" ) ;
425388 }
426389}
0 commit comments