aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/user/User.js
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 10:29:49 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 10:29:49 +0200
commite1313ee7abb93a8a20f978ac152b462c9ef74a43 (patch)
tree3c9828631ec4e21b801b3bd280b0847248308b0a /desktop/modules/user/User.js
parentd445397ff656c57589499f7a2215a0fe12a596c3 (diff)
downloadquickshell-e1313ee7abb93a8a20f978ac152b462c9ef74a43.tar.gz
quickshell-e1313ee7abb93a8a20f978ac152b462c9ef74a43.zip
feat(user): location suggestions from OpenStreetMap
There is no place database on this machine, and the user chose Nominatim over a tz city list for coverage. It is asked 1s after typing stops (its policy: one request a second, an identifying User-Agent, nothing personal sent), from three characters, in the desktop's language, and a reply to an older query is dropped. places() turns its JSON into 'place, region, country' labels and treats an error page as no suggestions; test_user.js covers it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/user/User.js')
-rw-r--r--desktop/modules/user/User.js18
1 files changed, 18 insertions, 0 deletions
diff --git a/desktop/modules/user/User.js b/desktop/modules/user/User.js
index 8160b7f..5c3d5a2 100644
--- a/desktop/modules/user/User.js
+++ b/desktop/modules/user/User.js
@@ -44,3 +44,21 @@ function gitName(name) {
if (w.length < 2) return w.join(" ");
return w.slice(0, -1).join(" ") + " " + Array.from(w[w.length - 1])[0] + ".";
}
+
+// Nominatim jsonv2 search results as location labels, "place, region,
+// country", deduplicated. Anything that is not a JSON array (an error page,
+// a rate-limit notice) is no suggestions rather than an error.
+function places(text) {
+ let rows;
+ try { rows = JSON.parse(text); } catch (e) { return []; }
+ if (!Array.isArray(rows)) return [];
+ const out = [];
+ for (const r of rows) {
+ const a = r.address || {};
+ const parts = [a.city || a.town || a.village || a.hamlet || a.municipality || r.name,
+ a.state, a.country].filter(p => p);
+ const label = parts.filter((p, i) => parts.indexOf(p) === i).join(", ");
+ if (label && !out.includes(label)) out.push(label);
+ }
+ return out;
+}