Merge remote-tracking branch 'origin/disjointed-popovers' into disjointed-popovers

* origin/disjointed-popovers:
  popover controls for user-card
  unify user popovers into a separate component
This commit is contained in:
Henry Jameson 2022-06-20 23:57:44 +03:00
commit 01e56a3e10
12 changed files with 205 additions and 151 deletions

View File

@ -16,8 +16,7 @@ const MentionLink = {
name: 'MentionLink', name: 'MentionLink',
components: { components: {
UserAvatar, UserAvatar,
Popover: defineAsyncComponent(() => import('../popover/popover.vue')), UserPopover: defineAsyncComponent(() => import('../user_popover/user_popover.vue'))
UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue'))
}, },
props: { props: {
url: { url: {

View File

@ -10,14 +10,11 @@
target="_blank" target="_blank"
v-html="content" v-html="content"
/><!-- eslint-enable vue/no-v-html --> /><!-- eslint-enable vue/no-v-html -->
<Popover <UserPopover
trigger="click" v-else
:bound-to="{ x: 'container'}" :userId="user.id"
bound-to-selector=".column"
popover-class="popover-default mention-popover"
:disabled="!shouldShowTooltip" :disabled="!shouldShowTooltip"
> >
<template v-slot:trigger>
<span <span
v-if="user" v-if="user"
class="new" class="new"
@ -76,18 +73,8 @@
<!-- eslint-enable vue/no-v-html --> <!-- eslint-enable vue/no-v-html -->
</span> </span>
</span> </span>
</span></template> </span>
<template v-slot:content> </UserPopover>
<UserCard
class="mention-link-popover"
:user-id="user.id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</span> </span>
</template> </template>

View File

@ -5,7 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
import UserCard from '../user_card/user_card.vue' import UserCard from '../user_card/user_card.vue'
import Timeago from '../timeago/timeago.vue' import Timeago from '../timeago/timeago.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import Popover from '../popover/popover.vue' import UserPopover from '../user_popover/user_popover.vue'
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js' import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@ -48,7 +48,7 @@ const Notification = {
Timeago, Timeago,
Status, Status,
RichContent, RichContent,
Popover UserPopover
}, },
methods: { methods: {
toggleUserExpanded () { toggleUserExpanded () {

View File

@ -36,13 +36,10 @@
:href="$router.resolve(userProfileLink).href" :href="$router.resolve(userProfileLink).href"
@click.prevent @click.prevent
> >
<Popover <UserPopover
trigger="click" :userId="notification.from_profile.id"
popover-class="popover-default user-popover" :overlayCenters="true"
:overlay-centers="true"
overlay-centers-selector=".user-info-avatar-link .Avatar"
> >
<template v-slot:trigger>
<UserAvatar <UserAvatar
class="post-avatar" class="post-avatar"
:bot="botIndicator" :bot="botIndicator"
@ -50,18 +47,7 @@
:better-shadow="betterShadow" :better-shadow="betterShadow"
:user="notification.from_profile" :user="notification.from_profile"
/> />
</template> </UserPopover>
<template v-slot:content>
<UserCard
class="mention-link-popover"
:user-id="getUser(notification).id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</a> </a>
<div class="notification-right"> <div class="notification-right">
<span class="notification-details"> <span class="notification-details">

View File

@ -81,7 +81,7 @@ const Popover = {
y: anchorScreenBox.top + anchorHeight * 0.5 y: anchorScreenBox.top + anchorHeight * 0.5
} }
const content = this.$refs.content const content = this.$refs.content
const overlayCenter = this.overlayCentersSelector const overlayCenter = this.overlayCenters
? this.$refs.content.querySelector(this.overlayCentersSelector) ? this.$refs.content.querySelector(this.overlayCentersSelector)
: null : null

View File

@ -4,14 +4,13 @@ import ReactButton from '../react_button/react_button.vue'
import RetweetButton from '../retweet_button/retweet_button.vue' import RetweetButton from '../retweet_button/retweet_button.vue'
import ExtraButtons from '../extra_buttons/extra_buttons.vue' import ExtraButtons from '../extra_buttons/extra_buttons.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue' import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCard from '../user_card/user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue' import UserAvatar from '../user_avatar/user_avatar.vue'
import AvatarList from '../avatar_list/avatar_list.vue' import AvatarList from '../avatar_list/avatar_list.vue'
import Timeago from '../timeago/timeago.vue' 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 UserPopover from '../user_popover/user_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'
@ -106,7 +105,6 @@ const Status = {
RetweetButton, RetweetButton,
ExtraButtons, ExtraButtons,
PostStatusForm, PostStatusForm,
UserCard,
UserAvatar, UserAvatar,
AvatarList, AvatarList,
Timeago, Timeago,
@ -117,7 +115,7 @@ const Status = {
RichContent, RichContent,
MentionLink, MentionLink,
MentionsLine, MentionsLine,
Popover UserPopover
}, },
props: [ props: [
'statusoid', 'statusoid',

View File

@ -123,13 +123,10 @@
class="left-side" class="left-side"
> >
<a :href="$router.resolve(userProfileLink).href" @click.prevent> <a :href="$router.resolve(userProfileLink).href" @click.prevent>
<Popover <UserPopover
trigger="click" :userId="status.user.id"
popover-class="popover-default user-popover" :overlayCenters="true"
:overlay-centers="true"
overlay-centers-selector=".user-info-avatar-link .Avatar"
> >
<template v-slot:trigger>
<UserAvatar <UserAvatar
class="post-avatar" class="post-avatar"
:bot="botIndicator" :bot="botIndicator"
@ -137,28 +134,10 @@
:better-shadow="betterShadow" :better-shadow="betterShadow"
:user="status.user" :user="status.user"
/> />
</template> </UserPopover>
<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">
<UserCard
v-if="userExpanded"
:user-id="status.user.id"
:rounded="true"
:bordered="true"
class="usercard"
/>
<div <div
v-if="!noHeading" v-if="!noHeading"
class="status-heading" class="status-heading"

View File

@ -14,7 +14,9 @@ import {
faRss, faRss,
faSearchPlus, faSearchPlus,
faExternalLinkAlt, faExternalLinkAlt,
faEdit faEdit,
faTimes,
faExpandAlt
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
@ -22,12 +24,21 @@ library.add(
faBell, faBell,
faSearchPlus, faSearchPlus,
faExternalLinkAlt, faExternalLinkAlt,
faEdit faEdit,
faTimes,
faExpandAlt
) )
export default { export default {
props: [ props: [
'userId', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar' 'userId',
'switcher',
'selected',
'hideBio',
'rounded',
'bordered',
'allowZoomingAvatar',
'onClose'
], ],
data () { data () {
return { return {
@ -47,9 +58,10 @@ export default {
}, },
classes () { classes () {
return [{ return [{
'user-card-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius '-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius
'user-card-rounded': this.rounded === true, // set border-radius for all sides '-rounded': this.rounded === true, // set border-radius for all sides
'user-card-bordered': this.bordered === true // set border for all sides '-bordered': this.bordered === true, // set border for all sides
'-popover': !!this.onClose // set popover rounding
}] }]
}, },
style () { style () {

View File

@ -42,8 +42,10 @@
mask-composite: exclude; mask-composite: exclude;
background-size: cover; background-size: cover;
mask-size: 100% 60%; mask-size: 100% 60%;
border-top-left-radius: calc(var(--panelRadius) - 1px); border-top-left-radius: calc(var(--__roundnessTop, --panelRadius) - 1px);
border-top-right-radius: calc(var(--panelRadius) - 1px); border-top-right-radius: calc(var(--__roundnessTop, --panelRadius) - 1px);
border-bottom-left-radius: calc(var(--__roundnessBottom, --panelRadius) - 1px);
border-bottom-right-radius: calc(var(--__roundnessBottom, --panelRadius) - 1px);
background-color: var(--profileBg); background-color: var(--profileBg);
z-index: -2; z-index: -2;
@ -72,21 +74,33 @@
} }
} }
// Modifiers &.-rounded-t {
&-rounded-t {
border-top-left-radius: $fallback--panelRadius; border-top-left-radius: $fallback--panelRadius;
border-top-left-radius: var(--panelRadius, $fallback--panelRadius); border-top-left-radius: var(--panelRadius, $fallback--panelRadius);
border-top-right-radius: $fallback--panelRadius; border-top-right-radius: $fallback--panelRadius;
border-top-right-radius: var(--panelRadius, $fallback--panelRadius); border-top-right-radius: var(--panelRadius, $fallback--panelRadius);
--__roundnessTop: var(--panelRadius);
--__roundnessBottom: 0;
} }
&-rounded { &.-rounded {
border-radius: $fallback--panelRadius; border-radius: $fallback--panelRadius;
border-radius: var(--panelRadius, $fallback--panelRadius); border-radius: var(--panelRadius, $fallback--panelRadius);
--__roundnessTop: var(--panelRadius);
--__roundnessBottom: var(--panelRadius);
} }
&-bordered { &.-popover {
border-radius: $fallback--tooltipRadius;
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
--__roundnessTop: var(--tooltipRadius);
--__roundnessBottom: var(--tooltipRadius);
}
&.-bordered {
border-width: 1px; border-width: 1px;
border-style: solid; border-style: solid;
border-color: $fallback--border; border-color: $fallback--border;
@ -99,6 +113,15 @@
color: var(--lightText, $fallback--lightText); color: var(--lightText, $fallback--lightText);
padding: 0 26px; padding: 0 26px;
a {
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
&:hover {
color: var(--icon);
}
}
.container { .container {
min-width: 0; min-width: 0;
padding: 16px 0 6px; padding: 16px 0 6px;
@ -206,8 +229,6 @@
flex: 0 1 auto; flex: 0 1 auto;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
} }
.dailyAvg { .dailyAvg {

View File

@ -8,7 +8,7 @@
:style="style" :style="style"
class="background-image" class="background-image"
/> />
<div class="panel-heading -flexible-height"> <div :class="onClose ? '' : panel-heading -flexible-height">
<div class="user-info"> <div class="user-info">
<div class="container"> <div class="container">
<a <a
@ -38,12 +38,16 @@
</router-link> </router-link>
<div class="user-summary"> <div class="user-summary">
<div class="top-line"> <div class="top-line">
<router-link
:to="userProfileLink(user)"
class="user-name"
>
<RichContent <RichContent
:title="user.name" :title="user.name"
class="user-name"
:html="user.name" :html="user.name"
:emoji="user.emoji" :emoji="user.emoji"
/> />
</router-link>
<button <button
v-if="!isOtherUser && user.is_local" v-if="!isOtherUser && user.is_local"
class="button-unstyled edit-profile-button" class="button-unstyled edit-profile-button"
@ -72,6 +76,27 @@
:user="user" :user="user"
:relationship="relationship" :relationship="relationship"
/> />
<router-link
v-if="onClose"
:to="userProfileLink(user)"
class="button-unstyled external-link-button"
@click="onClose"
>
<FAIcon
class="icon"
icon="expand-alt"
/>
</router-link>
<button
v-if="onClose"
class="button-unstyled external-link-button"
@click="onClose"
>
<FAIcon
class="icon"
icon="times"
/>
</button>
</div> </div>
<div class="bottom-line"> <div class="bottom-line">
<router-link <router-link

View File

@ -0,0 +1,14 @@
import { defineAsyncComponent } from 'vue'
const UserPopover = {
name: 'UserPopover',
props: [
'userId', 'overlayCenters', 'disabled'
],
components: {
UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue')),
Popover: defineAsyncComponent(() => import('../popover/popover.vue'))
}
}
export default UserPopover

View File

@ -0,0 +1,33 @@
<template>
<Popover
trigger="click"
popover-class="popover-default user-popover"
overlay-centers-selector=".user-info-avatar-link .Avatar"
:overlay-centers="overlayCenters"
:disabled="disabled"
>
<template v-slot:trigger>
<slot />
</template>
<template v-slot:content={close}>
<UserCard
class="user-popover"
:user-id="userId"
:hide-bio="true"
:allow-zooming-avatar="true"
:onClose="close"
/>
</template>
</Popover>
</template>
<script src="./user_popover.js" ></script>
<style lang="scss">
@import '../../_variables.scss';
/* popover styles load on-demand, so we need to override */
.user-popover.popover {
}
</style>