diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index 9fcd0640..41fe4b56 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -23,7 +23,9 @@ const Popover = { // Additional styles you may want for the popover container popoverClass: String, // 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 () { return { @@ -38,6 +40,13 @@ const Popover = { return this.$store.state.interface.mobileLayout } }, + watch: { + disabled (newValue, oldValue) { + if (newValue === true) { + this.hidePopover() + } + } + }, methods: { containerBoundingClientRect () { const container = this.boundToSelector ? this.$el.closest(this.boundToSelector) : this.$el.offsetParent @@ -127,12 +136,19 @@ const Popover = { } }, 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.$nextTick(this.updateStyles) }, hidePopover () { - if (!this.hidden) this.$emit('close') + if (!this.hidden) { + this.$emit('close') + document.removeEventListener('click', this.onClickOutside, true) + } if (this.timeout) { clearTimeout(this.timeout) this.timeout = null @@ -158,8 +174,7 @@ const Popover = { } else { this.hidePopover() } - } else if (this.trigger === 'hover' && this.isMobileLayout) { - console.log(this.isMobileLayout) + } else if ((this.trigger === 'hover') && this.isMobileLayout) { // This is to enable using hover stuff with mobile: // on first touch it opens the popover, when touching the trigger // again it will do the click action. Can't use touch events as @@ -169,11 +184,11 @@ const Popover = { this.$emit('enter') this.showPopover() e.preventDefault() - e.stopPropagation() } } }, onClickOutside (e) { + console.log('onClickOutside') if (this.hidden) return if (this.$el.contains(e.target)) return this.hidePopover() @@ -192,11 +207,7 @@ const Popover = { this.oldSize = { width: content.offsetWidth, height: content.offsetHeight } } }, - created () { - document.addEventListener('click', this.onClickOutside) - }, destroyed () { - document.removeEventListener('click', this.onClickOutside) this.hidePopover() } } diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js index 34eeda9a..9b4f503c 100644 --- a/src/components/status_content/status_content.js +++ b/src/components/status_content/status_content.js @@ -153,6 +153,17 @@ const StatusContent = { }) }, 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) { const target = event.target.closest('.status-content a') if (target) { @@ -160,8 +171,10 @@ const StatusContent = { const href = target.href const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) if (attn) { - event.stopPropagation() - event.preventDefault() + if (this.$store.state.interface.mobileLayout) { + this.setUserPopoverTarget(event, target, attn) + return + } const link = this.generateUserProfileLink(attn.id, attn.screen_name) this.$router.push(link) return @@ -177,29 +190,23 @@ const StatusContent = { } } window.open(target.href, '_blank') - event.preventDefault() } }, linkHover (event) { const target = event.target.closest('.status-content a') this.focusedUserId = null + console.log('hover first') if (target) { if (target.className.match(/mention/)) { const href = target.href const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) if (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 } + this.setUserPopoverTarget(event, target, attn) } } } + event.preventDefault() + event.stopPropagation() }, toggleShowMore () { if (this.mightHideBecauseTall) { diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue index f4e7d57c..abb1f6b8 100644 --- a/src/components/status_content/status_content.vue +++ b/src/components/status_content/status_content.vue @@ -51,7 +51,7 @@ v-if="!hideSubjectStatus" :class="{ 'single-line': singleLine }" class="status-content media-body" - @click="linkClicked" + @click.prevent="linkClicked" @mouseover="linkHover" v-html="postBodyHtml" /> diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index d341bb7a..dd9a369f 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -24,7 +24,10 @@ export default { } }, 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: { user () { diff --git a/src/components/user_popover/user_popover.js b/src/components/user_popover/user_popover.js index c7fce3ff..ab8d6107 100644 --- a/src/components/user_popover/user_popover.js +++ b/src/components/user_popover/user_popover.js @@ -7,7 +7,8 @@ const UserPopover = { ], data () { return { - error: false + error: false, + fetching: false } }, computed: { @@ -26,15 +27,20 @@ const UserPopover = { methods: { enter () { if (!this.userId) return + if (this.fetching) return + const promises = [] if (!this.user) { - this.$store.dispatch('fetchUser', this.userId) - .then(data => (this.error = false)) - .catch(e => (this.error = true)) + promises.push(this.$store.dispatch('fetchUser', this.userId)) } - if (!this.relationship) { - this.$store.dispatch('fetchUserRelationship', this.userId) + if (!this.relationshipAvailable) { + promises.push(this.$store.dispatch('fetchUserRelationship', this.userId)) + } + if (promises.length > 0) { + this.fetching = true + Promise.all(promises) .then(data => (this.error = false)) .catch(e => (this.error = true)) + .finally(() => (this.fetching = false)) } } } diff --git a/src/components/user_popover/user_popover.vue b/src/components/user_popover/user_popover.vue index 8029eace..dcb66f28 100644 --- a/src/components/user_popover/user_popover.vue +++ b/src/components/user_popover/user_popover.vue @@ -1,6 +1,5 @@