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 Vue from 'vue'
|
||||||
import $ from 'jquery'
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'FtIconButton',
|
name: 'FtIconButton',
|
||||||
|
@ -56,64 +55,45 @@ export default Vue.extend({
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
dropdownShown: false,
|
dropdownShown: false,
|
||||||
id: ''
|
mouseDownOnIcon: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
|
||||||
this.id = `iconButton${this._uid}`
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
toggleDropdown: function () {
|
// used by the share menu
|
||||||
const dropdownBox = $(`#${this.id}`)
|
hideDropdown: function () {
|
||||||
|
|
||||||
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'
|
|
||||||
this.dropdownShown = false
|
this.dropdownShown = false
|
||||||
},
|
},
|
||||||
|
|
||||||
handleIconClick: function () {
|
handleIconClick: function () {
|
||||||
if (this.forceDropdown || (this.dropdownOptions.length > 0)) {
|
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 {
|
} else {
|
||||||
this.$emit('click')
|
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 }) {
|
handleDropdownClick: function ({ url, index }) {
|
||||||
if (this.returnIndex) {
|
if (this.returnIndex) {
|
||||||
this.$emit('click', index)
|
this.$emit('click', index)
|
||||||
|
@ -121,7 +101,7 @@ export default Vue.extend({
|
||||||
this.$emit('click', url)
|
this.$emit('click', url)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.focusOut()
|
this.dropdownShown = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
color: var(--favorite-icon-color)
|
color: var(--favorite-icon-color)
|
||||||
|
|
||||||
.iconDropdown
|
.iconDropdown
|
||||||
display: none
|
display: inline
|
||||||
position: absolute
|
position: absolute
|
||||||
text-align: center
|
text-align: center
|
||||||
list-style-type: none
|
list-style-type: none
|
||||||
|
@ -68,9 +68,6 @@
|
||||||
color: var(--secondary-text-color)
|
color: var(--secondary-text-color)
|
||||||
user-select: none
|
user-select: none
|
||||||
|
|
||||||
&:focus
|
|
||||||
display: inline
|
|
||||||
|
|
||||||
&.left
|
&.left
|
||||||
right: calc(50% - 10px)
|
right: calc(50% - 10px)
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@
|
||||||
fontSize: size + 'px'
|
fontSize: size + 'px'
|
||||||
}"
|
}"
|
||||||
@click="handleIconClick"
|
@click="handleIconClick"
|
||||||
|
@mousedown="handleIconMouseDown"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
:id="id"
|
v-show="dropdownShown"
|
||||||
|
ref="dropdown"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
class="iconDropdown"
|
class="iconDropdown"
|
||||||
:class="{
|
:class="{
|
||||||
|
@ -25,6 +27,7 @@
|
||||||
bottom: dropdownPositionY === 'bottom',
|
bottom: dropdownPositionY === 'bottom',
|
||||||
top: dropdownPositionY === 'top'
|
top: dropdownPositionY === 'top'
|
||||||
}"
|
}"
|
||||||
|
@focusout="handleDropdownFocusOut"
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<ul
|
<ul
|
||||||
|
|
|
@ -79,42 +79,42 @@ export default Vue.extend({
|
||||||
|
|
||||||
openInvidious() {
|
openInvidious() {
|
||||||
this.openExternalLink(this.getFinalUrl(this.invidiousURL))
|
this.openExternalLink(this.getFinalUrl(this.invidiousURL))
|
||||||
this.$refs.iconButton.focusOut()
|
this.$refs.iconButton.hideDropdown()
|
||||||
},
|
},
|
||||||
|
|
||||||
copyInvidious() {
|
copyInvidious() {
|
||||||
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousURL), messageOnSuccess: this.$t('Share.Invidious URL copied to clipboard') })
|
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() {
|
openYoutube() {
|
||||||
this.openExternalLink(this.getFinalUrl(this.youtubeURL))
|
this.openExternalLink(this.getFinalUrl(this.youtubeURL))
|
||||||
this.$refs.iconButton.focusOut()
|
this.$refs.iconButton.hideDropdown()
|
||||||
},
|
},
|
||||||
|
|
||||||
copyYoutube() {
|
copyYoutube() {
|
||||||
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeShareURL), messageOnSuccess: this.$t('Share.YouTube URL copied to clipboard') })
|
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() {
|
openYoutubeEmbed() {
|
||||||
this.openExternalLink(this.getFinalUrl(this.youtubeEmbedURL))
|
this.openExternalLink(this.getFinalUrl(this.youtubeEmbedURL))
|
||||||
this.$refs.iconButton.focusOut()
|
this.$refs.iconButton.hideDropdown()
|
||||||
},
|
},
|
||||||
|
|
||||||
copyYoutubeEmbed() {
|
copyYoutubeEmbed() {
|
||||||
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeEmbedURL), messageOnSuccess: this.$t('Share.YouTube Embed URL copied to clipboard') })
|
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() {
|
openInvidiousEmbed() {
|
||||||
this.openExternalLink(this.getFinalUrl(this.invidiousEmbedURL))
|
this.openExternalLink(this.getFinalUrl(this.invidiousEmbedURL))
|
||||||
this.$refs.iconButton.focusOut()
|
this.$refs.iconButton.hideDropdown()
|
||||||
},
|
},
|
||||||
|
|
||||||
copyInvidiousEmbed() {
|
copyInvidiousEmbed() {
|
||||||
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousEmbedURL), messageOnSuccess: this.$t('Share.Invidious Embed URL copied to clipboard') })
|
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() {
|
updateIncludeTimestamp() {
|
||||||
|
|
Loading…
Reference in New Issue