Merge branch 'develop' into 'feat/timeline-quick-settings'

# Conflicts:
#   CHANGELOG.md
This commit is contained in:
Shpuld Shpludson 2021-02-28 15:37:39 +00:00
commit 91f93d4a55
37 changed files with 127 additions and 70 deletions

View file

@ -9,14 +9,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fixed shoutbox not working in mobile layout - Fixed shoutbox not working in mobile layout
- Fixed missing highlighted border in expanded conversations again - Fixed missing highlighted border in expanded conversations again
- Fixed some UI jumpiness when opening images particularly in chat view - Fixed some UI jumpiness when opening images particularly in chat view
- Fixed chat unread badge looking weird
- Fixed punycode names not working properly
- Fixed notifications crashing on an invalid notification
### Changed ### Changed
- Display 'people voted' instead of 'votes' for multi-choice polls - 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 - 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
- Added reason field for registration when approval is required - Added reason field for registration when approval is required
- Added a quick settings to timeline header for easier access - Added a quick settings to timeline header for easier access
- Added option to mark posts as sensitive by default
## [2.2.3] - 2021-01-18 ## [2.2.3] - 2021-01-18
### Added ### Added

View file

@ -103,7 +103,7 @@
"selenium-server": "2.53.1", "selenium-server": "2.53.1",
"semver": "^5.3.0", "semver": "^5.3.0",
"serviceworker-webpack-plugin": "^1.0.0", "serviceworker-webpack-plugin": "^1.0.0",
"shelljs": "^0.7.4", "shelljs": "^0.8.4",
"sinon": "^2.1.0", "sinon": "^2.1.0",
"sinon-chai": "^2.8.0", "sinon-chai": "^2.8.0",
"stylelint": "^13.6.1", "stylelint": "^13.6.1",

View file

@ -42,7 +42,7 @@
class="basic-user-card-screen-name" class="basic-user-card-screen-name"
:to="userProfileLink(user)" :to="userProfileLink(user)"
> >
@{{ user.screen_name }} @{{ user.screen_name_ui }}
</router-link> </router-link>
</div> </div>
<slot /> <slot />

View file

