Emojis and gender flags for users

This commit is contained in:
Noah 2023-08-05 19:38:04 -07:00
parent 4fbf3e7d75
commit 52b1271591
6 changed files with 61 additions and 8 deletions

View File

@ -13,10 +13,12 @@ import (
// Custom JWT Claims. // Custom JWT Claims.
type Claims struct { type Claims struct {
// Custom claims. // Custom claims.
IsAdmin bool `json:"op"` IsAdmin bool `json:"op,omitempty"`
Avatar string `json:"img"` Avatar string `json:"img,omitempty"`
ProfileURL string `json:"url"` ProfileURL string `json:"url,omitempty"`
Nick string `json:"nick"` Nick string `json:"nick,omitempty"`
Emoji string `json:"emoji,omitempty"`
Gender string `json:"gender,omitempty"`
// Standard claims. Notes: // Standard claims. Notes:
// subject = username // subject = username

View File

@ -86,6 +86,8 @@ type WhoList struct {
Operator bool `json:"op"` Operator bool `json:"op"`
Avatar string `json:"avatar,omitempty"` Avatar string `json:"avatar,omitempty"`
ProfileURL string `json:"profileURL,omitempty"` ProfileURL string `json:"profileURL,omitempty"`
Emoji string `json:"emoji,omitempty"`
Gender string `json:"gender,omitempty"`
} }
// VideoFlags to convey the state and setting of users' cameras concisely. // VideoFlags to convey the state and setting of users' cameras concisely.

View File

@ -407,6 +407,8 @@ func (s *Server) SendWhoList() {
who.Avatar = user.JWTClaims.Avatar who.Avatar = user.JWTClaims.Avatar
who.ProfileURL = user.JWTClaims.ProfileURL who.ProfileURL = user.JWTClaims.ProfileURL
who.Nickname = user.JWTClaims.Nick who.Nickname = user.JWTClaims.Nick
who.Emoji = user.JWTClaims.Emoji
who.Gender = user.JWTClaims.Gender
} }
users = append(users, who) users = append(users, who)
} }

View File

@ -301,3 +301,14 @@ div.feed.popped-out {
background-color: rgba(255, 255, 255, 0.5); background-color: rgba(255, 255, 255, 0.5);
/* color: rgba(0, 0, 0, 0.5); */ /* color: rgba(0, 0, 0, 0.5); */
} }
/* Gender colors for profile icon */
.has-text-gender-male {
color: #0099ff !important;
}
.has-text-gender-female {
color: #ff99ff !important;
}
.has-text-gender-other {
color: #cc00cc !important;
}

View File

@ -432,6 +432,20 @@ const app = Vue.createApp({
return b.op - a.op; return b.op - a.op;
}); });
break; break;
case "emoji":
result.sort((a, b) => {
if (a.emoji === b.emoji) return 0;
return a.emoji < b.emoji ? -1 : 1;
})
break;
case "gender":
result.sort((a, b) => {
if (a.gender === b.gender) return 0;
let left = a.gender || 'z',
right = b.gender || 'z';
return left < right ? -1 : 1;
})
break;
case "z-a": case "z-a":
result = result.reverse(); result = result.reverse();
} }
@ -1865,6 +1879,19 @@ const app = Vue.createApp({
return `${(hour)}:${minutes} ${ampm}`; return `${(hour)}:${minutes} ${ampm}`;
}, },
// CSS classes for the profile button (color coded genders)
profileButtonClass(user) {
let gender = (user.gender || "").toLowerCase();
if (gender.indexOf("m") === 0) {
return "has-text-gender-male";
} else if (gender.indexOf("f") === 0) {
return "has-text-gender-female";
} else if (gender.length > 0) {
return "has-text-gender-other";
}
return "";
},
/** /**
* Image sharing in chat * Image sharing in chat
*/ */

View File

@ -990,6 +990,8 @@
<option value="broadcasting">Broadcasting</option> <option value="broadcasting">Broadcasting</option>
<option value="nsfw" v-show="config.permitNSFW">Red cameras</option> <option value="nsfw" v-show="config.permitNSFW">Red cameras</option>
<option value="status">Status</option> <option value="status">Status</option>
<option value="emoji">Emoji/country flag</option>
<option value="gender">Gender</option>
<option value="op">User level</option> <option value="op">User level</option>
</select> </select>
</div> </div>
@ -1036,18 +1038,25 @@
</div> </div>
<div class="column pr-0 is-clipped" <div class="column pr-0 is-clipped"
:class="{'pl-1': u.avatar}"> :class="{'pl-1': u.avatar}">
<i class="fa fa-gavel has-text-warning-dark" <strong class="truncate-text-line is-size-7">[[ u.username ]]</strong>
<sup class="fa fa-gavel has-text-warning-dark is-size-7 ml-1"
v-if="u.op" v-if="u.op"
title="Operator"></i> title="Operator"></sup>
<span class="truncate-text-line">[[ u.username ]]</span>
</div> </div>
<div class="column is-narrow pl-0"> <div class="column is-narrow pl-0">
<!-- Emoji icon -->
<span v-if="u.emoji" class="pr-1 cursor-default"
:title="u.emoji.indexOf(' ') > -1 ? u.emoji.split(' ')[1] : u.emoji">
[[ u.emoji.split(" ")[0] ]]
</span>
<!-- Profile button --> <!-- Profile button -->
<button type="button" <button type="button"
v-if="u.profileURL" v-if="u.profileURL"
class="button is-small px-2 py-1" class="button is-small px-2 py-1"
:class="profileButtonClass(u)"
@click="openProfile(u)" @click="openProfile(u)"
title="Open profile page"> :title="'Open profile page' + (u.gender ? ` (gender: ${u.gender})` : '')">
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
</button> </button>