Merge remote-tracking branch 'origin/develop' into shigusegubu

* origin/develop:
  Fix lint warning in filtering_tab.vue
  Fix Follow button missing on follow list
  Hide mention link avatar by default
  Add English translation for mention link prefs
  Make mention link prefs ui more intuitive
  Add option to fade domains in mention link
  Make avatar unselectable
  Add option to display user avatar in mention link
  Make (You) unselectable
  Style properly usernames without tooltips
  Add pref for whether to display full user names and tooltips
  Add a pref for whether to display mention as icon or text
This commit is contained in:
Henry Jameson 2022-02-03 23:00:01 +02:00
commit ca79122c0b
10 changed files with 150 additions and 11 deletions

View file

@ -20,6 +20,7 @@
:relationship="relationship"
:label-following="$t('user_card.follow_unfollow')"
class="follow-card-follow-button"
:user="user"
/>
</template>
</div>

View file

@ -1,6 +1,7 @@
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { mapGetters, mapState } from 'vuex'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import UserAvatar from '../user_avatar/user_avatar.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAt
@ -12,6 +13,9 @@ library.add(
const MentionLink = {
name: 'MentionLink',
components: {
UserAvatar
},
props: {
url: {
required: true,
@ -50,6 +54,10 @@ const MentionLink = {
userName () {
return this.user && this.userNameFullUi.split('@')[0]
},
serverName () {
// XXX assumed that domain does not contain @
return this.user && (this.userNameFullUi.split('@')[1] || this.$store.getters.instanceDomain)
},
userNameFull () {
return this.user && this.user.screen_name
},
@ -85,6 +93,31 @@ const MentionLink = {
this.highlightType
]
},
useAtIcon () {
return this.mergedConfig.useAtIcon
},
isRemote () {
return this.userName !== this.userNameFull
},
shouldShowFullUserName () {
const conf = this.mergedConfig.mentionLinkDisplay
if (conf === 'short') {
return false
} else if (conf === 'full') {
return true
} else { // full_for_remote
return this.isRemote
}
},
shouldShowTooltip () {
return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote
},
shouldShowAvatar () {
return this.mergedConfig.mentionLinkShowAvatar
},
shouldFadeDomain () {
return this.mergedConfig.mentionLinkFadeDomain
},
...mapGetters(['mergedConfig']),
...mapState({
currentUser: state => state.users.currentUser

View file

@ -1,3 +1,5 @@
@import '../../_variables.scss';
.MentionLink {
position: relative;
white-space: normal;
@ -10,6 +12,15 @@
border-radius: 2px;
}
.mention-avatar {
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
width: 1.5em;
height: 1.5em;
vertical-align: middle;
user-select: none;
margin-right: 0.2em;
}
.full {
position: absolute;
display: inline-block;
@ -27,7 +38,8 @@
user-select: all;
}
.short {
.short.-with-tooltip,
.you {
user-select: none;
}
@ -56,7 +68,7 @@
}
&.-striped {
& .userName,
& .shortName,
& .full {
background-image:
repeating-linear-gradient(
@ -70,14 +82,14 @@
}
&.-solid {
& .userName,
& .shortName,
& .full {
background-image: linear-gradient(var(--____highlight-tintColor2), var(--____highlight-tintColor2));
}
}
&.-side {
& .userName,
& .shortName,
& .userNameFull {
box-shadow: 0 -5px 3px -4px inset var(--____highlight-solidColor);
}
@ -88,4 +100,12 @@
opacity: 1;
pointer-events: initial;
}
.serverName.-faded {
color: var(--faintLink, $fallback--link);
}
.full .-faded {
color: var(--faint, $fallback--faint);
}
}

View file

@ -19,17 +19,30 @@
>
<a
class="short button-unstyled"
:class="{ '-with-tooltip': shouldShowTooltip }"
:href="url"
@click.prevent="onClick"
>
<!-- eslint-disable vue/no-v-html -->
<FAIcon
<UserAvatar
v-if="shouldShowAvatar"
class="mention-avatar"
:user="user"
/><span
class="shortName"
><FAIcon
v-if="useAtIcon"
size="sm"
icon="at"
class="at"
/><span class="shortName"><span
/>{{ !useAtIcon ? '@' : '' }}<span
class="userName"
v-html="userName"
/><span
v-if="shouldShowFullUserName"
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/></span>
<span
v-if="isYou"
@ -38,14 +51,24 @@
<!-- eslint-enable vue/no-v-html -->
</a>
<span
v-if="userName !== userNameFull"
v-if="shouldShowTooltip"
class="full popover-default"
:class="[highlightType]"
>
<span
class="userNameFull"
v-text="'@' + userNameFull"
/>
>
<!-- eslint-disable vue/no-v-html -->
@<span
class="userName"
v-html="userName"
/><span
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
<!-- eslint-enable vue/no-v-html -->
</span>
</span>
</span>
</span>

View file

@ -31,7 +31,7 @@
<BooleanSetting
:disabled="hideFilteredStatuses"
path="hideMutedPosts"
>
>
{{ $t('settings.hide_muted_posts') }}
</BooleanSetting>
</li>

View file

@ -20,6 +20,11 @@ const GeneralTab = {
value: mode,
label: this.$t(`settings.subject_line_${mode === 'masto' ? 'mastodon' : mode}`)
})),
mentionLinkDisplayOptions: ['short', 'full_for_remote', 'full'].map(mode => ({
key: mode,
value: mode,
label: this.$t(`settings.mention_link_display_${mode}`)
})),
loopSilentAvailable:
// Firefox
Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') ||

View file

@ -152,6 +152,41 @@
{{ $t('settings.greentext') }}
</BooleanSetting>
</li>
<li>
<ChoiceSetting
id="mentionLinkDisplay"
path="mentionLinkDisplay"
:options="mentionLinkDisplayOptions"
>
{{ $t('settings.mention_link_display') }}
</ChoiceSetting>
</li>
<ul
class="setting-list suboptions"
>
<li
v-if="mentionLinkDisplay === 'short'"
>
<BooleanSetting path="mentionLinkShowTooltip">
{{ $t('settings.mention_link_show_tooltip') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="useAtIcon">
{{ $t('settings.use_at_icon') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="mentionLinkShowAvatar">
{{ $t('settings.mention_link_show_avatar') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="mentionLinkFadeDomain">
{{ $t('settings.mention_link_fade_domain') }}
</BooleanSetting>
</li>
</ul>
</ul>
</div>

View file

@ -487,6 +487,14 @@
"true": "yes"
},
"virtual_scrolling": "Optimize timeline rendering",
"use_at_icon": "Display @ symbol as an icon instead of text",
"mention_link_display": "Display mention links",
"mention_link_display_short": "always as short names (e.g. @foo)",
"mention_link_display_full_for_remote": "as full names only for remote users (e.g. @foo@example.org)",
"mention_link_display_full": "always as full names (e.g. @foo@example.org)",
"mention_link_show_tooltip": "Show full user names as tooltip for remote users",
"mention_link_show_avatar": "Show user avatar beside the link",
"mention_link_fade_domain": "Fade domains (e.g. @example.org in @foo@example.org)",
"fun": "Fun",
"greentext": "Meme arrows",
"notifications": "Notifications",

View file

@ -11,7 +11,8 @@ const browserLocale = (window.navigator.language || 'en').split('-')[0]
*/
export const multiChoiceProperties = [
'postContentType',
'subjectLineBehavior'
'subjectLineBehavior',
'mentionLinkDisplay' // short | full_for_remote | full
]
export const defaultState = {
@ -70,6 +71,11 @@ export const defaultState = {
useOneClickNsfw: false,
useContainFit: false,
greentext: undefined, // instance default
useAtIcon: undefined, // instance default
mentionLinkDisplay: undefined, // instance default
mentionLinkShowTooltip: undefined, // instance default
mentionLinkShowAvatar: undefined, // instance default
mentionLinkFadeDomain: undefined, // instance default
hidePostStats: undefined, // instance default
hideUserStats: undefined, // instance default
virtualScrolling: undefined, // instance default

View file

@ -20,6 +20,11 @@ const defaultState = {
background: '/static/aurora_borealis.jpg',
collapseMessageWithSubject: false,
greentext: false,
useAtIcon: false,
mentionLinkDisplay: 'short',
mentionLinkShowTooltip: true,
mentionLinkShowAvatar: false,
mentionLinkFadeDomain: true,
hideFilteredStatuses: false,
// bad name: actually hides posts of muted USERS
hideMutedPosts: false,
@ -100,6 +105,9 @@ const instance = {
return instanceDefaultProperties
.map(key => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
instanceDomain (state) {
return new URL(state.server).hostname
}
},
actions: {