Ability to ignore friend requests
This commit is contained in:
parent
61c47c032d
commit
a97ed4562e
|
@ -4,6 +4,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"code.nonshy.com/nonshy/website/pkg/config"
|
||||
"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"
|
||||
|
@ -17,6 +18,7 @@ func Friends() http.HandlerFunc {
|
|||
view = r.FormValue("view")
|
||||
isRequests = view == "requests"
|
||||
isPending = view == "pending"
|
||||
isIgnored = view == "ignored"
|
||||
)
|
||||
|
||||
currentUser, err := session.CurrentUser(r)
|
||||
|
@ -32,7 +34,7 @@ func Friends() http.HandlerFunc {
|
|||
Sort: "updated_at desc",
|
||||
}
|
||||
pager.ParsePage(r)
|
||||
friends, err := models.PaginateFriends(currentUser, isRequests, isPending, pager)
|
||||
friends, err := models.PaginateFriends(currentUser, isRequests, isPending, isIgnored, pager)
|
||||
if err != nil {
|
||||
session.FlashError(w, r, "Couldn't paginate friends: %s", err)
|
||||
templates.Redirect(w, "/")
|
||||
|
@ -42,10 +44,18 @@ func Friends() http.HandlerFunc {
|
|||
// Inject relationship booleans.
|
||||
models.SetUserRelationships(currentUser, friends)
|
||||
|
||||
// Ignored friend request count.
|
||||
ignoredFriendCount, err := models.CountIgnoredFriendRequests(currentUser.ID)
|
||||
if err != nil {
|
||||
log.Error("Ignored Friend Request Count (%s): %s", currentUser.Username, err)
|
||||
}
|
||||
|
||||
var vars = map[string]interface{}{
|
||||
"IsRequests": isRequests,
|
||||
"IsPending": isPending,
|
||||
"IsIgnored": isIgnored,
|
||||
"Friends": friends,
|
||||
"IgnoredFriendCount": ignoredFriendCount,
|
||||
"Pager": pager,
|
||||
}
|
||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||
|
|
|
@ -71,6 +71,15 @@ func AddFriend() http.HandlerFunc {
|
|||
templates.Redirect(w, "/friends?view=requests")
|
||||
}
|
||||
templates.Redirect(w, "/friends")
|
||||
return
|
||||
} else if verdict == "ignore" {
|
||||
if err := models.IgnoreFriendRequest(currentUser, user); err != nil {
|
||||
session.FlashError(w, r, "Error marking the friend request as ignored: %s", err)
|
||||
} else {
|
||||
session.Flash(w, r, "You have ignored the friend request from %s.", username)
|
||||
}
|
||||
templates.Redirect(w, "/friends")
|
||||
return
|
||||
} else {
|
||||
// Post the friend request.
|
||||
if err := models.AddFriend(currentUser.ID, user.ID); err != nil {
|
||||
|
|
|
@ -44,14 +44,6 @@ func SiteGallery() http.HandlerFunc {
|
|||
sort = sortWhitelist[0]
|
||||
}
|
||||
|
||||
// Defaults.
|
||||
if viewStyle != "full" {
|
||||
viewStyle = "cards"
|
||||
}
|
||||
if who != "friends" && who != "everybody" {
|
||||
who = "friends"
|
||||
}
|
||||
|
||||
// Load the current user.
|
||||
currentUser, err := session.CurrentUser(r)
|
||||
if err != nil {
|
||||
|
@ -59,7 +51,23 @@ func SiteGallery() http.HandlerFunc {
|
|||
}
|
||||
|
||||
// Is the current viewer shy?
|
||||
var isShy = currentUser.IsShy()
|
||||
var (
|
||||
isShy = currentUser.IsShy()
|
||||
myFriendCount = models.CountFriends(currentUser.ID)
|
||||
)
|
||||
|
||||
// Defaults.
|
||||
if viewStyle != "full" {
|
||||
viewStyle = "cards"
|
||||
}
|
||||
if who != "friends" && who != "everybody" {
|
||||
// Default Who setting should be Friends-only, unless you have no friends.
|
||||
if myFriendCount > 0 {
|
||||
who = "friends"
|
||||
} else {
|
||||
who = "everybody"
|
||||
}
|
||||
}
|
||||
|
||||
// Admin scope warning.
|
||||
if adminView && !currentUser.HasAdminScope(config.ScopePhotoModerator) {
|
||||
|
|
|
@ -15,6 +15,7 @@ type Friend struct {
|
|||
SourceUserID uint64 `gorm:"index"`
|
||||
TargetUserID uint64 `gorm:"index"`
|
||||
Approved bool `gorm:"index"`
|
||||
Ignored bool
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
@ -39,6 +40,7 @@ func AddFriend(sourceUserID, targetUserID uint64) error {
|
|||
if reverse == nil && forward != nil {
|
||||
// Approve the reverse.
|
||||
rev.Approved = true
|
||||
rev.Ignored = false
|
||||
rev.Save()
|
||||
|
||||
// Add the matching forward.
|
||||
|
@ -46,6 +48,7 @@ func AddFriend(sourceUserID, targetUserID uint64) error {
|
|||
SourceUserID: sourceUserID,
|
||||
TargetUserID: targetUserID,
|
||||
Approved: true,
|
||||
Ignored: false,
|
||||
}
|
||||
return DB.Create(f).Error
|
||||
}
|
||||
|
@ -240,13 +243,25 @@ func FriendIDsInCircleAreExplicit(userId uint64) []uint64 {
|
|||
func CountFriendRequests(userID uint64) (int64, error) {
|
||||
var count int64
|
||||
result := DB.Where(
|
||||
"target_user_id = ? AND approved = ?",
|
||||
"target_user_id = ? AND approved = ? AND ignored IS NOT true",
|
||||
userID,
|
||||
false,
|
||||
).Model(&Friend{}).Count(&count)
|
||||
return count, result.Error
|
||||
}
|
||||
|
||||
// CountIgnoredFriendRequests gets a count of ignored pending friend requests for the user.
|
||||
func CountIgnoredFriendRequests(userID uint64) (int64, error) {
|
||||
var count int64
|
||||
result := DB.Where(
|
||||
"target_user_id = ? AND approved = ? AND ignored = ?",
|
||||
userID,
|
||||
false,
|
||||
true,
|
||||
).Model(&Friend{}).Count(&count)
|
||||
return count, result.Error
|
||||
}
|
||||
|
||||
// CountFriends gets a count of friends for the user.
|
||||
func CountFriends(userID uint64) int64 {
|
||||
var count int64
|
||||
|
@ -269,7 +284,7 @@ The `requests` and `sent` bools are mutually exclusive (use only one, or neither
|
|||
asks for unanswered friend requests to you, and `sent` returns the friend requests that you
|
||||
have sent and have not been answered.
|
||||
*/
|
||||
func PaginateFriends(user *User, requests bool, sent bool, pager *Pagination) ([]*User, error) {
|
||||
func PaginateFriends(user *User, requests bool, sent bool, ignored bool, pager *Pagination) ([]*User, error) {
|
||||
// We paginate over the Friend table.
|
||||
var (
|
||||
fs = []*Friend{}
|
||||
|
@ -277,20 +292,25 @@ func PaginateFriends(user *User, requests bool, sent bool, pager *Pagination) ([
|
|||
query *gorm.DB
|
||||
)
|
||||
|
||||
if requests && sent {
|
||||
if requests && sent && ignored {
|
||||
return nil, errors.New("requests and sent are mutually exclusive options, use one or neither")
|
||||
}
|
||||
|
||||
if requests {
|
||||
query = DB.Where(
|
||||
"target_user_id = ? AND approved = ?",
|
||||
"target_user_id = ? AND approved = ? AND ignored IS NOT true",
|
||||
user.ID, false,
|
||||
)
|
||||
} else if sent {
|
||||
query = DB.Where(
|
||||
"source_user_id = ? AND approved = ?",
|
||||
"source_user_id = ? AND approved = ? AND ignored IS NOT true",
|
||||
user.ID, false,
|
||||
)
|
||||
} else if ignored {
|
||||
query = DB.Where(
|
||||
"target_user_id = ? AND approved = ? AND ignored = ?",
|
||||
user.ID, false, true,
|
||||
)
|
||||
} else {
|
||||
query = DB.Where(
|
||||
"source_user_id = ? AND approved = ?",
|
||||
|
@ -307,7 +327,7 @@ func PaginateFriends(user *User, requests bool, sent bool, pager *Pagination) ([
|
|||
|
||||
// Now of these friends get their User objects.
|
||||
for _, friend := range fs {
|
||||
if requests {
|
||||
if requests || ignored {
|
||||
userIDs = append(userIDs, friend.SourceUserID)
|
||||
} else {
|
||||
userIDs = append(userIDs, friend.TargetUserID)
|
||||
|
@ -384,6 +404,28 @@ func GetFriendRequests(userID uint64) ([]*Friend, error) {
|
|||
return fs, result.Error
|
||||
}
|
||||
|
||||
// IgnoreFriendRequest ignores a pending friend request that was sent to targetUserID.
|
||||
func IgnoreFriendRequest(currentUser *User, fromUser *User) error {
|
||||
// Is there a reverse friend request pending? (The one we ideally hope to mark Ignored)
|
||||
rev := &Friend{}
|
||||
reverse := DB.Where(
|
||||
"source_user_id = ? AND target_user_id = ?",
|
||||
fromUser.ID, currentUser.ID,
|
||||
).First(&rev).Error
|
||||
|
||||
// If the reverse exists (requested us) mark it as Ignored.
|
||||
if reverse == nil {
|
||||
// Ignore the reverse friend request (happy path).
|
||||
log.Error("%s ignoring friend request from %s", currentUser.Username, fromUser.Username)
|
||||
rev.Approved = false
|
||||
rev.Ignored = true
|
||||
return rev.Save()
|
||||
}
|
||||
|
||||
log.Error("rev: %+v", rev)
|
||||
return errors.New("unexpected error while ignoring friend request")
|
||||
}
|
||||
|
||||
// RemoveFriend severs a friend connection both directions, used when
|
||||
// rejecting a request or removing a friend.
|
||||
func RemoveFriend(sourceUserID, targetUserID uint64) error {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<div class="level-item">
|
||||
<div class="tabs is-toggle">
|
||||
<ul>
|
||||
<li{{if and (not .IsRequests) (not .IsPending)}} class="is-active"{{end}}>
|
||||
<li{{if and (not .IsRequests) (not .IsPending) (not .IsIgnored)}} class="is-active"{{end}}>
|
||||
<a href="/friends">My Friends</a>
|
||||
</li>
|
||||
<li{{if .IsRequests}} class="is-active"{{end}}>
|
||||
|
@ -32,6 +32,12 @@
|
|||
Sent
|
||||
</a>
|
||||
</li>
|
||||
<li{{if .IsIgnored}} class="is-active"{{end}}>
|
||||
<a href="/friends?view=ignored">
|
||||
Ignored
|
||||
{{if .IgnoredFriendCount}}<span class="tag ml-2">{{.IgnoredFriendCount}}</span>{{end}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,6 +58,7 @@
|
|||
{{Pluralize64 .Pager.Total "has" "have"}} not been approved yet.
|
||||
{{else}}
|
||||
You have {{.Pager.Total}} friend{{if .IsRequests}} request{{end}}{{Pluralize64 .Pager.Total}}
|
||||
{{if .IsIgnored}} on ignore -- they don't know you ignored their request and they can not send another one.{{end}}
|
||||
(page {{.Pager.Page}} of {{.Pager.Pages}}).
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -108,7 +115,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if $Root.IsRequests}}
|
||||
{{if or $Root.IsRequests $Root.IsIgnored}}
|
||||
<footer class="card-footer">
|
||||
<button type="submit" name="verdict" value="approve" class="card-footer-item button is-success">
|
||||
<span class="icon"><i class="fa fa-check"></i></span>
|
||||
|
@ -118,6 +125,12 @@
|
|||
<span class="icon"><i class="fa fa-xmark"></i></span>
|
||||
<span>Reject</span>
|
||||
</button>
|
||||
{{if not $Root.IsIgnored}}
|
||||
<button type="submit" name="verdict" value="ignore" class="card-footer-item button">
|
||||
<span class="icon"><i class="fa fa-moon"></i></span>
|
||||
<span>Ignore</span>
|
||||
</button>
|
||||
{{end}}
|
||||
</footer>
|
||||
{{else}}
|
||||
<footer class="card-footer">
|
||||
|
|
Loading…
Reference in New Issue
Block a user