diff --git a/pkg/handlers.go b/pkg/handlers.go index 149e655..690bfdf 100644 --- a/pkg/handlers.go +++ b/pkg/handlers.go @@ -453,6 +453,7 @@ func (s *Server) OnBlocklist(sub *Subscriber, msg messages.Message) { sub.muteMu.Lock() for _, username := range msg.Usernames { + sub.muted[username] = struct{}{} sub.blocked[username] = struct{}{} } diff --git a/pkg/websocket.go b/pkg/websocket.go index 59f909a..272e684 100644 --- a/pkg/websocket.go +++ b/pkg/websocket.go @@ -354,7 +354,7 @@ func (s *Server) Broadcast(msg messages.Message) { } // VIP channels: only deliver to subscribed VIP users. - if ch, ok := config.Current.GetChannel(msg.Channel); ok && ch.VIP && !sub.IsVIP() { + if ch, ok := config.Current.GetChannel(msg.Channel); ok && ch.VIP && !sub.IsVIP() && !sub.IsAdmin() { log.Debug("Do not broadcast message to %s: VIP channel and they are not VIP", sub.Username) continue } @@ -499,6 +499,11 @@ func (s *Subscriber) Blocks(other *Subscriber) bool { return false } + // If either side is an admin, blocking is not allowed. + if s.IsAdmin() || other.IsAdmin() { + return false + } + s.muteMu.RLock() defer s.muteMu.RUnlock() diff --git a/src/components/WhoListRow.vue b/src/components/WhoListRow.vue index e7b804d..7c2ad45 100644 --- a/src/components/WhoListRow.vue +++ b/src/components/WhoListRow.vue @@ -27,8 +27,9 @@ export default { return null; }, profileButtonClass() { - // VIP background. let result = ""; + + // VIP background. if (this.user.vip) { result = "has-background-vip "; } @@ -43,6 +44,43 @@ export default { } return ""; }, + videoButtonClass() { + let result = ""; + + // VIP background if their cam is set to VIPs only + if ((this.user.video & VideoFlag.Active) && (this.user.video & VideoFlag.VipOnly)) { + result = "has-background-vip "; + } + + // Colors and/or cursors. + if ((this.user.video & VideoFlag.Active) && (this.user.video & VideoFlag.NSFW)) { + result += "is-danger is-outlined"; + } else if ((this.user.video & VideoFlag.Active) && !(this.user.video & VideoFlag.NSFW)) { + result += "is-info is-outlined"; + } else if (this.isVideoNotAllowed) { + result += "cursor-notallowed"; + } + + return result; + }, + videoButtonTitle() { + // Mouse-over title text for the video button. + let parts = ["Open video stream"]; + + if (this.user.video & VideoFlag.MutualRequired) { + parts.push("mutual video sharing required"); + } + + if (this.user.video & VideoFlag.MutualOpen) { + parts.push("will auto-open your video"); + } + + if (this.user.video & VideoFlag.VipOnly) { + parts.push(`${this.vipConfig.Name} only`); + } + + return parts.join("; "); + }, avatarURL() { if (this.user.avatar) { return this.urlFor(this.user.avatar); @@ -179,13 +217,9 @@ export default {