Tweaks to Who's Nearby

This commit is contained in:
Noah Petherbridge 2023-08-19 21:09:23 -07:00
parent cc628afd44
commit a785b093e7
7 changed files with 104 additions and 10 deletions

View File

@ -78,7 +78,8 @@ func Dashboard() http.HandlerFunc {
// Geolocation/Who's Nearby: if the current user uses GeoIP, update
// 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)
}
@ -92,6 +93,9 @@ func Dashboard() http.HandlerFunc {
"HasPublicPhoto": hasPublic,
"PhotoLikeMap": models.MapLikes(currentUser, "photos", photoIDs),
// Who's Nearby stats.
"MyLocation": myLocation,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -5,6 +5,8 @@ import (
"strconv"
"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/session"
"code.nonshy.com/nonshy/website/pkg/templates"
@ -51,6 +53,13 @@ func Search() http.HandlerFunc {
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.
for _, v := range sortWhitelist {
if sort == v {
@ -87,6 +96,9 @@ func Search() http.HandlerFunc {
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{}{
"Users": users,
"Pager": pager,
@ -106,8 +118,9 @@ func Search() http.HandlerFunc {
"PhotoCountMap": models.MapPhotoCounts(users),
// Current user's location setting.
"MyLocation": models.GetUserLocation(currentUser.ID),
"DistanceMap": models.MapDistances(currentUser, users),
"MyLocation": myLocation,
"GeoIPInsights": insights,
"DistanceMap": models.MapDistances(currentUser, users),
}
if err := tmpl.Execute(w, r, vars); err != nil {

View File

@ -43,6 +43,16 @@ func (i Insights) String() string {
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.
func GetRequestInsights(r *http.Request) (Insights, error) {
var (

View File

@ -47,18 +47,18 @@ func (ul *UserLocation) Save() error {
}
// 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)
if loc.Source == LocationSourceGeoIP {
if insights, err := geoip.GetRequestInsights(r); err == nil {
loc.Latitude = insights.Latitude
loc.Longitude = insights.Longitude
return loc.Save()
return loc, loc.Save()
} 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.

View File

@ -133,6 +133,45 @@
</div>
{{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">
<header class="card-header has-background-link">
<p class="card-header-title has-text-light">My Account</p>

View File

@ -6,7 +6,7 @@
<div class="hero-body">
<div class="container">
<h1 class="title">
{{if eq .Pager.Sort "distance"}}
{{if eq .Sort "distance"}}
<i class="fa fa-location-dot mr-2"></i>
Who's Nearby
{{else}}
@ -41,7 +41,18 @@
{{else}}
<div class="notification is-success is-light">
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>
{{end}}

View File

@ -426,6 +426,12 @@
feature and you have your choice of options how you want your location to be found.
</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">
<label class="label">How do you want your location to be determined?</label>
<label class="checkbox">
@ -525,7 +531,7 @@
</div>
<div class="field">
<button type="submit" class="button is-success"
<button type="submit" class="button is-success mr-2"
name="intent" value="location">
Save My Location Settings
</button>
@ -799,6 +805,11 @@ window.addEventListener("DOMContentLoaded", (event) => {
getLocation();
});
// If the page loaded w/ the GPS option on, ask right away.
if ($optionGPS.checked) {
$optionGPS.click();
}
// Wire the refresh button.
$gpsRefreshButton.addEventListener("click", (e) => {
e.preventDefault();
@ -809,6 +820,12 @@ window.addEventListener("DOMContentLoaded", (event) => {
$optionGeoIP.addEventListener("click", (e) => {
// Set the form fields.
// 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]);
if (setMapPin !== null) {