Skip to content

Commit

Permalink
* Update top nav search input to direct to channel panel when channel…
Browse files Browse the repository at this point in the history
… URL provided (FreeTubeApp#1221)

* $ Extract function which extract details from a Youtube URL

* * Update top nav handling to use extract function to handle input text if it's Youtube URL

* - Remove no longer used function
  • Loading branch information
PikachuEXE authored Apr 28, 2021
1 parent 754f3d6 commit 82aeaac
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 148 deletions.
170 changes: 58 additions & 112 deletions src/renderer/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,129 +297,75 @@ export default Vue.extend({
},

handleYoutubeLink: function (href) {
const v = this
this.$store.dispatch('getYoutubeUrlInfo', href).then((result) => {
switch (result.urlType) {
case 'video': {
const { videoId, timestamp } = result

this.$router.push({
path: `/watch/${videoId}`,
query: timestamp ? { timestamp } : {}
})
break
}

// 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 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)?\/?$/

const typePatterns = new Map([
['playlist', /^\/playlist\/?$/],
['search', /^\/results\/?$/],
['hashtag', /^\/hashtag\/([^/?&#]+)$/],
['channel', channelPattern]
])

for (const [type, pattern] of typePatterns) {
const matchFound = pattern.test(url.pathname)
if (matchFound) {
urlType = type
break
}
case 'playlist': {
const { playlistId, query } = result

this.$router.push({
path: `/playlist/${playlistId}`,
query
})
break
}

switch (urlType) {
case 'playlist': {
if (!url.searchParams.has('list')) {
throw new Error('Playlist: "list" field not found')
}

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': {
const { searchQuery, query } = result

case 'search': {
if (!url.searchParams.has('search_query')) {
throw new Error('Search: "search_query" field not found')
}

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
}
this.$router.push({
path: `/search/${encodeURIComponent(searchQuery)}`,
query
})
break
}

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 '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)
}

case 'channel': {
const channelId = url.pathname.match(channelPattern)[1]
if (!channelId) {
throw new Error('Channel: could not extract id')
}
this.showToast({
message: message
})
break
}

v.$router.push({
path: `/channel/${channelId}`
})
break
}
case 'channel': {
const { channelId } = result

this.$router.push({
path: `/channel/${channelId}`
})
break
}

default: {
// 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)
}
case 'invalid_url': {
// Do nothing
break
}

this.showToast({
message: message
})
default: {
// 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)
}

this.showToast({
message: message
})
}
}
})
Expand Down
89 changes: 66 additions & 23 deletions src/renderer/components/top-nav/top-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import FtInput from '../ft-input/ft-input.vue'
import FtSearchFilters from '../ft-search-filters/ft-search-filters.vue'
import FtProfileSelector from '../ft-profile-selector/ft-profile-selector.vue'
import $ from 'jquery'
import router from '../../router/index.js'
import debounce from 'lodash.debounce'
import ytSuggest from 'youtube-suggest'
const { ipcRenderer } = require('electron')
Expand Down Expand Up @@ -90,32 +89,76 @@ export default Vue.extend({
searchInput.blur()
}

const { videoId, timestamp } = await this.$store.dispatch('getVideoParamsFromUrl', query)
const playlistId = await this.$store.dispatch('getPlaylistIdFromUrl', query)
this.$store.dispatch('getYoutubeUrlInfo', query).then((result) => {
switch (result.urlType) {
case 'video': {
const { videoId, timestamp } = result

console.log(playlistId)
this.$router.push({
path: `/watch/${videoId}`,
query: timestamp ? { timestamp } : {}
})
break
}

if (videoId) {
this.$router.push({
path: `/watch/${videoId}`,
query: timestamp ? { timestamp } : {}
})
} else if (playlistId) {
this.$router.push({
path: `/playlist/${playlistId}`
})
} else {
router.push({
path: `/search/${encodeURIComponent(query)}`,
query: {
sortBy: this.searchSettings.sortBy,
time: this.searchSettings.time,
type: this.searchSettings.type,
duration: this.searchSettings.duration
case 'playlist': {
const { playlistId, query } = result

this.$router.push({
path: `/playlist/${playlistId}`,
query
})
break
}
})
}

case 'search': {
const { searchQuery, query } = result

this.$router.push({
path: `/search/${encodeURIComponent(searchQuery)}`,
query
})
break
}

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 } = result

this.$router.push({
path: `/channel/${channelId}`
})
break
}

case 'invalid_url':
default: {
this.$router.push({
path: `/search/${encodeURIComponent(query)}`,
query: {
sortBy: this.searchSettings.sortBy,
time: this.searchSettings.time,
type: this.searchSettings.type,
duration: this.searchSettings.duration
}
})
}
}
})

// Close the filter panel
this.showFilters = false
},

Expand Down
Loading

0 comments on commit 82aeaac

Please sign in to comment.