Kick off conflicting usernames + Frontend mobile fixes
* When JWT tokens are used to join the chat and the username conflicts: instead of renaming the new user to add a "2" it will disconnect the original login (sending a message that they have signed in somewhere else and are logged out now) * When disconnected the text entry box will be greyed out. * Improvements for the mobile user experience: if you're viewing the chat history panel and have unread messages or DMs, a number indicator appears on the channels button. It is grey for public channel messages or red if any of them are DMs * Fix the emoji picker drop-down on the first messages of a DM thread
This commit is contained in:
parent
6724792ba0
commit
75c7511410
|
@ -51,7 +51,25 @@ func (s *Server) OnLogin(sub *Subscriber, msg Message) {
|
|||
}
|
||||
|
||||
// Ensure the username is unique, or rename it.
|
||||
msg.Username = s.UniqueUsername(msg.Username)
|
||||
username, err := s.UniqueUsername(msg.Username)
|
||||
if err != nil {
|
||||
// If JWT authentication was used: disconnect the original (conflicting) username.
|
||||
if claims.Subject == msg.Username {
|
||||
if other, err := s.GetSubscriber(msg.Username); err == nil {
|
||||
other.ChatServer("You have been signed out of chat because you logged in from another location.")
|
||||
other.SendJSON(Message{
|
||||
Action: ActionKick,
|
||||
})
|
||||
s.DeleteSubscriber(other)
|
||||
}
|
||||
|
||||
// They will take over their original username.
|
||||
username = msg.Username
|
||||
}
|
||||
|
||||
// If JWT auth was not used: UniqueUsername already gave them a uniquely spelled name.
|
||||
}
|
||||
msg.Username = username
|
||||
|
||||
// Use their username.
|
||||
sub.Username = msg.Username
|
||||
|
|
|
@ -275,8 +275,8 @@ func (s *Server) IterSubscribers(isLocked ...bool) []*Subscriber {
|
|||
return result
|
||||
}
|
||||
|
||||
// UniqueUsername ensures a username will be unique or renames it.
|
||||
func (s *Server) UniqueUsername(username string) string {
|
||||
// UniqueUsername ensures a username will be unique or renames it. If the name is already unique, the error result is nil.
|
||||
func (s *Server) UniqueUsername(username string) (string, error) {
|
||||
var (
|
||||
subs = s.IterSubscribers()
|
||||
usernames = map[string]interface{}{}
|
||||
|
@ -297,7 +297,11 @@ func (s *Server) UniqueUsername(username string) string {
|
|||
}
|
||||
}
|
||||
|
||||
return username
|
||||
if username != origUsername {
|
||||
return username, errors.New("username was not unique and a unique name has been returned")
|
||||
}
|
||||
|
||||
return username, nil
|
||||
}
|
||||
|
||||
// Broadcast a message to the chat room.
|
||||
|
|
|
@ -975,6 +975,23 @@ const app = Vue.createApp({
|
|||
}
|
||||
return this.channels[channel].unread;
|
||||
},
|
||||
hasAnyUnread() {
|
||||
// Returns total unread count (for mobile responsive view to show in the left drawer button)
|
||||
let count = 0;
|
||||
for (let channel of Object.keys(this.channels)) {
|
||||
count += this.channels[channel].unread;
|
||||
}
|
||||
return count;
|
||||
},
|
||||
anyUnreadDMs() {
|
||||
// Returns true if any unread messages are DM threads
|
||||
for (let channel of Object.keys(this.channels)) {
|
||||
if (channel.indexOf("@") === 0 && this.channels[channel].unread > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
openDMs(user) {
|
||||
let channel = "@" + user.username;
|
||||
this.initHistory(channel);
|
||||
|
|
|
@ -503,7 +503,7 @@
|
|||
<div class="columns is-mobile card-header-title has-text-light">
|
||||
<div class="column is-narrow mobile-only">
|
||||
<button type="button"
|
||||
class="button is-success"
|
||||
class="button is-success px-2"
|
||||
@click="openChatPanel">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
</button>
|
||||
|
@ -525,7 +525,7 @@
|
|||
:class="{'is-active': c.ID == channel}">
|
||||
[[c.Name]]
|
||||
<span v-if="hasUnread(c.ID)"
|
||||
class="tag is-danger">
|
||||
class="tag">
|
||||
[[hasUnread(c.ID)]]
|
||||
</span>
|
||||
</a>
|
||||
|
@ -581,11 +581,16 @@
|
|||
<div class="column is-narrow mobile-only pr-0">
|
||||
<!-- Responsive mobile button to pan to Left Column -->
|
||||
<button type="button"
|
||||
class="button is-success"
|
||||
:class="{'is-small': isDM}"
|
||||
class="button is-success px-2"
|
||||
@click="openChannelsPanel">
|
||||
<i v-if="isDM" class="fa fa-arrow-left"></i>
|
||||
<i v-else class="fa fa-message"></i>
|
||||
<i v-else class="fa fa-comments"></i>
|
||||
|
||||
<!-- Indicator badge for unread messages -->
|
||||
<span v-if="hasAnyUnread() > 0"
|
||||
class="tag ml-1" :class="{'is-danger': anyUnreadDMs()}">
|
||||
[[hasAnyUnread()]]
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
|
@ -613,7 +618,7 @@
|
|||
<div v-if="!isDM" class="column is-narrow mobile-only">
|
||||
<!-- Responsive mobile button to pan to Right Column -->
|
||||
<button type="button"
|
||||
class="button is-success"
|
||||
class="button is-success px-2"
|
||||
@click="openWhoPanel">
|
||||
<i class="fa fa-user-group"></i>
|
||||
</button>
|
||||
|
@ -881,7 +886,9 @@
|
|||
</div>
|
||||
|
||||
<!-- Emoji reactions menu -->
|
||||
<div v-if="msg.msgID" class="dropdown is-up is-right emoji-button" onclick="this.classList.toggle('is-active')">
|
||||
<div v-if="msg.msgID" class="dropdown is-right emoji-button"
|
||||
:class="{'is-up': i >= 2}"
|
||||
onclick="this.classList.toggle('is-active')">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-small px-2" aria-haspopup="true" :aria-controls="`react-menu-${msg.msgID}`">
|
||||
<span>
|
||||
|
@ -956,7 +963,8 @@
|
|||
<input type="text" class="input"
|
||||
v-model="message"
|
||||
placeholder="Message"
|
||||
@keydown="sendTypingNotification()">
|
||||
@keydown="sendTypingNotification()"
|
||||
:disabled="!ws.connected">
|
||||
</form>
|
||||
</div>
|
||||
<div class="column pl-1 is-narrow">
|
||||
|
@ -979,7 +987,7 @@
|
|||
<div class="column">Who Is Online</div>
|
||||
<div class="column is-narrow mobile-only">
|
||||
<button type="button"
|
||||
class="button is-success"
|
||||
class="button is-success px-2"
|
||||
@click="openChatPanel">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
</button>
|
||||
|
|
Loading…
Reference in New Issue
Block a user