@ -73,7 +73,7 @@ const Chat = {
}, },
formPlaceholder () { formPlaceholder () {
if (this.recipient) { 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 { } else {
return '' return ''
} }

View file

@ -98,10 +98,10 @@
.unread-message-count { .unread-message-count {
font-size: 0.8em; font-size: 0.8em;
left: 50%; left: 50%;
transform: translate(-50%, 0);
border-radius: 100%;
margin-top: -1rem; margin-top: -1rem;
padding: 0; padding: 0.1em;
border-radius: 50px;
position: absolute;
} }
.chat-loading-error { .chat-loading-error {

View file

@ -12,7 +12,7 @@ export default Vue.component('chat-title', {
], ],
computed: { computed: {
title () { title () {
return this.user ? this.user.screen_name : '' return this.user ? this.user.screen_name_ui : ''
}, },
htmlTitle () { htmlTitle () {
return this.user ? this.user.name_html : '' return this.user ? this.user.name_html : ''

View file

@ -194,11 +194,18 @@ const EmojiInput = {
} }
}, },
methods: { methods: {
focusPickerInput () {
const pickerEl = this.$refs.picker.$el
if (!pickerEl) return
const pickerInput = pickerEl.querySelector('input')
if (pickerInput) pickerInput.focus()
},
triggerShowPicker () { triggerShowPicker () {
this.showPicker = true this.showPicker = true
this.$refs.picker.startEmojiLoad() this.$refs.picker.startEmojiLoad()
this.$nextTick(() => { this.$nextTick(() => {
this.scrollIntoView() this.scrollIntoView()
this.focusPickerInput()
}) })
// This temporarily disables "click outside" handler // This temporarily disables "click outside" handler
// since external trigger also means click originates // since external trigger also means click originates
@ -214,6 +221,7 @@ const EmojiInput = {
if (this.showPicker) { if (this.showPicker) {
this.scrollIntoView() this.scrollIntoView()
this.$refs.picker.startEmojiLoad() this.$refs.picker.startEmojiLoad()
this.$nextTick(this.focusPickerInput)
} }
}, },
replace (replacement) { replace (replacement) {

View file

@ -9,8 +9,8 @@
<button <button
v-if="!hideEmojiButton" v-if="!hideEmojiButton"
class="button-unstyled emoji-picker-icon" class="button-unstyled emoji-picker-icon"
@click.prevent="togglePicker"
type="button" type="button"
@click.prevent="togglePicker"
> >
<FAIcon :icon="['far', 'smile-beam']" /> <FAIcon :icon="['far', 'smile-beam']" />
</button> </button>

View file

@ -116,8 +116,8 @@ export const suggestUsers = ({ dispatch, state }) => {
return diff + nameAlphabetically + screenNameAlphabetically return diff + nameAlphabetically + screenNameAlphabetically
/* eslint-disable camelcase */ /* eslint-disable camelcase */
}).map(({ screen_name, name, profile_image_url_original }) => ({ }).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({
displayText: screen_name, displayText: screen_name_ui,
detailText: name, detailText: name,
imageUrl: profile_image_url_original, imageUrl: profile_image_url_original,
replacement: '@' + screen_name + ' ' replacement: '@' + screen_name + ' '

View file

@ -25,16 +25,16 @@
<div> <div>
<button <button
class="button-unstyled -link" class="button-unstyled -link"
@click.prevent="requireTOTP"
type="button" type="button"
@click.prevent="requireTOTP"
> >
{{ $t('login.enter_two_factor_code') }} {{ $t('login.enter_two_factor_code') }}
</button> </button>
<br> <br>
<button <button
class="button-unstyled -link" class="button-unstyled -link"
@click.prevent="abortMFA"
type="button" type="button"
@click.prevent="abortMFA"
> >
{{ $t('general.cancel') }} {{ $t('general.cancel') }}
</button> </button>

View file

@ -27,16 +27,16 @@
<div> <div>
<button <button
class="button-unstyled -link" class="button-unstyled -link"
@click.prevent="requireRecovery"
type="button" type="button"
@click.prevent="requireRecovery"
> >
{{ $t('login.enter_recovery_code') }} {{ $t('login.enter_recovery_code') }}
</button> </button>
<br> <br>
<button <button
class="button-unstyled -link" class="button-unstyled -link"
@click.prevent="abortMFA"
type="button" type="button"
@click.prevent="abortMFA"
> >
{{ $t('general.cancel') }} {{ $t('general.cancel') }}
</button> </button>

View file

@ -11,7 +11,7 @@
> >
<small> <small>
<router-link :to="userProfileLink"> <router-link :to="userProfileLink">
{{ notification.from_profile.screen_name }} {{ notification.from_profile.screen_name_ui }}
</router-link> </router-link>
</small> </small>
<button <button
@ -54,14 +54,14 @@
<bdi <bdi
v-if="!!notification.from_profile.name_html" v-if="!!notification.from_profile.name_html"
class="username" class="username"
:title="'@'+notification.from_profile.screen_name" :title="'@'+notification.from_profile.screen_name_ui"
v-html="notification.from_profile.name_html" v-html="notification.from_profile.name_html"
/> />
<!-- eslint-enable vue/no-v-html --> <!-- eslint-enable vue/no-v-html -->
<span <span
v-else v-else
class="username" class="username"
:title="'@'+notification.from_profile.screen_name" :title="'@'+notification.from_profile.screen_name_ui"
>{{ notification.from_profile.name }}</span> >{{ notification.from_profile.name }}</span>
<span v-if="notification.type === 'like'"> <span v-if="notification.type === 'like'">
<FAIcon <FAIcon
@ -152,7 +152,7 @@
:to="userProfileLink" :to="userProfileLink"
class="follow-name" class="follow-name"
> >
@{{ notification.from_profile.screen_name }} @{{ notification.from_profile.screen_name_ui }}
</router-link> </router-link>
<div <div
v-if="notification.type === 'follow_request'" v-if="notification.type === 'follow_request'"
@ -177,7 +177,7 @@
class="move-text" class="move-text"
> >
<router-link :to="targetUserProfileLink"> <router-link :to="targetUserProfileLink">
@{{ notification.target.screen_name }} @{{ notification.target.screen_name_ui }}
</router-link> </router-link>
</div> </div>
<template v-else> <template v-else>

View file

@ -128,9 +128,12 @@ const Popover = {
} }
}, },
showPopover () { showPopover () {
if (this.hidden) this.$emit('show') const wasHidden = this.hidden
this.hidden = false this.hidden = false
this.$nextTick(this.updateStyles) this.$nextTick(() => {
if (wasHidden) this.$emit('show')
this.updateStyles()
})
}, },
hidePopover () { hidePopover () {
if (!this.hidden) this.$emit('close') if (!this.hidden) this.$emit('close')

View file

@ -115,7 +115,7 @@ const PostStatusForm = {
? this.copyMessageScope ? this.copyMessageScope
: this.$store.state.users.currentUser.default_scope : this.$store.state.users.currentUser.default_scope
const { postContentType: contentType } = this.$store.getters.mergedConfig const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig
return { return {
dropFiles: [], dropFiles: [],
@ -126,7 +126,7 @@ const PostStatusForm = {
newStatus: { newStatus: {
spoilerText: this.subject || '', spoilerText: this.subject || '',
status: statusText, status: statusText,
nsfw: false, nsfw: !!sensitiveByDefault,
files: [], files: [],
poll: {}, poll: {},
mediaDescriptions: {}, mediaDescriptions: {},

View file

@ -23,6 +23,12 @@ const ReactButton = {
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji }) this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
} }
close() close()
},
focusInput () {
this.$nextTick(() => {
const input = this.$el.querySelector('input')
if (input) input.focus()
})
} }
}, },
computed: { computed: {

View file

@ -6,6 +6,7 @@
:offset="{ y: 5 }" :offset="{ y: 5 }"
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
remove-padding remove-padding
@show="focusInput"
> >
<div <div
slot="content" slot="content"

View file

@ -8,8 +8,8 @@
class="button-unstyled scope" class="button-unstyled scope"
:class="css.direct" :class="css.direct"
:title="$t('post_status.scope.direct')" :title="$t('post_status.scope.direct')"
@click="changeVis('direct')"
type="button" type="button"
@click="changeVis('direct')"
> >
<FAIcon <FAIcon
icon="envelope" icon="envelope"
@ -21,8 +21,8 @@
class="button-unstyled scope" class="button-unstyled scope"
:class="css.private" :class="css.private"
:title="$t('post_status.scope.private')" :title="$t('post_status.scope.private')"
@click="changeVis('private')"
type="button" type="button"
@click="changeVis('private')"
> >
<FAIcon <FAIcon
icon="lock" icon="lock"
@ -34,8 +34,8 @@
class="button-unstyled scope" class="button-unstyled scope"
:class="css.unlisted" :class="css.unlisted"
:title="$t('post_status.scope.unlisted')" :title="$t('post_status.scope.unlisted')"
@click="changeVis('unlisted')"
type="button" type="button"
@click="changeVis('unlisted')"
> >
<FAIcon <FAIcon
icon="lock-open" icon="lock-open"
@ -47,8 +47,8 @@
class="button-unstyled scope" class="button-unstyled scope"
:class="css.public" :class="css.public"
:title="$t('post_status.scope.public')" :title="$t('post_status.scope.public')"
@click="changeVis('public')"
type="button" type="button"
@click="changeVis('public')"
> >
<FAIcon <FAIcon
icon="globe" icon="globe"

View file

@ -15,8 +15,8 @@
> >
<button <button
class="btn button-default search-button" class="btn button-default search-button"
@click="newQuery(searchTerm)"
type="submit" type="submit"
@click="newQuery(searchTerm)"
> >
<FAIcon icon="search" /> <FAIcon icon="search" />
</button> </button>

View file

@ -7,8 +7,8 @@
v-if="hidden" v-if="hidden"
class="button-unstyled nav-icon" class="button-unstyled nav-icon"
:title="$t('nav.search')" :title="$t('nav.search')"
@click.prevent.stop="toggleHidden"
type="button" type="button"
@click.prevent.stop="toggleHidden"
> >
<FAIcon <FAIcon
fixed-width fixed-width
@ -28,8 +28,8 @@
> >
<button <button
class="button-default search-button" class="button-default search-button"
@click="find(searchTerm)"
type="submit" type="submit"
@click="find(searchTerm)"
> >
<FAIcon <FAIcon
fixed-width fixed-width
@ -38,8 +38,8 @@
</button> </button>
<button <button
class="button-unstyled cancel-search" class="button-unstyled cancel-search"
@click.prevent.stop="toggleHidden"
type="button" type="button"
@click.prevent.stop="toggleHidden"
> >
<FAIcon <FAIcon
fixed-width fixed-width

View file

@ -13,8 +13,8 @@
/> />
</span> </span>
<div <div
class="modified-tooltip"
slot="content" slot="content"
class="modified-tooltip"
> >
{{ $t('settings.setting_changed') }} {{ $t('settings.setting_changed') }}
</div> </div>
@ -32,8 +32,8 @@ library.add(
) )
export default { export default {
props: ['changed'], components: { Popover },
components: { Popover } props: ['changed']
} }
</script> </script>

View file

@ -75,8 +75,8 @@
<p>{{ $t('settings.filtering_explanation') }}</p> <p>{{ $t('settings.filtering_explanation') }}</p>
<textarea <textarea
id="muteWords" id="muteWords"
class="resize-height"
v-model="muteWordsString" v-model="muteWordsString"
class="resize-height"
/> />
</div> </div>
<div> <div>

View file

@ -144,7 +144,12 @@
</li> </li>
<li> <li>
<BooleanSetting path="minimalScopesMode"> <BooleanSetting path="minimalScopesMode">
{{ $t('settings.minimal_scopes_mode') }} {{ minimalScopesModeDefaultValue }} {{ $t('settings.minimal_scopes_mode') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="sensitiveByDefault">
{{ $t('settings.sensitive_by_default') }}
</BooleanSetting> </BooleanSetting>
</li> </li>
<li> <li>

View file

@ -136,7 +136,7 @@ const Status = {
} }
}, },
retweet () { return !!this.statusoid.retweeted_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 }, retweeterHtml () { return this.statusoid.user.name_html },
retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) }, retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) },
status () { status () {
@ -216,7 +216,7 @@ const Status = {
return this.status.in_reply_to_screen_name return this.status.in_reply_to_screen_name
} else { } else {
const user = this.$store.getters.findUser(this.status.in_reply_to_user_id) 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 () { replySubject () {

View file

@ -26,7 +26,7 @@
icon="retweet" icon="retweet"
/> />
<router-link :to="userProfileLink"> <router-link :to="userProfileLink">
{{ status.user.screen_name }} {{ status.user.screen_name_ui }}
</router-link> </router-link>
</small> </small>
<small <small
@ -156,10 +156,10 @@
</h4> </h4>
<router-link <router-link
class="account-name" class="account-name"
:title="status.user.screen_name" :title="status.user.screen_name_ui"
:to="userProfileLink" :to="userProfileLink"
> >
{{ status.user.screen_name }} {{ status.user.screen_name_ui }}
</router-link> </router-link>
<img <img
v-if="!!(status.user && status.user.favicon)" v-if="!!(status.user && status.user.favicon)"

View file

@ -2,8 +2,8 @@
<StillImage <StillImage
v-if="user" v-if="user"
class="Avatar" class="Avatar"
:alt="user.screen_name" :alt="user.screen_name_ui"
:title="user.screen_name" :title="user.screen_name_ui"
:src="imgSrc(user.profile_image_url_original)" :src="imgSrc(user.profile_image_url_original)"
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }" :class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
:image-load-error="imageLoadError" :image-load-error="imageLoadError"

View file

@ -73,10 +73,10 @@
<div class="bottom-line"> <div class="bottom-line">
<router-link <router-link
class="user-screen-name" class="user-screen-name"
:title="user.screen_name" :title="user.screen_name_ui"
:to="userProfileLink(user)" :to="userProfileLink(user)"
> >
@{{ user.screen_name }} @{{ user.screen_name_ui }}
</router-link> </router-link>
<template v-if="!hideBio"> <template v-if="!hideBio">
<span <span

View file

@ -26,7 +26,7 @@
<!-- eslint-disable vue/no-v-html --> <!-- eslint-disable vue/no-v-html -->
<span v-html="user.name_html" /> <span v-html="user.name_html" />
<!-- eslint-enable vue/no-v-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> </div>
</div> </div>

View file

@ -6,7 +6,7 @@
<div class="user-reporting-panel panel"> <div class="user-reporting-panel panel">
<div class="panel-heading"> <div class="panel-heading">
<div class="title"> <div class="title">
{{ $t('user_reporting.title', [user.screen_name]) }} {{ $t('user_reporting.title', [user.screen_name_ui]) }}
</div> </div>
</div> </div>
<div class="panel-body"> <div class="panel-body">

View file

@ -434,6 +434,7 @@
"subject_line_mastodon": "Like mastodon: copy as is", "subject_line_mastodon": "Like mastodon: copy as is",
"subject_line_noop": "Do not copy", "subject_line_noop": "Do not copy",
"post_status_content_type": "Post status content type", "post_status_content_type": "Post status content type",
"sensitive_by_default": "Mark posts as sensitive by default",
"stop_gifs": "Play-on-hover GIFs", "stop_gifs": "Play-on-hover GIFs",
"streaming": "Enable automatic streaming of new posts when scrolled to the top", "streaming": "Enable automatic streaming of new posts when scrolled to the top",
"user_mutes": "Users", "user_mutes": "Users",

View file

@ -67,7 +67,8 @@ export const defaultState = {
greentext: undefined, // instance default greentext: undefined, // instance default
hidePostStats: undefined, // instance default hidePostStats: undefined, // instance default
hideUserStats: undefined, // instance default hideUserStats: undefined, // instance default
virtualScrolling: undefined // instance default virtualScrolling: undefined, // instance default
sensitiveByDefault: undefined // instance default
} }
// caching the instance default properties // caching the instance default properties

View file

@ -43,6 +43,7 @@ const defaultState = {
subjectLineBehavior: 'email', subjectLineBehavior: 'email',
theme: 'pleroma-dark', theme: 'pleroma-dark',
virtualScrolling: true, virtualScrolling: true,
sensitiveByDefault: false,
// Nasty stuff // Nasty stuff
customEmoji: [], customEmoji: [],

View file

@ -13,7 +13,11 @@ import {
omitBy omitBy
} from 'lodash' } from 'lodash'
import { set } from 'vue' import { set } from 'vue'
import { isStatusNotification, maybeShowNotification } from '../services/notification_utils/notification_utils.js' import {
isStatusNotification,
isValidNotification,
maybeShowNotification
} from '../services/notification_utils/notification_utils.js'
import apiService from '../services/api/api.service.js' import apiService from '../services/api/api.service.js'
const emptyTl = (userId = 0) => ({ const emptyTl = (userId = 0) => ({
@ -310,8 +314,24 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
} }
} }
const updateNotificationsMinMaxId = (state, notification) => {
state.notifications.maxId = notification.id > state.notifications.maxId
? notification.id
: state.notifications.maxId
state.notifications.minId = notification.id < state.notifications.minId
? notification.id
: state.notifications.minId
}
const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters, newNotificationSideEffects }) => { const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters, newNotificationSideEffects }) => {
each(notifications, (notification) => { each(notifications, (notification) => {
// If invalid notification, update ids but don't add it to store
if (!isValidNotification(notification)) {
console.error('Invalid notification:', notification)
updateNotificationsMinMaxId(state, notification)
return
}
if (isStatusNotification(notification.type)) { if (isStatusNotification(notification.type)) {
notification.action = addStatusToGlobalStorage(state, notification.action).item notification.action = addStatusToGlobalStorage(state, notification.action).item
notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item
@ -323,12 +343,7 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
// Only add a new notification if we don't have one for the same action // Only add a new notification if we don't have one for the same action
if (!state.notifications.idStore.hasOwnProperty(notification.id)) { if (!state.notifications.idStore.hasOwnProperty(notification.id)) {
state.notifications.maxId = notification.id > state.notifications.maxId updateNotificationsMinMaxId(state, notification)
? notification.id
: state.notifications.maxId
state.notifications.minId = notification.id < state.notifications.minId
? notification.id
: state.notifications.minId
state.notifications.data.push(notification) state.notifications.data.push(notification)
state.notifications.idStore[notification.id] = notification state.notifications.idStore[notification.id] = notification

View file

@ -203,7 +203,8 @@ export const parseUser = (data) => {
output.rights = output.rights || {} output.rights = output.rights || {}
output.notification_settings = output.notification_settings || {} 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('@')) { if (output.screen_name.includes('@')) {
const parts = output.screen_name.split('@') const parts = output.screen_name.split('@')
let unicodeDomain = punycode.toUnicode(parts[1]) let unicodeDomain = punycode.toUnicode(parts[1])
@ -211,7 +212,7 @@ export const parseUser = (data) => {
// Add some identifier so users can potentially spot spoofing attempts: // Add some identifier so users can potentially spot spoofing attempts:
// lain.com and xn--lin-6cd.com would appear identical otherwise. // lain.com and xn--lin-6cd.com would appear identical otherwise.
unicodeDomain = '🌏' + unicodeDomain unicodeDomain = '🌏' + unicodeDomain
output.screen_name = [parts[0], unicodeDomain].join('@') output.screen_name_ui = [parts[0], unicodeDomain].join('@')
} }
} }

View file

@ -22,6 +22,13 @@ const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reactio
export const isStatusNotification = (type) => includes(statusNotifications, type) export const isStatusNotification = (type) => includes(statusNotifications, type)
export const isValidNotification = (notification) => {
if (isStatusNotification(notification.type) && !notification.status) {
return false
}
return true
}
const sortById = (a, b) => { const sortById = (a, b) => {
const seqA = Number(a.id) const seqA = Number(a.id)
const seqB = Number(b.id) const seqB = Number(b.id)

View file

@ -31,13 +31,15 @@ const testGetters = {
const localUser = { const localUser = {
id: 100, id: 100,
is_local: true, is_local: true,
screen_name: 'testUser' screen_name: 'testUser',
screen_name_ui: 'testUser'
} }
const extUser = { const extUser = {
id: 100, id: 100,
is_local: false, is_local: false,
screen_name: 'testUser@test.instance' screen_name: 'testUser@test.instance',
screen_name_ui: 'testUser@test.instance'
} }
const externalProfileStore = new Vuex.Store({ const externalProfileStore = new Vuex.Store({

View file

@ -315,7 +315,7 @@ describe('API Entities normalizer', () => {
it('converts IDN to unicode and marks it as internatonal', () => { it('converts IDN to unicode and marks it as internatonal', () => {
const user = makeMockUserMasto({ acct: 'lain@xn--lin-6cd.com' }) 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')
}) })
}) })

View file

@ -7842,9 +7842,10 @@ shebang-regex@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
shelljs@^0.7.4: shelljs@^0.8.4:
version "0.7.8" version "0.8.4"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
dependencies: dependencies:
glob "^7.0.0" glob "^7.0.0"
interpret "^1.0.0" interpret "^1.0.0"