2023-05-25 21:23:24 +02:00
import Adw from 'gi://Adw?version=1' ;
import GLib from 'gi://GLib' ;
import Gio from 'gi://Gio' ;
import GObject from 'gi://GObject' ;
import Gtk from 'gi://Gtk?version=4.0' ;
import Shew from 'gi://Shew' ;
2023-12-19 13:11:11 +01:00
import { setConsoleLogDomain } from 'console' ;
2023-05-25 21:23:24 +02:00
import * as Gettext from 'gettext' ;
2020-03-19 20:38:16 +01:00
const Package = imports . package ;
2012-01-18 21:21:56 -05:00
2020-03-19 20:38:16 +01:00
Package . initFormat ( ) ;
2012-01-18 21:21:56 -05:00
2023-08-07 17:18:13 +02:00
import * as Config from './misc/config.js' ;
2023-07-30 11:36:56 +03:00
import * as ExtensionUtils from './misc/extensionUtils.js' ;
2012-01-18 21:21:56 -05:00
2023-07-30 11:36:56 +03:00
import { ExtensionState , ExtensionType } from './misc/extensionUtils.js' ;
2018-11-01 13:55:17 +01:00
2018-09-06 02:55:20 +02:00
const GnomeShellIface = loadInterfaceXML ( 'org.gnome.Shell.Extensions' ) ;
2012-01-18 21:21:56 -05:00
const GnomeShellProxy = Gio . DBusProxy . makeProxyWrapper ( GnomeShellIface ) ;
2022-02-11 00:09:54 +01:00
Gio . _promisify ( Gio . DBusConnection . prototype , 'call' ) ;
Gio . _promisify ( Shew . WindowExporter . prototype , 'export' ) ;
2020-03-05 18:01:38 +01:00
2020-03-07 19:26:06 +01:00
function loadInterfaceXML ( iface ) {
2022-02-07 15:14:06 +01:00
const uri = ` resource:///org/gnome/Extensions/dbus-interfaces/ ${ iface } .xml ` ;
2020-03-07 19:26:06 +01:00
const f = Gio . File . new _for _uri ( uri ) ;
try {
let [ ok _ , bytes ] = f . load _contents ( null ) ;
2021-08-12 16:38:57 +02:00
return new TextDecoder ( ) . decode ( bytes ) ;
2020-03-07 19:26:06 +01:00
} catch ( e ) {
2023-12-19 13:11:11 +01:00
console . error ( ` Failed to load D-Bus interface ${ iface } ` ) ;
2020-03-07 19:26:06 +01:00
}
return null ;
}
2020-03-05 18:46:18 +01:00
function toggleState ( action ) {
let state = action . get _state ( ) ;
action . change _state ( new GLib . Variant ( 'b' , ! state . get _boolean ( ) ) ) ;
}
2019-10-28 19:35:33 +01:00
var Application = GObject . registerClass (
2021-10-04 15:18:51 +02:00
class Application extends Adw . Application {
2019-05-28 23:22:37 +02:00
_init ( ) {
2020-04-10 04:27:31 +02:00
GLib . set _prgname ( 'gnome-extensions-app' ) ;
2023-08-07 00:40:20 +02:00
super . _init ( { application _id : Package . name } ) ;
2020-11-18 02:16:26 +01:00
this . connect ( 'window-removed' , ( a , window ) => window . run _dispose ( ) ) ;
2019-11-30 02:48:18 +01:00
}
get shellProxy ( ) {
return this . _shellProxy ;
}
vfunc _activate ( ) {
2023-12-19 13:11:11 +01:00
this . _shellProxy . CheckForUpdatesAsync ( ) . catch ( console . error ) ;
2019-11-30 02:48:18 +01:00
this . _window . present ( ) ;
}
vfunc _startup ( ) {
super . vfunc _startup ( ) ;
2022-07-06 14:16:38 +02:00
this . add _action _entries (
[ {
name : 'quit' ,
activate : ( ) => this . _window . close ( ) ,
} ] ) ;
2020-10-28 21:42:48 +01:00
this . set _accels _for _action ( 'app.quit' , [ '<Primary>q' ] ) ;
2020-03-04 05:05:08 +01:00
this . _shellProxy = new GnomeShellProxy ( Gio . DBus . session ,
'org.gnome.Shell.Extensions' , '/org/gnome/Shell/Extensions' ) ;
2023-08-07 00:40:20 +02:00
this . _window = new ExtensionsWindow ( { application : this } ) ;
2019-11-30 02:48:18 +01:00
}
} ) ;
2019-11-30 02:48:18 +01:00
var ExtensionsWindow = GObject . registerClass ( {
GTypeName : 'ExtensionsWindow' ,
2020-03-05 17:44:27 +01:00
Template : 'resource:///org/gnome/Extensions/ui/extensions-window.ui' ,
2019-11-30 02:48:18 +01:00
InternalChildren : [
2021-10-18 15:18:11 +02:00
'userGroup' ,
2019-11-30 08:08:05 +01:00
'userList' ,
2021-10-18 15:18:11 +02:00
'systemGroup' ,
2019-11-30 08:08:05 +01:00
'systemList' ,
2019-11-30 02:48:18 +01:00
'mainStack' ,
2020-11-11 02:37:20 +01:00
'searchBar' ,
'searchButton' ,
'searchEntry' ,
2023-12-07 19:10:40 +01:00
'updatesBanner' ,
2019-11-30 02:48:18 +01:00
] ,
2023-06-18 20:53:30 -04:00
} , class ExtensionsWindow extends Adw . ApplicationWindow {
2019-11-30 02:48:18 +01:00
_init ( params ) {
super . _init ( params ) ;
2012-01-18 21:21:56 -05:00
2023-07-12 16:46:29 +02:00
if ( Config . PROFILE === 'development' )
this . add _css _class ( 'devel' ) ;
2019-11-30 15:20:04 +01:00
this . _updatesCheckId = 0 ;
2019-11-30 02:48:18 +01:00
2023-08-07 00:40:20 +02:00
this . _exporter = new Shew . WindowExporter ( { window : this } ) ;
2020-03-05 18:01:38 +01:00
this . _exportedHandle = '' ;
2022-07-06 14:16:38 +02:00
this . add _action _entries (
[ {
name : 'show-about' ,
activate : ( ) => this . _showAbout ( ) ,
} , {
name : 'logout' ,
activate : ( ) => this . _logout ( ) ,
} , {
name : 'user-extensions-enabled' ,
state : 'false' ,
change _state : ( a , state ) => {
this . _shellProxy . UserExtensionsEnabled = state . get _boolean ( ) ;
} ,
} ] ) ;
2019-11-30 02:48:18 +01:00
2020-11-11 02:37:20 +01:00
this . _searchTerms = [ ] ;
this . _searchEntry . connect ( 'search-changed' , ( ) => {
2023-08-07 00:40:20 +02:00
const { text } = this . _searchEntry ;
2020-11-11 02:37:20 +01:00
if ( text === '' )
this . _searchTerms = [ ] ;
else
[ this . _searchTerms ] = GLib . str _tokenize _and _fold ( text , null ) ;
this . _userList . invalidate _filter ( ) ;
this . _systemList . invalidate _filter ( ) ;
} ) ;
2019-11-30 08:08:05 +01:00
this . _userList . set _sort _func ( this . _sortList . bind ( this ) ) ;
2020-11-11 02:37:20 +01:00
this . _userList . set _filter _func ( this . _filterList . bind ( this ) ) ;
this . _userList . set _placeholder ( new Gtk . Label ( {
label : _ ( 'No Matches' ) ,
2020-04-15 20:27:15 +02:00
margin _start : 12 ,
margin _end : 12 ,
margin _top : 12 ,
margin _bottom : 12 ,
2020-11-11 02:37:20 +01:00
} ) ) ;
2022-01-18 13:04:55 +01:00
this . _userList . connect ( 'row-activated' , ( _list , row ) => row . activate ( ) ) ;
2019-11-30 08:08:05 +01:00
this . _systemList . set _sort _func ( this . _sortList . bind ( this ) ) ;
2020-11-11 02:37:20 +01:00
this . _systemList . set _filter _func ( this . _filterList . bind ( this ) ) ;
this . _systemList . set _placeholder ( new Gtk . Label ( {
label : _ ( 'No Matches' ) ,
2020-04-15 20:27:15 +02:00
margin _start : 12 ,
margin _end : 12 ,
margin _top : 12 ,
margin _bottom : 12 ,
2020-11-11 02:37:20 +01:00
} ) ) ;
2022-01-18 13:04:55 +01:00
this . _systemList . connect ( 'row-activated' , ( _list , row ) => row . activate ( ) ) ;
2019-11-30 02:48:18 +01:00
this . _shellProxy . connectSignal ( 'ExtensionStateChanged' ,
this . _onExtensionStateChanged . bind ( this ) ) ;
2020-03-05 18:46:18 +01:00
this . _shellProxy . connect ( 'g-properties-changed' ,
this . _onUserExtensionsEnabledChanged . bind ( this ) ) ;
this . _onUserExtensionsEnabledChanged ( ) ;
2019-11-30 02:48:18 +01:00
this . _scanExtensions ( ) ;
2018-11-01 13:55:17 +01:00
}
2019-11-30 02:48:18 +01:00
get _shellProxy ( ) {
return this . application . shellProxy ;
}
2019-11-30 06:06:08 +01:00
uninstall ( uuid ) {
let row = this . _findExtensionRow ( uuid ) ;
let dialog = new Gtk . MessageDialog ( {
transient _for : this ,
modal : true ,
text : _ ( 'Remove “%s”?' ) . format ( row . name ) ,
secondary _text : _ ( 'If you remove the extension, you need to return to download it if you want to enable it again' ) ,
} ) ;
2023-12-14 19:14:33 +01:00
dialog . add _button ( _ ( '_Cancel' ) , Gtk . ResponseType . CANCEL ) ;
dialog . add _button ( _ ( '_Remove' ) , Gtk . ResponseType . ACCEPT )
2019-11-30 06:06:08 +01:00
. get _style _context ( ) . add _class ( 'destructive-action' ) ;
dialog . connect ( 'response' , ( dlg , response ) => {
if ( response === Gtk . ResponseType . ACCEPT )
2023-12-19 13:11:11 +01:00
this . _shellProxy . UninstallExtensionAsync ( uuid ) . catch ( console . error ) ;
2019-11-30 06:06:08 +01:00
dialog . destroy ( ) ;
} ) ;
dialog . present ( ) ;
}
2020-03-05 18:01:38 +01:00
async openPrefs ( uuid ) {
if ( ! this . _exportedHandle ) {
try {
this . _exportedHandle = await this . _exporter . export ( ) ;
} catch ( e ) {
2023-12-19 13:11:11 +01:00
console . warn ( ` Failed to export window: ${ e . message } ` ) ;
2020-03-05 18:01:38 +01:00
}
}
2022-06-23 14:53:29 +02:00
this . _shellProxy . OpenExtensionPrefsAsync ( uuid ,
2020-03-05 18:01:38 +01:00
this . _exportedHandle ,
2023-12-19 13:11:11 +01:00
{ modal : new GLib . Variant ( 'b' , true ) } ) . catch ( console . error ) ;
2017-10-31 02:19:44 +01:00
}
2012-01-18 21:21:56 -05:00
2019-11-30 06:51:35 +01:00
_showAbout ( ) {
2022-07-09 10:23:12 -04:00
let aboutWindow = new Adw . AboutWindow ( {
developers : [
2019-11-30 06:51:35 +01:00
'Florian Müllner <fmuellner@gnome.org>' ,
'Jasper St. Pierre <jstpierre@mecheye.net>' ,
'Didier Roche <didrocks@ubuntu.com>' ,
2022-01-18 13:24:21 +01:00
'Romain Vigier <contact@romainvigier.fr>' ,
2019-11-30 06:51:35 +01:00
] ,
2022-07-09 10:23:12 -04:00
designers : [
'Allan Day <allanpday@gmail.com>' ,
'Tobias Bernard <tbernard@gnome.org>' ,
] ,
2019-11-30 06:51:35 +01:00
translator _credits : _ ( 'translator-credits' ) ,
2022-07-09 10:23:12 -04:00
application _name : _ ( 'Extensions' ) ,
2019-11-30 06:51:35 +01:00
license _type : Gtk . License . GPL _2 _0 ,
2022-07-09 10:23:12 -04:00
application _icon : Package . name ,
2021-01-22 22:08:41 +01:00
version : Package . version ,
2022-07-09 10:23:12 -04:00
developer _name : _ ( 'The GNOME Project' ) ,
2022-07-13 17:10:25 -04:00
website : 'https://apps.gnome.org/app/org.gnome.Extensions/' ,
2022-07-09 10:23:12 -04:00
issue _url : 'https://gitlab.gnome.org/GNOME/gnome-shell/issues/new' ,
2019-11-30 06:51:35 +01:00
transient _for : this ,
} ) ;
2022-07-09 10:23:12 -04:00
aboutWindow . present ( ) ;
2019-11-30 06:51:35 +01:00
}
2019-11-30 15:20:04 +01:00
_logout ( ) {
this . application . get _dbus _connection ( ) . call (
'org.gnome.SessionManager' ,
'/org/gnome/SessionManager' ,
'org.gnome.SessionManager' ,
'Logout' ,
new GLib . Variant ( '(u)' , [ 0 ] ) ,
null ,
Gio . DBusCallFlags . NONE ,
- 1 ,
2019-12-19 20:50:37 +01:00
null ) ;
2019-11-30 15:20:04 +01:00
}
2017-10-31 01:03:21 +01:00
_sortList ( row1 , row2 ) {
2018-11-01 13:50:30 +01:00
return row1 . name . localeCompare ( row2 . name ) ;
2017-10-31 02:19:44 +01:00
}
2014-05-23 04:49:37 +02:00
2020-11-11 02:37:20 +01:00
_filterList ( row ) {
return this . _searchTerms . every (
t => row . keywords . some ( k => k . startsWith ( t ) ) ) ;
}
2018-11-01 13:55:17 +01:00
_findExtensionRow ( uuid ) {
2019-11-30 08:08:05 +01:00
return [
2020-04-15 20:27:15 +02:00
... this . _userList ,
... this . _systemList ,
2019-11-30 08:08:05 +01:00
] . find ( c => c . uuid === uuid ) ;
2018-11-01 13:55:17 +01:00
}
2020-03-05 18:46:18 +01:00
_onUserExtensionsEnabledChanged ( ) {
let action = this . lookup _action ( 'user-extensions-enabled' ) ;
action . set _state (
new GLib . Variant ( 'b' , this . _shellProxy . UserExtensionsEnabled ) ) ;
}
2018-11-01 13:55:17 +01:00
_onExtensionStateChanged ( proxy , senderName , [ uuid , newState ] ) {
2019-11-30 06:01:44 +01:00
let extension = ExtensionUtils . deserializeExtension ( newState ) ;
2018-11-01 13:55:17 +01:00
let row = this . _findExtensionRow ( uuid ) ;
2019-11-30 06:01:44 +01:00
2019-11-30 15:20:04 +01:00
this . _queueUpdatesCheck ( ) ;
2019-11-30 08:08:05 +01:00
// the extension's type changed; remove the corresponding row
// and reset the variable to null so that we create a new row
// below and add it to the appropriate list
if ( row && row . type !== extension . type ) {
2020-04-15 20:27:15 +02:00
row . get _parent ( ) . remove ( row ) ;
2019-11-30 08:08:05 +01:00
row = null ;
}
2018-11-01 13:55:17 +01:00
if ( row ) {
2019-11-30 06:01:44 +01:00
if ( extension . state === ExtensionState . UNINSTALLED )
2020-04-15 20:27:15 +02:00
row . get _parent ( ) . remove ( row ) ;
2020-03-12 22:55:43 +01:00
} else {
this . _addExtensionRow ( extension ) ;
2018-11-01 13:55:17 +01:00
}
2020-03-12 22:55:43 +01:00
this . _syncListVisibility ( ) ;
2018-11-01 13:55:17 +01:00
}
2022-06-23 14:53:29 +02:00
async _scanExtensions ( ) {
try {
const [ extensionsMap ] = await this . _shellProxy . ListExtensionsAsync ( ) ;
2018-11-01 13:55:17 +01:00
for ( let uuid in extensionsMap ) {
let extension = ExtensionUtils . deserializeExtension ( extensionsMap [ uuid ] ) ;
this . _addExtensionRow ( extension ) ;
}
this . _extensionsLoaded ( ) ;
2022-06-23 14:53:29 +02:00
} catch ( e ) {
if ( e instanceof Gio . DBusError ) {
2023-12-19 13:11:11 +01:00
console . log ( ` Failed to connect to shell proxy: ${ e } ` ) ;
2022-06-23 14:53:29 +02:00
this . _mainStack . visible _child _name = 'noshell' ;
} else {
throw e ;
}
}
2017-10-31 02:19:44 +01:00
}
2012-01-18 21:21:56 -05:00
2018-11-01 13:55:17 +01:00
_addExtensionRow ( extension ) {
2018-11-01 13:50:30 +01:00
let row = new ExtensionRow ( extension ) ;
2019-11-30 08:08:05 +01:00
if ( row . type === ExtensionType . PER _USER )
2020-04-15 20:27:15 +02:00
this . _userList . append ( row ) ;
2019-11-30 08:08:05 +01:00
else
2020-04-15 20:27:15 +02:00
this . _systemList . append ( row ) ;
2017-10-31 02:19:44 +01:00
}
2012-06-04 17:14:18 -04:00
2019-11-30 15:20:04 +01:00
_queueUpdatesCheck ( ) {
if ( this . _updatesCheckId )
return ;
this . _updatesCheckId = GLib . timeout _add _seconds (
GLib . PRIORITY _DEFAULT , 1 , ( ) => {
this . _checkUpdates ( ) ;
this . _updatesCheckId = 0 ;
return GLib . SOURCE _REMOVE ;
} ) ;
}
2020-03-12 22:55:43 +01:00
_syncListVisibility ( ) {
2021-10-18 15:18:11 +02:00
this . _userGroup . visible = [ ... this . _userList ] . length > 1 ;
this . _systemGroup . visible = [ ... this . _systemList ] . length > 1 ;
2020-03-12 22:55:43 +01:00
2021-10-18 15:18:11 +02:00
if ( this . _userGroup . visible || this . _systemGroup . visible )
2020-03-12 22:55:43 +01:00
this . _mainStack . visible _child _name = 'main' ;
else
this . _mainStack . visible _child _name = 'placeholder' ;
}
2019-11-30 15:20:04 +01:00
_checkUpdates ( ) {
2020-04-15 20:27:15 +02:00
let nUpdates = [ ... this . _userList ] . filter ( c => c . hasUpdate ) . length ;
2019-11-30 15:20:04 +01:00
2023-12-07 19:10:40 +01:00
this . _updatesBanner . title = Gettext . ngettext (
2019-11-30 15:20:04 +01:00
'%d extension will be updated on next login.' ,
2020-02-04 18:51:57 +01:00
'%d extensions will be updated on next login.' ,
2019-11-30 15:20:04 +01:00
nUpdates ) . format ( nUpdates ) ;
2023-12-07 19:10:40 +01:00
this . _updatesBanner . revealed = nUpdates > 0 ;
2019-11-30 15:20:04 +01:00
}
2017-10-31 01:03:21 +01:00
_extensionsLoaded ( ) {
2020-03-12 22:55:43 +01:00
this . _syncListVisibility ( ) ;
2019-11-30 15:20:04 +01:00
this . _checkUpdates ( ) ;
2017-10-31 02:19:44 +01:00
}
2019-05-28 23:22:37 +02:00
} ) ;
2012-01-18 21:21:56 -05:00
2019-11-30 04:12:54 +01:00
var ExtensionRow = GObject . registerClass ( {
GTypeName : 'ExtensionRow' ,
2020-03-05 17:44:27 +01:00
Template : 'resource:///org/gnome/Extensions/ui/extension-row.ui' ,
2019-11-30 04:12:54 +01:00
InternalChildren : [
2023-12-10 23:21:38 +01:00
'detailsPopover' ,
2019-11-30 04:12:54 +01:00
'descriptionLabel' ,
2019-11-30 18:11:03 +01:00
'versionLabel' ,
2020-05-11 15:31:29 +02:00
'errorLabel' ,
2023-12-10 23:59:04 +01:00
'errorButton' ,
'updatesButton' ,
2020-05-18 14:24:16 +02:00
'switch' ,
2022-01-18 13:00:03 +01:00
'actionsBox' ,
2019-11-30 04:12:54 +01:00
] ,
2023-12-10 23:21:38 +01:00
} , class ExtensionRow extends Adw . ActionRow {
2018-11-01 13:50:30 +01:00
_init ( extension ) {
2017-10-31 02:23:39 +01:00
super . _init ( ) ;
2014-05-23 04:49:37 +02:00
2018-11-01 13:55:17 +01:00
this . _app = Gio . Application . get _default ( ) ;
2018-11-01 13:50:30 +01:00
this . _extension = extension ;
this . _prefsModule = null ;
2014-05-23 04:49:37 +02:00
2020-11-11 02:37:20 +01:00
[ this . _keywords ] = GLib . str _tokenize _and _fold ( this . name , null ) ;
2019-11-30 04:24:39 +01:00
this . _actionGroup = new Gio . SimpleActionGroup ( ) ;
this . insert _action _group ( 'row' , this . _actionGroup ) ;
2019-11-30 04:12:54 +01:00
2019-11-30 04:24:39 +01:00
let action ;
action = new Gio . SimpleAction ( {
name : 'show-prefs' ,
enabled : this . hasPrefs ,
} ) ;
2023-12-10 23:21:38 +01:00
action . connect ( 'activate' , ( ) => {
this . _detailsPopover . popdown ( ) ;
this . get _root ( ) . openPrefs ( this . uuid ) ;
} ) ;
2019-11-30 04:24:39 +01:00
this . _actionGroup . add _action ( action ) ;
2019-11-30 04:12:54 +01:00
2019-11-30 18:11:03 +01:00
action = new Gio . SimpleAction ( {
name : 'show-url' ,
enabled : this . url !== '' ,
} ) ;
action . connect ( 'activate' , ( ) => {
2023-12-10 23:21:38 +01:00
this . _detailsPopover . popdown ( ) ;
2019-11-30 18:11:03 +01:00
Gio . AppInfo . launch _default _for _uri (
this . url , this . get _display ( ) . get _app _launch _context ( ) ) ;
} ) ;
this . _actionGroup . add _action ( action ) ;
2019-11-30 06:06:08 +01:00
action = new Gio . SimpleAction ( {
name : 'uninstall' ,
enabled : this . type === ExtensionType . PER _USER ,
} ) ;
2023-12-10 23:21:38 +01:00
action . connect ( 'activate' , ( ) => {
this . _detailsPopover . popdown ( ) ;
this . get _root ( ) . uninstall ( this . uuid ) ;
} ) ;
2019-11-30 06:06:08 +01:00
this . _actionGroup . add _action ( action ) ;
2019-11-30 04:24:39 +01:00
action = new Gio . SimpleAction ( {
name : 'enabled' ,
state : new GLib . Variant ( 'b' , false ) ,
} ) ;
2020-03-05 18:46:18 +01:00
action . connect ( 'activate' , toggleState ) ;
2019-11-30 04:24:39 +01:00
action . connect ( 'change-state' , ( a , state ) => {
if ( state . get _boolean ( ) )
2023-12-19 13:11:11 +01:00
this . _app . shellProxy . EnableExtensionAsync ( this . uuid ) . catch ( console . error ) ;
2019-11-30 04:12:54 +01:00
else
2023-12-19 13:11:11 +01:00
this . _app . shellProxy . DisableExtensionAsync ( this . uuid ) . catch ( console . error ) ;
2019-11-30 04:12:54 +01:00
} ) ;
2019-11-30 04:24:39 +01:00
this . _actionGroup . add _action ( action ) ;
2023-12-10 23:21:38 +01:00
this . title = this . name ;
2019-11-30 04:24:39 +01:00
2021-02-10 02:18:19 +01:00
const desc = this . _extension . metadata . description . split ( '\n' ) [ 0 ] ;
2019-11-30 04:24:39 +01:00
this . _descriptionLabel . label = desc ;
2019-09-09 17:06:55 +02:00
2019-11-30 04:12:54 +01:00
this . connect ( 'destroy' , this . _onDestroy . bind ( this ) ) ;
2019-09-09 17:06:55 +02:00
2018-11-01 13:55:17 +01:00
this . _extensionStateChangedId = this . _app . shellProxy . connectSignal (
'ExtensionStateChanged' , ( p , sender , [ uuid , newState ] ) => {
if ( this . uuid !== uuid )
return ;
this . _extension = ExtensionUtils . deserializeExtension ( newState ) ;
2019-11-30 04:12:54 +01:00
this . _updateState ( ) ;
2017-10-31 01:38:18 +01:00
} ) ;
2019-11-30 04:12:54 +01:00
this . _updateState ( ) ;
2017-10-31 02:23:39 +01:00
}
2014-05-23 04:49:37 +02:00
2018-11-01 13:50:30 +01:00
get uuid ( ) {
return this . _extension . uuid ;
}
get name ( ) {
return this . _extension . metadata . name ;
}
get hasPrefs ( ) {
return this . _extension . hasPrefs ;
}
2014-05-23 04:49:37 +02:00
2019-11-30 15:20:04 +01:00
get hasUpdate ( ) {
return this . _extension . hasUpdate || false ;
}
2020-05-11 15:31:29 +02:00
get hasError ( ) {
2023-08-07 00:40:20 +02:00
const { state } = this . _extension ;
2020-05-11 15:31:29 +02:00
return state === ExtensionState . OUT _OF _DATE ||
state === ExtensionState . ERROR ;
}
2019-11-30 06:06:08 +01:00
get type ( ) {
return this . _extension . type ;
}
2019-11-30 18:11:03 +01:00
get creator ( ) {
return this . _extension . metadata . creator || '' ;
}
2018-11-01 13:50:30 +01:00
get url ( ) {
2019-11-30 18:11:03 +01:00
return this . _extension . metadata . url || '' ;
}
get version ( ) {
2023-10-27 14:58:19 +05:30
return this . _extension . metadata [ 'version-name' ] || this . _extension . metadata . version || '' ;
2018-11-01 13:50:30 +01:00
}
2020-05-11 15:31:29 +02:00
get error ( ) {
if ( ! this . hasError )
return '' ;
2023-12-11 01:41:46 +01:00
if ( this . _extension . state === ExtensionState . OUT _OF _DATE ) {
const { ShellVersion : shellVersion } = this . _app . shellProxy ;
return this . version !== ''
? _ ( 'The installed version of this extension (%s) is incompatible with the current version of GNOME (%s). The extension has been disabled.' ) . format ( this . version , shellVersion )
: _ ( 'The installed version of this extension is incompatible with the current version of GNOME (%s). The extension has been disabled.' ) . format ( shellVersion ) ;
}
const message = [
_ ( 'An error has occurred in this extension. This could cause issues elsewhere in the system. It is recommended to turn the extension off until the error is resolved.' ) ,
] ;
if ( this . _extension . error ) {
message . push (
// translators: Details for an extension error
_ ( 'Error details:' ) , this . _extension . error ) ;
}
2020-05-11 15:31:29 +02:00
2023-12-11 01:41:46 +01:00
return message . join ( '\n\n' ) ;
2020-05-11 15:31:29 +02:00
}
2020-11-11 02:37:20 +01:00
get keywords ( ) {
return this . _keywords ;
}
2019-11-30 04:12:54 +01:00
_updateState ( ) {
let state = this . _extension . state === ExtensionState . ENABLED ;
2019-11-30 04:24:39 +01:00
let action = this . _actionGroup . lookup ( 'enabled' ) ;
action . set _state ( new GLib . Variant ( 'b' , state ) ) ;
action . enabled = this . _canToggle ( ) ;
2019-11-30 18:11:03 +01:00
2020-05-18 14:24:16 +02:00
if ( ! action . enabled )
this . _switch . active = state ;
2023-12-10 23:59:04 +01:00
this . _updatesButton . visible = this . hasUpdate ;
this . _errorButton . visible = this . hasError ;
2020-05-11 15:31:29 +02:00
this . _errorLabel . label = this . error ;
2019-11-30 15:20:04 +01:00
2023-12-10 23:21:38 +01:00
this . _versionLabel . label = _ ( 'Version %s' ) . format ( this . version . toString ( ) ) ;
2019-11-30 18:11:03 +01:00
this . _versionLabel . visible = this . version !== '' ;
2019-11-30 04:12:54 +01:00
}
2018-11-01 13:55:17 +01:00
_onDestroy ( ) {
if ( ! this . _app . shellProxy )
return ;
if ( this . _extensionStateChangedId )
this . _app . shellProxy . disconnectSignal ( this . _extensionStateChangedId ) ;
this . _extensionStateChangedId = 0 ;
}
_canToggle ( ) {
return this . _extension . canChange ;
2014-05-23 04:49:37 +02:00
}
2020-03-06 01:03:45 +01:00
} ) ;
2023-05-25 21:23:24 +02:00
/ * *
2023-07-30 15:56:59 +03:00
* Main entrypoint for the app
*
2023-05-25 21:23:24 +02:00
* @ param { string [ ] } argv - command line arguments
* @ returns { void }
* /
export async function main ( argv ) {
2020-03-19 20:38:16 +01:00
Package . initGettext ( ) ;
2023-12-19 13:11:11 +01:00
setConsoleLogDomain ( 'Extensions' ) ;
2012-01-18 21:21:56 -05:00
2023-05-25 21:23:24 +02:00
await new Application ( ) . runAsync ( argv ) ;
2012-01-18 21:21:56 -05:00
}