#
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#bebebe" d="M 8 1 C 7.45 1 7 1.45 7 2 C 7 2.03 6.9998 2.0696 7.0098 2.0996 C 6.513 2.1994 6.0506 2.385 5.6191 2.6191 L 13 10 L 13 9 L 13 7 C 13 4.57 11.28 2.5596 8.9902 2.0996 C 9.0002 2.0696 9 2.03 9 2 C 9 1.45 8.55 1 8 1 z M 4.0078 4.0078 C 3.3813 4.8419 3 5.8717 3 7 L 3 11.5 L 1 13.5 L 1 14 L 3 14 L 13 14 L 14 14 L 4.0078 4.0078 z M 6.2695 15 C 6.6295 15.62 7.29 16 8 16 C 8.71 16 9.3705 15.62 9.7305 15 L 6.2695 15 z"/>
|
||||
<path style="fill:#bebebe" d="M 2.5,1.5 15,14 13.5,15.5 1,3 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 596 B |
@@ -0,0 +1,84 @@
|
||||
class Extension {
|
||||
constructor(dnd, toggle, indicator, remote, audio){
|
||||
this.dnd = dnd;
|
||||
this.toggle = toggle;
|
||||
this.indicator = indicator;
|
||||
this.remote = remote;
|
||||
this.audio = audio;
|
||||
|
||||
this.enabled = false;
|
||||
|
||||
this.toggle.setToggleState(this.dnd.isEnabled());
|
||||
this.toggle.show();
|
||||
this.toggle.onToggleStateChanged(() => {
|
||||
if (this.toggle.getToggleState()){
|
||||
this.enable();
|
||||
} else {
|
||||
this.disable();
|
||||
}
|
||||
});
|
||||
|
||||
// this.dndID = this.dnd.addStatusListener((dndEnabled) => this._setDND(dndEnabled));
|
||||
|
||||
this.remoteID = this.remote.addRemoteListener((dndEnabled) => this._setDND(dndEnabled));
|
||||
|
||||
this._setDND(this.remote.getRemote());
|
||||
}
|
||||
|
||||
_setDND(enabled){
|
||||
if (enabled){
|
||||
this.enable();
|
||||
} else {
|
||||
this.disable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable do not disturb mode
|
||||
*/
|
||||
enable(){
|
||||
if (this.enabled){
|
||||
return;
|
||||
}
|
||||
this.enabled = true;
|
||||
this.dnd.enable();
|
||||
this.toggle.setToggleState(true);
|
||||
this.indicator.show();
|
||||
this.remote.setRemote(true);
|
||||
this.audio.mute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable do not disturb mode
|
||||
*/
|
||||
disable(){
|
||||
if (!this.enabled){
|
||||
return;
|
||||
}
|
||||
this.enabled = false;
|
||||
this.dnd.disable();
|
||||
this.toggle.setToggleState(false);
|
||||
this.indicator.hide();
|
||||
this.remote.setRemote(false);
|
||||
this.audio.unmute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Boolean} true if it is enabled, otherwise false
|
||||
*/
|
||||
isEnabled(){
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the extension and its components
|
||||
*/
|
||||
destroy(){
|
||||
this.enabled = false;
|
||||
// this.dnd.removeStatusListener(this.dndID);
|
||||
this.remote.removeRemoteListener(this.remoteID);
|
||||
this.toggle.destroy();
|
||||
this.indicator.destroy();
|
||||
this.dnd.disable();
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
|
||||
const BUSY = 2;
|
||||
const AVAILABLE = 0;
|
||||
|
||||
/**
|
||||
* A class which can enable do not disturb mode
|
||||
*/
|
||||
class DoNotDisturb {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {Presence} presence the interface to the Gnome Presence API
|
||||
*/
|
||||
constructor(presence){
|
||||
this.presence = presence;
|
||||
this.listeners = [];
|
||||
this.presenceListernerID = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable do not disturb mode
|
||||
*/
|
||||
enable(){
|
||||
this.presence.status = BUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable do not disturb mode
|
||||
*/
|
||||
disable(){
|
||||
this.presence.status = AVAILABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Boolean} true if do not disturb mode is on, otherwise false
|
||||
*/
|
||||
isEnabled(){
|
||||
return this.presence.status == BUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a status listener for when the do not disturb mode is toggled
|
||||
* @param {[Boolean => ()]} listener the listener to add
|
||||
* @return {Integer} the ID of the listener
|
||||
*/
|
||||
addStatusListener(listener){
|
||||
|
||||
if (listener == null){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this.listeners.length == 0){
|
||||
this.presenceListernerID = this.presence.addStatusListener((status) => {
|
||||
this.listeners.forEach((fn) => {
|
||||
fn(status == BUSY);
|
||||
});
|
||||
});
|
||||
}
|
||||
listener(this.isEnabled());
|
||||
return this.listeners.push(listener) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the status listener with the ID
|
||||
* @param {Integer} id the ID of the status listener
|
||||
*/
|
||||
removeStatusListener(id){
|
||||
if (id < 0 || id >= this.listeners.length){
|
||||
return;
|
||||
}
|
||||
this.listeners.splice(id, 1);
|
||||
if (this.listeners.length == 0) {
|
||||
this.presence.removeStatusListener(this.presenceListernerID);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Settings = Me.imports.settings;
|
||||
const System = Me.imports.system;
|
||||
const Widget = Me.imports.widgets;
|
||||
const DND = Me.imports.doNotDisturb;
|
||||
const Extension = Me.imports.dndExtension.Extension;
|
||||
|
||||
/**
|
||||
* Called when the extension is loaded.
|
||||
*/
|
||||
function init() {}
|
||||
|
||||
/**
|
||||
* Enable the do not disturb extension. Adds all UI elements and monitors the settings object.
|
||||
*/
|
||||
function enable() {
|
||||
var dnd = new DND.DoNotDisturb(new System.GnomePresence());
|
||||
var toggle = new Widget.DoNotDisturbToggle();
|
||||
var indicator = new Widget.DoNotDisturbIcon(new Settings.SettingsManager(), new System.NotificationManager());
|
||||
var remote = new Settings.RemoteAPI();
|
||||
var audio = new System.AudioManager(new Settings.SettingsManager());
|
||||
this.extension = new Extension(dnd, toggle, indicator, remote, audio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the extension. Tears down all UI components.
|
||||
*/
|
||||
function disable() {
|
||||
this.extension.destroy();
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/* From https://github.com/pop-os/gnome-shell-extension-pop-suspend-button */
|
||||
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/**
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gettext = imports.gettext;
|
||||
const Config = imports.misc.config;
|
||||
|
||||
function initTranslations(extension) {
|
||||
let localeDir = extension.dir.get_child('locale').get_path();
|
||||
|
||||
// Extension installed in .local
|
||||
if (GLib.file_test(localeDir, GLib.FileTest.EXISTS)) {
|
||||
Gettext.bindtextdomain('gnome-shell-extension-do-not-disturb', localeDir);
|
||||
}
|
||||
// Extension installed system-wide
|
||||
else {
|
||||
Gettext.bindtextdomain('gnome-shell-extension-do-not-disturb',
|
||||
Config.LOCALEDIR);
|
||||
}
|
||||
}
|
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gnome-Shell-Extension Do Not Disturb\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-04-09 18:13+0200\n"
|
||||
"PO-Revision-Date: 2018-10-14 07:30-0400\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German <mike@barkmin.eu>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2\n"
|
||||
|
||||
#: prefs.js:31
|
||||
msgid "Enabled Icon"
|
||||
msgstr "Icon anzeigen"
|
||||
|
||||
#: prefs.js:31
|
||||
msgid "Show an indicator icon when do not disturb is enabled."
|
||||
msgstr "Zeige ein Icon, wenn nicht stören aktiviert ist."
|
||||
|
||||
#: prefs.js:38
|
||||
msgid "Count"
|
||||
msgstr "Anzahl"
|
||||
|
||||
#: prefs.js:39
|
||||
msgid "Dot"
|
||||
msgstr "Punkt"
|
||||
|
||||
#: prefs.js:40
|
||||
msgid "Nothing"
|
||||
msgstr "Nichts"
|
||||
|
||||
#: prefs.js:50
|
||||
msgid "Mute Sounds"
|
||||
msgstr "Audio stumm schalten"
|
||||
|
||||
#: prefs.js:50
|
||||
msgid "Mutes all sound when do not disturb is enabled."
|
||||
msgstr "Audio stumm schalten, wenn nicht stören aktiviert ist."
|
||||
|
||||
#: widgets.js:40
|
||||
msgid "Do not disturb"
|
||||
msgstr "Nicht stören"
|
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gnome-Shell-Extension Do Not Disturb\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-10-14 7:24+0200\n"
|
||||
"PO-Revision-Date: 2018-10-14 07:30-0400\n"
|
||||
"Language-Team: Spanish <kylecorry31@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2\n"
|
||||
"Last-Translator: \n"
|
||||
"Language: es\n"
|
||||
|
||||
#: widgets.js:39
|
||||
msgid "Do not disturb"
|
||||
msgstr "No interrumpir"
|
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gnome-Shell-Extension Do Not Disturb\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-10-14 7:24+0200\n"
|
||||
"PO-Revision-Date: 2018-10-14 07:30-0400\n"
|
||||
"Language-Team: French <kylecorry31@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2\n"
|
||||
"Last-Translator: \n"
|
||||
"Language: fr\n"
|
||||
|
||||
#: widgets.js:36
|
||||
msgid "Do not disturb"
|
||||
msgstr "Ne pas déranger"
|
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gnome-Shell-Extension Do Not Disturb\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-10-14 7:24+0200\n"
|
||||
"PO-Revision-Date: 2018-10-14 07:30-0400\n"
|
||||
"Language-Team: Portuguese <kylecorry31@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2\n"
|
||||
"Last-Translator: \n"
|
||||
"Language: pt\n"
|
||||
|
||||
#: widgets.js:39
|
||||
msgid "Do not disturb"
|
||||
msgstr "Não perturbe"
|
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "Activate or deactivate do not disturb mode",
|
||||
"name": "Do Not Disturb",
|
||||
"original-author": "kylecorry31@gmail.com",
|
||||
"settings-schema": "org.gnome.shell.extensions.kylecorry31-do-not-disturb",
|
||||
"shell-version": [
|
||||
"3.18",
|
||||
"3.20",
|
||||
"3.22",
|
||||
"3.24",
|
||||
"3.26",
|
||||
"3.28",
|
||||
"3.30",
|
||||
"3.32"
|
||||
],
|
||||
"url": "https://github.com/kylecorry31/gnome-shell-extension-do-not-disturb",
|
||||
"uuid": "donotdisturb@kylecorry31.github.io",
|
||||
"version": 12
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
// Adapted from lockkeys@vaina.lt and https://github.com/pop-os/gnome-shell-extension-pop-suspend-button
|
||||
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Gettext = imports.gettext.domain('gnome-shell-extension-do-not-disturb');
|
||||
const _ = Gettext.gettext;
|
||||
const Settings = Me.imports.settings;
|
||||
const Lib = Me.imports.lib;
|
||||
|
||||
function init() {}
|
||||
|
||||
/**
|
||||
* Builds the GTK widget which displays all of the application specific settings.
|
||||
*
|
||||
* @returns {Gtk.Box} - The frame to display.
|
||||
*/
|
||||
function buildPrefsWidget() {
|
||||
let settings = new Settings.SettingsManager();
|
||||
let frame = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
border_width: 10,
|
||||
margin: 20,
|
||||
spacing: 8
|
||||
});
|
||||
|
||||
var box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.HORIZONTAL
|
||||
});
|
||||
|
||||
frame.add(createSwitch(settings.shouldShowIcon(), (b) => {settings.setShowIcon(b); if (b) { box.show(); } else { box.hide(); } }, _("Enabled Icon"), _("Show an indicator icon when do not disturb is enabled.")));
|
||||
|
||||
var indicatorLbl = new Gtk.Label({
|
||||
label: "Notification Indicator",
|
||||
xalign: 0
|
||||
});
|
||||
|
||||
var showCountRadio = createRadioButton(settings.showCount, (b) => { settings.showCount = b }, _("Count"));
|
||||
var showDotRadio = createRadioButton(settings.showDot, (b) => { settings.showDot = b }, _("Dot"), showCountRadio);
|
||||
var showNothingRadio = createRadioButton(!(settings.showCount || settings.showDot), (b) => { }, _("Nothing"), showCountRadio);
|
||||
|
||||
|
||||
box.pack_start(indicatorLbl, true, true, 0);
|
||||
box.add(showCountRadio);
|
||||
box.add(showDotRadio);
|
||||
box.add(showNothingRadio);
|
||||
|
||||
frame.add(box);
|
||||
|
||||
frame.add(createSwitch(settings.shouldMuteSound(), (b) => settings.setShouldMuteSound(b), _("Mute Sounds"), _("Mutes all sound when do not disturb is enabled.")));
|
||||
|
||||
frame.show_all();
|
||||
|
||||
if (!settings.shouldShowIcon()){
|
||||
box.hide();
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
function createRadioButton(active, set, text, group){
|
||||
var widget;
|
||||
if (group){
|
||||
widget = Gtk.RadioButton.new_with_label_from_widget(group, text);
|
||||
widget.set_active(active);
|
||||
} else {
|
||||
widget = new Gtk.RadioButton({
|
||||
active: active,
|
||||
label: text
|
||||
});
|
||||
}
|
||||
widget.connect('notify::active', function(switch_widget) {
|
||||
set(switch_widget.active);
|
||||
});
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a switch setting.
|
||||
*
|
||||
* @param {boolean} active - The starting state of the switch.
|
||||
* @param {(boolean) => ()} set - The setter function which is passed the value of the switch on state change.
|
||||
* @param {string} text - The label of the widget.
|
||||
* @param {string} tooltip - The description text to display on hover.
|
||||
* @returns {Gtk.Box} - The widget containing the switch and label.
|
||||
*/
|
||||
function createSwitch(active, set, text, tooltip) {
|
||||
let box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.HORIZONTAL
|
||||
});
|
||||
let label = new Gtk.Label({
|
||||
label: text,
|
||||
xalign: 0,
|
||||
tooltip_text: tooltip
|
||||
});
|
||||
let widget = new Gtk.Switch({
|
||||
active: active
|
||||
});
|
||||
widget.connect('notify::active', function(switch_widget) {
|
||||
set(switch_widget.active);
|
||||
});
|
||||
|
||||
box.pack_start(label, true, true, 0);
|
||||
box.add(widget);
|
||||
return box;
|
||||
}
|
||||
|
||||
Lib.initTranslations(Me);
|
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist gettext-domain="org-gnome-shell-extensions-kylecorry31-do-not-disturb">
|
||||
<schema path="/org/gnome/shell/extensions/kylecorry31-do-not-disturb/" id="org.gnome.shell.extensions.kylecorry31-do-not-disturb">
|
||||
<key type="b" name="show-icon">
|
||||
<default>true</default>
|
||||
<summary>Show an indicator icon when do not disturb is enabled.</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
<key type="b" name="mute-sounds">
|
||||
<default>false</default>
|
||||
<summary>Mutes all sound when do not disturb is enabled.</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
<key type="b" name="show-dot">
|
||||
<default>false</default>
|
||||
<summary>Shows a dot next to the date when notifications arrive during do not disturb mode.</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
<key type="b" name="show-count">
|
||||
<default>true</default>
|
||||
<summary>Displays the number of notifications during do not disturb mode.</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
<key type="b" name="do-not-disturb">
|
||||
<default>false</default>
|
||||
<summary>Activate the do not disturb mode.</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
@@ -0,0 +1,219 @@
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
|
||||
/**
|
||||
* A class which handles all interactions with the settings.
|
||||
*/
|
||||
class SettingsManager {
|
||||
/**
|
||||
* Represents a settings repository, where settings can be modified and read.
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
this.connections = [];
|
||||
this._appSettings = _getSettings();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable the icon in the system panel when do not disturb mode is enabled.
|
||||
*
|
||||
* @param {boolean} showIcon - True if the icon should be shown, false otherwise.
|
||||
*/
|
||||
setShowIcon(showIcon) {
|
||||
this._appSettings.set_boolean('show-icon', showIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the icon should be shown or not.
|
||||
*
|
||||
* @returns {boolean} - True if the icon should be shown when do not disturb is enabled, false otherwise.
|
||||
*/
|
||||
shouldShowIcon() {
|
||||
return this._appSettings.get_boolean('show-icon');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the status of the show icon setting has changed.
|
||||
*
|
||||
* @param {() => ()} fn - The function to call when the show icon setting is changed.
|
||||
*/
|
||||
onShowIconChanged(fn) {
|
||||
var id = this._appSettings.connect('changed::show-icon', fn);
|
||||
this.connections.push(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the sound should be muted when do not disturb is enabled.
|
||||
*
|
||||
* @returns {boolean} - True if the sound should be muted when do not disturb is enabled, false otherwise.
|
||||
*/
|
||||
shouldMuteSound() {
|
||||
return this._appSettings.get_boolean('mute-sounds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the muting of sound when do not disturb mode is enabled.
|
||||
*
|
||||
* @param {boolean} muteSound - True if the sound should be muted when do not disturb is enabled, false otherwise.
|
||||
*/
|
||||
setShouldMuteSound(muteSound) {
|
||||
this._appSettings.set_boolean('mute-sounds', muteSound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the status of the mute sounds setting has changed.
|
||||
*
|
||||
* @param {() => ()} fn - The function to call when the mute sounds setting is changed.
|
||||
*/
|
||||
onMuteSoundChanged(fn) {
|
||||
var id = this._appSettings.connect('changed::mute-sounds', fn);
|
||||
this.connections.push(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to show the count of notifications or not.
|
||||
* @param {Boolean} newShowCount True if the notification count should be shown.
|
||||
*/
|
||||
set showCount(newShowCount){
|
||||
this._appSettings.set_boolean('show-count', newShowCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to show the notification count.
|
||||
* @return {Boolean} True if the notification count should be shown.
|
||||
*/
|
||||
get showCount(){
|
||||
return this._appSettings.get_boolean('show-count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the status of the show count setting has changed.
|
||||
*
|
||||
* @param {() => ()} fn - The function to call when the show count setting is changed.
|
||||
*/
|
||||
onShowCountChanged(fn){
|
||||
var id = this._appSettings.connect('changed::show-count', fn);
|
||||
this.connections.push(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to show an indicator of hidden notifications or not.
|
||||
* @param {Boolean} newShowDot True if the notification dot should be shown.
|
||||
*/
|
||||
set showDot(newShowDot){
|
||||
this._appSettings.set_boolean('show-dot', newShowDot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to show the notification dot.
|
||||
* @return {Boolean} True if the notification dot should be shown.
|
||||
*/
|
||||
get showDot(){
|
||||
return this._appSettings.get_boolean('show-dot');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the status of the show dot setting has changed.
|
||||
*
|
||||
* @param {() => ()} fn - The function to call when the show dot setting is changed.
|
||||
*/
|
||||
onShowDotChanged(fn){
|
||||
var id = this._appSettings.connect('changed::show-dot', fn);
|
||||
this.connections.push(id);
|
||||
}
|
||||
|
||||
disconnectAll() {
|
||||
this.connections.forEach((id) => {
|
||||
this._appSettings.disconnect(id);
|
||||
});
|
||||
this.connections = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RemoteAPI {
|
||||
constructor() {
|
||||
this._appSettings = _getSettings();
|
||||
this.listeners = [];
|
||||
|
||||
this.id = this._appSettings.connect('changed::do-not-disturb', () => {
|
||||
this.listeners.forEach((fn) => fn(this.getRemote()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the status of the do not disturb setting has changed.
|
||||
*
|
||||
* @param {() => ()} listener - The function to call when the do not disturb setting is changed.
|
||||
*/
|
||||
addRemoteListener(listener) {
|
||||
if (listener == null){
|
||||
return -1;
|
||||
}
|
||||
if (this.listeners.length == 0){
|
||||
this.id = this._appSettings.connect('changed::do-not-disturb', () => {
|
||||
this.listeners.forEach((fn) => fn(this.getRemote()));
|
||||
});
|
||||
}
|
||||
return this.listeners.push(listener) - 1;
|
||||
}
|
||||
|
||||
removeRemoteListener(id) {
|
||||
if (id < 0 || id >= this.listeners.length){
|
||||
return;
|
||||
}
|
||||
this.listeners.splice(id, 1);
|
||||
if (this.listeners.length == 0) {
|
||||
this._appSettings.disconnect(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Boolean} true if the external do not disturb is on, false otherwise
|
||||
*/
|
||||
getRemote() {
|
||||
return this._appSettings.get_boolean('do-not-disturb');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Boolean} dnd true if the external do not disturb should be on, false otherwise
|
||||
*/
|
||||
setRemote(dnd) {
|
||||
this._appSettings.set_boolean('do-not-disturb', dnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A helper function to get the application specific settings. Adapted
|
||||
* from the System76 Pop Suspend Button extension: https://github.com/pop-os/gnome-shell-extension-pop-suspend-button
|
||||
*
|
||||
* @returns {Gio.Settings} - The application specific settings object.
|
||||
*/
|
||||
function _getSettings() {
|
||||
let schemaName = 'org.gnome.shell.extensions.kylecorry31-do-not-disturb';
|
||||
let schemaDir = Me.dir.get_child('schemas').get_path();
|
||||
|
||||
// Extension installed in .local
|
||||
if (GLib.file_test(schemaDir + '/gschemas.compiled', GLib.FileTest.EXISTS)) {
|
||||
let schemaSource = Gio.SettingsSchemaSource.new_from_directory(schemaDir,
|
||||
Gio.SettingsSchemaSource.get_default(),
|
||||
false);
|
||||
let schema = schemaSource.lookup(schemaName, false);
|
||||
|
||||
return new Gio.Settings({
|
||||
settings_schema: schema
|
||||
});
|
||||
}
|
||||
// Extension installed system-wide
|
||||
else {
|
||||
if (Gio.Settings.list_schemas().indexOf(schemaName) == -1)
|
||||
throw "Schema \"%s\" not found.".format(schemaName);
|
||||
return new Gio.Settings({
|
||||
schema: schemaName
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
.clear-button {
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.do-not-disturb:active {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
|
||||
.do-not-disturb-icon {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
-st-icon-style: symbolic;
|
||||
}
|
||||
|
||||
.hide-dot {
|
||||
color: transparent;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.notification-count {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
@@ -0,0 +1,156 @@
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Main = imports.ui.main;
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Settings = Me.imports.settings;
|
||||
|
||||
/**
|
||||
* A class for interacting with the Gnome Presence API.
|
||||
*/
|
||||
class GnomePresence {
|
||||
/**
|
||||
* Construct a new GnomePresence proxy.
|
||||
*/
|
||||
constructor() {
|
||||
this._presence = new GnomeSession.Presence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status of GnomePresence.
|
||||
* @param {number} newStatus A GnomeSession.PresenceStatus status constant to switch to.
|
||||
*/
|
||||
set status(newStatus) {
|
||||
this._presence.SetStatusSync(newStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of GnomePresence.
|
||||
* @return {number} The current GnomeSession.PresenceStatus status.
|
||||
*/
|
||||
get status() {
|
||||
return this._presence.status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener to the GnomePresence status.
|
||||
* @param {Function} fn The function to run when the status is changed (passed the current status).
|
||||
* @return {number} The ID of the listener, used by removeStatusListener.
|
||||
*/
|
||||
addStatusListener(fn) {
|
||||
return this._presence.connectSignal('StatusChanged', (proxy, _sender, [status]) => {
|
||||
if (proxy.status != status) {
|
||||
fn(status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a status listener to the GnomePresence status.
|
||||
* @param {number} listenerID The ID of the listener to remove.
|
||||
*/
|
||||
removeStatusListener(listenerID) {
|
||||
this._presence.disconnectSignal(listenerID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class for managing the audio on Gnome.
|
||||
*/
|
||||
class AudioManager {
|
||||
|
||||
constructor(settingsManager){
|
||||
this._settings = settingsManager;
|
||||
this.shouldMute = this._settings.shouldMuteSound();
|
||||
this.muted = false;
|
||||
this._settings.onMuteSoundChanged(() => {
|
||||
var shouldMute = this._settings.shouldMuteSound();
|
||||
if (this.muted && shouldMute){
|
||||
this._internalMute();
|
||||
} else if (this.muted && !shouldMute){
|
||||
this._internalUnmute();
|
||||
}
|
||||
this.shouldMute = shouldMute;
|
||||
});
|
||||
}
|
||||
|
||||
_internalMute(){
|
||||
_runCmd(["amixer", "-q", "-D", "pulse", "sset", "Master", "mute"]);
|
||||
}
|
||||
|
||||
_internalUnmute(){
|
||||
_runCmd(["amixer", "-q", "-D", "pulse", "sset", "Master", "unmute"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute the audio stream.
|
||||
*/
|
||||
mute() {
|
||||
this.muted = true;
|
||||
if (this.shouldMute){
|
||||
this._internalMute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmute the audio stream.
|
||||
*/
|
||||
unmute() {
|
||||
this.muted = false;
|
||||
if (this.shouldMute){
|
||||
this._internalUnmute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationManager {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current number of notifications in the system tray.
|
||||
* @return {number} The number of notifications.
|
||||
*/
|
||||
get notificationCount(){
|
||||
var count = 0;
|
||||
Main.messageTray.getSources().forEach(n => count += n.count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if there are any notifications.
|
||||
* @return {Boolean} True if there are notifications, false otherwise
|
||||
*/
|
||||
get hasNotifications(){
|
||||
return notificationCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for when the notification count changes.
|
||||
* @param {Function} fn The function to call when the notification count changes (passed the current notification count).
|
||||
* @return {number array} The IDs of the listeners.
|
||||
*/
|
||||
addNotificationCountListener(fn){
|
||||
var id1 = Main.messageTray.connect('source-added', () => fn(this.notificationCount));
|
||||
var id2 = Main.messageTray.connect('source-removed', () => fn(this.notificationCount));
|
||||
var id3 = Main.messageTray.connect('queue-changed', () => fn(this.notificationCount));
|
||||
|
||||
return [id1, id2, id3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a notification count listener.
|
||||
* @param {number array} ids The ID of the listener to remove.
|
||||
*/
|
||||
removeNotificationCountListener(ids){
|
||||
ids.forEach((id) => {
|
||||
Main.messageTray.disconnect(id);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function _runCmd(cmd) {
|
||||
GLib.spawn_sync(null, cmd, null, GLib.SpawnFlags.SEARCH_PATH, null);
|
||||
}
|
@@ -0,0 +1,236 @@
|
||||
const Lang = imports.lang;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const St = imports.gi.St;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Gettext = imports.gettext.domain('gnome-shell-extension-do-not-disturb');
|
||||
const _ = Gettext.gettext;
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Lib = Me.imports.lib;
|
||||
|
||||
|
||||
/**
|
||||
* A class which handles the UI of the do not disturb toggle.
|
||||
*/
|
||||
class DoNotDisturbToggle {
|
||||
/**
|
||||
* Represents a do not disturb toggle in the calendar/notification popup.
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
this._connections = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the do not disturb toggle in the calendar/notification popup.
|
||||
*/
|
||||
show() {
|
||||
this._clearButton = Main.panel.statusArea.dateMenu._messageList._clearButton;
|
||||
|
||||
this._calendarBox = this._clearButton.get_parent();
|
||||
|
||||
this._clearBox = new St.BoxLayout({
|
||||
vertical: false,
|
||||
x_expand: true,
|
||||
y_expand: false
|
||||
});
|
||||
|
||||
|
||||
this._disturbToggle = new PopupMenu.PopupSwitchMenuItem(_("Do not disturb"));
|
||||
|
||||
this._disturbToggle.actor.add_style_class_name('do-not-disturb');
|
||||
this._disturbToggle.actor.set_x_expand(true);
|
||||
this._disturbToggle.actor.track_hover = false;
|
||||
|
||||
this._disturbToggle.actor.set_x_align(Clutter.ActorAlign.START);
|
||||
this._disturbToggle.actor.remove_child(this._disturbToggle.label);
|
||||
this._disturbToggle.actor.add_child(this._disturbToggle.label);
|
||||
this._disturbToggle.label.set_y_align(Clutter.ActorAlign.CENTER);
|
||||
this._disturbToggle.actor.remove_child(this._disturbToggle._ornamentLabel);
|
||||
|
||||
this._clearBox.add_actor(this._disturbToggle.actor);
|
||||
|
||||
this._clearButton.reparent(this._clearBox);
|
||||
this._clearButton.add_style_class_name('clear-button');
|
||||
|
||||
this._calendarBox.add_actor(this._clearBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys all UI elements of the toggle and returns the clear button to its proper location.
|
||||
*/
|
||||
destroy() {
|
||||
if (this._disturbToggle) {
|
||||
this._connections.forEach((id) => {
|
||||
this._disturbToggle.disconnect(id);
|
||||
});
|
||||
this._connections = [];
|
||||
this._disturbToggle.destroy();
|
||||
this._disturbToggle = 0;
|
||||
}
|
||||
|
||||
if (this._clearButton) {
|
||||
this._clearButton.reparent(this._calendarBox);
|
||||
this._clearButton.remove_style_class_name('clear-button');
|
||||
}
|
||||
|
||||
if (this._clearBox) {
|
||||
this._clearBox.destroy();
|
||||
this._clearBox = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the activation state of the toggle.
|
||||
*
|
||||
* @param {boolean} state - The state of the toggle: true for on, false for off.
|
||||
*/
|
||||
setToggleState(state) {
|
||||
if (this._disturbToggle) {
|
||||
this._disturbToggle.setToggleState(state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activation state of the toggle.
|
||||
*
|
||||
* @returns {boolean} - True if the toggle is on, false otherwise.
|
||||
*/
|
||||
getToggleState() {
|
||||
if (this._disturbToggle) {
|
||||
return this._disturbToggle._switch.state;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function when the toggle state changes.
|
||||
*
|
||||
* @param {() => ()} fn - The function to call when the toggle state changes.
|
||||
*/
|
||||
onToggleStateChanged(fn) {
|
||||
if (this._disturbToggle) {
|
||||
var id = this._disturbToggle.connect("toggled", (item, event) => fn());
|
||||
this._connections.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class which handles the UI of the do not disturb status icon.
|
||||
*/
|
||||
class DoNotDisturbIcon {
|
||||
/**
|
||||
* Represents a do not disturb icon in the system status area of the panel.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(settingsManager, notificationCounter) {
|
||||
this._settings = settingsManager;
|
||||
this.notificationCounter = notificationCounter;
|
||||
this._indicatorArea = Main.panel._centerBox; //statusArea.aggregateMenu._indicators;
|
||||
|
||||
let icon = "notification-disabled-symbolic";
|
||||
let fallback = "user-busy-symbolic";
|
||||
|
||||
this._enabledIcon = new St.Icon({
|
||||
icon_name: icon,
|
||||
fallback_icon_name: fallback,
|
||||
style_class: 'popup-menu-icon do-not-disturb-icon'
|
||||
});
|
||||
|
||||
this._countLbl = new St.Label();
|
||||
this.updateCount(0);
|
||||
this._countLbl.add_style_class_name("notification-count");
|
||||
|
||||
this._iconBox = new St.BoxLayout();
|
||||
this._iconBox.add_actor(this._enabledIcon);
|
||||
this._iconBox.add_actor(this._countLbl);
|
||||
this.showDot = this._settings.showDot;
|
||||
this.showCount = this._settings.showCount;
|
||||
this.showIcon = this._settings.shouldShowIcon();
|
||||
this.shown = false;
|
||||
this.count = this.notificationCounter.notificationCount;
|
||||
this.updateCount(this.count);
|
||||
|
||||
this._settings.onShowIconChanged(() => {
|
||||
this.showIcon = this._settings.shouldShowIcon();
|
||||
if (this.shown){
|
||||
this.hide();
|
||||
this.show();
|
||||
}
|
||||
});
|
||||
this._settings.onShowCountChanged(() => {
|
||||
this.showCount = this._settings.showCount;
|
||||
this.updateCount(this.count);
|
||||
});
|
||||
this._settings.onShowDotChanged(() => {
|
||||
this.showDot = this._settings.showDot;
|
||||
this.updateCount(this.count);
|
||||
});
|
||||
this.notificationListenerID = this.notificationCounter.addNotificationCountListener((count) => {
|
||||
this.updateCount(count);
|
||||
});
|
||||
}
|
||||
|
||||
updateCount(newCount){
|
||||
this.count = newCount;
|
||||
if (newCount == 0){
|
||||
this._countLbl.add_style_class_name("hide-dot");
|
||||
} else {
|
||||
if (this.showCount){
|
||||
this._countLbl.set_text("" + newCount);
|
||||
this._countLbl.remove_style_class_name("hide-dot");
|
||||
} else if(this.showDot){
|
||||
this._countLbl.set_text("\u25CF");
|
||||
this._countLbl.remove_style_class_name("hide-dot");
|
||||
} else {
|
||||
this._countLbl.add_style_class_name("hide-dot");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the status icon.
|
||||
*/
|
||||
show() {
|
||||
if (this.showIcon){
|
||||
this._indicatorArea.add_child(this._iconBox);
|
||||
Main.panel.statusArea.dateMenu._indicator.actor.add_style_class_name("hide-dot");
|
||||
}
|
||||
this.shown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the status icon.
|
||||
*/
|
||||
hide() {
|
||||
Main.panel.statusArea.dateMenu._indicator.actor.remove_style_class_name("hide-dot");
|
||||
if (this._iconBox.get_parent()) {
|
||||
this._indicatorArea.remove_child(this._iconBox);
|
||||
}
|
||||
this.shown = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the status icon and removes it from the system status area.
|
||||
*/
|
||||
destroy() {
|
||||
if (this._enabledIcon) {
|
||||
if (this._iconBox.get_parent()) {
|
||||
this._indicatorArea.remove_child(this._iconBox);
|
||||
}
|
||||
this._countLbl.destroy();
|
||||
this._countLbl = 0;
|
||||
this._enabledIcon.destroy();
|
||||
this._enabledIcon = 0;
|
||||
this._iconBox.destroy();
|
||||
this._iconBox = 0;
|
||||
}
|
||||
this._settings.disconnectAll();
|
||||
this.notificationCounter.removeNotificationCountListener(this.notificationListenerID);
|
||||
}
|
||||
}
|
||||
|
||||
Lib.initTranslations(Me);
|
Reference in New Issue
Block a user