[gnome-maps/wip/mlundblad/search-as-you-type] WIP: placeEntry: Auto-complete searches



commit 7f59750c90e965ed1998af805c13107ac390aa66
Author: Marcus Lundblad <ml update uu se>
Date:   Sun May 5 21:38:14 2019 +0200

    WIP: placeEntry: Auto-complete searches

 src/placeEntry.js | 97 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 61 insertions(+), 36 deletions(-)
---
diff --git a/src/placeEntry.js b/src/placeEntry.js
index 8fc86f5..8882448 100644
--- a/src/placeEntry.js
+++ b/src/placeEntry.js
@@ -34,6 +34,9 @@ const PlaceStore = imports.placeStore;
 const PlacePopover = imports.placePopover;
 const Utils = imports.utils;
 
+// minimum number of characters to start completion, TODO: how to handle ideographs?
+const MIN_CHARS_COMPLETION = 3;
+
 var PlaceEntry = GObject.registerClass({
     Properties: {
         'place': GObject.ParamSpec.object('place',
@@ -54,11 +57,13 @@ var PlaceEntry = GObject.registerClass({
 
         if (p) {
             if (p.name) {
-                this.text = p.name;
+                this._placeText = p.name;
             } else
-                this.text = p.location.latitude + ', ' + p.location.longitude;
+                this._placeText = p.location.latitude + ', ' + p.location.longitude;
         } else
-            this.text = '';
+            this._placeText = '';
+
+        this.text = this._placeText;
 
         this._place = p;
         this.notify('place');
@@ -98,24 +103,7 @@ var PlaceEntry = GObject.registerClass({
 
         this._popover = this._createPopover(numVisible, maxChars);
 
-        this.connect('activate', this._onActivate.bind(this));
-        this.connect('search-changed', () => {
-            if (this._cancellable)
-                this._cancellable.cancel();
-
-            this._refreshFilter();
-
-            if (this.text.length === 0) {
-                this._popover.hide();
-                this.place = null;
-                return;
-            }
-
-            if (this._filter.iter_n_children(null) > 0)
-                this._popover.showCompletion();
-            else
-                this._popover.hide();
-        });
+        this.connect('search-changed', this._onSearchChanged.bind(this));
 
         if (parseOnFocusOut) {
             this.connect('focus-out-event', () => {
@@ -125,6 +113,42 @@ var PlaceEntry = GObject.registerClass({
         }
     }
 
+    _onSearchChanged() {
+        if (this._parse())
+            return;
+
+        // wait for an ongoing search
+        if (this._cancellable)
+            return;
+
+        //this._refreshFilter();
+
+        if (this.text.length < MIN_CHARS_COMPLETION) {
+            this._popover.hide();
+            this.place = null;
+            this._previousSearch = null;
+            return;
+        } else if (this.text.length >= MIN_CHARS_COMPLETION &&
+                   this.text !== this._placeText) {
+            // if no previous search has been performed, show spinner
+            if (!this._previousSearch ||
+                this._previousSearch.length < MIN_CHARS_COMPLETION ||
+                this._placeText) {
+                this._popover.showSpinner();
+            }
+            this._placeText = '';
+            this._doSearch();
+            return;
+        }
+
+        /*
+        if (this._filter.iter_n_children(null) > 0)
+            this._popover.showCompletion();
+        else
+            this._popover.hide();
+        */
+    }
+
     _locEquals(placeA, placeB) {
         if (!placeA.location || !placeB.location)
             return false;
@@ -172,10 +196,7 @@ var PlaceEntry = GObject.registerClass({
     }
 
     _parse() {
-        if (this.text.length === 0) {
-            this.place = null;
-            return true;
-        }
+        let parsed = false;
 
         if (this.text.startsWith('geo:')) {
             let location = new Geocode.Location();
@@ -188,33 +209,33 @@ var PlaceEntry = GObject.registerClass({
                 Utils.showDialog(msg, Gtk.MessageType.ERROR, this.get_toplevel());
             }
 
-            return true;
+            parsed = true;
         }
 
         let parsedLocation = Place.Place.parseCoordinates(this.text);
         if (parsedLocation) {
             this.place = new Place.Place({ location: parsedLocation });
-            return true;
+            parsed = true;
         }
 
-        return false;
-    }
-
-    _onActivate() {
-        if (this._parse())
-            return;
-
-        let bbox = this._mapView.view.get_bounding_box();
+        if (parsed && this._cancellable)
+            this._cancellable.cancel();
 
-        this._popover.showSpinner();
+        return parsed;
+    }
 
+    _doSearch() {
+        if (this._cancellable)
+            this._cancellable.cancel();
         this._cancellable = new Gio.Cancellable();
+        this._previousSearch = this.text;
         Application.photonGeocode.search(this.text,
                                          this._mapView.view.latitude,
                                          this._mapView.view.longitude,
                                          this._cancellable,
                                          (places, error) => {
             Utils.debug('places: ' + places);
+            this._cancellable = null;
             if (!places) {
                 this.place = null;
                 this._popover.showNoResult();
@@ -222,6 +243,10 @@ var PlaceEntry = GObject.registerClass({
             }
             this._popover.updateResult(places, this.text);
             this._popover.showResult();
+
+            // if search input has been updated, trigger a refresh
+            if (this.text !== this._previousSearch)
+                this._onSearchChanged();
         });
     }
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]