Skip to content

Commit

Permalink
Merge branch 'feature/history/remember-search-query' into custom-buil…
Browse files Browse the repository at this point in the history
…ds/tmp

* feature/history/remember-search-query:
  * Make channel page remember last query string only when going back
  * Make playlist page remember last query string only when going back
  * Make user playlists page remember last query string only when going back
  * Make subscribed channels page remember last query string only when going back
  ! Fix restoring filtered history having unnecessary delay
  * Make history page remember last query string & search limit only when going back
  $ Simplify boolean assignment, rename session storage key
  • Loading branch information
PikachuEXE committed Sep 16, 2024
2 parents af1949f + 47222b9 commit aae081f
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 44 deletions.
7 changes: 6 additions & 1 deletion src/renderer/components/ChannelDetails/ChannelDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
v-if="showSearchBar"
ref="searchBar"
:placeholder="$t('Channel.Search Channel')"
:value="props.query"
:show-clear-text-button="true"
class="channelSearch"
:maxlength="255"
Expand Down Expand Up @@ -274,7 +275,11 @@ const props = defineProps({
currentTab: {
type: String,
default: 'videos'
}
},
query: {
type: String,
default: ''
},
})
const emit = defineEmits(['change-tab', 'search'])
Expand Down
62 changes: 54 additions & 8 deletions src/renderer/views/Channel/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
getLocalPlaylist,
parseLocalPlaylistVideo
} from '../../helpers/api/local'
import { isNavigationFailure, NavigationFailureType } from 'vue-router'

