Tweaks to Who's Nearby
This commit is contained in:
parent
cc628afd44
commit
a785b093e7
|
@ -78,7 +78,8 @@ func Dashboard() http.HandlerFunc {
|
||||||
|
|
||||||
// Geolocation/Who's Nearby: if the current user uses GeoIP, update
|
// Geolocation/Who's Nearby: if the current user uses GeoIP, update
|
||||||
// their coordinates now.
|
// their coordinates now.
|
||||||
if err := models.RefreshGeoIP(currentUser.ID, r); err != nil {
|
myLocation, err := models.RefreshGeoIP(currentUser.ID, r)
|
||||||
|
if err != nil {
|
||||||
log.Error("RefreshGeoIP: %s", err)
|
log.Error("RefreshGeoIP: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +93,9 @@ func Dashboard() http.HandlerFunc {
|
||||||
"HasPublicPhoto": hasPublic,
|
"HasPublicPhoto": hasPublic,
|
||||||
|
|
||||||
"PhotoLikeMap": models.MapLikes(currentUser, "photos", photoIDs),
|
"PhotoLikeMap": models.MapLikes(currentUser, "photos", photoIDs),
|
||||||
|
|
||||||
|
// Who's Nearby stats.
|
||||||
|
"MyLocation": myLocation,
|
||||||
}
|
}
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/config"
|
"code.nonshy.com/nonshy/website/pkg/config"
|
||||||
|
"code.nonshy.com/nonshy/website/pkg/geoip"
|
||||||
|
"code.nonshy.com/nonshy/website/pkg/log"
|
||||||
"code.nonshy.com/nonshy/website/pkg/models"
|
"code.nonshy.com/nonshy/website/pkg/models"
|
||||||
"code.nonshy.com/nonshy/website/pkg/session"
|
"code.nonshy.com/nonshy/website/pkg/session"
|
||||||
"code.nonshy.com/nonshy/website/pkg/templates"
|
"code.nonshy.com/nonshy/website/pkg/templates"
|
||||||
|
@ -51,6 +53,13 @@ func Search() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Geolocation/Who's Nearby: if the current user uses GeoIP, update
|
||||||
|
// their coordinates now.
|
||||||
|
myLocation, err := models.RefreshGeoIP(currentUser.ID, r)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("RefreshGeoIP: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Sort options.
|
// Sort options.
|
||||||
for _, v := range sortWhitelist {
|
for _, v := range sortWhitelist {
|
||||||
if sort == v {
|
if sort == v {
|
||||||
|
@ -87,6 +96,9 @@ func Search() http.HandlerFunc {
|
||||||
session.FlashError(w, r, "Couldn't search users: %s", err)
|
session.FlashError(w, r, "Couldn't search users: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Who's Nearby feature, get some data.
|
||||||
|
insights, _ := geoip.GetRequestInsights(r)
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
var vars = map[string]interface{}{
|
||||||
"Users": users,
|
"Users": users,
|
||||||
"Pager": pager,
|
"Pager": pager,
|
||||||
|
@ -106,8 +118,9 @@ func Search() http.HandlerFunc {
|
||||||
"PhotoCountMap": models.MapPhotoCounts(users),
|
"PhotoCountMap": models.MapPhotoCounts(users),
|
||||||
|
|
||||||
// Current user's location setting.
|
// Current user's location setting.
|
||||||
"MyLocation": models.GetUserLocation(currentUser.ID),
|
"MyLocation": myLocation,
|
||||||
"DistanceMap": models.MapDistances(currentUser, users),
|
"GeoIPInsights": insights,
|
||||||
|
"DistanceMap": models.MapDistances(currentUser, users),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||||
|
|
|
@ -43,6 +43,16 @@ func (i Insights) String() string {
|
||||||
return strings.Join(parts, "; ")
|
return strings.Join(parts, "; ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Short prints a short summary string of the insights.
|
||||||
|
func (i Insights) Short() string {
|
||||||
|
var parts = []string{
|
||||||
|
i.CountryName,
|
||||||
|
strings.Join(i.Subdivisions, ", "),
|
||||||
|
i.City,
|
||||||
|
}
|
||||||
|
return strings.Join(parts, "; ")
|
||||||
|
}
|
||||||
|
|
||||||
// GetRequestInsights returns structured insights based on the current HTTP request.
|
// GetRequestInsights returns structured insights based on the current HTTP request.
|
||||||
func GetRequestInsights(r *http.Request) (Insights, error) {
|
func GetRequestInsights(r *http.Request) (Insights, error) {
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -47,18 +47,18 @@ func (ul *UserLocation) Save() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshGeoIP will auto-update a user's location by GeoIP if that's their setting.
|
// RefreshGeoIP will auto-update a user's location by GeoIP if that's their setting.
|
||||||
func RefreshGeoIP(userID uint64, r *http.Request) error {
|
func RefreshGeoIP(userID uint64, r *http.Request) (*UserLocation, error) {
|
||||||
loc := GetUserLocation(userID)
|
loc := GetUserLocation(userID)
|
||||||
if loc.Source == LocationSourceGeoIP {
|
if loc.Source == LocationSourceGeoIP {
|
||||||
if insights, err := geoip.GetRequestInsights(r); err == nil {
|
if insights, err := geoip.GetRequestInsights(r); err == nil {
|
||||||
loc.Latitude = insights.Latitude
|
loc.Latitude = insights.Latitude
|
||||||
loc.Longitude = insights.Longitude
|
loc.Longitude = insights.Longitude
|
||||||
return loc.Save()
|
return loc, loc.Save()
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("didn't get insights: %s", err)
|
return loc, fmt.Errorf("didn't get insights: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return loc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapDistances computes human readable distances between you and the set of users.
|
// MapDistances computes human readable distances between you and the set of users.
|
||||||
|
|
|
@ -133,6 +133,45 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
<!-- New Feature: Who's Nearby -->
|
||||||
|
{{if not .MyLocation.Source}}
|
||||||
|
<div class="card block">
|
||||||
|
<header class="card-header has-background-success-dark">
|
||||||
|
<p class="card-header-title has-text-light">
|
||||||
|
<i class="fa fa-gift mr-2"></i>
|
||||||
|
New Feature: Who's Nearby?
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="block">
|
||||||
|
We've recently added a new feature! <strong>Who's Nearby</strong> can allow you to sort the
|
||||||
|
<a href="/members">Member Directory</a> by their distance away from you.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block">
|
||||||
|
First, you'll need to opt-in where <em>your</em> location is so that the site can know who's
|
||||||
|
nearby. Please visit your <a href="/settings#location">Location Settings</a> page to choose
|
||||||
|
how you share your location -- you can even just drop a pin on a map anywhere you're comfortable
|
||||||
|
with!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block">
|
||||||
|
Then, you'll be able to <a href="/members?sort=distance">sort the Member Directory by distance</a>.
|
||||||
|
Only people whose location is known will show in the results.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block">
|
||||||
|
This feature is very privacy-conscious and you can turn it off again later, and we'll forget
|
||||||
|
any location data we had! For more information, see <a href="https://www.nonshy.com/forum/thread/161">this forum thread</a>.
|
||||||
|
This message will go away after you have set a <a href="/settings#location">location source</a>
|
||||||
|
for your profile -- or after a few weeks when enough people have had a chance to hear about
|
||||||
|
the new feature!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<div class="card block">
|
<div class="card block">
|
||||||
<header class="card-header has-background-link">
|
<header class="card-header has-background-link">
|
||||||
<p class="card-header-title has-text-light">My Account</p>
|
<p class="card-header-title has-text-light">My Account</p>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="hero-body">
|
<div class="hero-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">
|
<h1 class="title">
|
||||||
{{if eq .Pager.Sort "distance"}}
|
{{if eq .Sort "distance"}}
|
||||||
<i class="fa fa-location-dot mr-2"></i>
|
<i class="fa fa-location-dot mr-2"></i>
|
||||||
Who's Nearby
|
Who's Nearby
|
||||||
{{else}}
|
{{else}}
|
||||||
|
@ -41,7 +41,18 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="notification is-success is-light">
|
<div class="notification is-success is-light">
|
||||||
Showing you <strong>Who's Nearby.</strong>
|
Showing you <strong>Who's Nearby.</strong>
|
||||||
<a href="/settings#location">Update your location?</a>
|
|
||||||
|
<!-- Show options to refresh their location -->
|
||||||
|
{{if eq .MyLocation.Source "geoip"}}
|
||||||
|
You set your location automatically by your IP address <small>(currently {{.GeoIPInsights.Short}}).</small>
|
||||||
|
<a href="/settings#location">Update settings?</a>
|
||||||
|
{{else if eq .MyLocation.Source "gps"}}
|
||||||
|
Your location was set by your GPS location.
|
||||||
|
<a href="/settings#location" id="gpsRefresh">Refresh your location now?</a>
|
||||||
|
{{else if eq .MyLocation.Source "pin"}}
|
||||||
|
You set your location by pin on a map.
|
||||||
|
<a href="/settings#location">Update your location?</a>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -426,6 +426,12 @@
|
||||||
feature and you have your choice of options how you want your location to be found.
|
feature and you have your choice of options how you want your location to be found.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="notification is-info is-light py-2 px-3">
|
||||||
|
<i class="fa fa-exclamation-triangle"></i>
|
||||||
|
<strong>Notice:</strong>
|
||||||
|
Remember to click "Save" after setting your location preference!
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">How do you want your location to be determined?</label>
|
<label class="label">How do you want your location to be determined?</label>
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
|
@ -525,7 +531,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<button type="submit" class="button is-success"
|
<button type="submit" class="button is-success mr-2"
|
||||||
name="intent" value="location">
|
name="intent" value="location">
|
||||||
Save My Location Settings
|
Save My Location Settings
|
||||||
</button>
|
</button>
|
||||||
|
@ -799,6 +805,11 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||||
getLocation();
|
getLocation();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If the page loaded w/ the GPS option on, ask right away.
|
||||||
|
if ($optionGPS.checked) {
|
||||||
|
$optionGPS.click();
|
||||||
|
}
|
||||||
|
|
||||||
// Wire the refresh button.
|
// Wire the refresh button.
|
||||||
$gpsRefreshButton.addEventListener("click", (e) => {
|
$gpsRefreshButton.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -809,6 +820,12 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||||
$optionGeoIP.addEventListener("click", (e) => {
|
$optionGeoIP.addEventListener("click", (e) => {
|
||||||
// Set the form fields.
|
// Set the form fields.
|
||||||
// NOTE: defaultCoords are [lon, lat] we want [lat, lon]
|
// NOTE: defaultCoords are [lon, lat] we want [lat, lon]
|
||||||
|
if (geoIPInsights.Latitude != 0 || geoIPInsights.Longitude != 0) {
|
||||||
|
defaultCoords = [
|
||||||
|
geoIPInsights.Longitude,
|
||||||
|
geoIPInsights.Latitude,
|
||||||
|
];
|
||||||
|
}
|
||||||
saveCoords(defaultCoords[1], defaultCoords[0]);
|
saveCoords(defaultCoords[1], defaultCoords[0]);
|
||||||
|
|
||||||
if (setMapPin !== null) {
|
if (setMapPin !== null) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user