change how status content user popovers work, switching doesnt work right now

This commit is contained in:
Shpuld Shpuldson 2020-07-23 12:30:50 +03:00
parent 7cf6fc32c0
commit e785fbb3c3
6 changed files with 58 additions and 37 deletions

View File

@ -23,7 +23,9 @@ const Popover = {
// Additional styles you may want for the popover container // Additional styles you may want for the popover container
popoverClass: String, popoverClass: String,
// Time in milliseconds until the popup appears, default is 100ms // Time in milliseconds until the popup appears, default is 100ms
delay: Number delay: Number,
// If disabled, don't show popover even when trigger conditions met
disabled: Boolean
}, },
data () { data () {
return { return {
@ -38,6 +40,13 @@ const Popover = {
return this.$store.state.interface.mobileLayout return this.$store.state.interface.mobileLayout
} }
}, },
watch: {
disabled (newValue, oldValue) {
if (newValue === true) {
this.hidePopover()
}
}
},
methods: { methods: {
containerBoundingClientRect () { containerBoundingClientRect () {
const container = this.boundToSelector ? this.$el.closest(this.boundToSelector) : this.$el.offsetParent const container = this.boundToSelector ? this.$el.closest(this.boundToSelector) : this.$el.offsetParent
@ -127,12 +136,19 @@ const Popover = {
} }
}, },
showPopover () { showPopover () {
if (this.hidden) this.$emit('show') if (this.disabled) return
if (this.hidden) {
this.$emit('show')
document.addEventListener('click', this.onClickOutside, true)
}
this.hidden = false this.hidden = false
this.$nextTick(this.updateStyles) this.$nextTick(this.updateStyles)
}, },
hidePopover () { hidePopover () {
if (!this.hidden) this.$emit('close') if (!this.hidden) {
this.$emit('close')
document.removeEventListener('click', this.onClickOutside, true)
}
if (this.timeout) { if (this.timeout) {
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.timeout = null this.timeout = null
@ -158,8 +174,7 @@ const Popover = {
} else { } else {
this.hidePopover() this.hidePopover()
} }
} else if (this.trigger === 'hover' && this.isMobileLayout) { } else if ((this.trigger === 'hover') && this.isMobileLayout) {
console.log(this.isMobileLayout)
// This is to enable using hover stuff with mobile: // This is to enable using hover stuff with mobile:
// on first touch it opens the popover, when touching the trigger // on first touch it opens the popover, when touching the trigger
// again it will do the click action. Can't use touch events as // again it will do the click action. Can't use touch events as
@ -169,11 +184,11 @@ const Popover = {
this.$emit('enter') this.$emit('enter')
this.showPopover() this.showPopover()
e.preventDefault() e.preventDefault()
e.stopPropagation()
} }
} }
}, },
onClickOutside (e) { onClickOutside (e) {
console.log('onClickOutside')
if (this.hidden) return if (this.hidden) return
if (this.$el.contains(e.target)) return if (this.$el.contains(e.target)) return
this.hidePopover() this.hidePopover()
@ -192,11 +207,7 @@ const Popover = {
this.oldSize = { width: content.offsetWidth, height: content.offsetHeight } this.oldSize = { width: content.offsetWidth, height: content.offsetHeight }
} }
}, },
created () {
document.addEventListener('click', this.onClickOutside)
},
destroyed () { destroyed () {
document.removeEventListener('click', this.onClickOutside)
this.hidePopover() this.hidePopover()
} }
} }

View File

