feat: Sync location with query param / hash
This commit is contained in:
@@ -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);
|
||||
|
||||
if (!urlCoords) {
|
||||
try {
|
||||
const coords = await getUserLocation();
|
||||
await this.selectNearestLocation(coords.latitude, coords.longitude);
|
||||
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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user