Simplify playlist / history search and add video stats string for legacy videos
This commit is contained in:
parent
222c41c863
commit
dbf69f242a
|
@ -36,8 +36,7 @@ const DBActions = {
|
|||
},
|
||||
|
||||
HISTORY: {
|
||||
UPDATE_WATCH_PROGRESS: 'db-action-history-update-watch-progress',
|
||||
SEARCH: 'db-action-history-search'
|
||||
UPDATE_WATCH_PROGRESS: 'db-action-history-update-watch-progress'
|
||||
},
|
||||
|
||||
PLAYLISTS: {
|
||||
|
|
|
@ -38,11 +38,6 @@ class History {
|
|||
return db.history.find({}).sort({ timeWatched: -1 })
|
||||
}
|
||||
|
||||
static search(query) {
|
||||
const re = new RegExp(query, 'i')
|
||||
return db.history.find({ $or: [{ author: { $regex: re } }, { title: { $regex: re } }] }).sort({ timeWatched: -1 })
|
||||
}
|
||||
|
||||
static upsert(record) {
|
||||
return db.history.update({ videoId: record.videoId }, record, { upsert: true })
|
||||
}
|
||||
|
|
|
@ -25,13 +25,6 @@ class History {
|
|||
)
|
||||
}
|
||||
|
||||
static search(query) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.HISTORY.SEARCH, data: query }
|
||||
)
|
||||
}
|
||||
|
||||
static upsert(record) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
|
|
|
@ -25,10 +25,6 @@ class History {
|
|||
return baseHandlers.history.find()
|
||||
}
|
||||
|
||||
static search(query) {
|
||||
return baseHandlers.history.search(query)
|
||||
}
|
||||
|
||||
static upsert(record) {
|
||||
return baseHandlers.history.upsert(record)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,4 @@ db.profiles = Datastore.create({ filename: dbPath('profiles'), autoload: true })
|
|||
db.playlists = Datastore.create({ filename: dbPath('playlists'), autoload: true })
|
||||
db.history = Datastore.create({ filename: dbPath('history'), autoload: true })
|
||||
|
||||
db.history.ensureIndex({ fieldName: 'author' })
|
||||
db.history.ensureIndex({ fieldName: 'title' })
|
||||
|
||||
export default db
|
||||
|
|
|
@ -456,9 +456,6 @@ function runApp() {
|
|||
)
|
||||
return null
|
||||
|
||||
case DBActions.HISTORY.SEARCH:
|
||||
return await baseHandlers.history.search(data)
|
||||
|
||||
case DBActions.GENERAL.DELETE:
|
||||
await baseHandlers.history.delete(data)
|
||||
syncOtherWindows(
|
||||
|
|
|
@ -208,12 +208,6 @@ export default Vue.extend({
|
|||
return this.$store.getters.getSaveWatchedProgress
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: function () {
|
||||
this.parseVideoData()
|
||||
this.checkIfWatched()
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.parseVideoData()
|
||||
this.checkIfWatched()
|
||||
|
|
|
@ -1414,7 +1414,7 @@ export default Vue.extend({
|
|||
console.log(this.format)
|
||||
if (this.format !== 'dash') {
|
||||
this.showToast({
|
||||
message: 'Video statistics are not available for legacy videos'
|
||||
message: this.$t('Video.Stats.Video statistics are not available for legacy videos')
|
||||
})
|
||||
} else {
|
||||
this.showStatsModal = !this.showStatsModal
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import { DBHistoryHandlers } from '../../../datastores/handlers/index'
|
||||
|
||||
const state = {
|
||||
historyCache: [],
|
||||
searchHistoryCache: []
|
||||
historyCache: []
|
||||
}
|
||||
|
||||
const getters = {
|
||||
getHistoryCache: () => {
|
||||
return state.historyCache
|
||||
},
|
||||
getSearchHistoryCache: () => {
|
||||
return state.searchHistoryCache
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,15 +47,6 @@ const actions = {
|
|||
}
|
||||
},
|
||||
|
||||
async searchHistory({ commit }, query) {
|
||||
try {
|
||||
const results = await DBHistoryHandlers.search(query)
|
||||
commit('setSearchHistoryCache', results)
|
||||
} catch (errMessage) {
|
||||
console.error(errMessage)
|
||||
}
|
||||
},
|
||||
|
||||
async updateWatchProgress({ commit }, { videoId, watchProgress }) {
|
||||
try {
|
||||
await DBHistoryHandlers.updateWatchProgress(videoId, watchProgress)
|
||||
|
@ -79,10 +66,6 @@ const mutations = {
|
|||
state.historyCache = historyCache
|
||||
},
|
||||
|
||||
setSearchHistoryCache(state, result) {
|
||||
state.searchHistoryCache = result
|
||||
},
|
||||
|
||||
hoistEntryToTopOfHistoryCache(state, { currentIndex, updatedEntry }) {
|
||||
state.historyCache.splice(currentIndex, 1)
|
||||
state.historyCache.unshift(updatedEntry)
|
||||
|
|
|
@ -13,20 +13,14 @@ const state = {
|
|||
removeOnWatched: true,
|
||||
videos: []
|
||||
}
|
||||
],
|
||||
searchPlaylistCache: {
|
||||
videos: []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const getters = {
|
||||
getAllPlaylists: () => state.playlists,
|
||||
getFavorites: () => state.playlists[0],
|
||||
getPlaylist: (playlistId) => state.playlists.find(playlist => playlist._id === playlistId),
|
||||
getWatchLater: () => state.playlists[1],
|
||||
getSearchPlaylistCache: () => {
|
||||
return state.searchPlaylistCache
|
||||
}
|
||||
getWatchLater: () => state.playlists[1]
|
||||
}
|
||||
|
||||
const actions = {
|
||||
|
@ -136,25 +130,10 @@ const actions = {
|
|||
} catch (errMessage) {
|
||||
console.error(errMessage)
|
||||
}
|
||||
},
|
||||
async searchFavoritePlaylist({ commit }, query) {
|
||||
const re = new RegExp(query, 'i')
|
||||
// filtering in the frontend because the documents are the playlists and not the videos
|
||||
const results = state.playlists[0].videos.slice()
|
||||
.filter((video) => {
|
||||
return video.author.match(re) ||
|
||||
video.title.match(re)
|
||||
})
|
||||
commit('setPlaylistCache', results)
|
||||
}
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
setPlaylistCache(state, result) {
|
||||
state.searchPlaylistCache = {
|
||||
videos: result
|
||||
}
|
||||
},
|
||||
addPlaylist(state, payload) {
|
||||
state.playlists.push(payload)
|
||||
},
|
||||
|
|
|
@ -20,19 +20,19 @@ export default Vue.extend({
|
|||
return {
|
||||
isLoading: false,
|
||||
dataLimit: 100,
|
||||
hasQuery: false
|
||||
searchDataLimit: 100,
|
||||
showLoadMoreButton: false,
|
||||
hasQuery: false,
|
||||
query: '',
|
||||
activeData: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
historyCache: function () {
|
||||
if (!this.hasQuery) {
|
||||
return this.$store.getters.getHistoryCache
|
||||
} else {
|
||||
return this.$store.getters.getSearchHistoryCache
|
||||
}
|
||||
return this.$store.getters.getHistoryCache
|
||||
},
|
||||
|
||||
activeData: function () {
|
||||
fullData: function () {
|
||||
if (this.historyCache.length < this.dataLimit) {
|
||||
return this.historyCache
|
||||
} else {
|
||||
|
@ -40,30 +40,79 @@ export default Vue.extend({
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
query() {
|
||||
this.searchDataLimit = 100
|
||||
this.filterHistory()
|
||||
},
|
||||
activeData() {
|
||||
this.refreshPage()
|
||||
},
|
||||
fullData() {
|
||||
this.activeData = this.fullData
|
||||
this.filterHistory()
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
console.log(this.historyCache)
|
||||
|
||||
const limit = sessionStorage.getItem('historyLimit')
|
||||
|
||||
if (limit !== null) {
|
||||
this.dataLimit = limit
|
||||
}
|
||||
|
||||
this.activeData = this.fullData
|
||||
|
||||
if (this.activeData.length < this.historyCache.length) {
|
||||
this.showLoadMoreButton = true
|
||||
} else {
|
||||
this.showLoadMoreButton = false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
increaseLimit: function () {
|
||||
this.dataLimit += 100
|
||||
sessionStorage.setItem('historyLimit', this.dataLimit)
|
||||
if (this.query !== '') {
|
||||
this.searchDataLimit += 100
|
||||
this.filterHistory()
|
||||
} else {
|
||||
this.dataLimit += 100
|
||||
sessionStorage.setItem('historyLimit', this.dataLimit)
|
||||
}
|
||||
},
|
||||
filterHistory: function(query) {
|
||||
this.hasQuery = query !== ''
|
||||
this.$store.dispatch('searchHistory', query)
|
||||
if (this.query === '') {
|
||||
this.activeData = this.fullData
|
||||
if (this.activeData.length < this.historyCache.length) {
|
||||
this.showLoadMoreButton = true
|
||||
} else {
|
||||
this.showLoadMoreButton = false
|
||||
}
|
||||
} else {
|
||||
const filteredQuery = this.historyCache.filter((video) => {
|
||||
if (typeof (video.title) !== 'string' || typeof (video.author) !== 'string') {
|
||||
return false
|
||||
} else {
|
||||
return video.title.toLowerCase().includes(this.query.toLowerCase()) || video.author.toLowerCase().includes(this.query.toLowerCase())
|
||||
}
|
||||
}).sort((a, b) => {
|
||||
return b.timeWatched - a.timeWatched
|
||||
})
|
||||
if (filteredQuery.length <= this.searchDataLimit) {
|
||||
this.showLoadMoreButton = false
|
||||
} else {
|
||||
this.showLoadMoreButton = true
|
||||
}
|
||||
this.activeData = filteredQuery.length < this.searchDataLimit ? filteredQuery : filteredQuery.slice(0, this.searchDataLimit)
|
||||
}
|
||||
},
|
||||
load: function() {
|
||||
refreshPage: function() {
|
||||
const scrollPos = window.scrollY || window.scrollTop || document.getElementsByTagName('html')[0].scrollTop
|
||||
this.isLoading = true
|
||||
setTimeout(() => {
|
||||
Vue.nextTick(() => {
|
||||
this.isLoading = false
|
||||
}, 100)
|
||||
Vue.nextTick(() => {
|
||||
window.scrollTo(0, scrollPos)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<ft-loader
|
||||
v-if="isLoading"
|
||||
v-show="isLoading"
|
||||
:fullscreen="true"
|
||||
/>
|
||||
<ft-card
|
||||
v-else
|
||||
v-show="!isLoading"
|
||||
class="card"
|
||||
>
|
||||
<h3>{{ $t("History.History") }}</h3>
|
||||
|
@ -14,21 +14,21 @@
|
|||
:placeholder="$t('History.Search bar placeholder')"
|
||||
:show-clear-text-button="true"
|
||||
:show-action-button="false"
|
||||
@input="filterHistory"
|
||||
@input="(input) => query = input"
|
||||
/>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length === 0"
|
||||
v-show="activeData.length === 0"
|
||||
>
|
||||
<p class="message">
|
||||
{{ $t("History['Your history list is currently empty.']") }}
|
||||
</p>
|
||||
</ft-flex-box>
|
||||
<ft-element-list
|
||||
v-else
|
||||
v-if="activeData.length > 0 && !isLoading"
|
||||
:data="activeData"
|
||||
/>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length < historyCache.length"
|
||||
v-if="showLoadMoreButton"
|
||||
>
|
||||
<ft-button
|
||||
label="Load More"
|
||||
|
|
|
@ -22,19 +22,19 @@ export default Vue.extend({
|
|||
return {
|
||||
isLoading: false,
|
||||
dataLimit: 100,
|
||||
hasQuery: false
|
||||
searchDataLimit: 100,
|
||||
showLoadMoreButton: false,
|
||||
query: '',
|
||||
hasQuery: false,
|
||||
activeData: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
favoritesPlaylist: function () {
|
||||
if (!this.hasQuery) {
|
||||
return this.$store.getters.getFavorites
|
||||
} else {
|
||||
return this.$store.getters.getSearchPlaylistCache
|
||||
}
|
||||
return this.$store.getters.getFavorites
|
||||
},
|
||||
|
||||
activeData: function () {
|
||||
fullData: function () {
|
||||
const data = [].concat(this.favoritesPlaylist.videos).reverse()
|
||||
if (this.favoritesPlaylist.videos.length < this.dataLimit) {
|
||||
return data
|
||||
|
@ -44,7 +44,70 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
watch: {
|
||||
query() {
|
||||
this.searchDataLimit = 100
|
||||
this.filterPlaylist()
|
||||
},
|
||||
activeData() {
|
||||
this.refreshPage()
|
||||
},
|
||||
fullData() {
|
||||
this.activeData = this.fullData
|
||||
this.filterPlaylist()
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
const limit = sessionStorage.getItem('favoritesLimit')
|
||||
|
||||
if (limit !== null) {
|
||||
this.dataLimit = limit
|
||||
}
|
||||
|
||||
if (this.activeData.length < this.favoritesPlaylist.videos.length) {
|
||||
this.showLoadMoreButton = true
|
||||
} else {
|
||||
this.showLoadMoreButton = false
|
||||
}
|
||||
|
||||
this.activeData = this.fullData
|
||||
},
|
||||
methods: {
|
||||
increaseLimit: function () {
|
||||
if (this.query !== '') {
|
||||
this.searchDataLimit += 100
|
||||
this.filterPlaylist()
|
||||
} else {
|
||||
this.dataLimit += 100
|
||||
sessionStorage.setItem('favoritesLimit', this.dataLimit)
|
||||
}
|
||||
},
|
||||
filterPlaylist: function() {
|
||||
if (this.query === '') {
|
||||
this.activeData = this.fullData
|
||||
if (this.activeData.length < this.favoritesPlaylist.videos.length) {
|
||||
this.showLoadMoreButton = true
|
||||
} else {
|
||||
this.showLoadMoreButton = false
|
||||
}
|
||||
} else {
|
||||
const filteredQuery = this.favoritesPlaylist.videos.filter((video) => {
|
||||
if (typeof (video.title) !== 'string' || typeof (video.author) !== 'string') {
|
||||
return false
|
||||
} else {
|
||||
return video.title.toLowerCase().includes(this.query.toLowerCase()) || video.author.toLowerCase().includes(this.query.toLowerCase())
|
||||
}
|
||||
}).sort((a, b) => {
|
||||
return b.timeAdded - a.timeAdded
|
||||
})
|
||||
if (filteredQuery.length <= this.searchDataLimit) {
|
||||
this.showLoadMoreButton = false
|
||||
} else {
|
||||
this.showLoadMoreButton = true
|
||||
}
|
||||
this.activeData = filteredQuery.length < this.searchDataLimit ? filteredQuery : filteredQuery.slice(0, this.searchDataLimit)
|
||||
}
|
||||
},
|
||||
refreshPage: function() {
|
||||
const scrollPos = window.scrollY || window.scrollTop || document.getElementsByTagName('html')[0].scrollTop
|
||||
this.isLoading = true
|
||||
Vue.nextTick(() => {
|
||||
|
@ -54,22 +117,5 @@ export default Vue.extend({
|
|||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
const limit = sessionStorage.getItem('favoritesLimit')
|
||||
|
||||
if (limit !== null) {
|
||||
this.dataLimit = limit
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
increaseLimit: function () {
|
||||
this.dataLimit += 100
|
||||
sessionStorage.setItem('favoritesLimit', this.dataLimit)
|
||||
},
|
||||
filterPlaylist: function(query) {
|
||||
this.hasQuery = query !== ''
|
||||
this.$store.dispatch('searchFavoritePlaylist', query)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<ft-loader
|
||||
v-if="isLoading"
|
||||
v-show="isLoading"
|
||||
:fullscreen="true"
|
||||
/>
|
||||
<ft-card
|
||||
v-else
|
||||
v-show="!isLoading"
|
||||
class="card"
|
||||
>
|
||||
<h3>
|
||||
|
@ -21,21 +21,21 @@
|
|||
:placeholder="$t('User Playlists.Search bar placeholder')"
|
||||
:show-clear-text-button="true"
|
||||
:show-action-button="false"
|
||||
@input="filterPlaylist"
|
||||
@input="(input) => query = input"
|
||||
/>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length === 0"
|
||||
v-show="activeData.length === 0"
|
||||
>
|
||||
<p class="message">
|
||||
{{ $t("User Playlists['Your saved videos are empty. Click on the save button on the corner of a video to have it listed here']") }}
|
||||
</p>
|
||||
</ft-flex-box>
|
||||
<ft-element-list
|
||||
v-else
|
||||
v-if="activeData.length > 0 && !isLoading"
|
||||
:data="activeData"
|
||||
/>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length < favoritesPlaylist.videos.length"
|
||||
v-if="showLoadMoreButton"
|
||||
>
|
||||
<ft-button
|
||||
label="Load More"
|
||||
|
|
|
@ -556,6 +556,7 @@ Video:
|
|||
shuffling playlists: shuffling playlists
|
||||
looping playlists: looping playlists
|
||||
Stats:
|
||||
Video statistics are not available for legacy videos: Video statistics are not available for legacy videos
|
||||
Video ID: Video ID
|
||||
Resolution: Resolution
|
||||
Player Dimensions: Player Dimensions
|
||||
|
|
Loading…
Reference in New Issue