export default defineComponent({
name: 'Channel',
Expand All @@ -60,6 +61,7 @@ export default defineComponent({
},
data: function () {
return {
skipRouteChangeWatcherOnce: false,
isLoading: true,
isElementListLoading: false,
currentTab: 'videos',
Expand Down Expand Up @@ -301,6 +303,10 @@ export default defineComponent({
watch: {
$route() {
// react to route changes...
if (this.skipRouteChangeWatcherOnce) {
this.skipRouteChangeWatcherOnce = false
return
}
this.isLoading = true

if (this.$route.query.url) {
Expand Down Expand Up @@ -357,8 +363,9 @@ export default defineComponent({

// Re-enable auto refresh on sort value change AFTER update done
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
this.getChannelInfoInvidious()
this.autoRefreshOnSortByChangeEnabled = true
this.getChannelInfoInvidious().finally(() => {
this.autoRefreshOnSortByChangeEnabled = true
})
} else {
this.getChannelLocal().finally(() => {
this.autoRefreshOnSortByChangeEnabled = true
Expand Down Expand Up @@ -435,9 +442,9 @@ export default defineComponent({
}
}
},
mounted: function () {
mounted: async function () {
if (this.$route.query.url) {
this.resolveChannelUrl(this.$route.query.url, this.$route.params.currentTab)
await this.resolveChannelUrl(this.$route.query.url, this.$route.params.currentTab)
return
}

Expand All @@ -453,13 +460,19 @@ export default defineComponent({

// Enable auto refresh on sort value change AFTER initial update done
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
this.getChannelInfoInvidious()
this.autoRefreshOnSortByChangeEnabled = true
await this.getChannelInfoInvidious().finally(() => {
this.autoRefreshOnSortByChangeEnabled = true
})
} else {
this.getChannelLocal().finally(() => {
await this.getChannelLocal().finally(() => {
this.autoRefreshOnSortByChangeEnabled = true
})
}

const oldQuery = this.$route.query.searchQueryText ?? ''
if (oldQuery !== null && oldQuery !== '') {
this.newSearch(oldQuery)
}
},
methods: {
resolveChannelUrl: async function (url, tab = undefined) {
Expand Down Expand Up @@ -1013,7 +1026,7 @@ export default defineComponent({
this.channelInstance = null

const expectedId = this.id
invidiousGetChannelInfo(this.id).then((response) => {
return invidiousGetChannelInfo(this.id).then((response) => {
if (expectedId !== this.id) {
return
}
Expand Down Expand Up @@ -1900,6 +1913,10 @@ export default defineComponent({
break
}
},
newSearchWithStatePersist(query) {
this.saveStateInRouter(query)
this.newSearch(query)
},

searchChannelLocal: async function () {
const isNewSearch = this.searchContinuationData === null
Expand Down Expand Up @@ -1991,6 +2008,35 @@ export default defineComponent({
})
},

async saveStateInRouter(query) {
this.skipRouteChangeWatcherOnce = true
if (query === '') {
await this.$router.replace({ path: `/channel/${this.id}` }).catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
return
}

throw failure
})
return
}

await this.$router.replace({
path: `/channel/${this.id}`,
query: {
currentTab: 'search',
searchQueryText: query,
},
}).catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
return
}

throw failure
})
this.skipRouteChangeWatcherOnce = false
},

getIconForSortPreference: (s) => getIconForSortPreference(s),

...mapActions([
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/views/Channel/Channel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
:is-subscribed="isSubscribed"
:visible-tabs="tabInfoValues"
:current-tab="currentTab"
:query="lastSearchQuery"
class="card channelDetails"
@change-tab="changeTab"
@search="newSearch"
@search="(v) => newSearchWithStatePersist(v)"
/>
<ft-card
v-if="!isLoading && !errorMessage && (isFamilyFriendly || !showFamilyFriendlyOnly)"
Expand Down
65 changes: 52 additions & 13 deletions src/renderer/views/History/History.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineComponent } from 'vue'
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
import debounce from 'lodash.debounce'
import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtCard from '../../components/ft-card/ft-card.vue'
Expand Down Expand Up @@ -63,42 +64,55 @@ export default defineComponent({
},
},
watch: {
query() {
this.searchDataLimit = 100
this.filterHistoryAsync()
},
fullData() {
this.filterHistory()
},
doCaseSensitiveSearch() {
this.filterHistory()
},
},
mounted: function () {
created: function () {
document.addEventListener('keydown', this.keyboardShortcutHandler)
const limit = sessionStorage.getItem('historyLimit')

if (limit !== null) {
this.dataLimit = limit
const oldDataLimit = sessionStorage.getItem('History/dataLimit')
if (oldDataLimit !== null) {
this.dataLimit = oldDataLimit
}

this.activeData = this.fullData

this.showLoadMoreButton = this.activeData.length < this.historyCacheSorted.length

this.filterHistoryDebounce = debounce(this.filterHistory, 500)

const oldQuery = this.$route.query.searchQueryText ?? ''
if (oldQuery !== null && oldQuery !== '') {
// `handleQueryChange` must be called after `filterHistoryDebounce` assigned
this.handleQueryChange(oldQuery, this.$route.query.searchDataLimit, true)
} else {
// Only display unfiltered data when no query used last time
this.filterHistory()
}
},
beforeDestroy: function () {
document.removeEventListener('keydown', this.keyboardShortcutHandler)
},
methods: {
handleQueryChange(val, customLimit = null, filterNow = false) {
this.query = val

const newLimit = customLimit ?? 100
this.searchDataLimit = newLimit

this.saveStateInRouter(val, newLimit)

filterNow ? this.filterHistory() : this.filterHistoryAsync()
},

increaseLimit: function () {
if (this.query !== '') {
this.searchDataLimit += 100
this.saveStateInRouter(this.query, this.searchDataLimit)
this.filterHistory()
} else {
this.dataLimit += 100
sessionStorage.setItem('historyLimit', this.dataLimit)
sessionStorage.setItem('History/dataLimit', this.dataLimit)
}
},
filterHistoryAsync: function() {
Expand All @@ -122,6 +136,31 @@ export default defineComponent({
this.activeData = filteredQuery.length < this.searchDataLimit ? filteredQuery : filteredQuery.slice(0, this.searchDataLimit)
this.showLoadMoreButton = this.activeData.length > this.searchDataLimit
},

async saveStateInRouter(query, searchDataLimit) {
if (this.query === '') {
await this.$router.replace({ name: 'history' }).catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
return
}

throw failure
})
return
}

await this.$router.replace({
name: 'history',
query: { searchQueryText: query, searchDataLimit: searchDataLimit },
}).catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
return
}

throw failure
})
},

keyboardShortcutHandler: function (event) {
ctrlFHandler(event, this.$refs.searchBar)
},
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/views/History/History.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
:placeholder="$t('History.Search bar placeholder')"
:show-clear-text-button="true"
:show-action-button="false"
@input="(input) => query = input"
@clear="query = ''"
:value="query"
@input="(input) => handleQueryChange(input)"
@clear="() => handleQueryChange('')"
/>
<div
class="optionsRow"
Expand Down
29 changes: 28 additions & 1 deletion src/renderer/views/Playlist/Playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { invidiousGetPlaylistInfo, youtubeImageUrlToInvidious } from '../../help
import { getSortedPlaylistItems, SORT_BY_VALUES } from '../../helpers/playlists'
import packageDetails from '../../../../package.json'
import { MOBILE_WIDTH_THRESHOLD, PLAYLIST_HEIGHT_FORCE_LIST_THRESHOLD } from '../../../constants'
import { isNavigationFailure, NavigationFailureType } from 'vue-router'

export default defineComponent({
name: 'Playlist',
Expand Down Expand Up @@ -257,7 +258,7 @@ export default defineComponent({
this.getPlaylistInfoDebounce = debounce(this.getPlaylistInfo, 100)

if (this.isUserPlaylistRequested && this.searchQueryTextPresent) {
this.videoSearchQuery = this.searchQueryTextRequested
this.handleVideoSearchQueryChange(this.searchQueryTextRequested)
}
},
mounted: function () {
Expand Down Expand Up @@ -564,6 +565,32 @@ export default defineComponent({
this.forceListView = window.innerWidth <= MOBILE_WIDTH_THRESHOLD || window.innerHeight <= PLAYLIST_HEIGHT_FORCE_LIST_THRESHOLD
},

handleVideoSearchQueryChange(val) {
this.videoSearchQuery = val

this.saveStateInRouter(val)
},

async saveStateInRouter(query) {
const routeQuery = {
playlistType: this.$route.query.playlistType,
}
if (query !== '') {
routeQuery.searchQueryText = query
}

await this.$router.replace({
path: `/playlist/${this.playlistId}`,
query: routeQuery,
}).catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
return
}

throw failure
})
},

getIconForSortPreference: (s) => getIconForSortPreference(s),

...mapActions([
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/views/Playlist/Playlist.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
class="playlistInfo"
@enter-edit-mode="playlistInEditMode = true"
@exit-edit-mode="playlistInEditMode = false"
@search-video-query-change="(v) => videoSearchQuery = v"
@search-video-query-change="(v) => handleVideoSearchQueryChange(v)"
@prompt-open="promptOpen = true"
@prompt-close="promptOpen = false"
/>
Expand Down
Loading

0 comments on commit aae081f

Please sign in to comment.