@ -153,6 +153,17 @@ const StatusContent = {
}) })
}, },
methods: { methods: {
setUserPopoverTarget (event, target, attn) {
// event.stopPropagation()
// event.preventDefault()
this.focusedUserId = attn.id
// Give the popover an offset to place it over the hovered element
const containerWidth = this.$refs.userPopover.$el.offsetWidth
const elementWidth = target.offsetWidth
const x = -containerWidth / 2 + target.offsetLeft + elementWidth / 2
const y = target.offsetTop
this.userPopoverOffset = { x, y, h: target.offsetHeight }
},
linkClicked (event) { linkClicked (event) {
const target = event.target.closest('.status-content a') const target = event.target.closest('.status-content a')
if (target) { if (target) {
@ -160,8 +171,10 @@ const StatusContent = {
const href = target.href const href = target.href
const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href))
if (attn) { if (attn) {
event.stopPropagation() if (this.$store.state.interface.mobileLayout) {
event.preventDefault() this.setUserPopoverTarget(event, target, attn)
return
}
const link = this.generateUserProfileLink(attn.id, attn.screen_name) const link = this.generateUserProfileLink(attn.id, attn.screen_name)
this.$router.push(link) this.$router.push(link)
return return
@ -177,29 +190,23 @@ const StatusContent = {
} }
} }
window.open(target.href, '_blank') window.open(target.href, '_blank')
event.preventDefault()
} }
}, },
linkHover (event) { linkHover (event) {
const target = event.target.closest('.status-content a') const target = event.target.closest('.status-content a')
this.focusedUserId = null this.focusedUserId = null
console.log('hover first')
if (target) { if (target) {
if (target.className.match(/mention/)) { if (target.className.match(/mention/)) {
const href = target.href const href = target.href
const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href))
if (attn) { if (attn) {
event.stopPropagation() this.setUserPopoverTarget(event, target, attn)
event.preventDefault()
this.focusedUserId = attn.id
// Give the popover an offset to place it over the hovered element
const containerWidth = this.$refs.userPopover.$el.offsetWidth
const elementWidth = target.offsetWidth
const x = -containerWidth / 2 + target.offsetLeft + elementWidth / 2
const y = target.offsetTop
this.userPopoverOffset = { x, y, h: target.offsetHeight }
} }
} }
} }
event.preventDefault()
event.stopPropagation()
}, },
toggleShowMore () { toggleShowMore () {
if (this.mightHideBecauseTall) { if (this.mightHideBecauseTall) {

View File

@ -51,7 +51,7 @@
v-if="!hideSubjectStatus" v-if="!hideSubjectStatus"
:class="{ 'single-line': singleLine }" :class="{ 'single-line': singleLine }"
class="status-content media-body" class="status-content media-body"
@click="linkClicked" @click.prevent="linkClicked"
@mouseover="linkHover" @mouseover="linkHover"
v-html="postBodyHtml" v-html="postBodyHtml"
/> />

View File

@ -24,7 +24,10 @@ export default {
} }
}, },
created () { created () {
this.$store.dispatch('fetchUserRelationship', this.user.id) const relationship = this.$store.getters.relationship(this.userId)
if (!(relationship && !relationship.loading)) {
this.$store.dispatch('fetchUserRelationship', this.user.id)
}
}, },
computed: { computed: {
user () { user () {

View File

@ -7,7 +7,8 @@ const UserPopover = {
], ],
data () { data () {
return { return {
error: false error: false,
fetching: false
} }
}, },
computed: { computed: {
@ -26,15 +27,20 @@ const UserPopover = {
methods: { methods: {
enter () { enter () {
if (!this.userId) return if (!this.userId) return
if (this.fetching) return
const promises = []
if (!this.user) { if (!this.user) {
this.$store.dispatch('fetchUser', this.userId) promises.push(this.$store.dispatch('fetchUser', this.userId))
.then(data => (this.error = false))
.catch(e => (this.error = true))
} }
if (!this.relationship) { if (!this.relationshipAvailable) {
this.$store.dispatch('fetchUserRelationship', this.userId) promises.push(this.$store.dispatch('fetchUserRelationship', this.userId))
}
if (promises.length > 0) {
this.fetching = true
Promise.all(promises)
.then(data => (this.error = false)) .then(data => (this.error = false))
.catch(e => (this.error = true)) .catch(e => (this.error = true))
.finally(() => (this.fetching = false))
} }
} }
} }

View File

@ -1,6 +1,5 @@
<template> <template>
<Popover <Popover
v-if="userId"
class="user-popover-container" class="user-popover-container"
trigger="hover" trigger="hover"
popover-class="user-popover" popover-class="user-popover"
@ -8,6 +7,7 @@
:margin="{ left: 5, right: 5 }" :margin="{ left: 5, right: 5 }"
:delay="200" :delay="200"
:anchor-offset="anchorOffset" :anchor-offset="anchorOffset"
:disabled="!userId"
@enter="enter" @enter="enter"
> >
<template slot="trigger"> <template slot="trigger">
@ -37,12 +37,6 @@
</div> </div>
</div> </div>
</Popover> </Popover>
<div
v-else
class="user-popover-container"
>
<slot />
</div>
</template> </template>
<script src="./user_popover.js" ></script> <script src="./user_popover.js" ></script>