[gnome-maps] Add Check-in dialog
- From: Jonas Danielsson <jonasdn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps] Add Check-in dialog
- Date: Thu, 11 Dec 2014 06:12:17 +0000 (UTC)
commit fec9ef1f9191665fefbb076115a33b1886060234
Author: Damián Nohales <damiannohales gmail com>
Date: Mon Jun 2 14:48:49 2014 -0300
Add Check-in dialog
https://bugzilla.gnome.org/show_bug.cgi?id=731113
data/gnome-maps.css | 4 +
data/org.gnome.maps.gschema.xml.in | 20 ++
po/POTFILES.in | 4 +
src/account-row.ui | 76 ++++++
src/accountListBox.js | 85 ++++++
src/check-in-dialog.ui | 465 ++++++++++++++++++++++++++++++++++
src/checkIn.js | 41 +++
src/checkInDialog.js | 299 ++++++++++++++++++++++
src/gnome-maps.data.gresource.xml | 4 +
src/gnome-maps.js.gresource.xml | 4 +
src/social-place-more-results-row.ui | 22 ++
src/social-place-row.ui | 44 ++++
src/socialPlaceListBox.js | 110 ++++++++
src/socialPlaceMatcher.js | 126 +++++++++
14 files changed, 1304 insertions(+), 0 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index 42d6087..cf14d80 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -85,3 +85,7 @@
.bubble-content {
font-size: small;
}
+
+.maps-check-in GtkTextView {
+ font-size: large;
+}
diff --git a/data/org.gnome.maps.gschema.xml.in b/data/org.gnome.maps.gschema.xml.in
index d118207..96df8c4 100644
--- a/data/org.gnome.maps.gschema.xml.in
+++ b/data/org.gnome.maps.gschema.xml.in
@@ -25,5 +25,25 @@
<_summary>Number of recent places to store</_summary>
<_description>Number of recently visited places to store.</_description>
</key>
+ <key name="checkin-facebook-privacy" type="s">
+ <default>"EVERYONE"</default>
+ <_summary>Facebook check-in privacy setting</_summary>
+ <_description>Latest used Facebook check-in privacy setting. Possible values are: EVERYONE,
FRIENDS_OF_FRIENDS, ALL_FRIENDS or SELF.</_description>
+ </key>
+ <key name="checkin-foursquare-privacy" type="s">
+ <default>"public"</default>
+ <_summary>Foursquare check-in privacy setting</_summary>
+ <_description>Latest used Foursquare check-in privacy setting. Possible values are: public, followers
or private.</_description>
+ </key>
+ <key name="checkin-foursquare-broadcast-facebook" type="b">
+ <default>false</default>
+ <_summary>Foursquare check-in Facebook broadcasting</_summary>
+ <_description>Indicates if Foursquare should broadcast the check-in as a post in the Facebook account
associated with the Foursquare account.</_description>
+ </key>
+ <key name="checkin-foursquare-broadcast-twitter" type="b">
+ <default>false</default>
+ <_summary>Foursquare check-in Twitter broadcasting</_summary>
+ <_description>Indicates if Foursquare should broadcast the check-in as a tweet in the Twitter account
associated with the Foursquare account.</_description>
+ </key>
</schema>
</schemalist>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9417e87..44a76de 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,9 @@ data/org.gnome.Maps.desktop.in.in
data/org.gnome.maps.gschema.xml.in
src/application.js
[type: gettext/glade]src/app-menu.ui
+[type: gettext/glade]src/check-in-dialog.ui
+src/checkIn.js
+src/checkInDialog.js
[type: gettext/glade]src/context-menu.ui
src/geoclue.js
src/mainWindow.js
@@ -15,5 +18,6 @@ src/searchResultBubble.js
[type: gettext/glade]src/share-dialog.ui
src/sidebar.js
[type: gettext/glade]src/sidebar.ui
+[type: gettext/glade]src/social-place-more-results-row.ui
[type: gettext/glade]src/user-location-bubble.ui
src/utils.js
diff --git a/src/account-row.ui b/src/account-row.ui
new file mode 100644
index 0000000..60afd7c
--- /dev/null
+++ b/src/account-row.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="Gjs_AccountRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">10</property>
+ <property name="margin_end">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkGrid" id="labelsGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkLabel" id="providerLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="identityLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="providerImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="pixel_size">32</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="attentionNeededImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">dialog-warning-symbolic</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/accountListBox.js b/src/accountListBox.js
new file mode 100644
index 0000000..f1a96a2
--- /dev/null
+++ b/src/accountListBox.js
@@ -0,0 +1,85 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Gio = imports.gi.Gio;
+const Goa = imports.gi.Goa;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+
+const Application = imports.application;
+
+const AccountRow = new Lang.Class({
+ Name: 'AccountRow',
+ Extends: Gtk.ListBoxRow,
+ Template: 'resource:///org/gnome/maps/account-row.ui',
+ InternalChildren: [ 'providerLabel',
+ 'identityLabel',
+ 'providerImage',
+ 'attentionNeededImage' ],
+
+ _init: function(params) {
+ this.account = params.account;
+ delete params.account;
+
+ this.parent(params);
+
+ let account = this.account.get_account();
+
+ this._providerLabel.label = account.provider_name;
+ this._identityLabel.label = account.presentation_identity;
+ this._providerImage.gicon = Gio.Icon.new_for_string(account.provider_icon);
+ this._attentionNeededImage.visible = account.attention_needed;
+ }
+});
+
+const AccountListBox = new Lang.Class({
+ Name: 'AccountListBox',
+ Extends: Gtk.ListBox,
+ Signals: {
+ 'account-selected': { param_types: [Goa.Object] }
+ },
+
+ _init: function(params) {
+ params.activate_on_single_click = true;
+ this.parent(params);
+
+ Application.checkInManager.connect('accounts-refreshed', this.refresh.bind(this));
+
+ this.connect('row-activated', (function(list, row) {
+ this.emit('account-selected', row.account);
+ }).bind(this));
+
+ this.refresh();
+ },
+
+ refresh: function() {
+ let accounts = Application.checkInManager.accounts;
+
+ this.forall(function(row) {
+ row.destroy();
+ });
+
+ accounts.forEach((function(account) {
+ this.add(new AccountRow({ account: account }));
+ }).bind(this));
+ }
+});
diff --git a/src/check-in-dialog.ui b/src/check-in-dialog.ui
new file mode 100644
index 0000000..819ead9
--- /dev/null
+++ b/src/check-in-dialog.ui
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="Gjs_CheckInDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="type">popup</property>
+ <property name="type_hint">dialog</property>
+ <property name="width_request">500</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="contentArea">
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ <property name="transition_type">crossfade</property>
+ <child>
+ <object class="GtkGrid" id="loadingGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkSpinner" id="loadingSpinner">
+ <property name="height_request">32</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="active">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">loading</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="accountGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">15</property>
+ <property name="margin_end">15</property>
+ <property name="margin_top">15</property>
+ <property name="margin_bottom">15</property>
+ <child>
+ <object class="GtkFrame" id="accountFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">in</property>
+ <child type="label_item">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">account</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="placeGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">15</property>
+ <property name="margin_end">15</property>
+ <property name="margin_top">15</property>
+ <property name="margin_bottom">15</property>
+ <child>
+ <object class="GtkInfoBar" id="placeNotFoundInfoBar">
+ <property name="visible">True</property>
+ <property name="app_paintable">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">5</property>
+ <property name="hexpand">True</property>
+ <property name="message_type">warning</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="placeNotFoundInfoBarActionArea">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox" id="placeNotFoundInfoBarContentArea">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="placeNotFoundInfoBarImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">6</property>
+ <property name="icon_name">dialog-warning-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="placeNotFoundLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="placeScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="min_content_height">300</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">place</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="messageGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">15</property>
+ <property name="margin_end">15</property>
+ <property name="margin_top">8</property>
+ <property name="margin_bottom">10</property>
+ <property name="row_spacing">8</property>
+ <child>
+ <object class="GtkGrid" id="messageInfoGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">5</property>
+ <child>
+ <object class="GtkImage" id="messageInfoAccountImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="pixel_size">32</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="messageInfoLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_start">5</property>
+ <property name="hexpand">True</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFrame" id="messageTextViewFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="messageTextView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="pixels_above_lines">10</property>
+ <property name="wrap_mode">word-char</property>
+ <property name="left_margin">10</property>
+ <property name="right_margin">15</property>
+ <property name="input_hints">GTK_INPUT_HINT_SPELLCHECK |
GTK_INPUT_HINT_NONE</property>
+ </object>
+ </child>
+ <child type="label_item">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="messageOptionsGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkGrid" id="facebookOptionsGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">10</property>
+ <child>
+ <object class="GtkLabel" id="facebookOptionsPrivacyLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Visibility</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="facebookOptionsPrivacyComboBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">facebookOptionsPrivacyListStore</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText"
id="facebookOptionsPrivacyComboBoxCellRendererText"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="foursquareOptionsGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">8</property>
+ <child>
+ <object class="GtkGrid" id="foursquareOptionsPrivacyGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">10</property>
+ <child>
+ <object class="GtkLabel" id="foursquareOptionsPrivacyLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Visibility</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="foursquareOptionsPrivacyComboBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">foursquareOptionsPrivacyListStore</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText"
id="foursquareOptionsPrivacyComboBoxCellRendererText"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="foursquareOptionsBroadcastFacebookCheckButton">
+ <property name="label" translatable="yes">Post on Facebook</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="foursquareOptionsBroadcastTwitterCheckButton">
+ <property name="label" translatable="yes">Post on Twitter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">message</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="titlebar">
+ <object class="GtkHeaderBar" id="headerBar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="show-close-button">False</property>
+ <child>
+ <object class="GtkButton" id="cancelButton">
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="okButton">
+ <property name="label" translatable="yes">C_heck in</property>
+ <property name="visible">False</property>
+ <property name="can_focus">True</property>
+ <property name="use_underline">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="maps-check-in"/>
+ </style>
+ </template>
+ <object class="GtkListStore" id="facebookOptionsPrivacyListStore">
+ <columns>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">EVERYONE</col>
+ <col id="1" translatable="yes">Everyone</col>
+ </row>
+ <row>
+ <col id="0">FRIENDS_OF_FRIENDS</col>
+ <col id="1" translatable="yes">Friends of friends</col>
+ </row>
+ <row>
+ <col id="0">ALL_FRIENDS</col>
+ <col id="1" translatable="yes">Just friends</col>
+ </row>
+ <row>
+ <col id="0">SELF</col>
+ <col id="1" translatable="yes">Just me</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="foursquareOptionsPrivacyListStore">
+ <columns>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">public</col>
+ <col id="1" translatable="yes">Public</col>
+ </row>
+ <row>
+ <col id="0">followers</col>
+ <col id="1" translatable="yes">Followers</col>
+ </row>
+ <row>
+ <col id="0">private</col>
+ <col id="1" translatable="yes">Private</col>
+ </row>
+ </data>
+ </object>
+</interface>
diff --git a/src/checkIn.js b/src/checkIn.js
index 8d2ede3..88e9f0c 100644
--- a/src/checkIn.js
+++ b/src/checkIn.js
@@ -22,8 +22,11 @@
const GObject = imports.gi.GObject;
const Goa = imports.gi.Goa;
+const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
+const _ = imports.gettext.gettext;
+const CheckInDialog = imports.checkInDialog;
const FacebookBackend = imports.socialService.facebookBackend;
const FoursquareBackend = imports.socialService.foursquareBackend;
@@ -116,6 +119,44 @@ const CheckInManager = new Lang.Class({
findPlaces: function(account, latitude, longitude, distance, callback, cancellable) {
this._getBackend(account)
.findPlaces(this._getAuthorizer(account), latitude, longitude, distance, callback, cancellable);
+ },
+
+ showCheckInDialog: function(parentWindow, place, matchPlace) {
+ let dialog = new CheckInDialog.CheckInDialog({ transient_for: parentWindow,
+ matchPlace: matchPlace,
+ place: place });
+ let response = dialog.run();
+ dialog.destroy();
+
+ let message = null;
+
+ switch (response) {
+ case CheckInDialog.Response.FAILURE_NO_PLACES:
+ if (matchPlace)
+ /* Translators: %s is the place name that user wanted to check-in */
+ message = _("Cannot find \"%s\" in the social service").format(place.name);
+ else
+ message = _("Cannot find a suitable place to check-in in this location");
+ break;
+ case CheckInDialog.Response.FAILURE_GET_PLACES:
+ if (dialog.error.code === 401)
+ message = _("Credentials have expired, please open Online Accounts to sign in and enable
this account");
+ else
+ message = dialog.error.message;
+ break;
+ }
+
+ if (message) {
+ let messageDialog = new Gtk.MessageDialog({ transient_for: parentWindow,
+ destroy_with_parent: true,
+ message_type: Gtk.MessageType.ERROR,
+ buttons: Gtk.ButtonsType.OK,
+ modal: true,
+ text: _("An error has occurred"),
+ secondary_text: message });
+ messageDialog.run();
+ messageDialog.destroy();
+ }
}
});
diff --git a/src/checkInDialog.js b/src/checkInDialog.js
new file mode 100644
index 0000000..fe76689
--- /dev/null
+++ b/src/checkInDialog.js
@@ -0,0 +1,299 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+const _ = imports.gettext.gettext;
+
+const AccountListBox = imports.accountListBox;
+const Application = imports.application;
+const CheckIn = imports.checkIn;
+const SocialPlaceListBox = imports.socialPlaceListBox;
+const SocialPlaceMatcher = imports.socialPlaceMatcher;
+
+const Response = {
+ SUCCESS: 0,
+ CANCELLED: 1,
+ FAILURE_NO_PLACES: 2,
+ FAILURE_GET_PLACES: 3,
+ FAILURE_ACCOUNT_DISABLED: 4,
+ FAILURE_CHECKIN_DISABLED: 5
+};
+
+const CheckInDialog = new Lang.Class({
+ Name: 'CheckInDialog',
+ Extends: Gtk.Dialog,
+ Template: 'resource:///org/gnome/maps/check-in-dialog.ui',
+ InternalChildren: [ 'cancelButton',
+ 'okButton',
+ 'stack',
+ 'accountFrame',
+ 'placeScrolledWindow',
+ 'placeNotFoundInfoBar',
+ 'placeNotFoundLabel',
+ 'messageInfoLabel',
+ 'messageInfoAccountImage',
+ 'messageTextView',
+ 'facebookOptionsGrid',
+ 'facebookOptionsPrivacyComboBox',
+ 'foursquareOptionsGrid',
+ 'foursquareOptionsPrivacyComboBox',
+ 'foursquareOptionsBroadcastFacebookCheckButton',
+ 'foursquareOptionsBroadcastTwitterCheckButton' ],
+
+ _init: function(params) {
+ this._place = params.place;
+ delete params.place;
+
+ this._matchPlace = params.matchPlace;
+ delete params.matchPlace;
+
+ // This is a construct-only property and cannot be set by GtkBuilder
+ params.use_header_bar = true;
+
+ this.parent(params);
+
+ this._account = null;
+ this._checkIn = new CheckIn.CheckIn();
+ this.error = null;
+
+ this._cancellable = new Gio.Cancellable();
+ this._cancellable.connect((function() {
+ this.response(Response.CANCELLED);
+ }).bind(this));
+
+ this.connect('delete-event', (function() {
+ this._cancellable.cancel();
+ }).bind(this));
+
+ Application.checkInManager.connect('accounts-refreshed', this._onAccountRefreshed.bind(this));
+
+ this._initHeaderBar();
+ this._initWidgets();
+ },
+
+ _initHeaderBar: function() {
+ this._cancelButton.connect('clicked', (function() {
+ this._cancellable.cancel();
+ }).bind(this));
+
+ this._okButton.connect('clicked', (function() {
+ this._startCheckInStep();
+ }).bind(this));
+ },
+
+ _initWidgets: function() {
+ // Limitations in Gjs means we can't do this in UI files yet
+ this._accountListBox = new AccountListBox.AccountListBox({ visible: true });
+ this._accountFrame.add(this._accountListBox);
+
+ this._placeListBox = new SocialPlaceListBox.SocialPlaceListBox({ visible: true });
+ this._placeScrolledWindow.add(this._placeListBox);
+
+ Application.settings.bind('checkin-facebook-privacy',
+ this._facebookOptionsPrivacyComboBox,
+ 'active_id', Gio.SettingsBindFlags.DEFAULT);
+
+ Application.settings.bind('checkin-foursquare-privacy',
+ this._foursquareOptionsPrivacyComboBox,
+ 'active_id', Gio.SettingsBindFlags.DEFAULT);
+
+ Application.settings.bind('checkin-foursquare-broadcast-facebook',
+ this._foursquareOptionsBroadcastFacebookCheckButton,
+ 'active', Gio.SettingsBindFlags.DEFAULT);
+
+ Application.settings.bind('checkin-foursquare-broadcast-twitter',
+ this._foursquareOptionsBroadcastTwitterCheckButton,
+ 'active', Gio.SettingsBindFlags.DEFAULT);
+
+ this._accountListBox.connect('account-selected', (function(list, account) {
+ this._account = account;
+ this._startPlaceStep();
+ }).bind(this));
+
+ this._placeListBox.connect('place-selected', (function(list, place) {
+ this._checkIn.place = place;
+ this._startMessageStep();
+ }).bind(this));
+ },
+
+ vfunc_show: function() {
+ this._startup();
+ this.parent();
+ },
+
+ _startup: function() {
+ let accounts = Application.checkInManager.accounts;
+
+ if (accounts.length > 1)
+ this._startAccountStep();
+ else if (accounts.length === 1) {
+ this._account = Application.checkInManager.accounts[0];
+ this._startPlaceStep();
+ } else {
+ Mainloop.idle_add((function() {
+ this.response(Response.FAILURE_CHECKIN_DISABLED);
+ }).bind(this));
+ }
+ },
+
+ _onAccountRefreshed: function() {
+ let accounts = Application.checkInManager.accounts;
+
+ if (!Application.checkInManager.hasCheckIn)
+ this.response(Response.FAILURE_CHECKIN_DISABLED);
+ else if (this._account) {
+ for (let i in accounts) {
+ let account = accounts[i];
+ if (this._account.get_account().id === accounts[i].get_account().id)
+ return;
+ }
+
+ this.response(Response.FAILURE_ACCOUNT_DISABLED);
+ }
+ },
+
+ _startAccountStep: function() {
+ this.set_title(_("Select an account"));
+ this._stack.set_visible_child_name('account');
+ },
+
+ _startPlaceStep: function() {
+ this.set_title(_("Loading"));
+ this._stack.set_visible_child_name('loading');
+
+ Application.checkInManager.findPlaces(this._account,
+ this._place.location.latitude,
+ this._place.location.longitude,
+ 100,
+ this._onFindPlacesFinished.bind(this),
+ this._cancellable);
+ },
+
+ _onFindPlacesFinished: function(account, places, error) {
+ if (!error) {
+ if (places.length === 0) {
+ this.response(Response.FAILURE_NO_PLACES);
+ return;
+ }
+
+ let matches = SocialPlaceMatcher.match(this._place, places);
+
+ if (matches.exactMatches.length === 1 && this._matchPlace) {
+ this._checkIn.place = matches.exactMatches[0];
+ this._startMessageStep();
+ } else {
+ this.set_title(_("Select a place"));
+ this._placeListBox.matches = matches;
+
+ if (this._matchPlace) {
+ if (this._account.get_account().provider_type === 'facebook')
+ this._placeNotFoundLabel.label = _("Maps cannot find the place to check in to with
Facebook. Please select one from this list.");
+ else if (this._account.get_account().provider_type === 'foursquare')
+ this._placeNotFoundLabel.label = _("Maps cannot find the place to check in to with
Foursquare. Please select one from this list.");
+ } else
+ this._placeNotFoundInfoBar.hide();
+
+ this._stack.set_visible_child_name('place');
+ }
+ } else {
+ this.error = error;
+ this.response(Response.FAILURE_GET_PLACES);
+ }
+ },
+
+ _startMessageStep: function() {
+ /* Translators: %s is the name of the place to check in.
+ */
+ this.set_title(_("Check in to %s").format(this._checkIn.place.name));
+ this._stack.set_visible_child_name('message');
+
+ this._messageTextView.grab_focus();
+ this._okButton.show();
+
+ let account = this._account.get_account();
+
+ /* Translators: %s is the name of the place to check in.
+ */
+ let labelMessageInfo = _("Write an optional message to check in to %s.");
+ this._messageInfoLabel.label = labelMessageInfo.format('<a
href="%s">%s</a>'.format(this._checkIn.place.link,
+
this._checkIn.place.name));
+ this._messageInfoAccountImage.gicon = Gio.Icon.new_for_string(account.provider_icon);
+
+ let optionsGrids = { 'facebook': this._facebookOptionsGrid,
+ 'foursquare': this._foursquareOptionsGrid };
+
+ for (let provider in optionsGrids)
+ if (provider === account.provider_type)
+ optionsGrids[provider].show();
+ else
+ optionsGrids[provider].hide();
+ },
+
+ _startCheckInStep: function() {
+ this.set_title(_("Loading"));
+ this._stack.set_visible_child_name('loading');
+
+ this._okButton.hide();
+
+ let message = this._messageTextView.buffer.text;
+ let privacy;
+
+ if (this._account.get_account().provider_type === 'facebook')
+ privacy = this._facebookOptionsPrivacyComboBox.active_id;
+ else if (this._account.get_account().provider_type === 'foursquare')
+ privacy = this._foursquareOptionsPrivacyComboBox.active_id;
+
+ let broadcastFacebook = this._foursquareOptionsBroadcastFacebookCheckButton.active;
+ let broadcastTwitter = this._foursquareOptionsBroadcastTwitterCheckButton.active;
+
+ this._checkIn.message = message;
+ this._checkIn.privacy = privacy;
+ this._checkIn.broadcastFacebook = broadcastFacebook;
+ this._checkIn.broadcastTwitter = broadcastTwitter;
+
+ Application.checkInManager.performCheckIn(this._account,
+ this._checkIn,
+ this._onPerformCheckInFinished.bind(this),
+ this._cancellable);
+ },
+
+ _onPerformCheckInFinished: function (account, data, error) {
+ if (!error)
+ this.response(Response.SUCCESS);
+ else {
+ let messageDialog = new Gtk.MessageDialog({ transient_for: this,
+ destroy_with_parent: true,
+ message_type: Gtk.MessageType.ERROR,
+ buttons: Gtk.ButtonsType.OK,
+ modal: true,
+ text: _("An error has occurred"),
+ secondary_text: error.message });
+ messageDialog.run();
+ messageDialog.destroy();
+
+ this._startMessageStep();
+ }
+ }
+});
diff --git a/src/gnome-maps.data.gresource.xml b/src/gnome-maps.data.gresource.xml
index b19a625..9638968 100644
--- a/src/gnome-maps.data.gresource.xml
+++ b/src/gnome-maps.data.gresource.xml
@@ -17,6 +17,10 @@
<file preprocess="xml-stripblanks">search-result-bubble.ui</file>
<file preprocess="xml-stripblanks">share-dialog.ui</file>
<file preprocess="xml-stripblanks">user-location-bubble.ui</file>
+ <file preprocess="xml-stripblanks">check-in-dialog.ui</file>
+ <file preprocess="xml-stripblanks">account-row.ui</file>
+ <file preprocess="xml-stripblanks">social-place-row.ui</file>
+ <file preprocess="xml-stripblanks">social-place-more-results-row.ui</file>
<file alias="application.css">../data/gnome-maps.css</file>
<file alias="maptype-aerial.png">../data/media/maptype-aerial.png</file>
<file alias="maptype-street.png">../data/media/maptype-street.png</file>
diff --git a/src/gnome-maps.js.gresource.xml b/src/gnome-maps.js.gresource.xml
index 9d7c4bf..07ffff1 100644
--- a/src/gnome-maps.js.gresource.xml
+++ b/src/gnome-maps.js.gresource.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/maps">
+ <file>accountListBox.js</file>
<file>application.js</file>
<file>checkIn.js</file>
+ <file>checkInDialog.js</file>
<file>config.js</file>
<file>contextMenu.js</file>
<file>epaf.js</file>
@@ -38,6 +40,8 @@
<file>turnPointMarker.js</file>
<file>settings.js</file>
<file>sidebar.js</file>
+ <file>socialPlaceListBox.js</file>
+ <file>socialPlaceMatcher.js</file>
<file>userLocationMarker.js</file>
<file>userLocationBubble.js</file>
<file>socialService/facebookBackend.js</file>
diff --git a/src/social-place-more-results-row.ui b/src/social-place-more-results-row.ui
new file mode 100644
index 0000000..2dcca7f
--- /dev/null
+++ b/src/social-place-more-results-row.ui
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="Gjs_SocialPlaceMoreResultsRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="label" translatable="yes">Show more results</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_start">10</property>
+ <property name="margin_end">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <attributes>
+ <attribute name="foreground" value="#777777" />
+ </attributes>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/social-place-row.ui b/src/social-place-row.ui
new file mode 100644
index 0000000..623c92a
--- /dev/null
+++ b/src/social-place-row.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="Gjs_SocialPlaceRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">10</property>
+ <property name="margin_end">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <property name="row_spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="nameLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="wrap">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="categoryLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/socialPlaceListBox.js b/src/socialPlaceListBox.js
new file mode 100644
index 0000000..c9e744d
--- /dev/null
+++ b/src/socialPlaceListBox.js
@@ -0,0 +1,110 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+
+const SocialPlaceRow = new Lang.Class({
+ Name: 'SocialPlaceRow',
+ Extends: Gtk.ListBoxRow,
+ Template: 'resource:///org/gnome/maps/social-place-row.ui',
+ InternalChildren: [ 'nameLabel',
+ 'categoryLabel' ],
+
+ _init: function(params) {
+ this.place = params.place;
+ delete params.place;
+
+ this.parent(params);
+
+ this._nameLabel.label = this.place.name;
+ if (this.place.category)
+ this._categoryLabel.label = this.place.category;
+ else
+ this._categoryLabel.visible = false;
+ }
+});
+
+const SocialPlaceMoreResultsRow = new Lang.Class({
+ Name: 'SocialPlaceMoreResultsRow',
+ Extends: Gtk.ListBoxRow,
+ Template: 'resource:///org/gnome/maps/social-place-more-results-row.ui'
+});
+
+const SocialPlaceListBox = new Lang.Class({
+ Name: 'SocialPlaceListBox',
+ Extends: Gtk.ListBox,
+ Signals: {
+ 'place-selected': { param_types: [GObject.TYPE_OBJECT] }
+ },
+
+ _init: function(params) {
+ params.activate_on_single_click = true;
+ this.parent(params);
+
+ this.connect('row-activated', (function(list, row) {
+ if (!row.place) {
+ // "Show more results" row activated
+ row.destroy();
+ this._showBadMatches();
+ } else
+ this.emit('place-selected', row.place);
+ }).bind(this));
+ },
+
+ get matches() {
+ return this._matches;
+ },
+
+ set matches(matches) {
+ this.forall(function(row) {
+ row.destroy();
+ });
+
+ this._matches = matches;
+
+ if (this._matches.exactMatches.length +
+ this._matches.goodMatches.length === 0) {
+ this._showBadMatches();
+ } else {
+ this._matches.exactMatches.forEach(this._addPlace.bind(this));
+ this._matches.goodMatches.forEach(this._addPlace.bind(this));
+
+ if (this._matches.badMatches.length > 0)
+ this._addMoreResults();
+ }
+ },
+
+ _showBadMatches: function() {
+ this._matches.badMatches.forEach(this._addPlace.bind(this));
+ },
+
+ _addPlace: function(place) {
+ this.add(new SocialPlaceRow({ place: place }));
+ },
+
+ _addMoreResults: function() {
+ this.add(new SocialPlaceMoreResultsRow({}));
+ }
+});
diff --git a/src/socialPlaceMatcher.js b/src/socialPlaceMatcher.js
new file mode 100644
index 0000000..767d756
--- /dev/null
+++ b/src/socialPlaceMatcher.js
@@ -0,0 +1,126 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+/**
+ * The Levenshtein distance is a string comparison algorithm defined
+ * as the minimal number of characters you have to replace, insert or
+ * delete to transform string a into string b.
+ * We use it to compare the similarities of two place names.
+ *
+ * http://en.wikipedia.org/wiki/Levenshtein_distance
+ */
+function _getLevenshteinDistance(a, b) {
+ let i;
+ let j;
+ let d = [];
+
+ for (i = 0; i <= a.length; i++) {
+ d[i] = [];
+ for (j = 0; j <= b.length; j++)
+ d[i][j] = 0;
+ }
+
+ for (i = 1; i <= a.length; i++)
+ d[i][0] = i;
+
+ for (j = 1; j <= b.length; j++)
+ d[0][j] = j;
+
+ for (j = 1; j <= b.length; j++)
+ for (i = 1; i <= a.length; i++)
+ if (a[i] === b[j])
+ d[i][j] = d[i-1][j-1];
+ else
+ d[i][j] = Math.min(d[i-1][j] + 1,
+ d[i][j-1] + 1,
+ d[i-1][j-1] + 1);
+
+ return d[a.length][b.length];
+}
+
+function _normalize(name) {
+ return name.toLowerCase().trim().replace(/ +(?= )/g,'');
+}
+
+function _getPlacesLevenshteinDistance(geoPlace, socialPlace) {
+ let a = geoPlace.name;
+ let b = socialPlace.name;
+
+ return _getLevenshteinDistance(_normalize(a), _normalize(b));
+}
+
+/**
+ * Returns: 0 for bad match, 1 for good match and 2
+ * exact match.
+ */
+function _getKindOfMatch(geoPlace, socialPlace) {
+ let distance = geoPlace.location.get_distance_from(socialPlace.location);
+ let levenshtein = _getPlacesLevenshteinDistance(geoPlace, socialPlace);
+
+ if (distance < 0.01 && levenshtein <= 2)
+ return 2;
+ else if (distance < 0.03 && levenshtein <= 5)
+ return 1;
+ else
+ return 0;
+}
+
+function match(geoPlace, socialPlaces) {
+ let result = {
+ exactMatches: [],
+ goodMatches: [],
+ badMatches: []
+ };
+
+ socialPlaces.sort(function(a, b) {
+ let da = geoPlace.location.get_distance_from(a.location);
+ let db = geoPlace.location.get_distance_from(b.location);
+
+ if (da > db)
+ return 1;
+ else if (da < db)
+ return -1;
+
+ return 0;
+ });
+
+ socialPlaces.forEach(function(place) {
+ let match = _getKindOfMatch(geoPlace, place);
+
+ switch (match)
+ {
+ case 0:
+ result.badMatches.push(place);
+ break;
+
+ case 1:
+ result.goodMatches.push(place);
+ break;
+
+ case 2:
+ result.exactMatches.push(place);
+ break;
+ }
+ });
+
+ return result;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]