logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 7c633aa9525c8a0533281947c587ff1a5ded75ec
parent 3628fb4272c0b9f5a66f0de61e6c4f37f4908fe7
Author: Henry Jameson <me@hjkos.com>
Date:   Mon, 13 Jun 2022 13:45:04 +0300

user popovers WIP

Diffstat:

Msrc/components/popover/popover.js91++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/components/popover/popover.vue2+-
Msrc/components/status/status.js4+++-
Msrc/components/status/status.vue38+++++++++++++++++++++++++++-----------
4 files changed, 84 insertions(+), 51 deletions(-)

diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js @@ -34,7 +34,13 @@ const Popover = { removePadding: Boolean, // 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 () { return { @@ -73,7 +79,9 @@ const Popover = { x: anchorScreenBox.left + anchorWidth * 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 const parentScreenBox = this.boundTo && @@ -100,44 +108,51 @@ const Popover = { max: window.innerHeight - (margin.bottom || 5) } - let horizOffset = content.offsetWidth * -0.5 - const leftBorder = origin.x + horizOffset - const rightBorder = origin.x - horizOffset - // If overflowing from left, move it so that it doesn't - if (leftBorder < xBounds.min) { - horizOffset += xBounds.min - leftBorder - } + if (!this.overlayCenters) { + let horizOffset = content.offsetWidth * -0.5 + const leftBorder = origin.x + horizOffset + const rightBorder = origin.x - horizOffset + // If overflowing from left, move it so that it doesn't + if (leftBorder < xBounds.min) { + horizOffset += xBounds.min - leftBorder + } - // If overflowing from right, move it so that it doesn't - if (rightBorder > xBounds.max) { - horizOffset -= rightBorder - xBounds.max - } + // If overflowing from right, move it so that it doesn't + if (rightBorder > xBounds.max) { + horizOffset -= rightBorder - xBounds.max + } + + // Default to whatever user wished with placement prop + let usingTop = this.placement !== 'bottom' - // Default to whatever user wished with placement prop - let usingTop = this.placement !== '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 - // force to bottom, again regardless of what placement value was. - const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0) - const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0) - if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true - if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false - - const yOffset = (this.offset && this.offset.y) || 0 - const translateY = usingTop - ? topBoundary - yOffset - content.offsetHeight - : bottomBoundary + yOffset - - const xOffset = (this.offset && this.offset.x) || 0 - const translateX = origin.x + horizOffset + xOffset - - // Note, separate translateX and translateY avoids blurry text on chromium, - // single translate or translate3d resulted in blurry text. - this.styles = { - left: `${Math.round(translateX)}px`, - top: `${Math.round(translateY)}px`, - position: 'fixed' + // 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 + // force to bottom, again regardless of what placement value was. + const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0) + const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0) + if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true + if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false + + const yOffset = (this.offset && this.offset.y) || 0 + const translateY = usingTop + ? topBoundary - yOffset - content.offsetHeight + : bottomBoundary + yOffset + + const xOffset = (this.offset && this.offset.x) || 0 + const translateX = origin.x + horizOffset + xOffset + + this.styles = { + left: `${Math.round(translateX)}px`, + top: `${Math.round(translateY)}px` + } + } else { + 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) { diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue @@ -44,7 +44,7 @@ .popover { z-index: 90000; - position: absolute; + position: fixed; min-width: 0; box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); box-shadow: var(--popupShadow); diff --git a/src/components/status/status.js b/src/components/status/status.js @@ -11,6 +11,7 @@ import Timeago from '../timeago/timeago.vue' import StatusContent from '../status_content/status_content.vue' import RichContent from 'src/components/rich_content/rich_content.jsx' 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 EmojiReactions from '../emoji_reactions/emoji_reactions.vue' import MentionsLine from 'src/components/mentions_line/mentions_line.vue' @@ -115,7 +116,8 @@ const Status = { StatusContent, RichContent, MentionLink, - MentionsLine + MentionsLine, + Popover }, props: [ 'statusoid', diff --git a/src/components/status/status.vue b/src/components/status/status.vue @@ -122,17 +122,33 @@ v-if="!noHeading" class="left-side" > - <a - :href="$router.resolve(userProfileLink).href" - @click.stop.prevent.capture="toggleUserExpanded" - > - <UserAvatar - class="post-avatar" - :bot="botIndicator" - :compact="compact" - :better-shadow="betterShadow" - :user="status.user" - /> + <a :href="$router.resolve(userProfileLink).href" @click.prevent> + <Popover + trigger="click" + popover-class="popover-default user-popover" + :overlay-centers="true" + overlay-centers-selector=".user-info-avatar-link .Avatar" + > + <template v-slot:trigger> + <UserAvatar + 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> </div> <div class="right-side">