user popovers WIP

This commit is contained in:
Henry Jameson 2022-06-13 13:45:04 +03:00
parent 3628fb4272
commit 7c633aa952
4 changed files with 80 additions and 47 deletions

View File

@ -34,7 +34,13 @@ const Popover = {
removePadding: Boolean, removePadding: Boolean,
// self-explanatory (i hope) // self-explanatory (i hope)
disabled: Boolean disabled: Boolean,
// Instead of putting popover next to anchor, overlay popover's center on top of anchor's center
overlayCenters: Boolean,
// What selector (witin popover!) to use for determining center of popover
overlayCentersSelector: String
}, },
data () { data () {
return { return {
@ -73,7 +79,9 @@ const Popover = {
x: anchorScreenBox.left + anchorWidth * 0.5, x: anchorScreenBox.left + anchorWidth * 0.5,
y: anchorScreenBox.top + anchorHeight * 0.5 y: anchorScreenBox.top + anchorHeight * 0.5
} }
const content = this.$refs.content const content = this.overlayCentersSelector
? this.$refs.content.querySelector(this.overlayCentersSelector)
: this.$refs.content
// Minor optimization, don't call a slow reflow call if we don't have to // Minor optimization, don't call a slow reflow call if we don't have to
const parentScreenBox = this.boundTo && const parentScreenBox = this.boundTo &&
@ -100,44 +108,51 @@ const Popover = {
max: window.innerHeight - (margin.bottom || 5) max: window.innerHeight - (margin.bottom || 5)
} }
let horizOffset = content.offsetWidth * -0.5 if (!this.overlayCenters) {
const leftBorder = origin.x + horizOffset let horizOffset = content.offsetWidth * -0.5
const rightBorder = origin.x - horizOffset const leftBorder = origin.x + horizOffset
// If overflowing from left, move it so that it doesn't const rightBorder = origin.x - horizOffset
if (leftBorder < xBounds.min) { // If overflowing from left, move it so that it doesn't
horizOffset += xBounds.min - leftBorder if (leftBorder < xBounds.min) {
} horizOffset += xBounds.min - leftBorder
}
// If overflowing from right, move it so that it doesn't // If overflowing from right, move it so that it doesn't
if (rightBorder > xBounds.max) { if (rightBorder > xBounds.max) {
horizOffset -= rightBorder - xBounds.max horizOffset -= rightBorder - xBounds.max
} }
// Default to whatever user wished with placement prop // Default to whatever user wished with placement prop
let usingTop = this.placement !== 'bottom' let usingTop = this.placement !== 'bottom'
// Handle special cases, first force to displaying on top if there's not space on bottom, // Handle special cases, first force to displaying on top if there's not space on bottom,
// regardless of what placement value was. Then check if there's not space on top, and // regardless of what placement value was. Then check if there's not space on top, and
// force to bottom, again regardless of what placement value was. // force to bottom, again regardless of what placement value was.
const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0) const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0)
const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0) const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0)
if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true
if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false
const yOffset = (this.offset && this.offset.y) || 0 const yOffset = (this.offset && this.offset.y) || 0
const translateY = usingTop const translateY = usingTop
? topBoundary - yOffset - content.offsetHeight ? topBoundary - yOffset - content.offsetHeight
: bottomBoundary + yOffset : bottomBoundary + yOffset
const xOffset = (this.offset && this.offset.x) || 0 const xOffset = (this.offset && this.offset.x) || 0
const translateX = origin.x + horizOffset + xOffset const translateX = origin.x + horizOffset + xOffset
// Note, separate translateX and translateY avoids blurry text on chromium, this.styles = {
// single translate or translate3d resulted in blurry text. left: `${Math.round(translateX)}px`,
this.styles = { top: `${Math.round(translateY)}px`
left: `${Math.round(translateX)}px`, }
top: `${Math.round(translateY)}px`, } else {
position: 'fixed' const translateY = origin.y - content.offsetHeight
const translateX = origin.x - content.offsetWidth
this.styles = {
left: `${Math.round(translateX)}px`,
top: `${Math.round(translateY)}px`
}
} }
if (parentScreenBox) { if (parentScreenBox) {

View File

@ -44,7 +44,7 @@
.popover { .popover {
z-index: 90000; z-index: 90000;
position: absolute; position: fixed;
min-width: 0; min-width: 0;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
box-shadow: var(--popupShadow); box-shadow: var(--popupShadow);

View File

@ -11,6 +11,7 @@ import Timeago from '../timeago/timeago.vue'
import StatusContent from '../status_content/status_content.vue' import StatusContent from '../status_content/status_content.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import StatusPopover from '../status_popover/status_popover.vue' import StatusPopover from '../status_popover/status_popover.vue'
import Popover from '../popover/popover.vue'
import UserListPopover from '../user_list_popover/user_list_popover.vue' import UserListPopover from '../user_list_popover/user_list_popover.vue'
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
import MentionsLine from 'src/components/mentions_line/mentions_line.vue' import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
@ -115,7 +116,8 @@ const Status = {
StatusContent, StatusContent,
RichContent, RichContent,
MentionLink, MentionLink,
MentionsLine MentionsLine,
Popover
}, },
props: [ props: [
'statusoid', 'statusoid',

View File

@ -122,17 +122,33 @@
v-if="!noHeading" v-if="!noHeading"
class="left-side" class="left-side"
> >
<a <a :href="$router.resolve(userProfileLink).href" @click.prevent>
:href="$router.resolve(userProfileLink).href" <Popover
@click.stop.prevent.capture="toggleUserExpanded" trigger="click"
> popover-class="popover-default user-popover"
<UserAvatar :overlay-centers="true"
class="post-avatar" overlay-centers-selector=".user-info-avatar-link .Avatar"
:bot="botIndicator" >
:compact="compact" <template v-slot:trigger>
:better-shadow="betterShadow" <UserAvatar
:user="status.user" class="post-avatar"
/> :bot="botIndicator"
:compact="compact"
:better-shadow="betterShadow"
:user="status.user"
/>
</template>
<template v-slot:content>
<UserCard
class="mention-link-popover"
:user-id="status.user.id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</a> </a>
</div> </div>
<div class="right-side"> <div class="right-side">