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:
parent
498ae77ade
commit
c3f8a3561b
|
@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue