Skip to content

Commit

Permalink
Merge branch 'feature/playlist-search-videos-in-one-user-playlist-2' …
Browse files Browse the repository at this point in the history
…into custom-builds/current

* feature/playlist-search-videos-in-one-user-playlist-2:
  ! Fix load more button appears when searching & visible items under pagination limit
  * Update single playlist view for user playlists to add search video function
  Playlist performance improvements (FreeTubeApp#4597)
  ! Fix playlist type not passed when playing next/prev item in a user playlist (FreeTubeApp#4623)
  Properly localize playlist view and video counts (FreeTubeApp#4620)
  Translated using Weblate (Croatian)
  • Loading branch information
PikachuEXE committed Feb 1, 2024
2 parents 2331abf + 5271a80 commit 5909acd
Show file tree
Hide file tree
Showing 17 changed files with 409 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Set a height to invisible/unloaded elements, so that lazy loading actually works.
If we don't set a height, they all get a height of 0px (because they have no content),
so they all bunch up together and end up loading all of them in one go.
*/
.placeholder {
block-size: 40px;
}

.videoIndex {
color: var(--tertiary-text-color);
text-align: center;
}

.videoIndexIcon {
font-size: 14px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { defineComponent } from 'vue'
import FtListVideo from '../ft-list-video/ft-list-video.vue'

export default defineComponent({
name: 'FtListVideoNumbered',
components: {
'ft-list-video': FtListVideo
},
props: {
data: {
type: Object,
required: true
},
playlistId: {
type: String,
default: null
},
playlistType: {
type: String,
default: null
},
playlistIndex: {
type: Number,
default: null
},
playlistReverse: {
type: Boolean,
default: false
},
playlistShuffle: {
type: Boolean,
default: false
},
playlistLoop: {
type: Boolean,
default: false
},
playlistItemId: {
type: String,
default: null,
},
appearance: {
type: String,
required: true
},
initialVisibleState: {
type: Boolean,
default: false,
},
alwaysShowAddToPlaylistButton: {
type: Boolean,
default: false,
},
quickBookmarkButtonEnabled: {
type: Boolean,
default: true,
},
canMoveVideoUp: {
type: Boolean,
default: false,
},
canMoveVideoDown: {
type: Boolean,
default: false,
},
canRemoveFromPlaylist: {
type: Boolean,
default: false,
},
videoIndex: {
type: Number,
default: -1
},
isCurrentVideo: {
type: Boolean,
default: false
},
useChannelsHiddenPreference: {
type: Boolean,
default: false,
}
},
data: function () {
return {
visible: false,
show: true
}
},
computed: {
channelsHidden() {
// Some component users like channel view will have this disabled
if (!this.useChannelsHiddenPreference) { return [] }

return JSON.parse(this.$store.getters.getChannelsHidden).map((ch) => {
// Legacy support
if (typeof ch === 'string') {
return { name: ch, preferredName: '', icon: '' }
}
return ch
})
},

// As we only use this component in Playlist and watch-video-playlist,
// where title filtering is never desired, we don't have any title filtering logic here,
// like we do in ft-list-video-lazy

shouldBeVisible() {
return !(this.channelsHidden.some(ch => ch.name === this.data.authorId) ||
this.channelsHidden.some(ch => ch.name === this.data.author))
}
},
created() {
this.visible = this.initialVisibleState
},
methods: {
onVisibilityChanged: function (visible) {
if (visible && this.shouldBeVisible) {
this.visible = visible
} else if (visible) {
this.show = false
}
}
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<div
v-show="show"
v-observe-visibility="!initialVisibleState ? {
callback: onVisibilityChanged,
once: true,
} : null"
:class="{ placeholder: !visible }"
>
<template
v-if="visible"
>
<p
class="videoIndex"
>
<font-awesome-icon
v-if="isCurrentVideo"
class="videoIndexIcon"
:icon="['fas', 'play']"
/>
<template
v-else
>
{{ videoIndex + 1 }}
</template>
</p>
<ft-list-video
:data="data"
:playlist-id="playlistId"
:playlist-type="playlistType"
:playlist-index="playlistIndex"
:playlist-reverse="playlistReverse"
:playlist-shuffle="playlistShuffle"
:playlist-loop="playlistLoop"
:playlist-item-id="playlistItemId"
force-list-type="list"
:appearance="appearance"
:always-show-add-to-playlist-button="alwaysShowAddToPlaylistButton"
:quick-bookmark-button-enabled="quickBookmarkButtonEnabled"
:can-move-video-up="canMoveVideoUp"
:can-move-video-down="canMoveVideoDown"
:can-remove-from-playlist="canRemoveFromPlaylist"
@pause-player="$emit('pause-player')"
@move-video-up="$emit('move-video-up')"
@move-video-down="$emit('move-video-down')"
@remove-from-playlist="$emit('remove-from-playlist')"
/>
</template>
</div>
</template>

<script src="./ft-list-video-numbered.js" />
<style scoped src="./ft-list-video-numbered.css" />
15 changes: 4 additions & 11 deletions src/renderer/components/ft-list-video/ft-list-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export default defineComponent({
lengthSeconds: 0,
duration: '',
description: '',
watched: false,
watchProgress: 0,
publishedText: '',
isLive: false,
Expand Down Expand Up @@ -223,7 +222,7 @@ export default defineComponent({
dropdownOptions: function () {
const options = [
{
label: this.watched
label: this.historyEntryExists
? this.$t('Video.Remove From History')
: this.$t('Video.Mark As Watched'),
value: 'history'
Expand Down Expand Up @@ -343,7 +342,7 @@ export default defineComponent({
},

addWatchedStyle: function () {
return this.watched && !this.inHistory
return this.historyEntryExists && !this.inHistory
},

externalPlayer: function () {
Expand Down Expand Up @@ -576,15 +575,15 @@ export default defineComponent({
}
this.openInExternalPlayer(payload)

if (this.saveWatchedProgress && !this.watched) {
if (this.saveWatchedProgress && !this.historyEntryExists) {
this.markAsWatched()
}
},

handleOptionsClick: function (option) {
switch (option) {
case 'history':
if (this.watched) {
if (this.historyEntryExists) {
this.removeFromWatched()
} else {
this.markAsWatched()
Expand Down Expand Up @@ -727,8 +726,6 @@ export default defineComponent({

checkIfWatched: function () {
if (this.historyEntryExists) {
this.watched = true

const historyEntry = this.historyEntry

if (this.saveWatchedProgress) {
Expand All @@ -744,7 +741,6 @@ export default defineComponent({
this.publishedText = ''
}
} else {
this.watched = false
this.watchProgress = 0
}
},
Expand All @@ -766,16 +762,13 @@ export default defineComponent({
}
this.updateHistory(videoData)
showToast(this.$t('Video.Video has been marked as watched'))

this.watched = true
},

removeFromWatched: function () {
this.removeFromHistory(this.id)

showToast(this.$t('Video.Video has been removed from your history'))

this.watched = false
this.watchProgress = 0
},

Expand Down
17 changes: 9 additions & 8 deletions src/renderer/components/ft-list-video/ft-list-video.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
{{ $t("Video.Watched") }}
</div>
<div
v-if="watched"
v-if="historyEntryExists"
class="watchedProgressBar"
:style="{inlineSize: progressPercentage + '%'}"
/>
Expand All @@ -129,12 +129,13 @@
<span v-else-if="channelName !== null">
{{ channelName }}
</span>
<template v-if="!isLive && !isUpcoming && !isPremium && !hideViews && viewCount != null">
<span class="viewCount">
<template v-if="channelId !== null"> • </template>
{{ $tc('Global.Counts.View Count', viewCount, {count: parsedViewCount}) }}
</span>
</template>
<span
v-if="!isLive && !isUpcoming && !isPremium && !hideViews && viewCount != null"
class="viewCount"
>
<template v-if="channelId !== null || channelName !== null"> • </template>
{{ $tc('Global.Counts.View Count', viewCount, {count: parsedViewCount}) }}
</span>
<span
v-if="uploadedTime !== '' && !isLive && !inHistory"
class="uploadedTime"
Expand All @@ -160,7 +161,7 @@
@click="handleOptionsClick"
/>
<p
v-if="((listType === 'list' || forceListType === 'list') && forceListType !== 'grid') &&
v-if="description && ((listType === 'list' || forceListType === 'list') && forceListType !== 'grid') &&
appearance === 'result'"
class="description"
v-html="description"
Expand Down
38 changes: 37 additions & 1 deletion src/renderer/components/playlist-info/playlist-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
import FtInput from '../ft-input/ft-input.vue'
import FtPrompt from '../ft-prompt/ft-prompt.vue'
import FtButton from '../ft-button/ft-button.vue'
import {
formatNumber,
showToast,
} from '../../helpers/utils'
import debounce from 'lodash.debounce'

export default defineComponent({
name: 'PlaylistInfo',
Expand All @@ -17,6 +20,7 @@ export default defineComponent({
'ft-icon-button': FtIconButton,
'ft-input': FtInput,
'ft-prompt': FtPrompt,
'ft-button': FtButton,
},
props: {
id: {
Expand Down Expand Up @@ -82,6 +86,9 @@ export default defineComponent({
},
data: function () {
return {
searchVideoMode: false,
query: '',
updateQueryDebounce: function() {},
editMode: false,
showDeletePlaylistPrompt: false,
showRemoveVideosOnWatchPrompt: false,
Expand Down Expand Up @@ -145,6 +152,14 @@ export default defineComponent({
return this.firstVideoId !== ''
},

parsedViewCount() {
return formatNumber(this.viewCount)
},

parsedVideoCount() {
return formatNumber(this.videoCount)
},

thumbnail: function () {
if (this.thumbnailPreference === 'hidden' || !this.firstVideoIdExists) {
return require('../../assets/img/thumbnail_placeholder.svg')
Expand Down Expand Up @@ -223,10 +238,12 @@ export default defineComponent({
created: function () {
this.newTitle = this.title
this.newDescription = this.description

this.updateQueryDebounce = debounce(this.updateQuery, 500)
},
methods: {
toggleCopyVideosPrompt: function (force = false) {
if (this.moreVideoDataAvailable && !force) {
if (this.moreVideoDataAvailable && !this.isUserPlaylist && !force) {
showToast(this.$t('User Playlists.SinglePlaylistView.Toast["Some videos in the playlist are not loaded yet. Click here to copy anyway."]'), 5000, () => {
this.toggleCopyVideosPrompt(true)
})
Expand Down Expand Up @@ -364,6 +381,25 @@ export default defineComponent({
showToast(this.$t('User Playlists.SinglePlaylistView.Toast.Quick bookmark disabled'))
},

updateQuery(query) {
this.query = query
this.$emit('search-video-query-change', query)
},
enableVideoSearchMode() {
this.searchVideoMode = true
this.$emit('search-video-mode-on')

nextTick(() => {
// Some elements only present after rendering update
this.$refs.searchInput.focus()
})
},
disableVideoSearchMode() {
this.searchVideoMode = false
this.updateQuery('')
this.$emit('search-video-mode-off')
},

...mapActions([
'showAddToPlaylistPromptForManyVideos',
'updatePlaylist',
Expand Down
Loading

0 comments on commit 5909acd

Please sign in to comment.