refactor(extension): improve code quality #23

Merged
kiyui merged 10 commits from refactor into master 4 years ago
  1. 1
      .gitignore
  2. 8
      makefile
  3. 243
      night-light-slider.timur@linux.com/extension.js
  4. 3
      night-light-slider.timur@linux.com/metadata.json
  5. 1921
      package-lock.json
  6. 39
      package.json

1
.gitignore

@ -1,2 +1,3 @@
node_modules/
night-light-slider.timur@linux.com.zip
*.compiled

8
makefile

@ -1,8 +0,0 @@
default: schema
cd night-light-slider.timur@linux.com/ && zip -r ../night-light-slider.timur@linux.com.zip ./*
copy: schema
cp -rvf night-light-slider.timur@linux.com/ ~/.local/share/gnome-shell/extensions/
schema:
glib-compile-schemas night-light-slider.timur@linux.com/schemas/

243
night-light-slider.timur@linux.com/extension.js

@ -1,11 +1,10 @@
/* global imports log */
const Lang = imports.lang
const St = imports.gi.St
const Gio = imports.gi.Gio
const Lang = imports.lang
const GLib = imports.gi.GLib
const Main = imports.ui.main
const Slider = imports.ui.slider
const Mainloop = imports.mainloop
const PanelMenu = imports.ui.panelMenu
const PopupMenu = imports.ui.popupMenu
const Me = imports.misc.extensionUtils.getCurrentExtension()
@ -15,6 +14,7 @@ const Convenience = Me.imports.convenience
const INDEX = 2
const BUS_NAME = 'org.gnome.SettingsDaemon.Color'
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Color'
const COLOR_SCHEMA = 'org.gnome.settings-daemon.plugins.color'
/* eslint-disable */
const ColorInterface = '<node> \
@ -25,137 +25,192 @@ const ColorInterface = '<node> \
</node>'
/* eslint-enable */
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface)
const SliderMenuItem = new Lang.Class({
Name: 'SliderMenuItem',
const NightLightSlider = new Lang.Class({
Name: 'NightLightSlider',
Extends: PanelMenu.SystemIndicator,
_init: function (schema, settings) {
this.parent('night-light-symbolic')
this._schema = schema
this._settings = settings
// We use this proxy to communicate external changes (like a stream) but set
// the value using the schema because using the proxy doesn't seem to reflect
// or be saved. This can be monitored in dconf. Not sure why :)
this._proxy = new ColorProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH, (proxy, error) => {
if (error) {
log(error.message)
return
}
this._proxy.connect('g-properties-changed', () => this.update_view())
this.update_view()
})
// Get settings
this._min = this._settings.get_int('minimum')
this._max = this._settings.get_int('maximum')
this._min = settings.minimum
this._max = settings.maximum
this._listeners = []
// Set up view
this._item = new PopupMenu.PopupBaseMenuItem({ activate: false })
this.menu.addMenuItem(this._item)
this._item.actor.add(new St.Icon({
icon_name: 'night-light-symbolic',
style_class: 'popup-menu-icon' }))
// Slider
this._slider = new Slider.Slider(0)
this._slider.connect('value-changed', (slider, value) => this._sliderChanged(slider, value))
this._slider.connect('value-changed', this._sliderChanged.bind(this))
this._slider.actor.accessible_name = 'Temperature'
this._item.actor.add(this._slider.actor, { expand: true })
const icon = new St.Icon({
icon_name: 'night-light-symbolic',
style_class: 'popup-menu-icon'
})
// Connect events
this._item.actor.connect('button-press-event',
(actor, event) => this._slider.startDragging(event))
this._item.actor.connect('key-press-event',
(actor, event) => this._slider.onKeyPressEvent(actor, event))
this._item.actor.add(icon)
this._item.actor.add(this._slider.actor, { expand: true })
this._item.actor.connect('button-press-event', (actor, event) => {
return this._slider.startDragging(event)
})
// Update initial view
this._updateView()
},
_proxyHandler: function (proxy, error) {
if (error) {
log(error.message)
return
}
this.proxy.connect('g-properties-changed', this.update_view.bind(this))
},
_sliderChanged: function (slider, value) {
const temperature = parseInt(value * (this._max - this._min)) + this._min
this._schema.set_uint('night-light-temperature', temperature)
this._item.actor.connect('key-press-event', (actor, event) => {
return this._slider.onKeyPressEvent(actor, event)
this._listeners.forEach(callback => {
callback(temperature)
})
},
_sliderChanged: function (slider, value) {
const temperature = (value * (this._max - this._min)) + this._min
this._schema.set_uint('night-light-temperature', parseInt(temperature))
// If slider is moved, enable night light
this._schema.set_boolean('night-light-enabled', true)
_onSliderChanged: function (callback) {
this._listeners.push(callback)
},
update_view: function () {
_updateView: function () {
// Update temperature view
const temperature = this._schema.get_uint('night-light-temperature')
const value = (temperature - this._min) / (this._max - this._min)
this._slider.setValue(value)
}
})
// Update visibility
if (!this._settings.get_boolean('show-always')) {
const active = this._proxy.NightLightActive
const menuItems = Main.panel.statusArea.aggregateMenu.menu._getMenuItems()
menuItems[INDEX].actor.visible = active
const NightLightSchedule = new Lang.Class({
Name: 'NightLightSchedule',
_init: function (schema) {
this._schema = schema
this._enabled = false
},
_updateSchedule: function () {
if (!this._enabled) {
return false
}
const date = new Date()
const hours = date.getHours()
date.setHours(hours - 6)
const from = date.getHours()
date.setHours(hours + 6)
const to = date.getHours()
log(`[night-light-slider] Setting night light schedule from ${from} to ${to}`)
this._schema.set_boolean('night-light-schedule-automatic', false)
this._schema.set_double('night-light-schedule-to', to)
this._schema.set_double('night-light-schedule-from', from)
return true
},
_enableLoop: function () {
this._enabled = true
// Get original values to reset to
this._to = this._schema.get_double('night-light-schedule-to')
this._from = this._schema.get_double('night-light-schedule-from')
this._auto = this._schema.get_boolean('night-light-schedule-automatic')
// Start loop
this.loopId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000 * 60 * 60, this._updateSchedule.bind(this))
this._updateSchedule()
},
_disableLoop: function () {
if (this._enabled) {
this._schema.set_double('night-light-schedule-to', this._to)
this._schema.set_double('night-light-schedule-from', this._from)
this._schema.set_boolean('night-light-schedule-automatic', this._auto)
}
}
})
// Extension initilization
function Extension () {
this.enable = () => {
const NightLightExtension = new Lang.Class({
Name: 'NightLightExtension',
_init: function () {
this._schema = new Gio.Settings({ schema: COLOR_SCHEMA })
this._colorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface)
this._scheduleUpdater = new NightLightSchedule(this._schema)
// Night light icon
this._icon = Main.panel.statusArea.aggregateMenu._nightLight
// This will be defined if icon is set to hide
this._indicator = null
this._indicators = null
this._construct = () => new Error('[night-light-slider] View construct stub not set up!')
this._deconstruct = () => new Error('[night-light-slider] View deconstruct stub not set up!')
},
enable: function () {
// Settings
const schema = new Gio.Settings({
schema: 'org.gnome.settings-daemon.plugins.color'
})
const settings = Convenience.getSettings()
// Create widget
const indicator = new SliderMenuItem(schema, settings)
Main.panel.statusArea.aggregateMenu.menu.addMenuItem(indicator.menu, INDEX)
// Enable night light, otherwise why use this extension :D?
this._schema.set_boolean('night-light-enabled', true)
this.icon = Main.panel.statusArea.aggregateMenu._nightLight
if (!settings.get_boolean('show-status-icon')) {
// TODO: Find alternative way to do this; hide() does not work because extension runs too early
this.indicators = Main.panel.statusArea.aggregateMenu._nightLight.indicators
Main.panel.statusArea.aggregateMenu._nightLight.indicators.hide()
Main.panel.statusArea.aggregateMenu._nightLight.indicators = new St.BoxLayout()
}
// Create and add widget
this._indicator = new NightLightSlider(this._schema, {
minimum: settings.get_int('minimum'),
maximum: settings.get_int('maximum')
})
// Set up display construction stubs
this._construct = () => Main.panel.statusArea.aggregateMenu.menu.addMenuItem(this._indicator.menu, INDEX)
this._deconstruct = () => this._indicator.menu.destroy()
// Set enabled 24 hours if set in settings
// Run construct function
this._construct()
// Set up updater loop to set night light schedule if update always is enabled
if (settings.get_boolean('enable-always')) {
function updateSchedule () {
const date = new Date()
const hours = date.getHours()
date.setHours(hours - 6)
const from = date.getHours()
date.setHours(hours + 6)
const to = date.getHours()
print(`Setting night light schedule from ${from} to ${to}`)
schema.set_boolean('night-light-schedule-automatic', false)
schema.set_double('night-light-schedule-from', from)
schema.set_double('night-light-schedule-to', to)
this._scheduleUpdater._enableLoop()
}
// Hide status icon if set to disable
if (!settings.get_boolean('show-status-icon') && this._icon) {
log(`[night-light-slider] Hiding status icon`)
this._indicators = this._icon.indicators
this._icon.indicators.hide()
this._icon.indicators = new St.BoxLayout()
}
// Set up proxy to update slider view
this._colorProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH, (proxy, error) => {
if (error) {
log(error.message)
return
}
updateSchedule()
const updateView = () => {
this._indicator._updateView()
if (!settings.get_boolean('show-always')) {
const active = proxy.NightLightActive
const menuItems = Main.panel.statusArea.aggregateMenu.menu._getMenuItems()
menuItems[INDEX].actor.visible = active
}
}
let id = Mainloop.timeout_add(1000 * 60 * 60, () => {
updateSchedule()
return true;
}, null);
// TODO: Ability to disable this loop
}
}
proxy.connect('g-properties-changed', updateView)
this.disable = () => {
const menuItems = Main.panel.statusArea.aggregateMenu.menu._getMenuItems()
menuItems[INDEX].destroy()
// Update view once on init
updateView()
})
},
disable: function () {
// Run deconstruct function
this._deconstruct()
// Restore default status icon behaviour
if (this.indicators) {
if (this._indicators) {
Main.panel.statusArea.aggregateMenu._nightLight.indicators.destroy()
Main.panel.statusArea.aggregateMenu._nightLight.indicators = this.indicators
Main.panel.statusArea.aggregateMenu._nightLight.indicators = this._indicators
Main.panel.statusArea.aggregateMenu._nightLight.indicators.show()
}
// Disable updater loop
this._scheduleUpdater._disableLoop()
}
}
})
function init () { // eslint-disable-line no-unused-vars
return new Extension()
function init () { // eslint-disable-line
return new NightLightExtension()
}

3
night-light-slider.timur@linux.com/metadata.json

@ -6,6 +6,7 @@
"url": "https://github.com/TimurKiyivinski/gnome-shell-night-light-slider-extension",
"shell-version": [
"3.24",
"3.26"
"3.26",
"3.28"
]
}

1921
package-lock.json

File diff suppressed because it is too large

39
package.json

@ -0,0 +1,39 @@
{
"name": "gnome-shell-night-light-slider-extension",
"description": "Change night light temperature",
"scripts": {
"lint": "standard",
"lint:fix": "standard --fix",
"build:schema": "glib-compile-schemas night-light-slider.timur@linux.com/schemas/",
"build:copy": "cp -rvf night-light-slider.timur@linux.com/ ~/.local/share/gnome-shell/extensions/",
"build:zip": "cd night-light-slider.timur@linux.com/ && zip -r ../night-light-slider.timur@linux.com.zip ./*",
"build": "npm run build:schema && npm run build:zip"
},
"repository": {
"type": "git",
"url": "git+https://github.com/TimurKiyivinski/gnome-shell-night-light-slider-extension.git"
},
"keywords": [
"gnome",
"gjs",
"night",
"light",
"extension"
],
"author": "Timur Kiyui",
"license": "GPL-2.0",
"bugs": {
"url": "https://github.com/TimurKiyivinski/gnome-shell-night-light-slider-extension/issues"
},
"homepage": "https://github.com/TimurKiyivinski/gnome-shell-night-light-slider-extension#readme",
"devDependencies": {
"pre-commit": "^1.2.2",
"standard": "^11.0.1"
},
"standard": {
"env": "jest"
},
"pre-commit": [
"lint:fix"
]
}
Loading…
Cancel
Save