diff --git a/src/App.scss b/src/App.scss index 5cd0b96e..79c07683 100644 --- 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 index 55eea195..4b088f88 100644 --- 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 index 1d856ff9..3b3a05b1 100644 --- 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 index 022f04c7..686ad27f 100644 --- 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" - /> + - - - {{ !useAtIcon ? '@' : '' }} - + + + diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index a91c084f..3c3a95bd 100644 --- 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 index 6103fbdc..528c4fb2 100644 --- a/src/components/popover/popover.vue +++ b/src/components/popover/popover.vue @@ -1,5 +1,5 @@