commit: 55adcd822e194be8aaeb9d6b649de90e9d5e1e45
parent 61d63b0e616392d841b78095ae8045e98d2b2fa6
Author: Henry Jameson <me@hjkos.com>
Date: Sun, 12 Jun 2022 16:31:56 +0300
fix animations, replace ugly old mentionlink tooltips with new usercard ones
Diffstat:
8 files changed, 140 insertions(+), 90 deletions(-)
diff --git a/src/App.scss b/src/App.scss
@@ -829,7 +829,7 @@ option {
// Vue transitions
.fade-enter-active,
.fade-leave-active {
- transition: opacity 0.2s;
+ transition: opacity 0.3s;
}
.fade-enter-from,
diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
@@ -2,6 +2,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p
import { mapGetters, mapState } from 'vuex'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import UserAvatar from '../user_avatar/user_avatar.vue'
+import { defineAsyncComponent } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAt
@@ -14,7 +15,9 @@ library.add(
const MentionLink = {
name: 'MentionLink',
components: {
- UserAvatar
+ UserAvatar,
+ Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
+ UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue'))
},
props: {
url: {
@@ -36,6 +39,7 @@ const MentionLink = {
},
methods: {
onClick () {
+ if (this.shouldShowTooltip) return
const link = generateProfileLink(
this.userId || this.user.id,
this.userScreenName || this.user.screen_name
@@ -110,7 +114,7 @@ const MentionLink = {
}
},
shouldShowTooltip () {
- return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote
+ return this.mergedConfig.mentionLinkShowTooltip
},
shouldShowAvatar () {
return this.mergedConfig.mentionLinkShowAvatar
diff --git a/src/components/mention_link/mention_link.scss b/src/components/mention_link/mention_link.scss
@@ -101,7 +101,6 @@
}
&:hover .new .full {
- opacity: 1;
pointer-events: initial;
}
@@ -113,3 +112,9 @@
color: var(--faint, $fallback--faint);
}
}
+
+.mention-link-popover {
+ max-width: 70ch;
+ max-height: 20rem;
+ overflow: hidden;
+}
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
@@ -9,66 +9,85 @@
class="original"
target="_blank"
v-html="content"
- /><!-- eslint-enable vue/no-v-html --><span
- v-if="user"
- class="new"
- :style="style"
- :class="classnames"
+ /><!-- eslint-enable vue/no-v-html -->
+ <Popover
+ trigger="click"
+ :bound-to="{ x: 'container'}"
+ bound-to-selector=".column"
+ popover-class="popover-default mention-popover"
+ :disabled="!shouldShowTooltip"
>
- <a
- class="short button-unstyled"
- :class="{ '-with-tooltip': shouldShowTooltip }"
- :href="url"
- @click.prevent="onClick"
- >
- <!-- eslint-disable vue/no-v-html -->
- <UserAvatar
- v-if="shouldShowAvatar"
- class="mention-avatar"
- :user="user"
- /><span
- class="shortName"
- ><FAIcon
- v-if="useAtIcon"
- size="sm"
- icon="at"
- class="at"
- />{{ !useAtIcon ? '@' : '' }}<span
- class="userName"
- v-html="userName"
- /><span
- v-if="shouldShowFullUserName"
- class="serverName"
- :class="{ '-faded': shouldFadeDomain }"
- v-html="'@' + serverName"
- />
- </span>
- <span
- v-if="isYou && shouldShowYous"
- :class="{ '-you': shouldBoldenYou }"
- > {{ ' ' + $t('status.you') }}</span>
- <!-- eslint-enable vue/no-v-html -->
- </a><span
- v-if="shouldShowTooltip"
- class="full popover-default"
- :class="[highlightType]"
- >
+ <template v-slot:trigger>
<span
- class="userNameFull"
+ v-if="user"
+ class="new"
+ :style="style"
+ :class="classnames"
>
- <!-- 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>
+ <a
+ class="short button-unstyled"
+ :class="{ '-with-tooltip': shouldShowTooltip }"
+ :href="url"
+ @click.prevent="onClick"
+ >
+ <!-- eslint-disable vue/no-v-html -->
+ <UserAvatar
+ v-if="shouldShowAvatar"
+ class="mention-avatar"
+ :user="user"
+ /><span
+ class="shortName"
+ ><FAIcon
+ v-if="useAtIcon"
+ size="sm"
+ icon="at"
+ class="at"
+ />{{ !useAtIcon ? '@' : '' }}<span
+ class="userName"
+ v-html="userName"
+ /><span
+ v-if="shouldShowFullUserName"
+ class="serverName"
+ :class="{ '-faded': shouldFadeDomain }"
+ v-html="'@' + serverName"
+ />
+ </span>
+ <span
+ v-if="isYou && shouldShowYous"
+ :class="{ '-you': shouldBoldenYou }"
+ > {{ ' ' + $t('status.you') }}</span>
+ <!-- eslint-enable vue/no-v-html -->
+ </a><span
+ v-if="shouldShowTooltip"
+ class="full"
+ >
+ <span
+ class="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></template>
+ <template v-slot:content>
+ <UserCard
+ class="mention-link-popover"
+ :user-id="user.id"
+ :hide-bio="true"
+ :bordered="false"
+ :allow-zooming-avatar="true"
+ :rounded="true"
+ />
+ </template>
+ </Popover>
</span>
</template>
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
@@ -31,13 +31,18 @@ const Popover = {
// If true, subtract padding when calculating position for the popover,
// use it when popover offset looks to be different on top vs bottom.
- removePadding: Boolean
+ removePadding: Boolean,
+
+ // self-explanatory (i hope)
+ disabled: Boolean
},
data () {
return {
hidden: true,
- styles: { opacity: 0 },
- oldSize: { width: 0, height: 0 }
+ styles: {},
+ oldSize: { width: 0, height: 0 },
+ // used to avoid blinking if hovered onto popover
+ graceTimeout: null
}
},
methods: {
@@ -47,9 +52,7 @@ const Popover = {
},
updateStyles () {
if (this.hidden) {
- this.styles = {
- opacity: 0
- }
+ this.styles = {}
return
}
@@ -132,7 +135,6 @@ const Popover = {
// Note, separate translateX and translateY avoids blurry text on chromium,
// single translate or translate3d resulted in blurry text.
this.styles = {
- opacity: 1,
left: `${Math.round(translateX)}px`,
top: `${Math.round(translateY)}px`,
position: 'fixed'
@@ -143,6 +145,7 @@ const Popover = {
}
},
showPopover () {
+ if (this.disabled) return
const wasHidden = this.hidden
this.hidden = false
this.$nextTick(() => {
@@ -153,13 +156,30 @@ const Popover = {
hidePopover () {
if (!this.hidden) this.$emit('close')
this.hidden = true
- this.styles = { opacity: 0 }
},
onMouseenter (e) {
- if (this.trigger === 'hover') this.showPopover()
+ if (this.trigger === 'hover') {
+ clearTimeout(this.graceTimeout)
+ this.graceTimeout = null
+ this.showPopover()
+ }
},
onMouseleave (e) {
- if (this.trigger === 'hover') this.hidePopover()
+ if (this.trigger === 'hover') {
+ this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
+ }
+ },
+ onMouseenterContent (e) {
+ if (this.trigger === 'hover') {
+ clearTimeout(this.graceTimeout)
+ this.graceTimeout = null
+ this.showPopover()
+ }
+ },
+ onMouseleaveContent (e) {
+ if (this.trigger === 'hover') {
+ this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
+ }
},
onClick (e) {
if (this.trigger === 'click') {
diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
@@ -1,5 +1,5 @@
<template>
- <div
+ <span
@mouseenter="onMouseenter"
@mouseleave="onMouseleave"
>
@@ -12,21 +12,25 @@
<slot name="trigger" />
</button>
<teleport to="#popovers">
- <div
- v-if="!hidden"
- ref="content"
- :style="styles"
- class="popover"
- :class="popoverClass || 'popover-default'"
- >
- <slot
- name="content"
- class="popover-inner"
- :close="hidePopover"
- />
- </div>
+ <transition name="fade">
+ <div
+ v-if="!hidden"
+ ref="content"
+ :style="styles"
+ class="popover"
+ :class="popoverClass || 'popover-default'"
+ @mouseenter="onMouseenterContent"
+ @mouseleave="onMouseleaveContent"
+ >
+ <slot
+ name="content"
+ class="popover-inner"
+ :close="hidePopover"
+ />
+ </div>
+ </transition>
</teleport>
- </div>
+ </span>
</template>
<script src="./popover.js" />
@@ -47,8 +51,6 @@
}
.popover-default {
- transition: opacity 0.3s;
-
&:after {
content: '';
position: absolute;
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
@@ -269,7 +269,7 @@
path="mentionLinkShowTooltip"
expert="1"
>
- {{ $t('settings.mention_link_show_tooltip') }}
+ {{ $t('settings.mention_link_use_tooltip') }}
</BooleanSetting>
</li>
</ul>
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -523,7 +523,7 @@
"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_use_tooltip": "Show user card when clicking mention links",
"mention_link_show_avatar": "Show user avatar beside the link",
"mention_link_fade_domain": "Fade domains (e.g. {'@'}example.org in {'@'}foo{'@'}example.org)",
"mention_link_bolden_you": "Highlight mention of you when you are mentioned",