make more components use new popover, fix some things
This commit is contained in:
parent
94eeca3e7e
commit
3c136c241f
16 changed files with 166 additions and 186 deletions
|
@ -12,7 +12,6 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
|
||||||
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||||
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
||||||
import PopoverTarget from './components/popover/popover_target.vue'
|
|
||||||
import { windowWidth } from './services/window_utils/window_utils'
|
import { windowWidth } from './services/window_utils/window_utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -31,8 +30,7 @@ export default {
|
||||||
MobilePostStatusButton,
|
MobilePostStatusButton,
|
||||||
MobileNav,
|
MobileNav,
|
||||||
UserReportingModal,
|
UserReportingModal,
|
||||||
PostStatusModal,
|
PostStatusModal
|
||||||
PopoverTarget
|
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
mobileActivePanel: 'timeline',
|
mobileActivePanel: 'timeline',
|
||||||
|
|
|
@ -123,7 +123,6 @@
|
||||||
<UserReportingModal />
|
<UserReportingModal />
|
||||||
<PostStatusModal />
|
<PostStatusModal />
|
||||||
<portal-target name="modal" />
|
<portal-target name="modal" />
|
||||||
<PopoverTarget />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ProgressButton from '../progress_button/progress_button.vue'
|
import ProgressButton from '../progress_button/progress_button.vue'
|
||||||
|
import Popover from '../popover/popover.vue'
|
||||||
|
|
||||||
const AccountActions = {
|
const AccountActions = {
|
||||||
props: [
|
props: [
|
||||||
|
@ -8,7 +9,8 @@ const AccountActions = {
|
||||||
return { }
|
return { }
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
ProgressButton
|
ProgressButton,
|
||||||
|
Popover
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showRepeats () {
|
showRepeats () {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="account-actions">
|
<div class="account-actions">
|
||||||
<v-popover
|
<Popover
|
||||||
trigger="click"
|
trigger="click"
|
||||||
class="account-tools-popover"
|
placement="bottom"
|
||||||
:container="false"
|
|
||||||
placement="bottom-end"
|
|
||||||
:offset="5"
|
|
||||||
>
|
>
|
||||||
<div slot="popover">
|
<div
|
||||||
|
slot="content"
|
||||||
|
class="account-tools-popover"
|
||||||
|
>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<template v-if="user.following">
|
<template v-if="user.following">
|
||||||
<button
|
<button
|
||||||
|
@ -51,10 +51,13 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn btn-default ellipsis-button">
|
<div
|
||||||
|
slot="trigger"
|
||||||
|
class="btn btn-default ellipsis-button"
|
||||||
|
>
|
||||||
<i class="icon-ellipsis trigger-button" />
|
<i class="icon-ellipsis trigger-button" />
|
||||||
</div>
|
</div>
|
||||||
</v-popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -67,6 +70,9 @@
|
||||||
margin: 0 .8em;
|
margin: 0 .8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.account-tools-popover {
|
||||||
|
}
|
||||||
|
|
||||||
.account-actions button.dropdown-item {
|
.account-actions button.dropdown-item {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
|
import Popover from '../popover/popover.vue'
|
||||||
|
|
||||||
const EMOJI_REACTION_COUNT_CUTOFF = 12
|
const EMOJI_REACTION_COUNT_CUTOFF = 12
|
||||||
|
|
||||||
const EmojiReactions = {
|
const EmojiReactions = {
|
||||||
name: 'EmojiReactions',
|
name: 'EmojiReactions',
|
||||||
components: {
|
components: {
|
||||||
UserAvatar
|
UserAvatar,
|
||||||
|
Popover
|
||||||
},
|
},
|
||||||
props: ['status'],
|
props: ['status'],
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="emoji-reactions">
|
<div class="emoji-reactions">
|
||||||
<v-popover
|
<Popover
|
||||||
v-for="(reaction) in emojiReactions"
|
v-for="(reaction) in emojiReactions"
|
||||||
:key="reaction.name"
|
:key="reaction.name"
|
||||||
:popper-options="popperOptions"
|
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
placement="top"
|
placement="top"
|
||||||
|
:offset="{ y: 5 }"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
slot="popover"
|
slot="content"
|
||||||
class="reacted-users"
|
class="reacted-users"
|
||||||
>
|
>
|
||||||
<div v-if="accountsForEmoji[reaction.name].length">
|
<div v-if="accountsForEmoji[reaction.name].length">
|
||||||
|
@ -34,6 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
slot="trigger"
|
||||||
class="emoji-reaction btn btn-default"
|
class="emoji-reaction btn btn-default"
|
||||||
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
|
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
|
||||||
@click="emojiOnClick(reaction.name, $event)"
|
@click="emojiOnClick(reaction.name, $event)"
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
<span class="reaction-emoji">{{ reaction.name }}</span>
|
<span class="reaction-emoji">{{ reaction.name }}</span>
|
||||||
<span>{{ reaction.count }}</span>
|
<span>{{ reaction.count }}</span>
|
||||||
</button>
|
</button>
|
||||||
</v-popover>
|
</Popover>
|
||||||
<a
|
<a
|
||||||
v-if="tooManyReactions"
|
v-if="tooManyReactions"
|
||||||
@click="toggleShowAll"
|
@click="toggleShowAll"
|
||||||
|
@ -78,6 +78,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
|
min-width: 5em;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 1em;
|
width: 1em;
|
||||||
|
|
|
@ -47,7 +47,10 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div slot="trigger" class="button-icon">
|
<div
|
||||||
|
slot="trigger"
|
||||||
|
class="button-icon"
|
||||||
|
>
|
||||||
<i class="icon-ellipsis" />
|
<i class="icon-ellipsis" />
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
@ -59,10 +62,6 @@
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
@import '../popper/popper.scss';
|
@import '../popper/popper.scss';
|
||||||
|
|
||||||
.dropdown-menu {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-ellipsis {
|
.icon-ellipsis {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ const Popover = {
|
||||||
props: [
|
props: [
|
||||||
'trigger',
|
'trigger',
|
||||||
'placement',
|
'placement',
|
||||||
'show'
|
'boundTo',
|
||||||
|
'padding',
|
||||||
|
'offset',
|
||||||
|
'popoverClass'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -31,55 +34,77 @@ const Popover = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
|
updateStyles () {
|
||||||
|
if (this.hidden) return { opacity: 0 }
|
||||||
|
|
||||||
|
// Popover will be anchored around this element
|
||||||
|
const anchorEl = this.$refs.trigger || this.$el
|
||||||
|
const screenBox = anchorEl.getBoundingClientRect()
|
||||||
|
// Screen position of the origin point for popover
|
||||||
|
const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top }
|
||||||
|
const content = this.$refs.content
|
||||||
|
const parentBounds = this.boundTo === 'container' && this.$el.offsetParent.getBoundingClientRect()
|
||||||
|
const padding = this.padding || {}
|
||||||
|
const bounds = this.boundTo === 'container'
|
||||||
|
? {
|
||||||
|
xMin: parentBounds.left + (padding.left || 0),
|
||||||
|
xMax: parentBounds.right - (padding.right || 0),
|
||||||
|
yMin: 0 + (padding.top || 50),
|
||||||
|
yMax: window.innerHeight - (padding.bottom || 5)
|
||||||
|
} : {
|
||||||
|
xMin: 0 + (padding.left || 10),
|
||||||
|
xMax: window.innerWidth - (padding.right || 10),
|
||||||
|
yMin: 0 + (padding.top || 50),
|
||||||
|
yMax: window.innerHeight - (padding.bottom || 5)
|
||||||
|
}
|
||||||
|
let horizOffset = 0
|
||||||
|
|
||||||
|
console.log(bounds, content.offsetWidth)
|
||||||
|
|
||||||
|
// If overflowing from left, move it
|
||||||
|
if ((origin.x - content.offsetWidth * 0.5) < bounds.xMin) {
|
||||||
|
horizOffset = -(origin.x - content.offsetWidth * 0.5) + bounds.xMin
|
||||||
|
}
|
||||||
|
|
||||||
|
// If overflowing from right, move it
|
||||||
|
if ((origin.x + horizOffset + content.offsetWidth * 0.5) > bounds.xMax) {
|
||||||
|
horizOffset -= (origin.x + horizOffset + content.offsetWidth * 0.5) - bounds.xMax
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
if (origin.y + content.offsetHeight > bounds.yMax) usingTop = true
|
||||||
|
if (origin.y - content.offsetHeight < bounds.yMin) usingTop = false
|
||||||
|
|
||||||
|
const yOffset = (this.offset && this.offset.y) || 0
|
||||||
|
const vertAlign = usingTop
|
||||||
|
? {
|
||||||
|
bottom: `${anchorEl.offsetHeight + yOffset}px`
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
top: `${anchorEl.offsetHeight + yOffset}px`
|
||||||
|
}
|
||||||
|
this.styles = {
|
||||||
|
opacity: '100%',
|
||||||
|
left: `${(anchorEl.offsetLeft + anchorEl.offsetWidth * 0.5) - content.offsetWidth * 0.5 + horizOffset}px`,
|
||||||
|
...vertAlign
|
||||||
|
}
|
||||||
|
},
|
||||||
showPopover () {
|
showPopover () {
|
||||||
|
if (this.hidden) this.$emit('show')
|
||||||
this.hidden = false
|
this.hidden = false
|
||||||
this.$nextTick(function () {
|
this.$nextTick(this.updateStyles)
|
||||||
if (this.hidden) return { opacity: 0 }
|
|
||||||
|
|
||||||
const anchorEl = this.$refs.trigger || this.$el
|
|
||||||
console.log(anchorEl)
|
|
||||||
const screenBox = anchorEl.getBoundingClientRect()
|
|
||||||
const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top}
|
|
||||||
const content = this.$refs.content
|
|
||||||
let horizOffset = 0
|
|
||||||
|
|
||||||
if ((origin.x - content.offsetWidth * 0.5) < 25) {
|
|
||||||
horizOffset += -(origin.x - content.offsetWidth * 0.5) + 25
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log((origin.x + content.offsetWidth * 0.5), (window.innerWidth - 25))
|
|
||||||
if ((origin.x + content.offsetWidth * 0.5) > window.innerWidth - 25) {
|
|
||||||
horizOffset -= (origin.x + content.offsetWidth * 0.5) - (window.innerWidth - 25)
|
|
||||||
}
|
|
||||||
// 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.
|
|
||||||
if (origin.y + content.offsetHeight > (window.innerHeight - 25)) usingTop = true
|
|
||||||
if (origin.y - content.offsetHeight < 50) usingTop = false
|
|
||||||
|
|
||||||
const vertAlign = usingTop ?
|
|
||||||
{
|
|
||||||
bottom: `${anchorEl.offsetHeight}px`
|
|
||||||
} :
|
|
||||||
{
|
|
||||||
top: `${anchorEl.offsetHeight}px`
|
|
||||||
}
|
|
||||||
this.styles = {
|
|
||||||
opacity: '100%',
|
|
||||||
left: `${(anchorEl.offsetLeft + anchorEl.offsetWidth * 0.5) - content.offsetWidth * 0.5 + horizOffset}px`,
|
|
||||||
...vertAlign
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
hidePopover () {
|
hidePopover () {
|
||||||
|
if (!this.hidden) this.$emit('close')
|
||||||
this.hidden = true
|
this.hidden = true
|
||||||
this.styles = { opacity: 0 }
|
this.styles = { opacity: 0 }
|
||||||
},
|
},
|
||||||
onMouseenter (e) {
|
onMouseenter (e) {
|
||||||
console.log(this.trigger)
|
|
||||||
if (this.trigger === 'hover') this.showPopover()
|
if (this.trigger === 'hover') this.showPopover()
|
||||||
},
|
},
|
||||||
onMouseleave (e) {
|
onMouseleave (e) {
|
||||||
|
@ -97,15 +122,18 @@ const Popover = {
|
||||||
onClickOutside (e) {
|
onClickOutside (e) {
|
||||||
if (this.hidden) return
|
if (this.hidden) return
|
||||||
if (this.$el.contains(e.target)) return
|
if (this.$el.contains(e.target)) return
|
||||||
console.log(e.target)
|
|
||||||
this.hidePopover()
|
this.hidePopover()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeUpdate () {
|
||||||
|
console.log('beforeupdate')
|
||||||
|
// if (!this.hidden) this.$nextTick(this.updateStyles)
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
document.addEventListener("click", this.onClickOutside)
|
document.addEventListener('click', this.onClickOutside)
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed () {
|
||||||
document.removeEventListener("click", this.onClickOutside)
|
document.removeEventListener('click', this.onClickOutside)
|
||||||
this.hidePopover()
|
this.hidePopover()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- This is for the weird portal shit
|
|
||||||
<div
|
|
||||||
@mouseenter="registerPopover"
|
|
||||||
@mouseleave="unregisterPopover"
|
|
||||||
>
|
|
||||||
<slot name="trigger"></slot>
|
|
||||||
<portal
|
|
||||||
v-if="targetId"
|
|
||||||
:to="targetId"
|
|
||||||
>
|
|
||||||
<slot name="content"></slot>
|
|
||||||
</portal>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<div
|
<div
|
||||||
@mouseenter="onMouseenter"
|
@mouseenter="onMouseenter"
|
||||||
@mouseleave="onMouseleave"
|
@mouseleave="onMouseleave"
|
||||||
>
|
>
|
||||||
<div @click="onClick" ref="trigger">
|
<div
|
||||||
<slot name="trigger"></slot>
|
ref="trigger"
|
||||||
|
@click="onClick"
|
||||||
|
>
|
||||||
|
<slot name="trigger" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="display"
|
v-if="display"
|
||||||
|
ref="content"
|
||||||
:style="styles"
|
:style="styles"
|
||||||
class="popover"
|
class="popover"
|
||||||
|
:class="popoverClass"
|
||||||
>
|
>
|
||||||
<div
|
<slot
|
||||||
ref="content"
|
name="content"
|
||||||
class="popover-inner"
|
class="popover-inner"
|
||||||
>
|
:close="hidePopover"
|
||||||
<!-- onSuccess is to mimic basic functionality of v-popover -->
|
/>
|
||||||
<slot
|
|
||||||
name="content"
|
|
||||||
@onSuccess="hidePopover"
|
|
||||||
></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -48,15 +34,14 @@
|
||||||
z-index: 8;
|
z-index: 8;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
|
||||||
.popover-inner {
|
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
||||||
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
box-shadow: var(--panelShadow);
|
||||||
box-shadow: var(--panelShadow);
|
border-radius: $fallback--btnRadius;
|
||||||
border-radius: $fallback--btnRadius;
|
border-radius: var(--btnRadius, $fallback--btnRadius);
|
||||||
border-radius: var(--btnRadius, $fallback--btnRadius);
|
background-color: $fallback--bg;
|
||||||
background-color: $fallback--bg;
|
background-color: var(--bg, $fallback--bg);
|
||||||
background-color: var(--bg, $fallback--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-arrow {
|
.popover-arrow {
|
||||||
width: 0;
|
width: 0;
|
||||||
|
|
|
@ -1,34 +1,25 @@
|
||||||
|
import Popover from '../popover/popover.vue'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
const ReactButton = {
|
const ReactButton = {
|
||||||
props: ['status', 'loggedIn'],
|
props: ['status', 'loggedIn'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showTooltip: false,
|
filterWord: ''
|
||||||
filterWord: '',
|
|
||||||
popperOptions: {
|
|
||||||
modifiers: {
|
|
||||||
preventOverflow: { padding: { top: 50 }, boundariesElement: 'viewport' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
Popover
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openReactionSelect () {
|
addReaction (event, emoji, close) {
|
||||||
this.showTooltip = true
|
|
||||||
this.filterWord = ''
|
|
||||||
},
|
|
||||||
closeReactionSelect () {
|
|
||||||
this.showTooltip = false
|
|
||||||
},
|
|
||||||
addReaction (event, emoji) {
|
|
||||||
const existingReaction = this.status.emoji_reactions.find(r => r.name === emoji)
|
const existingReaction = this.status.emoji_reactions.find(r => r.name === emoji)
|
||||||
if (existingReaction && existingReaction.me) {
|
if (existingReaction && existingReaction.me) {
|
||||||
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
|
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
|
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
|
||||||
}
|
}
|
||||||
this.closeReactionSelect()
|
close()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<v-popover
|
<Popover
|
||||||
:popper-options="popperOptions"
|
trigger="click"
|
||||||
:open="showTooltip"
|
|
||||||
trigger="manual"
|
|
||||||
placement="top"
|
placement="top"
|
||||||
class="react-button-popover"
|
class="react-button-popover"
|
||||||
@hide="closeReactionSelect"
|
|
||||||
>
|
>
|
||||||
<div slot="popover">
|
<div
|
||||||
|
slot="content"
|
||||||
|
slot-scope="{close}"
|
||||||
|
>
|
||||||
<div class="reaction-picker-filter">
|
<div class="reaction-picker-filter">
|
||||||
<input
|
<input
|
||||||
v-model="filterWord"
|
v-model="filterWord"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
v-for="emoji in commonEmojis"
|
v-for="emoji in commonEmojis"
|
||||||
:key="emoji"
|
:key="emoji"
|
||||||
class="emoji-button"
|
class="emoji-button"
|
||||||
@click="addReaction($event, emoji)"
|
@click="addReaction($event, emoji, close)"
|
||||||
>
|
>
|
||||||
{{ emoji }}
|
{{ emoji }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
v-for="(emoji, key) in emojis"
|
v-for="(emoji, key) in emojis"
|
||||||
:key="key"
|
:key="key"
|
||||||
class="emoji-button"
|
class="emoji-button"
|
||||||
@click="addReaction($event, emoji.replacement)"
|
@click="addReaction($event, emoji.replacement, close)"
|
||||||
>
|
>
|
||||||
{{ emoji.replacement }}
|
{{ emoji.replacement }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="loggedIn"
|
v-if="loggedIn"
|
||||||
@click.prevent="openReactionSelect"
|
slot="trigger"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="icon-smile button-icon add-reaction-button"
|
class="icon-smile button-icon add-reaction-button"
|
||||||
:title="$t('tool_tip.add_reaction')"
|
:title="$t('tool_tip.add_reaction')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</v-popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./react_button.js" ></script>
|
<script src="./react_button.js" ></script>
|
||||||
|
|
|
@ -177,6 +177,8 @@
|
||||||
<StatusPopover
|
<StatusPopover
|
||||||
v-if="!isPreview"
|
v-if="!isPreview"
|
||||||
:status-id="status.in_reply_to_status_id"
|
:status-id="status.in_reply_to_status_id"
|
||||||
|
class="reply-to-popover"
|
||||||
|
style="min-width: 0"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="reply-to"
|
class="reply-to"
|
||||||
|
@ -564,11 +566,10 @@ $status-margin: 0.75em;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
|
||||||
> .reply-to-and-accountname > a {
|
> .reply-to-and-accountname > a {
|
||||||
|
overflow: hidden;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: inline-block;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,7 +578,6 @@ $status-margin: 0.75em;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
overflow: hidden;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
.icon-reply {
|
.icon-reply {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
|
@ -588,6 +588,10 @@ $status-margin: 0.75em;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-to-popover {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.reply-to {
|
.reply-to {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -595,6 +599,7 @@ $status-margin: 0.75em;
|
||||||
.reply-to-text {
|
.reply-to-text {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
margin: 0 0.4em 0 0.2em;
|
margin: 0 0.4em 0 0.2em;
|
||||||
color: $fallback--faint;
|
color: $fallback--faint;
|
||||||
color: var(--faint, $fallback--faint);
|
color: var(--faint, $fallback--faint);
|
||||||
|
|
|
@ -5,15 +5,6 @@ const StatusPopover = {
|
||||||
props: [
|
props: [
|
||||||
'statusId'
|
'statusId'
|
||||||
],
|
],
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
popperOptions: {
|
|
||||||
modifiers: {
|
|
||||||
preventOverflow: { padding: { top: 50 }, boundariesElement: 'viewport' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
status () {
|
status () {
|
||||||
return find(this.$store.state.statuses.allStatuses, { id: this.statusId })
|
return find(this.$store.state.statuses.allStatuses, { id: this.statusId })
|
||||||
|
@ -28,6 +19,7 @@ const StatusPopover = {
|
||||||
if (!this.status) {
|
if (!this.status) {
|
||||||
this.$store.dispatch('fetchStatus', this.statusId)
|
this.$store.dispatch('fetchStatus', this.statusId)
|
||||||
}
|
}
|
||||||
|
console.log(this.$el.offsetParent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<Popover trigger="hover">
|
<Popover
|
||||||
|
trigger="hover"
|
||||||
|
bound-to="container"
|
||||||
|
popover-class="status-popover"
|
||||||
|
@show="enter"
|
||||||
|
>
|
||||||
<template slot="trigger">
|
<template slot="trigger">
|
||||||
<slot />
|
<slot />
|
||||||
</template>
|
</template>
|
||||||
<div slot="content" class="status-popover">
|
<div
|
||||||
|
slot="content"
|
||||||
|
>
|
||||||
<Status
|
<Status
|
||||||
v-if="status"
|
v-if="status"
|
||||||
:is-preview="true"
|
:is-preview="true"
|
||||||
|
@ -31,16 +38,14 @@
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
|
|
||||||
.popover-inner {
|
border-color: $fallback--border;
|
||||||
border-color: $fallback--border;
|
border-color: var(--border, $fallback--border);
|
||||||
border-color: var(--border, $fallback--border);
|
border-style: solid;
|
||||||
border-style: solid;
|
border-width: 1px;
|
||||||
border-width: 1px;
|
border-radius: $fallback--tooltipRadius;
|
||||||
border-radius: $fallback--tooltipRadius;
|
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-arrow::before {
|
.popover-arrow::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import oauthTokensModule from './modules/oauth_tokens.js'
|
||||||
import reportsModule from './modules/reports.js'
|
import reportsModule from './modules/reports.js'
|
||||||
import pollsModule from './modules/polls.js'
|
import pollsModule from './modules/polls.js'
|
||||||
import postStatusModule from './modules/postStatus.js'
|
import postStatusModule from './modules/postStatus.js'
|
||||||
import popoverModule from './modules/popover.js'
|
|
||||||
|
|
||||||
import VueI18n from 'vue-i18n'
|
import VueI18n from 'vue-i18n'
|
||||||
|
|
||||||
|
@ -90,8 +89,7 @@ const persistedStateOptions = {
|
||||||
oauthTokens: oauthTokensModule,
|
oauthTokens: oauthTokensModule,
|
||||||
reports: reportsModule,
|
reports: reportsModule,
|
||||||
polls: pollsModule,
|
polls: pollsModule,
|
||||||
postStatus: postStatusModule,
|
postStatus: postStatusModule
|
||||||
popover: popoverModule
|
|
||||||
},
|
},
|
||||||
plugins: [persistedState, pushNotifications],
|
plugins: [persistedState, pushNotifications],
|
||||||
strict: false // Socket modifies itself, let's ignore this for now.
|
strict: false // Socket modifies itself, let's ignore this for now.
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { omit } from 'lodash'
|
|
||||||
import { set } from 'vue'
|
|
||||||
|
|
||||||
const popover = {
|
|
||||||
state: {
|
|
||||||
popovers: {}
|
|
||||||
},
|
|
||||||
mutations: {
|
|
||||||
registerPopover (state, { id, el }) {
|
|
||||||
set(state.popovers, id, el)
|
|
||||||
},
|
|
||||||
unregisterPopover (state, { id }) {
|
|
||||||
state.popovers = omit(state.popovers, id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
registerPopover (store, el) {
|
|
||||||
// Generate unique id, it will be used to link portal and portal-target
|
|
||||||
// popover-target will make portal targets for each registered popover
|
|
||||||
// el will be used by popover target to put popovers in their places.
|
|
||||||
let id = Math.floor(Math.random() * 1000000).toString()
|
|
||||||
store.commit('registerPopover', { id, el })
|
|
||||||
return id
|
|
||||||
},
|
|
||||||
unregisterPopover (store, id) {
|
|
||||||
store.commit('unregisterPopover', { id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default popover
|
|
Loading…
Reference in a new issue