From 34e7690c387c41e0ccc378fa8fabadcd4a6217e2 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 13 Nov 2018 14:14:02 -0600 Subject: [PATCH] fix(usernames): various Disappearing input fields Text replacement in @mentions UUID visibility in profiles Purple dot for @mentioned usernames TypeError preventing RYA Group Plan member list error --- .../client/components/chat/autoComplete.vue | 13 +++++------ website/client/components/chat/chatCard.vue | 22 ++++++++++--------- .../client/components/groups/inviteModal.vue | 1 + website/client/components/notifications.vue | 3 +-- .../client/components/userMenu/profile.vue | 2 +- website/server/models/user/index.js | 2 +- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/website/client/components/chat/autoComplete.vue b/website/client/components/chat/autoComplete.vue index db18ca651c..fbce94d1e4 100644 --- a/website/client/components/chat/autoComplete.vue +++ b/website/client/components/chat/autoComplete.vue @@ -108,11 +108,11 @@ export default { searchResults () { if (!this.searchActive) return []; if (!this.atRegex.exec(this.text)) return []; - let currentSearch = this.atRegex.exec(this.text)[0]; - currentSearch = currentSearch.substring(1, currentSearch.length); + this.currentSearch = this.atRegex.exec(this.text)[0]; + this.currentSearch = this.currentSearch.substring(1, this.currentSearch.length); return this.tmpSelections.filter((option) => { - return option.displayName.toLowerCase().indexOf(currentSearch.toLowerCase()) !== -1 || option.username && option.username.toLowerCase().indexOf(currentSearch.toLowerCase()) !== -1; + return option.displayName.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1 || option.username && option.username.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1; }).slice(0, 4); }, @@ -186,11 +186,8 @@ export default { }, select (result) { let newText = this.text; - if (result.username) { - newText = `${newText}${result.username} `; - } else { - newText = `${newText}${result.displayName} `; - } + const targetName = `${result.username || result.displayName} `; + newText = newText.replace(new RegExp(`${this.currentSearch}$`), targetName); this.$emit('select', newText); }, handleEsc (e) { diff --git a/website/client/components/chat/chatCard.vue b/website/client/components/chat/chatCard.vue index f22e9bcb8f..f992148b26 100644 --- a/website/client/components/chat/chatCard.vue +++ b/website/client/components/chat/chatCard.vue @@ -137,6 +137,7 @@ import axios from 'axios'; import moment from 'moment'; import cloneDeep from 'lodash/cloneDeep'; import escapeRegExp from 'lodash/escapeRegExp'; +import max from 'lodash/max'; import habiticaMarkdown from 'habitica-markdown'; import { mapState } from 'client/libs/store'; @@ -197,23 +198,24 @@ export default { ...mapState({user: 'user.data'}), isUserMentioned () { const message = this.msg; - let user = this.user; + const user = this.user; if (message.hasOwnProperty('highlight')) return message.highlight; message.highlight = false; - let messagetext = message.text.toLowerCase(); - let username = user.profile.name; - let mentioned = messagetext.indexOf(username.toLowerCase()); - let escapedUsername = escapeRegExp(username); - let pattern = `@${escapedUsername}([^\w]|$){1}`; - + const messageText = message.text.toLowerCase(); + const displayName = user.profile.name; + const username = user.auth.local && user.auth.local.username; + const mentioned = max([messageText.indexOf(username.toLowerCase()), messageText.indexOf(displayName.toLowerCase())]); if (mentioned === -1) return message.highlight; - let preceedingchar = messagetext.substring(mentioned - 1, mentioned); - if (mentioned === 0 || preceedingchar.trim() === '' || preceedingchar === '@') { + const escapedDisplayName = escapeRegExp(displayName); + const escapedUsername = escapeRegExp(username); + const pattern = `@(${escapedUsername}|${escapedDisplayName})([^\w]|$)`; + const precedingChar = messageText.substring(mentioned - 1, mentioned); + if (mentioned === 0 || precedingChar.trim() === '' || precedingChar === '@') { let regex = new RegExp(pattern, 'i'); - message.highlight = regex.test(messagetext); + message.highlight = regex.test(messageText); } return message.highlight; diff --git a/website/client/components/groups/inviteModal.vue b/website/client/components/groups/inviteModal.vue index 166b75dfaa..727dc9347c 100644 --- a/website/client/components/groups/inviteModal.vue +++ b/website/client/components/groups/inviteModal.vue @@ -120,6 +120,7 @@ this.invites = filter(this.invites, (invite) => { return invite.text.length > 0; }); + while (this.invites.length < 2) this.invites.push(clone(INVITE_DEFAULTS)); if (this.invites[this.invites.length - 1].text.length > 0) this.invites.push(clone(INVITE_DEFAULTS)); forEach(this.invites, (value, index) => { if (value.text.length < 1) return this.invites[index].valid = null; diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index e3faa8c9bb..840462efb3 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -453,8 +453,7 @@ export default { Promise.all([ this.$store.dispatch('user:fetch', {forceLoad: true}), this.$store.dispatch('tasks:fetchUserTasks', {forceLoad: true}), - ]).then(() => this.forceVerifyUsername()) - .then(() => this.runYesterDailies()); + ]).then(() => this.runYesterDailies()); } }, 1000), scheduleNextCron () { diff --git a/website/client/components/userMenu/profile.vue b/website/client/components/userMenu/profile.vue index bf2c384be6..9d4c61544c 100644 --- a/website/client/components/userMenu/profile.vue +++ b/website/client/components/userMenu/profile.vue @@ -45,7 +45,7 @@ div div .name(v-if='user.auth && user.auth.local && user.auth.local.username') @{{ user.auth.local.username }} div - .name(v-if='this.userLoggedIn.contributor.admin') {{ user._id }} + .name {{ user._id }} .col-12.col-md-4 button.btn.btn-secondary(v-if='user._id === userLoggedIn._id', @click='editing = !editing') {{ $t('edit') }} .row(v-if='!editing') diff --git a/website/server/models/user/index.js b/website/server/models/user/index.js index a1a22fd922..75870bf58b 100644 --- a/website/server/models/user/index.js +++ b/website/server/models/user/index.js @@ -12,7 +12,7 @@ export let publicFields = `preferences.size preferences.hair preferences.skin pr flags.verifiedUsername auth.local.username`; // The minimum amount of data needed when populating multiple users -export let nameFields = 'profile.name'; +export let nameFields = 'profile.name auth.local.username flags.verifiedUsername'; export { schema };