Skip to content

Commit

Permalink
Merge branch 'feature/playlist-2023-05' into custom-builds/current
Browse files Browse the repository at this point in the history
* feature/playlist-2023-05: (31 commits)
  Miscellaneous CSS cleanup (FreeTubeApp#3847)
  Fix empty channels showing up as errored with RSS (FreeTubeApp#3824)
  Fix author for album playlists on the playlist page (FreeTubeApp#3838)
  Update Snap Source Host Location (FreeTubeApp#3844)
  * Show error message in popular tab when instance does not support it (FreeTubeApp#3841)
  Use video durations from the watch history for RSS (FreeTubeApp#3839)
  ! Fix unnecessary error message display in toast when paused before video started playing on load (FreeTubeApp#3835)
  Use emit and props instead of $parent (FreeTubeApp#3834)
  Add custom toast event bus for Vue 3 compatiblity (FreeTubeApp#3833)
  Fix handling of DeArrow titles (FreeTubeApp#3825)
  * Update top nav bar icon to remove focus state style (FreeTubeApp#3792)
  Update ft-input for top navbar search input to behave more like Youtube one (FreeTubeApp#3793)
  Translated using Weblate (Hungarian)
  Fix: importing subscriptions with terminated channels (FreeTubeApp#3816)
  Fix outdated subscription cache clearing code when "Remove All Subscriptions / Profiles" performed (FreeTubeApp#3817)
  Translated using Weblate (Croatian)
  Bump eslint-plugin-import from 2.27.5 to 2.28.0 (FreeTubeApp#3827)
  Bump eslint from 8.45.0 to 8.46.0 (FreeTubeApp#3829)
  Bump eslint-plugin-unicorn from 48.0.0 to 48.0.1 (FreeTubeApp#3828)
  Bump lefthook from 1.4.6 to 1.4.7 (FreeTubeApp#3830)
  ...
  • Loading branch information
PikachuEXE committed Aug 5, 2023
2 parents 9915f93 + 68ab480 commit 734a56e
Show file tree
Hide file tree
Showing 47 changed files with 1,083 additions and 538 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ These builds are maintained by the community. While they should be safe, downloa

* Scoop (Windows Only): [Usage](https://github.com/ScoopInstaller/Scoop)

* Snap: [Download](https://snapcraft.io/freetube-snap) and [Source Code](https://github.com/CapeCrusader321/Freetube-Snap)
* Snap: [Download](https://snapcraft.io/freetube-snap) and [Source Code](https://launchpad.net/freetube)

* Windows Package Manager (winget): [Usage](https://docs.microsoft.com/en-us/windows/package-manager/winget/)

Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"vue-router": "^3.6.5",
"vue-tiny-slider": "^0.1.39",
"vuex": "^3.6.2",
"youtubei.js": "^5.6.0"
"youtubei.js": "^5.8.0"
},
"devDependencies": {
"@babel/core": "^7.22.9",
Expand All @@ -91,23 +91,23 @@
"css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1",
"electron": "^22.3.18",
"electron-builder": "^23.6.0",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"electron-builder": "^24.6.3",
"eslint": "^8.46.0",
"eslint-config-prettier": "^8.9.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-import": "^2.28.0",
"eslint-plugin-jsonc": "^2.9.0",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^48.0.0",
"eslint-plugin-vue": "^9.15.1",
"eslint-plugin-unicorn": "^48.0.1",
"eslint-plugin-vue": "^9.16.1",
"eslint-plugin-vuejs-accessibility": "^2.1.0",
"eslint-plugin-yml": "^1.8.0",
"html-webpack-plugin": "^5.5.3",
"js-yaml": "^4.1.0",
"json-minimizer-webpack-plugin": "^4.0.0",
"lefthook": "^1.4.6",
"lefthook": "^1.4.7",
"mini-css-extract-plugin": "^2.7.6",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.26",
Expand Down
9 changes: 4 additions & 5 deletions src/renderer/components/data-settings/data-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ export default defineComponent({
}

const newPipeSubscriptions = newPipeData.subscriptions.filter((channel, index) => {
return channel.service_id === 0
return new URL(channel.url).hostname === 'www.youtube.com'
})

const subscriptions = []
Expand Down Expand Up @@ -1060,10 +1060,9 @@ export default defineComponent({
invidiousAPICall(subscriptionsPayload).then((response) => {
resolve(response)
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)')
showToast(`${errorMessage}: ${err.responseJSON.error}`, 10000, () => {
copyToClipboard(err.responseJSON.error)
showToast(`${errorMessage}: ${err}`, 10000, () => {
copyToClipboard(err)
})

if (process.env.IS_ELECTRON && this.backendFallback && this.backendPreference === 'invidious') {
Expand All @@ -1081,7 +1080,7 @@ export default defineComponent({
const channel = await getLocalChannel(channelId)

if (channel.alert) {
return undefined
return []
}

return {
Expand Down
82 changes: 56 additions & 26 deletions src/renderer/components/ft-input/ft-input.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineComponent } from 'vue'
import FtTooltip from '../ft-tooltip/ft-tooltip.vue'
import { mapActions } from 'vuex'
import { isKeyboardEventKeyPrintableChar, isNullOrEmpty } from '../../helpers/strings'

export default defineComponent({
name: 'FtInput',
Expand Down Expand Up @@ -78,7 +79,8 @@ export default defineComponent({
searchState: {
showOptions: false,
selectedOption: -1,
isPointerInList: false
isPointerInList: false,
keyboardSelectedOptionIndex: -1,
},
visibleDataList: this.dataList,
// This button should be invisible on app start
Expand All @@ -103,7 +105,23 @@ export default defineComponent({

inputDataPresent: function () {
return this.inputData.length > 0
}
},
inputDataDisplayed() {
if (!this.isSearch) { return this.inputData }

const selectedOptionValue = this.searchStateKeyboardSelectedOptionValue
if (selectedOptionValue != null && selectedOptionValue !== '') {
return selectedOptionValue
}

return this.inputData
},

searchStateKeyboardSelectedOptionValue() {
if (this.searchState.keyboardSelectedOptionIndex === -1) { return null }

return this.visibleDataList[this.searchState.keyboardSelectedOptionIndex]
},
},
watch: {
dataList(val, oldVal) {
Expand Down Expand Up @@ -133,11 +151,15 @@ export default defineComponent({
if (!this.inputDataPresent) { return }

this.searchState.showOptions = false
this.searchState.selectedOption = -1
this.searchState.keyboardSelectedOptionIndex = -1
this.$emit('input', this.inputData)
this.$emit('click', this.inputData, { event: e })
},

handleInput: function (val) {
this.inputData = val

if (this.isSearch &&
this.searchState.selectedOption !== -1 &&
this.inputData === this.visibleDataList[this.searchState.selectedOption]) { return }
Expand Down Expand Up @@ -217,6 +239,9 @@ export default defineComponent({
this.handleClick()
},

/**
* @param {KeyboardEvent} event
*/
handleKeyDown: function (event) {
if (event.key === 'Enter') {
// Update Input box value if enter key was pressed and option selected
Expand All @@ -234,25 +259,32 @@ export default defineComponent({

this.searchState.showOptions = true
const isArrow = event.key === 'ArrowDown' || event.key === 'ArrowUp'
if (isArrow) {
event.preventDefault()
if (event.key === 'ArrowDown') {
this.searchState.selectedOption = (this.searchState.selectedOption + 1) % this.visibleDataList.length
} else if (event.key === 'ArrowUp') {
if (this.searchState.selectedOption < 1) {
this.searchState.selectedOption = this.visibleDataList.length - 1
} else {
this.searchState.selectedOption--
}
}
if (this.searchState.selectedOption < 0) {
this.searchState.selectedOption = this.visibleDataList.length
} else if (this.searchState.selectedOption > this.visibleDataList.length - 1) {
this.searchState.selectedOption = 0
if (!isArrow) {
const selectedOptionValue = this.searchStateKeyboardSelectedOptionValue
// Keyboard selected & is char
if (!isNullOrEmpty(selectedOptionValue) && isKeyboardEventKeyPrintableChar(event.key)) {
// Update input based on KB selected suggestion value instead of current input value
event.preventDefault()
this.handleInput(`${selectedOptionValue}${event.key}`)
return
}
} else {
return
}

event.preventDefault()
if (event.key === 'ArrowDown') {
this.searchState.selectedOption++
} else if (event.key === 'ArrowUp') {
this.searchState.selectedOption--
}
// Allow deselecting suggestion
if (this.searchState.selectedOption < -1) {
this.searchState.selectedOption = this.visibleDataList.length - 1
} else if (this.searchState.selectedOption > this.visibleDataList.length - 1) {
this.searchState.selectedOption = -1
}
// Update displayed value
this.searchState.keyboardSelectedOptionIndex = this.searchState.selectedOption
},

handleInputBlur: function () {
Expand All @@ -265,21 +297,19 @@ export default defineComponent({

updateVisibleDataList: function () {
if (this.dataList.length === 0) { return }
// Reset selected option before it's updated
this.searchState.selectedOption = -1
this.searchState.keyboardSelectedOptionIndex = -1
if (this.inputData === '') {
this.visibleDataList = this.dataList
return
}
// get list of items that match input
const lowerCaseInputData = this.inputData.toLowerCase()
const visList = this.dataList.filter(x => {
if (x.toLowerCase().indexOf(lowerCaseInputData) !== -1) {
return true
} else {
return false
}
})

this.visibleDataList = visList
this.visibleDataList = this.dataList.filter(x => {
return x.toLowerCase().indexOf(lowerCaseInputData) !== -1
})
},

updateInputData: function(text) {
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/components/ft-input/ft-input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<input
:id="id"
ref="input"
v-model="inputData"
:value="inputDataDisplayed"
:list="idDataList"
class="ft-input"
:tabindex="inputTabindex >= -1 ? inputTabindex : null"
Expand Down Expand Up @@ -78,9 +78,10 @@
<li
v-for="(list, index) in visibleDataList"
:key="index"
:class="searchState.selectedOption == index ? 'hover': ''"
:class="searchState.selectedOption === index ? 'hover': ''"
@click="handleOptionClick(index)"
@mouseenter="searchState.selectedOption = index"
@mouseleave="searchState.selectedOption = -1"
>
{{ list }}
</li>
Expand Down
38 changes: 24 additions & 14 deletions src/renderer/components/ft-list-video/ft-list-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,17 @@ export default defineComponent({
},

displayTitle: function () {
let title
if (this.useDeArrowTitles && this.deArrowCache?.title) {
title = this.deArrowCache.title
} else {
title = this.title
}

if (this.showDistractionFreeTitles) {
return toDistractionFreeTitle(this.title)
return toDistractionFreeTitle(title)
} else {
return this.title
return title
}
},

Expand Down Expand Up @@ -376,7 +383,7 @@ export default defineComponent({
},

deArrowCache: function () {
return this.$store.getters.getDeArrowCache(this.id)
return this.$store.getters.getDeArrowCache[this.id]
},
},
watch: {
Expand All @@ -394,15 +401,13 @@ export default defineComponent({
created: function () {
this.parseVideoData()
this.checkIfWatched()

if (this.useDeArrowTitles && !this.deArrowCache) {
this.fetchDeArrowData()
}
},
methods: {
getDeArrowDataEntry: async function() {
// Read from local cache or remote
// Write to cache if read from remote
if (!this.useDeArrowTitles) { return null }

if (this.deArrowCache) { return this.deArrowCache }

fetchDeArrowData: async function() {
const videoId = this.id
const data = await deArrowData(this.id)
const cacheData = { videoId, title: null }
Expand All @@ -412,7 +417,6 @@ export default defineComponent({

// Save data to cache whether data available or not to prevent duplicate requests
this.$store.commit('addVideoToDeArrowCache', cacheData)
return cacheData
},

handleExternalPlayer: function () {
Expand Down Expand Up @@ -477,14 +481,20 @@ export default defineComponent({
}
},

parseVideoData: async function () {
parseVideoData: function () {
this.id = this.data.videoId
this.title = (await this.getDeArrowDataEntry())?.title ?? this.data.title
this.title = this.data.title
// this.thumbnail = this.data.videoThumbnails[4].url

this.channelName = this.data.author ?? null
this.channelId = this.data.authorId ?? null
this.duration = formatDurationAsTimestamp(this.data.lengthSeconds)

if (this.data.isRSS && this.historyIndex !== -1) {
this.duration = formatDurationAsTimestamp(this.historyCache[this.historyIndex].lengthSeconds)
} else {
this.duration = formatDurationAsTimestamp(this.data.lengthSeconds)
}

this.description = this.data.description
this.isLive = this.data.liveNow || this.data.lengthSeconds === 'undefined'
this.isUpcoming = this.data.isUpcoming || this.data.premiere
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
</template>

<script src="./ft-subscribe-button.js" />
<style scoped src="./ft-subscribe-button.scss" lang="scss" />
<style src="./ft-subscribe-button.css" />
4 changes: 1 addition & 3 deletions src/renderer/components/ft-toast/ft-toast-events.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
import Vue from 'vue'

const events = new Vue()
const events = new EventTarget()
export default events
6 changes: 3 additions & 3 deletions src/renderer/components/ft-toast/ft-toast.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export default defineComponent({
}
},
mounted: function () {
FtToastEvents.$on('toast-open', this.open)
FtToastEvents.addEventListener('toast-open', this.open)
},
beforeDestroy: function () {
FtToastEvents.$off('toast-open', this.open)
FtToastEvents.removeEventListener('toast-open', this.open)
},
methods: {
performAction: function (index) {
Expand All @@ -25,7 +25,7 @@ export default defineComponent({

toast.isOpen = false
},
open: function (message, time, action) {
open: function ({ detail: { message, time, action } }) {
const toast = { message: message, action: action || (() => { }), isOpen: false, timeout: null }
toast.timeout = setTimeout(this.close, time || 3000, toast)
setTimeout(() => { toast.isOpen = true })
Expand Down
Loading

0 comments on commit 734a56e

Please sign in to comment.