logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 35cde98d2c7b6edb458963effb3e40d36d1b3ebf
parent 44e687653cd79ca99950040c547a23e3a8a99c23
Author: Shpuld Shpuldson <shp@cock.li>
Date:   Mon,  1 Mar 2021 09:27:19 +0200

Merge branch 'fix/punycode-buggy' into rc/2.3.0

Diffstat:

MCHANGELOG.md2++
Msrc/components/basic_user_card/basic_user_card.vue2+-
Msrc/components/chat/chat.js2+-
Msrc/components/chat_title/chat_title.js2+-
Msrc/components/emoji_input/emoji_input.js8++++++++
Msrc/components/emoji_input/suggestor.js4++--
Msrc/components/notification/notification.vue10+++++-----
Msrc/components/popover/popover.js7+++++--
Msrc/components/react_button/react_button.js6++++++
Msrc/components/react_button/react_button.vue1+
Msrc/components/status/status.js4++--
Msrc/components/status/status.vue6+++---
Msrc/components/user_avatar/user_avatar.vue4++--
Msrc/components/user_card/user_card.vue4++--
Msrc/components/user_list_popover/user_list_popover.vue2+-
Msrc/components/user_reporting_modal/user_reporting_modal.vue2+-
Msrc/services/entity_normalizer/entity_normalizer.service.js5+++--
Mtest/unit/specs/components/user_profile.spec.js6++++--
Mtest/unit/specs/services/entity_normalizer/entity_normalizer.spec.js2+-
19 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -11,10 +11,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed missing highlighted border in expanded conversations again - Fixed some UI jumpiness when opening images particularly in chat view - Fixed chat unread badge looking weird +- Fixed punycode names not working properly ### Changed - Display 'people voted' instead of 'votes' for multi-choice polls - Optimized chat to not get horrible performance after keeping the same chat open for a long time +- When opening emoji picker or react picker, it automatically focuses the search field ### Added - Added reason field for registration when approval is required diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue @@ -42,7 +42,7 @@ class="basic-user-card-screen-name" :to="userProfileLink(user)" > - @{{ user.screen_name }} + @{{ user.screen_name_ui }} </router-link> </div> <slot /> diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js @@ -73,7 +73,7 @@ const Chat = { }, formPlaceholder () { if (this.recipient) { - return this.$t('chats.message_user', { nickname: this.recipient.screen_name }) + return this.$t('chats.message_user', { nickname: this.recipient.screen_name_ui }) } else { return '' } diff --git a/src/components/chat_title/chat_title.js b/src/components/chat_title/chat_title.js @@ -12,7 +12,7 @@ export default Vue.component('chat-title', { ], computed: { title () { - return this.user ? this.user.screen_name : '' + return this.user ? this.user.screen_name_ui : '' }, htmlTitle () { return this.user ? this.user.name_html : '' diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js @@ -194,11 +194,18 @@ const EmojiInput = { } }, methods: { + focusPickerInput () { + const pickerEl = this.$refs.picker.$el + if (!pickerEl) return + const pickerInput = pickerEl.querySelector('input') + if (pickerInput) pickerInput.focus() + }, triggerShowPicker () { this.showPicker = true this.$refs.picker.startEmojiLoad() this.$nextTick(() => { this.scrollIntoView() + this.focusPickerInput() }) // This temporarily disables "click outside" handler // since external trigger also means click originates @@ -214,6 +221,7 @@ const EmojiInput = { if (this.showPicker) { this.scrollIntoView() this.$refs.picker.startEmojiLoad() + this.$nextTick(this.focusPickerInput) } }, replace (replacement) { diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js @@ -116,8 +116,8 @@ export const suggestUsers = ({ dispatch, state }) => { return diff + nameAlphabetically + screenNameAlphabetically /* eslint-disable camelcase */ - }).map(({ screen_name, name, profile_image_url_original }) => ({ - displayText: screen_name, + }).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({ + displayText: screen_name_ui, detailText: name, imageUrl: profile_image_url_original, replacement: '@' + screen_name + ' ' diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue @@ -11,7 +11,7 @@ > <small> <router-link :to="userProfileLink"> - {{ notification.from_profile.screen_name }} + {{ notification.from_profile.screen_name_ui }} </router-link> </small> <button @@ -54,14 +54,14 @@ <bdi v-if="!!notification.from_profile.name_html" class="username" - :title="'@'+notification.from_profile.screen_name" + :title="'@'+notification.from_profile.screen_name_ui" v-html="notification.from_profile.name_html" /> <!-- eslint-enable vue/no-v-html --> <span v-else class="username" - :title="'@'+notification.from_profile.screen_name" + :title="'@'+notification.from_profile.screen_name_ui" >{{ notification.from_profile.name }}</span> <span v-if="notification.type === 'like'"> <FAIcon @@ -152,7 +152,7 @@ :to="userProfileLink" class="follow-name" > - @{{ notification.from_profile.screen_name }} + @{{ notification.from_profile.screen_name_ui }} </router-link> <div v-if="notification.type === 'follow_request'" @@ -177,7 +177,7 @@ class="move-text" > <router-link :to="targetUserProfileLink"> - @{{ notification.target.screen_name }} + @{{ notification.target.screen_name_ui }} </router-link> </div> <template v-else> diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js @@ -121,9 +121,12 @@ const Popover = { } }, showPopover () { - if (this.hidden) this.$emit('show') + const wasHidden = this.hidden this.hidden = false - this.$nextTick(this.updateStyles) + this.$nextTick(() => { + if (wasHidden) this.$emit('show') + this.updateStyles() + }) }, hidePopover () { if (!this.hidden) this.$emit('close') diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js @@ -23,6 +23,12 @@ const ReactButton = { this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji }) } close() + }, + focusInput () { + this.$nextTick(() => { + const input = this.$el.querySelector('input') + if (input) input.focus() + }) } }, computed: { diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue @@ -6,6 +6,7 @@ :offset="{ y: 5 }" :bound-to="{ x: 'container' }" remove-padding + @show="focusInput" > <div slot="content" diff --git a/src/components/status/status.js b/src/components/status/status.js @@ -136,7 +136,7 @@ const Status = { } }, retweet () { return !!this.statusoid.retweeted_status }, - retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name }, + retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name_ui }, retweeterHtml () { return this.statusoid.user.name_html }, retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) }, status () { @@ -216,7 +216,7 @@ const Status = { return this.status.in_reply_to_screen_name } else { const user = this.$store.getters.findUser(this.status.in_reply_to_user_id) - return user && user.screen_name + return user && user.screen_name_ui } }, replySubject () { diff --git a/src/components/status/status.vue b/src/components/status/status.vue @@ -26,7 +26,7 @@ icon="retweet" /> <router-link :to="userProfileLink"> - {{ status.user.screen_name }} + {{ status.user.screen_name_ui }} </router-link> </small> <small @@ -156,10 +156,10 @@ </h4> <router-link class="account-name" - :title="status.user.screen_name" + :title="status.user.screen_name_ui" :to="userProfileLink" > - {{ status.user.screen_name }} + {{ status.user.screen_name_ui }} </router-link> <img v-if="!!(status.user && status.user.favicon)" diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue @@ -2,8 +2,8 @@ <StillImage v-if="user" class="Avatar" - :alt="user.screen_name" - :title="user.screen_name" + :alt="user.screen_name_ui" + :title="user.screen_name_ui" :src="imgSrc(user.profile_image_url_original)" :class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }" :image-load-error="imageLoadError" diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue @@ -73,10 +73,10 @@ <div class="bottom-line"> <router-link class="user-screen-name" - :title="user.screen_name" + :title="user.screen_name_ui" :to="userProfileLink(user)" > - @{{ user.screen_name }} + @{{ user.screen_name_ui }} </router-link> <template v-if="!hideBio"> <span diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue @@ -26,7 +26,7 @@ <!-- eslint-disable vue/no-v-html --> <span v-html="user.name_html" /> <!-- eslint-enable vue/no-v-html --> - <span class="user-list-screen-name">{{ user.screen_name }}</span> + <span class="user-list-screen-name">{{ user.screen_name_ui }}</span> </div> </div> </div> diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue @@ -6,7 +6,7 @@ <div class="user-reporting-panel panel"> <div class="panel-heading"> <div class="title"> - {{ $t('user_reporting.title', [user.screen_name]) }} + {{ $t('user_reporting.title', [user.screen_name_ui]) }} </div> </div> <div class="panel-body"> diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js @@ -203,7 +203,8 @@ export const parseUser = (data) => { output.rights = output.rights || {} output.notification_settings = output.notification_settings || {} - // Convert punycode to unicode + // Convert punycode to unicode for UI + output.screen_name_ui = output.screen_name if (output.screen_name.includes('@')) { const parts = output.screen_name.split('@') let unicodeDomain = punycode.toUnicode(parts[1]) @@ -211,7 +212,7 @@ export const parseUser = (data) => { // Add some identifier so users can potentially spot spoofing attempts: // lain.com and xn--lin-6cd.com would appear identical otherwise. unicodeDomain = '🌏' + unicodeDomain - output.screen_name = [parts[0], unicodeDomain].join('@') + output.screen_name_ui = [parts[0], unicodeDomain].join('@') } } diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js @@ -31,13 +31,15 @@ const testGetters = { const localUser = { id: 100, is_local: true, - screen_name: 'testUser' + screen_name: 'testUser', + screen_name_ui: 'testUser' } const extUser = { id: 100, is_local: false, - screen_name: 'testUser@test.instance' + screen_name: 'testUser@test.instance', + screen_name_ui: 'testUser@test.instance' } const externalProfileStore = new Vuex.Store({ diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -315,7 +315,7 @@ describe('API Entities normalizer', () => { it('converts IDN to unicode and marks it as internatonal', () => { const user = makeMockUserMasto({ acct: 'lain@xn--lin-6cd.com' }) - expect(parseUser(user)).to.have.property('screen_name').that.equal('lain@🌏lаin.com') + expect(parseUser(user)).to.have.property('screen_name_ui').that.equal('lain@🌏lаin.com') }) })