feat: Update UI
This commit is contained in:
+31
-16
@@ -84,16 +84,21 @@
|
|||||||
x-text='formatDate(userNow)'></time>
|
x-text='formatDate(userNow)'></time>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span class='salath-name'
|
<div class='salath-name-group salath-name-group--center'>
|
||||||
lang='tr'
|
<span class='salath-name salath-name--primary'
|
||||||
x-text='todayTimes.currentSalath.name("tr")'></span>
|
:class="{'text--arabic': salathNameDisplay(todayTimes.currentSalath.salath).primary.lang === 'ar'}"
|
||||||
<span class='salath-name'
|
:lang='salathNameDisplay(todayTimes.currentSalath.salath).primary.lang'
|
||||||
lang='de'
|
x-text='salathNameDisplay(todayTimes.currentSalath.salath).primary.text'></span>
|
||||||
x-text='todayTimes.currentSalath.name("de")'></span>
|
<div class="salath-name-alternatives">
|
||||||
<span class='salath-name text--arabic'
|
<template x-for='item in salathNameDisplay(todayTimes.currentSalath.salath).secondary'
|
||||||
lang='ar'
|
:key='item.lang'>
|
||||||
x-text='todayTimes.currentSalath.name("ar")'></span>
|
<span class='salath-name salath-name--secondary'
|
||||||
</p>
|
:class="{'text--arabic': item.lang === 'ar'}"
|
||||||
|
:lang='item.lang'
|
||||||
|
x-text='item.text'></span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<time :datetime='todayTimes.nextSalath.startsAt'
|
<time :datetime='todayTimes.nextSalath.startsAt'
|
||||||
class='text--numeric text--time'
|
class='text--numeric text--time'
|
||||||
@@ -110,12 +115,22 @@
|
|||||||
<tr class='salath'
|
<tr class='salath'
|
||||||
:class='{current: it.salath === todayTimes.currentSalath.salath}'>
|
:class='{current: it.salath === todayTimes.currentSalath.salath}'>
|
||||||
<td class='cell-names'>
|
<td class='cell-names'>
|
||||||
<span class='salath-name'
|
<div class='salath-name-group'>
|
||||||
x-text='it.name("tr")'></span>
|
<span class='salath-name salath-name--primary'
|
||||||
<span class='salath-name'
|
:class="{'text--arabic': salathNameDisplay(it.salath).primary.lang === 'ar'}"
|
||||||
x-text='it.name("de")'></span>
|
:lang='salathNameDisplay(it.salath).primary.lang'
|
||||||
<span class='salath-name text--arabic'
|
x-text='salathNameDisplay(it.salath).primary.text'></span>
|
||||||
x-text='it.name("ar")'></span>
|
<div class="salath-name-alternatives">
|
||||||
|
|
||||||
|
<template x-for='item in salathNameDisplay(it.salath).secondary'
|
||||||
|
:key='item.lang'>
|
||||||
|
<span class='salath-name salath-name--secondary'
|
||||||
|
:class="{'text--arabic': item.lang === 'ar'}"
|
||||||
|
:lang='item.lang'
|
||||||
|
x-text='item.text'></span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class='cell-times'>
|
<td class='cell-times'>
|
||||||
<span class='salath-time text--time text--numeric'
|
<span class='salath-time text--time text--numeric'
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const app = () => ({
|
|||||||
searchLoading: false,
|
searchLoading: false,
|
||||||
searchError: "",
|
searchError: "",
|
||||||
searchDebounceTimer: null,
|
searchDebounceTimer: null,
|
||||||
|
supportedSalathLangs: ["tr", "de", "en", "ar"],
|
||||||
userMinutes: 0,
|
userMinutes: 0,
|
||||||
now: new Date(),
|
now: new Date(),
|
||||||
debug: location.hash === "#debug",
|
debug: location.hash === "#debug",
|
||||||
@@ -131,18 +132,73 @@ const app = () => ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new PrayerTimes(this.futureTimes[0], () => this.userNow);
|
return new PrayerTimes(this.futureTimes[0], () => this.userNow);
|
||||||
|
},
|
||||||
|
|
||||||
|
get preferredSalathLangs() {
|
||||||
|
const browserLanguages = (navigator.languages && navigator.languages.length > 0)
|
||||||
|
? navigator.languages
|
||||||
|
: [navigator.language];
|
||||||
|
|
||||||
|
const preferred = browserLanguages
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((tag) => normalizeLanguageTag(tag))
|
||||||
|
.filter((lang) => this.supportedSalathLangs.includes(lang));
|
||||||
|
|
||||||
|
return Array.from(new Set([...preferred, ...this.supportedSalathLangs]));
|
||||||
|
},
|
||||||
|
|
||||||
|
salathNameDisplay(salath) {
|
||||||
|
const names = this.preferredSalathLangs.map((lang) => ({
|
||||||
|
lang,
|
||||||
|
text: PrayerTimes.translations[salath]?.[lang] ?? salath
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
primary: names[0],
|
||||||
|
secondary: names.slice(1)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class PrayerTimes {
|
class PrayerTimes {
|
||||||
static salaths = ["fajr", "sunrise", "dhuhr", "asr", "maghrib", "isha"];
|
static salaths = ["fajr", "sunrise", "dhuhr", "asr", "maghrib", "isha"];
|
||||||
static translations = {
|
static translations = {
|
||||||
fajr: {tr: "İmsak", de: "Fruehgebet", ar: "صلاة الفجر"},
|
fajr: {
|
||||||
sunrise: {tr: "Günes", de: "Sonnenaufgang", ar: "الشروق"},
|
tr: "İmsak",
|
||||||
dhuhr: {tr: "Öğle", de: "Mittagsgebet", ar: "صلاة الظهر"},
|
en: "Fajr",
|
||||||
asr: {tr: "İkindi", de: "Nachmittagsgebet", ar: "صلاة العصر"},
|
de: "Fruehgebet",
|
||||||
maghrib: {tr: "Aksam", de: "Abendgebet", ar: "صلاة المغرب"},
|
ar: "صلاة الفجر"
|
||||||
isha: {tr: "Yatsı", de: "Nachtgebet", ar: "صلاة العشاء"}
|
},
|
||||||
|
sunrise: {
|
||||||
|
tr: "Güneş",
|
||||||
|
en: "Sunrise",
|
||||||
|
de: "Sonnenaufgang",
|
||||||
|
ar: "الشروق"
|
||||||
|
},
|
||||||
|
dhuhr: {
|
||||||
|
tr: "Öğle",
|
||||||
|
en: "Dhuhr",
|
||||||
|
de: "Mittagsgebet",
|
||||||
|
ar: "صلاة الظهر"
|
||||||
|
},
|
||||||
|
asr: {
|
||||||
|
tr: "İkindi",
|
||||||
|
en: "Asr",
|
||||||
|
de: "Nachmittagsgebet",
|
||||||
|
ar: "صلاة العصر"
|
||||||
|
},
|
||||||
|
maghrib: {
|
||||||
|
tr: "Akşam",
|
||||||
|
en: "Maghrib",
|
||||||
|
de: "Abendgebet",
|
||||||
|
ar: "صلاة المغرب"
|
||||||
|
},
|
||||||
|
isha: {
|
||||||
|
tr: "Yatsı",
|
||||||
|
en: "Isha",
|
||||||
|
de: "Nachtgebet",
|
||||||
|
ar: "صلاة العشاء"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor({date, ...rest}, clock = () => new Date()) {
|
constructor({date, ...rest}, clock = () => new Date()) {
|
||||||
@@ -199,8 +255,12 @@ class PrayerTimes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatDuration(seconds) {
|
function formatDuration(seconds) {
|
||||||
const d = new Date(0, 0, 0, 0, 0, seconds);
|
const totalSeconds = Math.max(0, Math.floor(seconds));
|
||||||
return formatTime(d);
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const secs = totalSeconds % 60;
|
||||||
|
|
||||||
|
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTime(then) {
|
function formatTime(then) {
|
||||||
@@ -244,3 +304,7 @@ function getUserLocation() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeLanguageTag(tag) {
|
||||||
|
return String(tag).toLowerCase().split("-")[0];
|
||||||
|
}
|
||||||
|
|||||||
@@ -132,14 +132,37 @@ td {
|
|||||||
.salath-name {
|
.salath-name {
|
||||||
}
|
}
|
||||||
|
|
||||||
.current {
|
.salath-name-group {
|
||||||
color: tomato;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.1rem;
|
||||||
|
}
|
||||||
|
.salath-name-alternatives {
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
.salath-name-alternatives span + span:before {
|
||||||
|
content: " / ";
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.salath-name + .salath-name:before {
|
.salath-name-group--center {
|
||||||
content: '/';
|
align-items: center;
|
||||||
opacity: 0.25;
|
}
|
||||||
margin: 0 0.5em;
|
|
||||||
|
.salath-name--primary {
|
||||||
|
line-height: 1.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
.salath-name--secondary {
|
||||||
|
font-size: 0.58em;
|
||||||
|
font-weight: 500;
|
||||||
|
opacity: 0.75;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current {
|
||||||
|
color: tomato;
|
||||||
}
|
}
|
||||||
|
|
||||||
.salath-time {
|
.salath-time {
|
||||||
|
|||||||
Reference in New Issue
Block a user