feat: Sync location with query param / hash

master
Abdussamet Kocak 4 weeks ago
parent c106d57fe6
commit 960e6f713a

@ -11,10 +11,13 @@ const app = () => ({
supportedSalathLangs: ["tr", "de", "en", "ar"],
userMinutes: 0,
now: new Date(),
debug: location.hash === "#debug",
debug: hasDebugHashFlag(),
async init() {
if (this.selectedLocation) {
const urlCoords = getURLCoords();
if (urlCoords) {
await this.selectNearestLocation(urlCoords.latitude, urlCoords.longitude, {updateURL: false});
} else if (this.selectedLocation) {
this.searchQuery = this.formatLocationLabel(this.selectedLocation);
await this.refreshPrayerTimes();
}
@ -23,16 +26,23 @@ const app = () => ({
this.now = new Date();
}, 500);
try {
const coords = await getUserLocation();
await this.selectNearestLocation(coords.latitude, coords.longitude);
} catch (_error) {
// Ignore geolocation errors and rely on manual search.
if (!urlCoords) {
try {
const coords = await getUserLocation();
await this.selectNearestLocation(coords.latitude, coords.longitude, {updateURL: true});
} catch (_error) {
// Ignore geolocation errors and rely on manual search.
}
}
},
onHash() {
this.debug = location.hash === "#debug";
this.debug = hasDebugHashFlag();
const urlCoords = getURLCoords();
if (urlCoords) {
this.selectNearestLocation(urlCoords.latitude, urlCoords.longitude, {updateURL: false});
}
},
onSearchInput() {
@ -67,20 +77,23 @@ const app = () => ({
}
},
async selectNearestLocation(latitude, longitude) {
async selectNearestLocation(latitude, longitude, {updateURL = false} = {}) {
const response = await fetchJSON(`/api/v1/diyanet/location?latitude=${encodeURIComponent(latitude)}&longitude=${encodeURIComponent(longitude)}`);
const first = (response.locations ?? [])[0];
if (!first) {
return;
}
await this.selectLocation(first);
await this.selectLocation(first, {updateURL});
},
async selectLocation(location) {
async selectLocation(location, {updateURL = true} = {}) {
this.selectedLocation = location;
this.searchQuery = this.formatLocationLabel(location);
this.searchOpen = false;
this.searchResults = [];
if (updateURL) {
setURLCoords(location.latitude, location.longitude);
}
await this.refreshPrayerTimes();
},
@ -308,3 +321,49 @@ function getUserLocation() {
function normalizeLanguageTag(tag) {
return String(tag).toLowerCase().split("-")[0];
}
function parseCoordinate(value) {
const parsed = Number.parseFloat(value);
return Number.isFinite(parsed) ? parsed : null;
}
function parseCoordsFromSearchParams(params) {
const latitude = parseCoordinate(params.get("latitude") ?? params.get("lat"));
const longitude = parseCoordinate(params.get("longitude") ?? params.get("lon"));
if (latitude === null || longitude === null) {
return null;
}
return {latitude, longitude};
}
function getHashSearchParams() {
const hash = location.hash.startsWith("#") ? location.hash.slice(1) : location.hash;
if (hash === "") {
return new URLSearchParams();
}
return new URLSearchParams(hash);
}
function hasDebugHashFlag() {
const params = getHashSearchParams();
return params.has("debug") || location.hash === "#debug";
}
function getURLCoords() {
const queryCoords = parseCoordsFromSearchParams(new URLSearchParams(location.search));
if (queryCoords) {
return queryCoords;
}
return parseCoordsFromSearchParams(getHashSearchParams());
}
function setURLCoords(latitude, longitude) {
const url = new URL(window.location.href);
url.searchParams.set("latitude", String(latitude));
url.searchParams.set("longitude", String(longitude));
url.searchParams.delete("lat");
url.searchParams.delete("lon");
window.history.replaceState({}, "", url.toString());
}

Loading…
Cancel
Save