Chat landing page: show online friends

face-detect
Noah Petherbridge 2023-10-08 13:35:11 -07:00
parent c9c89100f9
commit a16894a1b1
4 changed files with 100 additions and 2 deletions

View File

@ -150,12 +150,19 @@ func Landing() http.HandlerFunc {
return
}
// Get the ChatStatistics and select our friend names from it.
var (
stats = FilteredChatStatistics(currentUser)
friendsOnline = models.FilterFriendUsernames(currentUser, stats.Usernames)
)
var vars = map[string]interface{}{
"ChatAPI": strings.TrimSuffix(config.Current.BareRTC.URL, "/") + "/api/statistics",
"IsShyUser": isShy,
// Pre-populate the "who's online" widget from backend cache data
"ChatStatistics": FilteredChatStatistics(currentUser),
"ChatStatistics": stats,
"FriendsOnline": friendsOnline,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -127,6 +127,39 @@ func FilterFriendIDs(userIDs []uint64, friendIDs []uint64) []uint64 {
return filtered
}
// FilterFriendUsernames takes a list of usernames and returns only the ones who are your friends.
func FilterFriendUsernames(currentUser *User, usernames []string) []string {
var (
fs = []*Friend{}
userIDs = []uint64{}
userMap = map[uint64]string{}
result = []string{}
)
// Map usernames to user IDs.
users, err := GetUsersByUsernames(currentUser, usernames)
if err != nil {
log.Error("FilterFriendUsernames: GetUsersByUsernames: %s", err)
return result
}
for _, user := range users {
userIDs = append(userIDs, user.ID)
userMap[user.ID] = user.Username
}
if len(userIDs) == 0 {
return result
}
DB.Where("source_user_id = ? AND approved = ? AND target_user_id IN ?", currentUser.ID, true, userIDs).Find(&fs)
for _, row := range fs {
result = append(result, userMap[row.TargetUserID])
}
return result
}
// FriendIDsAreExplicit returns friend IDs who have opted-in for Explicit content,
// e.g. to notify only them when you uploaded a new Explicit photo so that non-explicit
// users don't need to see that notification.

View File

@ -124,6 +124,51 @@ func GetUsers(currentUser *User, userIDs []uint64) ([]*User, error) {
return users, nil
}
// GetUsersByUsernames queries for multiple usernames and returns users in the same order.
func GetUsersByUsernames(currentUser *User, usernames []string) ([]*User, error) {
// Map the usernames.
var (
usermap = map[string]*User{}
set = map[string]interface{}{}
distinct = []string{}
)
// Uniqueify usernames.
for _, name := range usernames {
if _, ok := set[name]; ok {
continue
}
set[name] = nil
distinct = append(distinct, name)
}
var (
users = []*User{}
result = (&User{}).Preload().Where("username IN ?", distinct).Find(&users)
)
if result.Error != nil {
return nil, result.Error
}
// Map users.
for _, user := range users {
usermap[user.Username] = user
}
// Inject relationships.
SetUserRelationships(currentUser, users)
// Re-order them per the original sequence.
var ordered = []*User{}
for _, name := range usernames {
if user, ok := usermap[name]; ok {
ordered = append(ordered, user)
}
}
return ordered, nil
}
// FindUser by username or email.
func FindUser(username string) (*User, error) {
if username == "" {

View File

@ -47,9 +47,22 @@
<a id="whoLink" href="#" style="visibility: hidden">Who?</a>
<span id="whoList" style="display: none"></span>
<!-- Friends online? -->
{{if .FriendsOnline}}
<div class="mt-2">
<i class="fa fa-user-group mr-1"></i>
<strong>{{len .FriendsOnline}} friend{{Pluralize (len .FriendsOnline)}}</strong>
{{Pluralize (len .FriendsOnline) "is" "are"}} currently online:
{{$FriendsOnline := .FriendsOnline}}
{{range $i, $name := .FriendsOnline -}}
{{- if $i -}}, {{end}}<a href="/u/{{ $name }}">{{ $name }}</a>
{{- end}}
</div>
{{end}}
<!-- Camera stats if active -->
<div id="cameraStats" style="display: none" class="mt-2">
<i class="fa fa-camera"></i>
<i class="fa fa-camera mr-1"></i>
<span id="cameraCount">0 people are on camera</span>
<span class="is-size-7">
(<i class="fa fa-video has-text-info"></i> <span id="cameraBlue" class="has-text-info">0</span> /