feat(web): Add geolocation button, clear location, i18n, and spacing fixes

Add a "use my current location" button next to the search box (shown
only when no location is selected), make clearing the search box reset
selected location, prayer times, and URL coords, rebalance vertical
spacing so the clock isn't flush against the viewport edge, and
translate all UI copy based on browser language.
This commit is contained in:
abdus committed 2026-10-08 21:00:44 +02:00
1 parent b55fc2333c
commit b5aecf4304
3 files changed
+156 -9

No files matched your search

+88 -1
View File
@@ -12,6 +12,13 @@ const app = () => ({
userMinutes: 0,
now: new Date(),
debug: hasDebugHashFlag(),
locating: false,
locateError: "",
t(key) {
const lang = this.preferredSalathLangs[0];
return UI_STRINGS[key]?.[lang] ?? UI_STRINGS[key]?.en ?? key;
},
async init() {
const urlCoords = getURLCoords();
@@ -45,6 +52,19 @@ const app = () => ({
}
},
async useCurrentLocation() {
this.locateError = "";
this.locating = true;
try {
const coords = await getUserLocation();
await this.selectNearestLocation(coords.latitude, coords.longitude, {updateURL: true});
} catch (_error) {
this.locateError = "locateFailed";
} finally {
this.locating = false;
}
},
onSearchInput() {
this.searchError = "";
if (this.searchDebounceTimer) {
@@ -55,6 +75,9 @@ const app = () => ({
if (query === "") {
this.searchResults = [];
this.searchOpen = false;
if (this.selectedLocation) {
this.clearLocation();
}
return;
}
@@ -71,7 +94,7 @@ const app = () => ({
this.searchResults = response.locations ?? [];
} catch (_error) {
this.searchResults = [];
this.searchError = "Failed to search locations.";
this.searchError = "searchFailed";
} finally {
this.searchLoading = false;
}
@@ -97,6 +120,16 @@ const app = () => ({
await this.refreshPrayerTimes();
},
clearLocation() {
this.selectedLocation = null;
this.searchQuery = "";
this.searchResults = [];
this.searchOpen = false;
this.futureTimes = [];
this.lastUpdated = null;
clearURLCoords();
},
formatLocationLabel(location) {
if (!location) {
return "";
@@ -173,6 +206,51 @@ const app = () => ({
}
});
const UI_STRINGS = {
appTitle: {
tr: "Namaz Vakitleri",
en: "Prayer Times",
de: "Gebetszeiten",
ar: "مواقيت الصلاة"
},
searchPlaceholder: {
tr: "Konum ara...",
en: "Search location...",
de: "Ort suchen...",
ar: "ابحث عن موقع..."
},
useCurrentLocation: {
tr: "Mevcut konumumu kullan",
en: "Use my current location",
de: "Meinen aktuellen Standort verwenden",
ar: "استخدم موقعي الحالي"
},
searching: {
tr: "Aranıyor...",
en: "Searching...",
de: "Suche läuft...",
ar: "جارٍ البحث..."
},
noResults: {
tr: "Sonuç bulunamadı",
en: "No results",
de: "Keine Ergebnisse",
ar: "لا توجد نتائج"
},
locateFailed: {
tr: "Konumunuz alınamadı.",
en: "Could not get your location.",
de: "Standort konnte nicht ermittelt werden.",
ar: "تعذر تحديد موقعك."
},
searchFailed: {
tr: "Konum araması başarısız oldu.",
en: "Failed to search locations.",
de: "Ortssuche fehlgeschlagen.",
ar: "فشل البحث عن الموقع."
}
};
class PrayerTimes {
static salaths = ["fajr", "sunrise", "dhuhr", "asr", "maghrib", "isha"];
static translations = {
@@ -367,3 +445,12 @@ function setURLCoords(latitude, longitude) {
url.searchParams.delete("lon");
window.history.replaceState({}, "", url.toString());
}
function clearURLCoords() {
const url = new URL(window.location.href);
url.searchParams.delete("latitude");
url.searchParams.delete("longitude");
url.searchParams.delete("lat");
url.searchParams.delete("lon");
window.history.replaceState({}, "", url.toString());
}