diff --git a/src/Library/demos/Location/main.blp b/src/Library/demos/Location/main.blp new file mode 100644 index 000000000..1c3d585b1 --- /dev/null +++ b/src/Library/demos/Location/main.blp @@ -0,0 +1,177 @@ +using Gtk 4.0; +using Adw 1; + +Adw.StatusPage { + title: _("Location"); + description: _("Request the user location"); + margin-top: 48; + + Adw.Clamp { + maximum-size: 480; + + Box { + orientation: vertical; + halign: center; + + ListBox { + selection-mode: none; + margin-bottom: 18; + + styles ["boxed-list"] + + Adw.ActionRow { + title: _("Distance Threshold"); + subtitle: _("In meters"); + + SpinButton distance_threshold { + valign: center; + wrap: true; + value: 0; + climb-rate: 1; + adjustment: Adjustment { + lower: 0; + upper: 100; + step-increment: 1; + value: 0; + }; + } + } + + Adw.ActionRow { + title: _("Time Threshold"); + subtitle: _("In meters"); + + SpinButton time_threshold { + valign: center; + wrap: true; + value: 0; + climb-rate: 1; + adjustment: Adjustment { + lower: 0; + upper: 100; + step-increment: 1; + value: 0; + }; + } + } + + Adw.ComboRow accuracy_button { + title: _("Accuracy"); + model: Gtk.StringList { + strings [C_("Accuracy", "Exact"), C_("Accuracy", "Street"), C_("Accuracy", "Neighborhood"), C_("Accuracy", "City"), C_("Accuracy", "Country"), C_("Accuracy", "None")] + }; + } + } + + Box { + halign: center; + spacing: 30; + margin-bottom: 24; + + Button start { + label: _("Start Session"); + halign: center; + styles ["suggested-action", "pill"] + } + + Button close { + label: _("Close Session"); + halign: center; + sensitive: false; + styles ["destructive-action", "pill"] + } + } + + Revealer revealer { + transition-duration: 300; + transition-type: slide_up; + + ListBox { + selection-mode: none; + margin-bottom: 18; + + styles ["boxed-list"] + + Adw.ActionRow { + title: _("Latitude"); + subtitle: _("In degrees"); + + Label latitude { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Longitude"); + subtitle: _("In degrees"); + + Label longitude { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Accuracy"); + subtitle: _("In meters"); + + Label accuracy { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Altitude"); + subtitle: _("In meters"); + + Label altitude { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Speed"); + subtitle: _("In meters per second"); + + Label speed { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Heading"); + subtitle: _("In degrees, clockwise"); + + Label heading { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Description"); + + Label description { + label: _("N/A"); + } + } + + Adw.ActionRow { + title: _("Timestamp"); + + Label timestamp { + label: _("N/A"); + } + } + } + } + + LinkButton { + label: "API Reference"; + uri: "https://libportal.org/method.Portal.location_monitor_start.html"; + } + } + } +} + + + + diff --git a/src/Library/demos/Location/main.js b/src/Library/demos/Location/main.js new file mode 100644 index 000000000..91ee0873b --- /dev/null +++ b/src/Library/demos/Location/main.js @@ -0,0 +1,118 @@ +import Xdp from "gi://Xdp"; +import XdpGtk from "gi://XdpGtk4"; +import Gio from "gi://Gio"; +import Gdk from "gi://Gdk"; +import Gtk from "gi://Gtk"; +import Adw from "gi://Adw"; + +Gio._promisify( + Xdp.Portal.prototype, + "location_monitor_start", + "location_monitor_start_finish", +); + +const portal = new Xdp.Portal(); +const parent = XdpGtk.parent_new_gtk(workbench.window); + +const revealer = workbench.builder.get_object("revealer"); +const start = workbench.builder.get_object("start"); +const close = workbench.builder.get_object("close"); +const distance_threshold = workbench.builder.get_object("distance_threshold"); +const time_threshold = workbench.builder.get_object("time_threshold"); +const accuracy_button = workbench.builder.get_object("accuracy_button"); + +const latitude_label = workbench.builder.get_object("latitude"); +const longitude_label = workbench.builder.get_object("longitude"); +const accuracy_label = workbench.builder.get_object("accuracy"); +const altitude_label = workbench.builder.get_object("altitude"); +const speed_label = workbench.builder.get_object("speed"); +const heading_label = workbench.builder.get_object("heading"); +const description_label = workbench.builder.get_object("description"); +const timestamp_label = workbench.builder.get_object("timestamp"); + +let locationAccuracy = Xdp.LocationAccuracy.Exact; +let distanceThreshold = distance_threshold.value; +let timeThreshold = time_threshold.value; + +time_threshold.connect("value-changed", () => { + portal.location_monitor_stop(); + revealer.reveal_child = false; + timeThreshold = time_threshold.value; + console.log("Time threshold changed"); + startSession(); +}); + +distance_threshold.connect("value-changed", () => { + portal.location_monitor_stop(); + revealer.reveal_child = false; + distanceThreshold = distance_threshold.value; + console.log("Distance threshold changed"); + startSession(); +}); + +accuracy_button.connect("notify::selected-item", () => { + console.log("Accuracy changed"); + portal.location_monitor_stop(); + revealer.reveal_child = false; + const accuracy_flag = accuracy_button.selected_item.get_string(); + locationAccuracy = Xdp.LocationAccuracy[accuracy_flag]; + startSession(); +}); + +async function startSession() { + start.sensitive = false; + close.sensitive = true; + const result = await portal.location_monitor_start( + parent, + distanceThreshold, + timeThreshold, + locationAccuracy, + Xdp.LocationMonitorFlags.NONE, + null, + ); + if (result === true) { + console.log("Location access granted"); + revealer.reveal_child = true; + } else { + console.log("Error retrieving location"); + } +} + +portal.connect( + "location-updated", + ( + portal, + latitude, + longitude, + altitude, + accuracy, + speed, + heading, + description, + timestamp_s, + ) => { + latitude_label.label = latitude.toString(); + longitude_label.label = longitude.toString(); + accuracy_label.label = accuracy.toString(); + altitude_label.label = altitude.toString(); + speed_label.label = speed.toString(); + heading_label.label = heading.toString(); + description_label.label = description.toString(); + + const timestamp = new Date(timestamp_s * 1000); // Convert UNIX timestamp to milliseconds + const formattedTimestamp = timestamp.toLocaleString(); // Convert timestamp to local date and time string + timestamp_label.label = formattedTimestamp; + }, +); + +start.connect("clicked", () => { + startSession().catch(logError); +}); + +close.connect("clicked", () => { + start.sensitive = true; + close.sensitive = false; + portal.location_monitor_stop(); + revealer.reveal_child = false; + console.log("Session closed"); +}); diff --git a/src/Library/demos/Location/main.json b/src/Library/demos/Location/main.json new file mode 100644 index 000000000..9624e57b1 --- /dev/null +++ b/src/Library/demos/Location/main.json @@ -0,0 +1,7 @@ +{ + "name": "Location", + "category": "platform", + "description": "Request the user location", + "panels": ["code", "preview"], + "autorun": true +}