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 { mapActions } from 'vuex'
|
||||
import { ObserveVisibility } from 'vue-observe-visibility'
|
||||
import FtFlexBox from './components/ft-flex-box/ft-flex-box.vue'
|
||||
import TopNav from './components/top-nav/top-nav.vue'
|
||||
|
@ -280,7 +281,7 @@ export default Vue.extend({
|
|||
console.log(el)
|
||||
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 isYoutubeLink = youtubeUrlPattern.test(el.href)
|
||||
|
||||
|
@ -306,22 +307,31 @@ export default Vue.extend({
|
|||
query: timestamp ? { timestamp } : {}
|
||||
})
|
||||
} else {
|
||||
// Could be playlist, search, hashtag or channel
|
||||
// For now, ignore hashtags
|
||||
// Could be a playlist, channel, search query or hashtag
|
||||
// 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)
|
||||
let urlType = 'unknown'
|
||||
|
||||
const channelPattern =
|
||||
/^\/(?:c\/|channel\/|user\/)?([^/]+)(?:\/join)?\/?$/
|
||||
|
||||
let urlType
|
||||
const typePatterns = new Map([
|
||||
['playlist', /\/playlist$/],
|
||||
['search', /\/results$/],
|
||||
// ['hashtag', /\/hashtag\/([^/?&#]+)/],
|
||||
['channel', /\/(?:c\/|channel\/)?([^/?&#]+).*$/]
|
||||
['playlist', /^\/playlist\/?$/],
|
||||
['search', /^\/results\/?$/],
|
||||
['hashtag', /^\/hashtag\/([^/?&#]+)$/],
|
||||
['channel', channelPattern]
|
||||
])
|
||||
|
||||
for (const [type, pattern] of typePatterns) {
|
||||
const isAMatch = pattern.test(url.pathname)
|
||||
if (isAMatch) {
|
||||
const matchFound = pattern.test(url.pathname)
|
||||
if (matchFound) {
|
||||
urlType = type
|
||||
break
|
||||
}
|
||||
|
@ -330,7 +340,7 @@ export default Vue.extend({
|
|||
switch (urlType) {
|
||||
case 'playlist': {
|
||||
if (!url.searchParams.has('list')) {
|
||||
return
|
||||
throw new Error('Playlist: "list" field not found')
|
||||
}
|
||||
|
||||
const playlistId = url.searchParams.get('list')
|
||||
|
@ -350,7 +360,7 @@ export default Vue.extend({
|
|||
|
||||
case 'search': {
|
||||
if (!url.searchParams.has('search_query')) {
|
||||
return
|
||||
throw new Error('Search: "search_query" field not found')
|
||||
}
|
||||
|
||||
const searchQuery = url.searchParams.get('search_query')
|
||||
|
@ -373,14 +383,24 @@ export default Vue.extend({
|
|||
})
|
||||
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
|
||||
} */
|
||||
}
|
||||
|
||||
case 'channel': {
|
||||
const channelId = url.pathname.match(/\/(?:c\/|channel\/)?([^/?&#]+).*$/)[1]
|
||||
const channelId = url.pathname.match(channelPattern)[1]
|
||||
if (!channelId) {
|
||||
return
|
||||
throw new Error('Channel: could not extract id')
|
||||
}
|
||||
|
||||
v.$router.push({
|
||||
|
@ -390,10 +410,15 @@ export default Vue.extend({
|
|||
}
|
||||
|
||||
default: {
|
||||
if (typeof (shell) !== 'undefined') {
|
||||
shell.openExternal(href)
|
||||
// Unknown URL type
|
||||
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) => {
|
||||
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
|
||||
unavailability.
|
||||
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 enabled: Loop is now enabled
|
||||
Shuffle is now disabled: Shuffle is now disabled
|
||||
|
|
Loading…
Reference in New Issue