mirror of
https://github.com/Hopiu/RandomWallpaperGnome3.git
synced 2026-04-30 11:24:44 +00:00
implement basic auto fetching feature
This commit is contained in:
parent
c119247182
commit
d286edff8b
6 changed files with 240 additions and 84 deletions
|
|
@ -4,6 +4,9 @@ const St = imports.gi.St;
|
|||
const Slider = imports.ui.slider;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const Self = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Timer = Self.imports.timer;
|
||||
|
||||
const HistoryElement = new Lang.Class({
|
||||
Name: 'HistoryElement',
|
||||
Extends: PopupMenu.PopupBaseMenuItem,
|
||||
|
|
@ -50,6 +53,64 @@ const HistoryElement = new Lang.Class({
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Element for the New Wallpaper button and the remaining time for the auto fetch
|
||||
* feature.
|
||||
* The remaining time will only be displayed if the af-feature is activated.
|
||||
*
|
||||
* @type {Lang.Class}
|
||||
*/
|
||||
const NewWallpaperElement = new Lang.Class({
|
||||
Name: 'NewWallpaperElement',
|
||||
Extends: PopupMenu.PopupBaseMenuItem,
|
||||
|
||||
_init: function(params) {
|
||||
this.parent(params);
|
||||
|
||||
this._timer = new Timer.AFTimer();
|
||||
|
||||
this._container = new St.BoxLayout({
|
||||
vertical: true
|
||||
});
|
||||
|
||||
this._newWPLabel = new St.Label({
|
||||
text: 'New Wallpaper',
|
||||
style_class: 'rwg-new-lable'
|
||||
});
|
||||
this._container.add_child(this._newWPLabel);
|
||||
|
||||
this._remainingLabel = new St.Label({
|
||||
text: '1 minute remaining'
|
||||
});
|
||||
this._container.add_child(this._remainingLabel);
|
||||
|
||||
this.actor.add_child(this._container);
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if (this._timer.isActive()) {
|
||||
let remainingMinutes = this._timer.remainingMinutes();
|
||||
let minutes = remainingMinutes % 60;
|
||||
let hours = Math.floor(remainingMinutes / 60);
|
||||
|
||||
let hoursText = hours.toString();
|
||||
hoursText += (hours == 1) ? ' hour' : ' hours';
|
||||
let minText = minutes.toString();
|
||||
minText += (minutes == 1) ? ' minute' : ' minutes';
|
||||
|
||||
if (hours >= 1) {
|
||||
this._remainingLabel.text = '... ' + hoursText + ' and ' + minText + ' remaining.'
|
||||
} else {
|
||||
this._remainingLabel.text = '... ' + minText + ' remaining.'
|
||||
}
|
||||
|
||||
this._remainingLabel.show();
|
||||
} else {
|
||||
this._remainingLabel.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const StatusElement = new Lang.Class({
|
||||
Name: 'StatusElement',
|
||||
Extends: St.Icon,
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
const Lang = imports.lang;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Prefs = Self.imports.settings;
|
||||
|
||||
let AFTimer = new Lang.Class({
|
||||
|
||||
_timeout: null,
|
||||
_timoutEndCallback: null,
|
||||
|
||||
_init: function() {
|
||||
this._settings = new Prefs.Settings();
|
||||
// this._settings.observe('minutes_elapsed', function() { // TODO: determine what to do });
|
||||
this._settings.observe('minutes', this._loadSettings.bind(this));
|
||||
}
|
||||
|
||||
_remainingMinutes: function() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
registerCallback: function(callback) {
|
||||
this._timoutEndCallback = callback;
|
||||
},
|
||||
|
||||
begin: function() {
|
||||
if (this._timeout) {
|
||||
this.pause();
|
||||
}
|
||||
|
||||
//this._settings.get()
|
||||
|
||||
// TODO: calc elapsed time
|
||||
// TODO: check > 0
|
||||
|
||||
this._timeout = GLib.timeout_add(Glib.PRIORITY_DEFAULT, delay, function() {
|
||||
this._settings.set(minutes_elapsed)
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
if (_timeout) {
|
||||
Glib.source_remove(_timeout)
|
||||
this._settings.set('minutes_elapsed', 'int', 0)
|
||||
}
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
if (_timeout) {
|
||||
Glib.source_remove(_timeout)
|
||||
this._settings.set('minutes_elapsed', 'int', this._remainingMinutes())
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -42,9 +42,7 @@ let RandomWallpaperEntry = new Lang.Class({
|
|||
this.actor.add_child(this.statusIcon);
|
||||
|
||||
// new wallpaper button
|
||||
this.newWallpaperItem = new PopupMenu.PopupMenuItem('New Wallpaper', {
|
||||
style_class: 'rwg-new-lable'
|
||||
});
|
||||
this.newWallpaperItem = new CustomElements.NewWallpaperElement();
|
||||
|
||||
this.menu.addMenuItem(this.newWallpaperItem);
|
||||
|
||||
|
|
@ -67,19 +65,17 @@ let RandomWallpaperEntry = new Lang.Class({
|
|||
this.menu.addMenuItem(this.openFolder);
|
||||
|
||||
//this.menu.addMenuItem(new CustomElements.DelaySlider(60));
|
||||
|
||||
/*
|
||||
add eventlistener
|
||||
*/
|
||||
|
||||
let _this = this;
|
||||
wallpaperController.registerStartLoadingHook(this.statusIcon.startLoading.bind(this.statusIcon));
|
||||
wallpaperController.registerStopLoadingHook(this.statusIcon.stopLoading.bind(this.statusIcon));
|
||||
wallpaperController.registerStopLoadingHook(this.setHistoryList.bind(this));
|
||||
|
||||
// new wallpaper event
|
||||
this.newWallpaperItem.connect('activate', function() {
|
||||
_this.statusIcon.startLoading();
|
||||
wallpaperController.fetchNewWallpaper(function() {
|
||||
_this.setHistoryList();
|
||||
_this.statusIcon.stopLoading();
|
||||
});
|
||||
wallpaperController.fetchNewWallpaper();
|
||||
});
|
||||
|
||||
// clear history event
|
||||
|
|
@ -94,14 +90,15 @@ let RandomWallpaperEntry = new Lang.Class({
|
|||
});
|
||||
|
||||
this.menu.actor.connect('show', function() {
|
||||
this.newWallpaperItem.show();
|
||||
wallpaperController.menuShowHook();
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
// when the popupmenu disapears, check if the wallpaper is the original and
|
||||
// reset it if needed
|
||||
this.menu.actor.connect('hide', function() {
|
||||
this.menu.actor.connect('hide', () => {
|
||||
wallpaperController.resetWallpaper();
|
||||
_this.setHistoryList();
|
||||
this.setHistoryList();
|
||||
});
|
||||
|
||||
this.menu.actor.connect('leave-event', function(e, t, a) {
|
||||
|
|
@ -163,7 +160,6 @@ let RandomWallpaperEntry = new Lang.Class({
|
|||
|
||||
function enable() {
|
||||
// Extension enabled
|
||||
this.settings = Convenience.getSettings();
|
||||
|
||||
// UI
|
||||
panelEntry = new RandomWallpaperEntry(0, "Random wallpaper");
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="duration-minutes">
|
||||
<property name="lower">5</property>
|
||||
<property name="lower">1</property>
|
||||
<property name="upper">59</property>
|
||||
<property name="value">30</property>
|
||||
<property name="step_increment">1</property>
|
||||
|
|
@ -23,17 +23,14 @@
|
|||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkBox" id="main-widget">
|
||||
<property name="width_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="margin_left">15</property>
|
||||
<property name="margin_right">15</property>
|
||||
<property name="margin_top">15</property>
|
||||
<property name="margin_bottom">15</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="baseline_position">top</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -42,25 +39,27 @@
|
|||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="width_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<property name="baseline_row">2</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="source-label">
|
||||
|
|
@ -78,9 +77,10 @@
|
|||
<object class="GtkLabel" id="source-description">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">The source that is used to fetch random wallpapers. You can select between desktoppr.co (default) and an experimental version of wallheaven.cc.</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
|
|
@ -134,6 +134,7 @@
|
|||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
|
|
@ -185,12 +186,13 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="width_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
|
|
@ -227,9 +229,10 @@
|
|||
<object class="GtkLabel" id="history-size-description">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">The number of wallpapers that will be shown in the history and stored in the wallpaper folder of this extension.</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
|
|
@ -279,12 +282,13 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="width_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
|
|
@ -309,7 +313,7 @@
|
|||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="af-label">
|
||||
|
|
@ -327,9 +331,11 @@
|
|||
<object class="GtkLabel" id="af-description">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Automatically fetch a new wallpaper based on a period.</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
|
|
@ -350,7 +356,6 @@
|
|||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="af-switch">
|
||||
|
|
|
|||
118
randomwallpaper@iflow.space/timer.js
Normal file
118
randomwallpaper@iflow.space/timer.js
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
const Lang = imports.lang;
|
||||
const GLib = imports.gi.GLib;
|
||||
|
||||
const Self = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const Prefs = Self.imports.settings;
|
||||
|
||||
let _afTimerInstance = null;
|
||||
|
||||
// Singleton implementation of _AFTimer
|
||||
let AFTimer = function() {
|
||||
if (!_afTimerInstance) {
|
||||
_afTimerInstance = new _AFTimer();
|
||||
}
|
||||
return _afTimerInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Timer for the auto fetch feature.
|
||||
*
|
||||
* TODO: find way to store elapsed time on shutdown/logout/gnome-shell-restart/etc.
|
||||
* @type {Lang}
|
||||
*/
|
||||
let _AFTimer = new Lang.Class({
|
||||
Name: 'AFTimer',
|
||||
|
||||
_timeout: null,
|
||||
_timoutEndCallback: null,
|
||||
_timestamp: null,
|
||||
|
||||
_init: function() {
|
||||
this._settings = new Prefs.Settings();
|
||||
},
|
||||
|
||||
/**
|
||||
* Side effect is that the elapsed minutes will be stored in the GSettings.
|
||||
*/
|
||||
_minutesElapsed: function() {
|
||||
let timestamp = this._timestamp;
|
||||
if (!timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let now = new Date().getTime();
|
||||
let elapsed = this._settings.get('minutes-elapsed', 'int');
|
||||
|
||||
let diffMin = Math.floor((now-timestamp)/(60*1000));
|
||||
|
||||
if (diffMin >= 1) {
|
||||
elapsed += diffMin;
|
||||
this._settings.set('minutes-elapsed', 'int', elapsed);
|
||||
this._timestamp += diffMin*60*1000;
|
||||
}
|
||||
|
||||
return elapsed;
|
||||
},
|
||||
|
||||
isActive: function () {
|
||||
return this._settings.get('auto-fetch', 'boolean');
|
||||
},
|
||||
|
||||
remainingMinutes: function() {
|
||||
let hours = this._settings.get('hours', 'int');
|
||||
let minutes = hours * 60 + this._settings.get('minutes', 'int');
|
||||
let minutesElapsed = this._minutesElapsed();
|
||||
|
||||
return (minutes - minutesElapsed);
|
||||
},
|
||||
|
||||
registerCallback: function(callback) {
|
||||
this._timoutEndCallback = callback;
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts a new timer.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
begin: function() {
|
||||
this.end(); // stop any running timer
|
||||
|
||||
this._timestamp = new Date().getTime();
|
||||
|
||||
let millisToWait = this.remainingMinutes() * 60 * 1000;
|
||||
if (millisToWait <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, millisToWait, function() {
|
||||
this.end();
|
||||
if (this._timoutEndCallback) {
|
||||
this._timoutEndCallback();
|
||||
}
|
||||
this.begin(); // restart timer
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop the timer and set elapsed minutes to 0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
end: function() {
|
||||
this._settings.set('minutes-elapsed', 'int', 0);
|
||||
if (this._timeout) {
|
||||
GLib.source_remove(this._timeout)
|
||||
this._timeout = null;
|
||||
}
|
||||
},
|
||||
|
||||
// currently not used
|
||||
pause: function() {
|
||||
if (this._timeout) {
|
||||
GLib.source_remove(this._timeout)
|
||||
this._minutesElapsed();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -13,6 +13,7 @@ const Self = imports.misc.extensionUtils.getCurrentExtension();
|
|||
const SourceAdapter = Self.imports.sourceAdapter;
|
||||
const Convenience = Self.imports.convenience;
|
||||
const Prefs = Self.imports.settings;
|
||||
const Timer = Self.imports.timer;
|
||||
|
||||
let WallpaperController = new Lang.Class({
|
||||
Name: "WallpaperController",
|
||||
|
|
@ -24,15 +25,23 @@ let WallpaperController = new Lang.Class({
|
|||
history: [],
|
||||
imageSourceAdapter: undefined,
|
||||
|
||||
_timer: null,
|
||||
_autoFetch : {
|
||||
active: false,
|
||||
duration: 30,
|
||||
},
|
||||
|
||||
// functions will be called uppon loading a new wallpaper
|
||||
_startLoadingHooks: [],
|
||||
// functions will be called when loading a new wallpaper stopped. If an error occured then the error will be passed as parameter.
|
||||
_stopLoadingHooks: [],
|
||||
|
||||
_init: function(extensionMeta){
|
||||
this.extensionMeta = extensionMeta;
|
||||
this.wallpaperlocation = this.extensionMeta.path + '/wallpapers/';
|
||||
|
||||
this._timer = new Timer.AFTimer();
|
||||
|
||||
this._settings = new Prefs.Settings();
|
||||
this._settings.observe('history-length', this._updateHistory.bind(this));
|
||||
this._settings.observe('auto-fetch', this._updateAutoFetching.bind(this));
|
||||
|
|
@ -61,9 +70,10 @@ let WallpaperController = new Lang.Class({
|
|||
this._autoFetch.active = this._settings.get('auto-fetch', 'boolean');
|
||||
|
||||
if (this._autoFetch.active) {
|
||||
// TODO: this._timer.begin(this._autoFetch.duration);
|
||||
this._timer.registerCallback(this.fetchNewWallpaper.bind(this));
|
||||
this._timer.begin();
|
||||
} else {
|
||||
// TODO: this._timer.end(this._autoFetch.duration);
|
||||
this._timer.end();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -211,6 +221,11 @@ let WallpaperController = new Lang.Class({
|
|||
},
|
||||
|
||||
fetchNewWallpaper: function(callback) {
|
||||
this._startLoadingHooks.forEach((element) => {
|
||||
element();
|
||||
});
|
||||
this._timer.begin(); // reset timer
|
||||
|
||||
let _this = this;
|
||||
this._requestRandomImageFromAdapter(function(imageUrl){
|
||||
_this._fetchFile(imageUrl, function(historyid, path) {
|
||||
|
|
@ -219,6 +234,9 @@ let WallpaperController = new Lang.Class({
|
|||
|
||||
_this._setBackground(_this.wallpaperlocation + historyid, function(){
|
||||
// call callback if given
|
||||
_this._stopLoadingHooks.forEach((element) => {
|
||||
element(null);
|
||||
});
|
||||
if (callback) {
|
||||
callback();
|
||||
};
|
||||
|
|
@ -298,6 +316,17 @@ let WallpaperController = new Lang.Class({
|
|||
|
||||
menuShowHook: function() {
|
||||
this.currentWallpaper = this._getCurrentWallpaper();
|
||||
}
|
||||
},
|
||||
|
||||
registerStartLoadingHook: function(fn) {
|
||||
if (typeof fn === "function") {
|
||||
this._startLoadingHooks.push(fn)
|
||||
}
|
||||
},
|
||||
|
||||
registerStopLoadingHook: function(fn) {
|
||||
if (typeof fn === "function") {
|
||||
this._stopLoadingHooks.push(fn)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue