diff --git a/js/extensionPrefs/css/application.css b/js/extensionPrefs/css/application.css index 1a35205f1..37105d081 100644 --- a/js/extensionPrefs/css/application.css +++ b/js/extensionPrefs/css/application.css @@ -7,3 +7,5 @@ .details-button.expanded:dir(rtl) image { -gtk-icon-transform: rotate(-0.25turn); } + +image.warning { color: @warning_color; } diff --git a/js/extensionPrefs/main.js b/js/extensionPrefs/main.js index f8ce4fb7a..67ff6c5c1 100644 --- a/js/extensionPrefs/main.js +++ b/js/extensionPrefs/main.js @@ -86,6 +86,8 @@ var ExtensionsWindow = GObject.registerClass({ 'mainBox', 'mainStack', 'scrolledWindow', + 'updatesBar', + 'updatesLabel', ], }, class ExtensionsWindow extends Gtk.ApplicationWindow { _init(params) { @@ -94,6 +96,7 @@ var ExtensionsWindow = GObject.registerClass({ this._startupUuid = null; this._loaded = false; this._prefsDialog = null; + this._updatesCheckId = 0; this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment); @@ -102,6 +105,10 @@ var ExtensionsWindow = GObject.registerClass({ action.connect('activate', this._showAbout.bind(this)); this.add_action(action); + action = new Gio.SimpleAction({ name: 'logout' }); + action.connect('activate', this._logout.bind(this)); + this.add_action(action); + this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' }); this._settings.bind('disable-user-extensions', this._killSwitch, 'active', @@ -219,6 +226,22 @@ var ExtensionsWindow = GObject.registerClass({ aboutDialog.present(); } + _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, + null, + (o, res) => { + o.call_finish(res); + }); + } + _buildErrorUI(row, exc) { let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER, @@ -357,6 +380,8 @@ var ExtensionsWindow = GObject.registerClass({ let extension = ExtensionUtils.deserializeExtension(newState); let row = this._findExtensionRow(uuid); + this._queueUpdatesCheck(); + // 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 @@ -403,6 +428,29 @@ var ExtensionsWindow = GObject.registerClass({ this._systemList.add(row); } + _queueUpdatesCheck() { + if (this._updatesCheckId) + return; + + this._updatesCheckId = GLib.timeout_add_seconds( + GLib.PRIORITY_DEFAULT, 1, () => { + this._checkUpdates(); + + this._updatesCheckId = 0; + return GLib.SOURCE_REMOVE; + }); + } + + _checkUpdates() { + let nUpdates = this._userList.get_children().filter(c => c.hasUpdate).length; + + this._updatesLabel.label = Gettext.ngettext( + '%d extension will be updated on next login.', + '%d extensions will be updated on next login.e', + nUpdates).format(nUpdates); + this._updatesBar.visible = nUpdates > 0; + } + _extensionsLoaded() { this._userList.visible = this._userList.get_children().length > 0; this._systemList.visible = this._systemList.get_children().length > 0; @@ -412,6 +460,8 @@ var ExtensionsWindow = GObject.registerClass({ else this._mainStack.visible_child_name = 'placeholder'; + this._checkUpdates(); + if (this._startupUuid) this._showPrefs(this._startupUuid); this._startupUuid = null; @@ -526,6 +576,7 @@ var ExtensionRow = GObject.registerClass({ 'descriptionLabel', 'versionLabel', 'authorLabel', + 'updatesIcon', 'revealButton', 'revealer', ], @@ -622,6 +673,10 @@ var ExtensionRow = GObject.registerClass({ return this._extension.hasPrefs; } + get hasUpdate() { + return this._extension.hasUpdate || false; + } + get type() { return this._extension.type; } @@ -645,6 +700,8 @@ var ExtensionRow = GObject.registerClass({ action.set_state(new GLib.Variant('b', state)); action.enabled = this._canToggle(); + this._updatesIcon.visible = this.hasUpdate; + this._versionLabel.label = `${this.version}`; this._versionLabel.visible = this.version !== ''; diff --git a/js/extensionPrefs/ui/extension-row.ui b/js/extensionPrefs/ui/extension-row.ui index c4f4e6050..f54ab3c76 100644 --- a/js/extensionPrefs/ui/extension-row.ui +++ b/js/extensionPrefs/ui/extension-row.ui @@ -13,8 +13,21 @@ True + + + + + True + software-update-available-symbolic + + + + + + True True - start @@ -196,7 +209,7 @@ 0 1 - 5 + 7 diff --git a/js/extensionPrefs/ui/extensions-window.ui b/js/extensionPrefs/ui/extensions-window.ui index 3d211395f..c288bb371 100644 --- a/js/extensionPrefs/ui/extensions-window.ui +++ b/js/extensionPrefs/ui/extensions-window.ui @@ -100,144 +100,204 @@ - + True - crossfade + vertical - + True - never + crossfade + True - + True + never - + True - vertical - center - 36 - 12 - - - start - True - Manually Installed - - - - - - - + True - none - 24 - - - - - - - start - True - Built-In - - - - - - - - True - none - + vertical + center + 36 + 12 + + + + start + True + Manually Installed + + + + + + + + True + none + 24 + + + + + + + start + True + Built-In + + + + + + + + True + none + + + + + main + + + + + True + vertical + 32 + 6 + center + + + True + 96 + org.gnome.Extensions-symbolic + + + + + True + No Installed Extensions + + + + + + + + + placeholder + + + + + True + 100 + 100 + 100 + 60 + vertical + 12 + + + True + Something’s gone wrong + + + + + + + + + True + We’re very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again. + center + True + + + + + + noshell + - - main - - - True - vertical - 32 - 6 - center + + True True - 96 - org.gnome.Extensions-symbolic - - - - - True - No Installed Extensions - - - - - - - - - placeholder - - - - - True - 100 - 100 - 100 - 60 - vertical - 12 - - - True - Something’s gone wrong - - - + 24 + 6 + software-update-available-symbolic - + True - We’re very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again. - center - True - + vertical + + + True + start + Extension Updates Ready + + + + + + + + True + start + + + + + Logout… + True + center + win.logout + True + + + + end + + - - noshell -