Feat: Invidious instance autofill (#1784)

* filter invidious instances

* remove watch for value

* update list on mount

* hide on misspell + empty

* Fix spelling mistake

* minor fix

* remove "Clear" to "from." from locale  files
This commit is contained in:
ChunkyProgrammer 2021-10-05 01:58:35 -04:00 committed by GitHub
parent f257d04406
commit e681772192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 15 deletions

View File

@ -62,6 +62,7 @@ export default Vue.extend({
selectedOption: -1, selectedOption: -1,
isPointerInList: false isPointerInList: false
}, },
visibleDataList: this.dataList,
// This button should be invisible on app start // This button should be invisible on app start
// As the text input box should be empty // As the text input box should be empty
clearTextButtonExisting: false, clearTextButtonExisting: false,
@ -87,9 +88,6 @@ export default Vue.extend({
} }
}, },
watch: { watch: {
value: function (val) {
this.inputData = val
},
inputDataPresent: function (newVal, oldVal) { inputDataPresent: function (newVal, oldVal) {
if (newVal) { if (newVal) {
// The button needs to be visible **immediately** // The button needs to be visible **immediately**
@ -114,6 +112,7 @@ export default Vue.extend({
mounted: function () { mounted: function () {
this.id = this._uid this.id = this._uid
this.inputData = this.value this.inputData = this.value
this.updateVisibleDataList()
setTimeout(this.addListener, 200) setTimeout(this.addListener, 200)
}, },
@ -127,17 +126,19 @@ export default Vue.extend({
this.$emit('click', this.inputData) this.$emit('click', this.inputData)
}, },
handleInput: function () { handleInput: function (val) {
if (this.isSearch && if (this.isSearch &&
this.searchState.selectedOption !== -1 && this.searchState.selectedOption !== -1 &&
this.inputData === this.dataList[this.searchState.selectedOption]) { return } this.inputData === this.visibleDataList[this.searchState.selectedOption]) { return }
this.handleActionIconChange() this.handleActionIconChange()
this.$emit('input', this.inputData) this.updateVisibleDataList()
this.$emit('input', val)
}, },
handleClearTextClick: function () { handleClearTextClick: function () {
this.inputData = '' this.inputData = ''
this.handleActionIconChange() this.handleActionIconChange()
this.updateVisibleDataList()
this.$emit('input', this.inputData) this.$emit('input', this.inputData)
// Focus on input element after text is clear for better UX // Focus on input element after text is clear for better UX
@ -208,14 +209,13 @@ export default Vue.extend({
handleOptionClick: function (index) { handleOptionClick: function (index) {
this.searchState.showOptions = false this.searchState.showOptions = false
this.inputData = this.dataList[index] this.inputData = this.visibleDataList[index]
this.$emit('input', this.inputData) this.$emit('input', this.inputData)
this.handleClick() this.handleClick()
}, },
handleKeyDown: function (keyCode) { handleKeyDown: function (keyCode) {
if (this.dataList.length === 0) { return } if (this.dataList.length === 0) { return }
// Update selectedOption based on arrow key pressed // Update selectedOption based on arrow key pressed
if (keyCode === 40) { if (keyCode === 40) {
this.searchState.selectedOption = (this.searchState.selectedOption + 1) % this.dataList.length this.searchState.selectedOption = (this.searchState.selectedOption + 1) % this.dataList.length
@ -229,8 +229,16 @@ export default Vue.extend({
this.searchState.selectedOption = -1 this.searchState.selectedOption = -1
} }
// Key pressed isn't enter
if (keyCode !== 13) {
this.searchState.showOptions = true
}
// Update Input box value if arrow keys were pressed // Update Input box value if arrow keys were pressed
if ((keyCode === 40 || keyCode === 38) && this.searchState.selectedOption !== -1) { this.inputData = this.dataList[this.searchState.selectedOption] } if ((keyCode === 40 || keyCode === 38) && this.searchState.selectedOption !== -1) {
this.inputData = this.visibleDataList[this.searchState.selectedOption]
} else {
this.updateVisibleDataList()
}
}, },
handleInputBlur: function () { handleInputBlur: function () {
@ -244,6 +252,24 @@ export default Vue.extend({
} }
}, },
updateVisibleDataList: function () {
if (this.dataList.length === 0) { return }
if (this.inputData === '') {
this.visibleDataList = this.dataList
return
}
// get list of items that match input
const visList = this.dataList.filter(x => {
if (x.toLowerCase().indexOf(this.inputData.toLowerCase()) !== -1) {
return true
} else {
return false
}
})
this.visibleDataList = visList
},
...mapActions([ ...mapActions([
'getYoutubeUrlInfo' 'getYoutubeUrlInfo'
]) ])

View File

@ -60,14 +60,14 @@
<div class="options"> <div class="options">
<ul <ul
v-if="inputData !== '' && dataList.length > 0 && searchState.showOptions" v-if="inputData !== '' && visibleDataList.length > 0 && searchState.showOptions"
:id="idDataList" :id="idDataList"
class="list" class="list"
@mouseenter="searchState.isPointerInList = true" @mouseenter="searchState.isPointerInList = true"
@mouseleave="searchState.isPointerInList = false" @mouseleave="searchState.isPointerInList = false"
> >
<li <li
v-for="(list, index) in dataList" v-for="(list, index) in visibleDataList"
:key="index" :key="index"
:class="searchState.selectedOption == index ? 'hover': ''" :class="searchState.selectedOption == index ? 'hover': ''"
@click="handleOptionClick(index)" @click="handleOptionClick(index)"

View File

@ -625,8 +625,7 @@ Tooltips:
Thumbnail Preference: All thumbnails throughout FreeTube will be replaced with Thumbnail Preference: All thumbnails throughout FreeTube will be replaced with
a frame of the video instead of the default thumbnail. a frame of the video instead of the default thumbnail.
Invidious Instance: The Invidious instance that FreeTube will connect to for API Invidious Instance: The Invidious instance that FreeTube will connect to for API
calls. Clear the current instance to see a list of public instances to choose calls.
from.
Region for Trending: The region of trends allows you to pick which country's trending Region for Trending: The region of trends allows you to pick which country's trending
videos you want to have displayed. Not all countries displayed are actually videos you want to have displayed. Not all countries displayed are actually
supported by YouTube. supported by YouTube.

View File

@ -701,8 +701,7 @@ Tooltips:
videos you want to have displayed. Not all countries displayed are actually videos you want to have displayed. Not all countries displayed are actually
supported by YouTube. supported by YouTube.
Invidious Instance: The Invidious instance that FreeTube will connect to for API Invidious Instance: The Invidious instance that FreeTube will connect to for API
calls. Clear the current instance to see a list of public instances to choose calls.
from.
Thumbnail Preference: All thumbnails throughout FreeTube will be replaced with Thumbnail Preference: All thumbnails throughout FreeTube will be replaced with
a frame of the video instead of the default thumbnail. a frame of the video instead of the default thumbnail.
Fallback to Non-Preferred Backend on Failure: When your preferred API has a problem, Fallback to Non-Preferred Backend on Failure: When your preferred API has a problem,