Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vaktija-desklet@MuxBH28 New version with settings/configuration added. #1258

Merged
merged 12 commits into from
Aug 15, 2024
4 changes: 3 additions & 1 deletion vaktija-desklet@MuxBH28/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ Vaktija Desklet is a simple desklet that displays prayer times using data from t

1. Add the Vaktija Desklet to your desktop via the "Add Desklets" menu.
2. The desklet will automatically fetch and display prayer times for the default location.
3. Configure the desklet’s settings, including location, appearance, and other preferences, through the settings menu. This allows you to customize the desklet to suit your needs and preferences.

## Configuration

Currently, the desklet uses default settings for the Sarajevo location. Future versions will include configuration options.
Currently, the desklet supports 177 locations across Bosnia and Herzegovina and southern Serbia. Future versions will include additional configuration options and more locations.

## Links

- Website - [Vaktija Desklet](https://sehic.rf.gd/?project=vaktija)
- Vaktija API - [Vaktija API](https://vaktija.ba/)

## Author
Expand Down
248 changes: 139 additions & 109 deletions vaktija-desklet@MuxBH28/files/vaktija-desklet@MuxBH28/desklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,108 +2,196 @@ const Desklet = imports.ui.desklet;
const St = imports.gi.St;
const Gio = imports.gi.Gio;
const ByteArray = imports.byteArray;
const Settings = imports.ui.settings;
const GLib = imports.gi.GLib;
const Clutter = imports.gi.Clutter;

const uuid = "vaktija-desklet@MuxBH28";

function main(metadata, desklet_id) {
return new VaktijaDesklet(metadata, desklet_id);
}

function VaktijaDesklet(metadata, desklet_id) {
this._init(metadata, desklet_id);
}

VaktijaDesklet.prototype = {
__proto__: Desklet.Desklet.prototype,
lastFetchedData: null,

_init: function (metadata, desklet_id) {
global.log("Initializing Vaktija desklet");
Desklet.Desklet.prototype._init.call(this, metadata, desklet_id);

this.settings = new Settings.DeskletSettings(this, uuid, desklet_id);

this.settings.bindProperty(Settings.BindingDirection.IN,
'api-url', 'apiUrl',
this.fetchData, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'api-location', 'apiLocation',
this.fetchData, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'update-interval', 'updateInterval',
this.setupUpdateInterval, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'show-date', 'showDate',
this.updateDisplay, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'show-islamic-date', 'showIslamicDate',
this.updateDisplay, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'show-seconds', 'showSeconds',
this.updateDisplay, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'height', 'height',
this.updateDisplay, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'width', 'width',
this.updateDisplay, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'transparency', 'transparency',
this.updateAppearance, this);

this.settings.bindProperty(Settings.BindingDirection.IN,
'backgroundColor', 'backgroundColor',
this.updateAppearance, this);

this.setupUI();
this.fetchData();
this.setupMidnightTimer();
this.setupTimeUpdateInterval();
this.setupUpdateInterval();
this.setupCountdownUpdateInterval();
},

setupUI: function () {
global.log("Setting up UI");
this.window = new St.Bin();
this.window = new St.BoxLayout({ vertical: true });
this.text = new St.Label({ style_class: 'label' });
this.text.set_text("Fetching data...");

this.window.add_actor(this.text);
this.setContent(this.window);

this.updateAppearance();
},

updateAppearance: function () {
this.window.set_width(this.width);
this.window.set_height(this.height);

this.window.set_opacity(Math.round(this.transparency * 255));

let backgroundColor = Clutter.Color.from_string(this.backgroundColor)[1];
this.window.set_style(`background-color: rgba(${backgroundColor.red}, ${backgroundColor.green}, ${backgroundColor.blue}, ${this.transparency});`);
},

fetchData: function () {
global.log("Fetching data from API");
let url = this.apiUrl || "https://api.vaktija.ba/";

let url = "https://api.vaktija.ba/";
let location = this.apiLocation || 77;

if (url === "https://api.vaktija.ba/") {
url = url + 'vaktija/v1/' + location;
}

let file = Gio.File.new_for_uri(url);
file.load_contents_async(null, (obj, result) => {
try {
let [success, contents] = obj.load_contents_finish(result);
if (!success) {
global.log("Error fetching data");
this.text.set_text("Error fetching data");
return;
}

let data = ByteArray.toString(contents);
let json = JSON.parse(data);
global.log("Data fetched: " + JSON.stringify(json));
this.lastFetchedData = data;
this.updateDisplay(json);
this.lastFetchedData = JSON.parse(data);
this.updateDisplay();
} catch (e) {
global.log("Error fetching data: " + e.message);
this.text.set_text("Error fetching data");
}
});
},

updateDisplay: function (json) {
let currentTime = new Date().toLocaleTimeString();
updateDisplay: function () {
if (!this.lastFetchedData) return;

let now = new Date();
let timeFormat = this.showSeconds ? 'HH:mm:ss' : 'HH:mm';
let formattedTime = this.formatTime(now, timeFormat);

let showIslamicDate = this.showIslamicDate ? `${this.lastFetchedData.datum[0]}\n` : '';
let showDate = this.showDate ? `Datum: ${this.lastFetchedData.datum[1]}\n` : '';

let vakatTimes = [
"Sabah", "Izlazak", "Podne", "Ikindija", "Akšam", "Jacija"
"Zora", "Izlazak sunca", "Podne", "Ikindija", "Akšam", "Jacija"
];

let now = new Date();
let nextVakat = null;
let countdown = "";

for (let i = 0; i < json.vakat.length; i++) {
let vakatTime = json.vakat[i].split(":");
for (let i = 0; i < this.lastFetchedData.vakat.length; i++) {
let vakatTime = this.lastFetchedData.vakat[i].split(":");
let vakatDate = new Date(now);
vakatDate.setHours(parseInt(vakatTime[0], 10));
vakatDate.setMinutes(parseInt(vakatTime[1], 10));

if (vakatDate > now) {
nextVakat = vakatTimes[i];
let diff = Math.abs(vakatDate - now) / 1000;
let hours = Math.floor(diff / 3600) % 24;
let minutes = Math.floor(diff / 60) % 60;
let seconds = Math.floor(diff % 60);
let diff = vakatDate - now;
let hours = Math.floor(diff / (1000 * 60 * 60));
let minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((diff % (1000 * 60)) / 1000);

countdown = `${hours}h ${minutes}m ${seconds}s`;
countdown = `${this.pad(hours)}h ${this.pad(minutes)}m ${this.pad(seconds)}s`;
break;
}
}

if (!nextVakat) {
let firstVakatTomorrow = this.parseTime(this.lastFetchedData.vakat[0]) + 24 * 60 * 60 * 1000;
let timeUntilNextVakat = firstVakatTomorrow - now.getTime();
let hours = Math.floor(timeUntilNextVakat / (1000 * 60 * 60)) % 24;
let minutes = Math.floor((timeUntilNextVakat % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((timeUntilNextVakat % (1000 * 60)) / 1000);

countdown = `${this.pad(hours)}h ${this.pad(minutes)}m ${this.pad(seconds)}s`;
}

let displayText = `
Trenutno vrijeme: ${currentTime}\n
Lokacija: ${json.lokacija}\n
Datum: ${json.datum[1]}\n
\n
Trenutno vrijeme: ${formattedTime}\n
Lokacija: ${this.lastFetchedData.lokacija}\n
${showDate}
${showIslamicDate}
Do sljedećeg vakta: ${countdown}\n
Sabah: ${json.vakat[0]}\n
Izlazak: ${json.vakat[1]}\n
Podne: ${json.vakat[2]}\n
Ikindija: ${json.vakat[3]}\n
Akšam: ${json.vakat[4]}\n
Jacija: ${json.vakat[5]}
Zora: ${this.lastFetchedData.vakat[0]}\n
Izlazak sunca: ${this.lastFetchedData.vakat[1]}\n
Podne: ${this.lastFetchedData.vakat[2]}\n
Ikindija: ${this.lastFetchedData.vakat[3]}\n
Akšam: ${this.lastFetchedData.vakat[4]}\n
Jacija: ${this.lastFetchedData.vakat[5]}
`;

this.text.set_text(displayText);
},

formatTime: function (date, format) {
let hours = date.getHours().toString().padStart(2, '0');
let minutes = date.getMinutes().toString().padStart(2, '0');
let seconds = date.getSeconds().toString().padStart(2, '0');

if (format === 'HH:mm:ss') {
return `${hours}:${minutes}:${seconds}`;
} else {
return `${hours}:${minutes}`;
}
},

setupMidnightTimer: function () {
let now = new Date();
let tomorrowMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 0, 0);
Expand All @@ -115,88 +203,30 @@ VaktijaDesklet.prototype = {
}, timeUntilMidnight);
},

setupTimeUpdateInterval: function () {
setInterval(() => {
this.updateTime();
}, 1000);
setupUpdateInterval: function () {
if (this.updateInterval && this.updateInterval > 0) {
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, this.updateInterval, () => {
this.fetchData();
return GLib.SOURCE_CONTINUE;
});
}
},

setupCountdownUpdateInterval: function () {
setInterval(() => {
this.updateCountdown();
}, 1000);
},

updateTime: function () {
let currentTime = new Date().toLocaleTimeString();
let displayText = this.text.get_text();
displayText = displayText.replace(/Trenutno vrijeme: .+/, `Trenutno vrijeme: ${currentTime}`);
this.text.set_text(displayText);
},

updateCountdown: function () {
let json = JSON.parse(this.lastFetchedData);

let now = new Date();
let currentTime = now.getTime();

let vakatTimes = [
{ name: "Sabah", time: this.parseTime(json.vakat[0]) },
{ name: "Izlazak", time: this.parseTime(json.vakat[1]) },
{ name: "Podne", time: this.parseTime(json.vakat[2]) },
{ name: "Ikindija", time: this.parseTime(json.vakat[3]) },
{ name: "Akšam", time: this.parseTime(json.vakat[4]) },
{ name: "Jacija", time: this.parseTime(json.vakat[5]) }
];

let nextVakat = null;
let countdown = "";

// Pronalazi sljedeći vakat
for (let i = 0; i < vakatTimes.length; i++) {
if (vakatTimes[i].time > currentTime) {
nextVakat = vakatTimes[i];
break;
}
}

if (nextVakat) {
let timeUntilNextVakat = nextVakat.time - currentTime;
let hours = Math.floor(timeUntilNextVakat / (1000 * 60 * 60));
let minutes = Math.floor((timeUntilNextVakat % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((timeUntilNextVakat % (1000 * 60)) / 1000);

countdown = `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}`;
} else {
let firstVakatTomorrow = this.parseTime(json.vakat[0]) + 24 * 60 * 60 * 1000;
let timeUntilNextVakat = firstVakatTomorrow - currentTime;
let hours = Math.floor(timeUntilNextVakat / (1000 * 60 * 60)) % 24;
let minutes = Math.floor((timeUntilNextVakat % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((timeUntilNextVakat % (1000 * 60)) / 1000);

countdown = `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}`;
}

let displayText = this.text.get_text();
displayText = displayText.replace(/Do sljedećeg vakta: .+/, `Do sljedećeg vakta: ${countdown}`);
this.text.set_text(displayText);
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
this.updateDisplay();
return GLib.SOURCE_CONTINUE;
});
},

pad: function (num) {
return (num < 10 ? '0' : '') + num;
},

parseTime: function (timeString) {
let parts = timeString.split(":");
let hours = parseInt(parts[0], 10);
let minutes = parseInt(parts[1], 10);
return new Date().setHours(hours, minutes, 0, 0);
},


let [hours, minutes] = timeString.split(':').map(Number);
let now = new Date();
let vakatDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes, 0, 0);
return vakatDate.getTime();
}
};

function main(metadata, desklet_id) {
global.log("Creating new desklet instance");
return new VaktijaDesklet(metadata, desklet_id);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"uuid": "vaktija-desklet@MuxBH28",
"name": "Vaktija Desklet",
"description": "Displays Vaktija available from vaktija.ba API!",
"description": "This desklet fetches and displays prayer times using data from vaktija.ba API.",
"max-instances": "1",
"version": "1.1",
"version": "1.2",
"author": "MuxBH28",
"website": "https://github.com/MuxBH28/vaktija-desklet",
"description": "This desklet fetches and displays prayer times using data from vaktija.ba API.",
"credits": "Desklet created by MuxBH28 - https://github.com/MuxBH28/ \nAPI created by vaktija.ba - https://github.com/vaktija"
"website": "https://sehic.rf.gd/?project=vaktija",
"credits": "API created by vaktija.ba - https://github.com/vaktija"
}
Loading