Merge pull request #1148 from Svallinn/811-youtube-links-inside-app

Link app views to related YouTube url navigations
This commit is contained in:
Luca Hohmann 2021-04-10 21:20:12 +02:00 committed by GitHub
commit d75ded4d41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 7 deletions

View File

@ -269,14 +269,128 @@ export default Vue.extend({
},
openAllLinksExternally: function () {
// Open links externally by default
$(document).on('click', 'a[href^="http"]', (event) => {
const el = event.currentTarget
console.log(useElectron)
console.log(el)
if (typeof (shell) !== 'undefined') {
event.preventDefault()
shell.openExternal(el.href)
event.preventDefault()
// Check if YouTube video, channel or playlist
const youtubeUrlPattern = /^https?:\/\/((www\.)?youtube\.com(\/embed)?|youtu\.be)\/.*$/
const isYoutubeLink = youtubeUrlPattern.test(el.href)
if (isYoutubeLink) {
this.handleYoutubeLink(el.href)
} else {
// Open links externally by default
if (typeof (shell) !== 'undefined') {
shell.openExternal(el.href)
}
}
})
},
handleYoutubeLink: function (href) {
const v = this
// Assume it's a video
this.$store.dispatch('getVideoParamsFromUrl', href).then(({ videoId, timestamp }) => {
if (videoId) {
v.$router.push({
path: `/watch/${videoId}`,
query: timestamp ? { timestamp } : {}
})
} else {
// Could be playlist, search, hashtag or channel
// For now, ignore hashtags
const url = new URL(href)
let urlType
const typePatterns = new Map([
['playlist', /\/playlist$/],
['search', /\/results$/],
// ['hashtag', /\/hashtag\/([^/?&#]+)/],
['channel', /\/(?:c\/|channel\/)?([^/?&#]+).*$/]
])
for (const [type, pattern] of typePatterns) {
const isAMatch = pattern.test(url.pathname)
if (isAMatch) {
urlType = type
break
}
}
switch (urlType) {
case 'playlist': {
if (!url.searchParams.has('list')) {
return
}
const playlistId = url.searchParams.get('list')
url.searchParams.delete('list')
const query = {}
for (const [param, value] of url.searchParams) {
query[param] = value
}
v.$router.push({
path: `/playlist/${playlistId}`,
query
})
break
}
case 'search': {
if (!url.searchParams.has('search_query')) {
return
}
const searchQuery = url.searchParams.get('search_query')
url.searchParams.delete('search_query')
const query = {
sortBy: this.searchSettings.sortBy,
time: this.searchSettings.time,
type: this.searchSettings.type,
duration: this.searchSettings.duration
}
for (const [param, value] of url.searchParams) {
query[param] = value
}
v.$router.push({
path: `/search/${encodeURIComponent(searchQuery)}`,
query
})
break
}
/* case 'hashtag': {
// placeholder
break
} */
case 'channel': {
const channelId = url.pathname.match(/\/(?:c\/|channel\/)?([^/?&#]+).*$/)[1]
if (!channelId) {
return
}
v.$router.push({
path: `/channel/${channelId}`
})
break
}
default: {
if (typeof (shell) !== 'undefined') {
shell.openExternal(href)
}
break
}
}
}
})
},

View File

@ -55,9 +55,8 @@ export default Vue.extend({
descriptionText = descriptionText.replace(/&v.+?(?=")/g, '')
descriptionText = descriptionText.replace(/&redirect-token.+?(?=")/g, '')
descriptionText = descriptionText.replace(/&redir_token.+?(?=")/g, '')
descriptionText = descriptionText.replace(/href="http(s)?:\/\/youtube\.com/g, 'href="freetube://https://youtube.com')
descriptionText = descriptionText.replace(/href="\/watch/g, 'href="freetube://https://youtube.com')
descriptionText = descriptionText.replace(/href="\/results\?search_query=/g, 'href="freetube://')
descriptionText = descriptionText.replace(/href="\//g, 'href="https://www.youtube.com/')
// TODO: Implement hashtag support
descriptionText = descriptionText.replace(/href="\/hashtag\//g, 'href="freetube://')
descriptionText = descriptionText.replace(/yt\.www\.watch\.player\.seekTo/g, 'changeDuration')