Replace jquery in ft-icon-button with vue functionality (#2617)

* Replace jquery in ft-icon-button with vue functionality

* Rename hide method to hideDropdown

* Fix typo in comment

Co-authored-by: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>

* Fix menu reappearing too soon

* Fix share menu buttons not triggering

Co-authored-by: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>
This commit is contained in:
absidue 2022-09-27 14:16:56 +02:00 committed by GitHub
parent 498ae77ade
commit c3f8a3561b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 60 deletions

View File

@ -1,5 +1,4 @@
import Vue from 'vue'
import $ from 'jquery'
export default Vue.extend({
name: 'FtIconButton',
@ -56,64 +55,45 @@ export default Vue.extend({
data: function () {
return {
dropdownShown: false,
id: ''
mouseDownOnIcon: false
}
},
mounted: function () {
this.id = `iconButton${this._uid}`
},
methods: {
toggleDropdown: function () {
const dropdownBox = $(`#${this.id}`)
if (this.dropdownShown) {
dropdownBox.get(0).style.display = 'none'
this.dropdownShown = false
} else {
dropdownBox.get(0).style.display = 'inline'
dropdownBox.get(0).focus()
this.dropdownShown = true
dropdownBox.focusout(() => {
const shareLinks = dropdownBox.find('.shareLinks')
if (shareLinks.length > 0) {
if (!shareLinks[0].parentNode.matches(':hover')) {
dropdownBox.get(0).style.display = 'none'
// When pressing the profile button
// It will make the menu reappear if we set `dropdownShown` immediately
setTimeout(() => {
this.dropdownShown = false
}, 100)
}
} else {
dropdownBox.get(0).style.display = 'none'
// When pressing the profile button
// It will make the menu reappear if we set `dropdownShown` immediately
setTimeout(() => {
this.dropdownShown = false
}, 100)
}
})
}
},
focusOut: function () {
const dropdownBox = $(`#${this.id}`)
dropdownBox.focusout()
dropdownBox.get(0).style.display = 'none'
// used by the share menu
hideDropdown: function () {
this.dropdownShown = false
},
handleIconClick: function () {
if (this.forceDropdown || (this.dropdownOptions.length > 0)) {
this.toggleDropdown()
this.dropdownShown = !this.dropdownShown
if (this.dropdownShown) {
// wait until the dropdown is visible
// then focus it so we can hide it automatically when it loses focus
setTimeout(() => {
this.$refs.dropdown.focus()
}, 0)
}
} else {
this.$emit('click')
}
},
handleIconMouseDown: function () {
if (this.dropdownShown) {
this.mouseDownOnIcon = true
}
},
handleDropdownFocusOut: function () {
if (this.mouseDownOnIcon) {
this.mouseDownOnIcon = false
} else if (!this.$refs.dropdown.matches(':focus-within')) {
this.dropdownShown = false
}
},
handleDropdownClick: function ({ url, index }) {
if (this.returnIndex) {
this.$emit('click', index)
@ -121,7 +101,7 @@ export default Vue.extend({
this.$emit('click', url)
}
this.focusOut()
this.dropdownShown = false
}
}
})

View File

@ -56,7 +56,7 @@
color: var(--favorite-icon-color)
.iconDropdown
display: none
display: inline
position: absolute
text-align: center
list-style-type: none
@ -68,9 +68,6 @@
color: var(--secondary-text-color)
user-select: none
&:focus
display: inline
&.left
right: calc(50% - 10px)

View File

@ -13,9 +13,11 @@
fontSize: size + 'px'
}"
@click="handleIconClick"
@mousedown="handleIconMouseDown"
/>
<div
:id="id"
v-show="dropdownShown"
ref="dropdown"
tabindex="-1"
class="iconDropdown"
:class="{
@ -25,6 +27,7 @@
bottom: dropdownPositionY === 'bottom',
top: dropdownPositionY === 'top'
}"
@focusout="handleDropdownFocusOut"
>
<slot>
<ul

View File

@ -79,42 +79,42 @@ export default Vue.extend({
openInvidious() {
this.openExternalLink(this.getFinalUrl(this.invidiousURL))
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
copyInvidious() {
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousURL), messageOnSuccess: this.$t('Share.Invidious URL copied to clipboard') })
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
openYoutube() {
this.openExternalLink(this.getFinalUrl(this.youtubeURL))
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
copyYoutube() {
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeShareURL), messageOnSuccess: this.$t('Share.YouTube URL copied to clipboard') })
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
openYoutubeEmbed() {
this.openExternalLink(this.getFinalUrl(this.youtubeEmbedURL))
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
copyYoutubeEmbed() {
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeEmbedURL), messageOnSuccess: this.$t('Share.YouTube Embed URL copied to clipboard') })
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
openInvidiousEmbed() {
this.openExternalLink(this.getFinalUrl(this.invidiousEmbedURL))
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
copyInvidiousEmbed() {
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousEmbedURL), messageOnSuccess: this.$t('Share.Invidious Embed URL copied to clipboard') })
this.$refs.iconButton.focusOut()
this.$refs.iconButton.hideDropdown()
},
updateIncludeTimestamp() {