Improve YouTube link handler
* Handle /user channel URL type * Fix minor problems with the regexps * Display informational toasts for hashtag and unknown URL types * Add toast messages to the default locale
This commit is contained in:
parent
726d16bc41
commit
61b2fc4b48
|
@ -1,4 +1,5 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import { mapActions } from 'vuex'
|
||||||
import { ObserveVisibility } from 'vue-observe-visibility'
|
import { ObserveVisibility } from 'vue-observe-visibility'
|
||||||
import FtFlexBox from './components/ft-flex-box/ft-flex-box.vue'
|
import FtFlexBox from './components/ft-flex-box/ft-flex-box.vue'
|
||||||
import TopNav from './components/top-nav/top-nav.vue'
|
import TopNav from './components/top-nav/top-nav.vue'
|
||||||
|
@ -280,7 +281,7 @@ export default Vue.extend({
|
||||||
console.log(el)
|
console.log(el)
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
// Check if YouTube video, channel or playlist
|
// Check if it's a YouTube link
|
||||||
const youtubeUrlPattern = /^https?:\/\/((www\.)?youtube\.com(\/embed)?|youtu\.be)\/.*$/
|
const youtubeUrlPattern = /^https?:\/\/((www\.)?youtube\.com(\/embed)?|youtu\.be)\/.*$/
|
||||||
const isYoutubeLink = youtubeUrlPattern.test(el.href)
|
const isYoutubeLink = youtubeUrlPattern.test(el.href)
|
||||||
|
|
||||||
|
@ -306,22 +307,31 @@ export default Vue.extend({
|
||||||
query: timestamp ? { timestamp } : {}
|
query: timestamp ? { timestamp } : {}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Could be playlist, search, hashtag or channel
|
// Could be a playlist, channel, search query or hashtag
|
||||||
// For now, ignore hashtags
|
// If it's none of these, do nothing
|
||||||
|
//
|
||||||
|
// There's a limitation where some unknown URL types will be
|
||||||
|
// determined to be channels
|
||||||
|
// This is due to the ambiguity of some of the existing
|
||||||
|
// channel URL formats and there's not much that can be
|
||||||
|
// done to remedy it
|
||||||
|
|
||||||
const url = new URL(href)
|
const url = new URL(href)
|
||||||
|
let urlType = 'unknown'
|
||||||
|
|
||||||
|
const channelPattern =
|
||||||
|
/^\/(?:c\/|channel\/|user\/)?([^/]+)(?:\/join)?\/?$/
|
||||||
|
|
||||||
let urlType
|
|
||||||
const typePatterns = new Map([
|
const typePatterns = new Map([
|
||||||
['playlist', /\/playlist$/],
|
['playlist', /^\/playlist\/?$/],
|
||||||
['search', /\/results$/],
|
['search', /^\/results\/?$/],
|
||||||
// ['hashtag', /\/hashtag\/([^/?&#]+)/],
|
['hashtag', /^\/hashtag\/([^/?&#]+)$/],
|
||||||
['channel', /\/(?:c\/|channel\/)?([^/?&#]+).*$/]
|
['channel', channelPattern]
|
||||||
])
|
])
|
||||||
|
|
||||||
for (const [type, pattern] of typePatterns) {
|
for (const [type, pattern] of typePatterns) {
|
||||||
const isAMatch = pattern.test(url.pathname)
|
const matchFound = pattern.test(url.pathname)
|
||||||
if (isAMatch) {
|
if (matchFound) {
|
||||||
urlType = type
|
urlType = type
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -330,7 +340,7 @@ export default Vue.extend({
|
||||||
switch (urlType) {
|
switch (urlType) {
|
||||||
case 'playlist': {
|
case 'playlist': {
|
||||||
if (!url.searchParams.has('list')) {
|
if (!url.searchParams.has('list')) {
|
||||||
return
|
throw new Error('Playlist: "list" field not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
const playlistId = url.searchParams.get('list')
|
const playlistId = url.searchParams.get('list')
|
||||||
|
@ -350,7 +360,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
case 'search': {
|
case 'search': {
|
||||||
if (!url.searchParams.has('search_query')) {
|
if (!url.searchParams.has('search_query')) {
|
||||||
return
|
throw new Error('Search: "search_query" field not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchQuery = url.searchParams.get('search_query')
|
const searchQuery = url.searchParams.get('search_query')
|
||||||
|
@ -373,14 +383,24 @@ export default Vue.extend({
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
/* case 'hashtag': {
|
|
||||||
// placeholder
|
case 'hashtag': {
|
||||||
|
// TODO: Implement a hashtag related view
|
||||||
|
let message = 'Hashtags have not yet been implemented, try again later'
|
||||||
|
if (this.$te(message) && this.$t(message) !== '') {
|
||||||
|
message = this.$t(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showToast({
|
||||||
|
message: message
|
||||||
|
})
|
||||||
break
|
break
|
||||||
} */
|
}
|
||||||
|
|
||||||
case 'channel': {
|
case 'channel': {
|
||||||
const channelId = url.pathname.match(/\/(?:c\/|channel\/)?([^/?&#]+).*$/)[1]
|
const channelId = url.pathname.match(channelPattern)[1]
|
||||||
if (!channelId) {
|
if (!channelId) {
|
||||||
return
|
throw new Error('Channel: could not extract id')
|
||||||
}
|
}
|
||||||
|
|
||||||
v.$router.push({
|
v.$router.push({
|
||||||
|
@ -390,10 +410,15 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (typeof (shell) !== 'undefined') {
|
// Unknown URL type
|
||||||
shell.openExternal(href)
|
let message = 'Unknown YouTube url type, cannot be opened in app'
|
||||||
|
if (this.$te(message) && this.$t(message) !== '') {
|
||||||
|
message = this.$t(message)
|
||||||
}
|
}
|
||||||
break
|
|
||||||
|
this.showToast({
|
||||||
|
message: message
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,6 +440,10 @@ export default Vue.extend({
|
||||||
window.onbeforeunload = (e) => {
|
window.onbeforeunload = (e) => {
|
||||||
electron.ipcRenderer.send('setBounds')
|
electron.ipcRenderer.send('setBounds')
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
...mapActions([
|
||||||
|
'showToast'
|
||||||
|
])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -586,6 +586,8 @@ This video is unavailable because of missing formats. This can happen due to cou
|
||||||
video is unavailable because of missing formats. This can happen due to country
|
video is unavailable because of missing formats. This can happen due to country
|
||||||
unavailability.
|
unavailability.
|
||||||
Subscriptions have not yet been implemented: Subscriptions have not yet been implemented
|
Subscriptions have not yet been implemented: Subscriptions have not yet been implemented
|
||||||
|
Unknown YouTube url type, cannot be opened in app: Unknown YouTube url type, cannot be opened in app
|
||||||
|
Hashtags have not yet been implemented, try again later: Hashtags have not yet been implemented, try again later
|
||||||
Loop is now disabled: Loop is now disabled
|
Loop is now disabled: Loop is now disabled
|
||||||
Loop is now enabled: Loop is now enabled
|
Loop is now enabled: Loop is now enabled
|
||||||
Shuffle is now disabled: Shuffle is now disabled
|
Shuffle is now disabled: Shuffle is now disabled
|
||||||
|
|
Loading…
Reference in New Issue