Skip to content

Commit

Permalink
vaktija-desklet@MuxBH28: Version 1.2 (#1258)
Browse files Browse the repository at this point in the history
* Added extensive configuration options in the latest version:
   * Visual Customization: Enhanced appearance settings to adjust the desklet’s look and feel
   * Location Settings: Users can now select from 177 locations across Bosnia and Herzegovina and southern Serbia, with plans to include more locations in future updates
   * Hijri Calendar: Added support for displaying the Hijri (Islamic) calendar date
   * Additional Options: Introduced various new options for further customization
  • Loading branch information
MuxBH28 authored Aug 15, 2024
1 parent 8abfa49 commit eb1bdc9
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 117 deletions.
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

0 comments on commit eb1bdc9

Please sign in to comment.