Skip to content

Commit 1bfe0ad

Browse files
committed
* Update single playlist view for user playlists to add search video function
1 parent 67e6e0f commit 1bfe0ad

File tree

6 files changed

+92
-5
lines changed

6 files changed

+92
-5
lines changed

src/renderer/components/playlist-info/playlist-info.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
55
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
66
import FtInput from '../ft-input/ft-input.vue'
77
import FtPrompt from '../ft-prompt/ft-prompt.vue'
8+
import FtButton from '../ft-button/ft-button.vue'
89
import {
910
showToast,
1011
} from '../../helpers/utils'
12+
import debounce from 'lodash.debounce'
1113

1214
export default defineComponent({
1315
name: 'PlaylistInfo',
@@ -17,6 +19,7 @@ export default defineComponent({
1719
'ft-icon-button': FtIconButton,
1820
'ft-input': FtInput,
1921
'ft-prompt': FtPrompt,
22+
'ft-button': FtButton,
2023
},
2124
props: {
2225
id: {
@@ -82,6 +85,9 @@ export default defineComponent({
8285
},
8386
data: function () {
8487
return {
88+
searchVideoMode: false,
89+
query: '',
90+
updateQueryDebounce: function() {},
8591
editMode: false,
8692
showDeletePlaylistPrompt: false,
8793
showRemoveVideosOnWatchPrompt: false,
@@ -223,6 +229,8 @@ export default defineComponent({
223229
created: function () {
224230
this.newTitle = this.title
225231
this.newDescription = this.description
232+
233+
this.updateQueryDebounce = debounce(this.updateQuery, 500)
226234
},
227235
methods: {
228236
toggleCopyVideosPrompt: function (force = false) {
@@ -364,6 +372,25 @@ export default defineComponent({
364372
showToast(this.$t('User Playlists.SinglePlaylistView.Toast.Quick bookmark disabled'))
365373
},
366374

375+
updateQuery(query) {
376+
this.query = query
377+
this.$emit('search-video-query-change', query)
378+
},
379+
enableVideoSearchMode() {
380+
this.searchVideoMode = true
381+
this.$emit('search-video-mode-on')
382+
383+
nextTick(() => {
384+
// Some elements only present after rendering update
385+
this.$refs.searchInput.focus()
386+
})
387+
},
388+
disableVideoSearchMode() {
389+
this.searchVideoMode = false
390+
this.updateQuery('')
391+
this.$emit('search-video-mode-off')
392+
},
393+
367394
...mapActions([
368395
'showAddToPlaylistPromptForManyVideos',
369396
'updatePlaylist',

src/renderer/components/playlist-info/playlist-info.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,13 @@
7272
column-gap: 8px;
7373
justify-content: flex-end;
7474
}
75+
76+
.searchInputsRow {
77+
margin-block-start: 8px;
78+
79+
display: grid;
80+
81+
/* 2 columns */
82+
grid-template-columns: 1fr auto;
83+
column-gap: 8px;
84+
}

src/renderer/components/playlist-info/playlist-info.vue

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<hr>
7777

7878
<div
79+
v-if="!searchVideoMode"
7980
class="channelShareWrapper"
8081
>
8182
<router-link
@@ -106,6 +107,13 @@
106107
</div>
107108

108109
<div class="playlistOptions">
110+
<ft-icon-button
111+
v-if="isUserPlaylist && !editMode"
112+
:title="$t('User Playlists.SinglePlaylistView.Search for Videos')"
113+
:icon="['fas', 'search']"
114+
theme="secondary"
115+
@click="enableVideoSearchMode"
116+
/>
109117
<ft-icon-button
110118
v-if="editMode"
111119
:title="$t('User Playlists.Save Changes')"
@@ -186,6 +194,28 @@
186194
@click="handleRemoveVideosOnWatchPromptAnswer"
187195
/>
188196
</div>
197+
198+
<div
199+
v-if="isUserPlaylist && searchVideoMode"
200+
class="searchInputsRow"
201+
>
202+
<ft-input
203+
ref="searchInput"
204+
class="searchInput"
205+
:placeholder="$t('User Playlists.SinglePlaylistView.Search for Videos')"
206+
:show-clear-text-button="true"
207+
:show-action-button="false"
208+
@input="(input) => updateQueryDebounce(input)"
209+
@clear="updateQueryDebounce('')"
210+
/>
211+
<ft-icon-button
212+
v-if="isUserPlaylist && searchVideoMode"
213+
:title="$t('User Playlists.Cancel')"
214+
:icon="['fas', 'times']"
215+
theme="secondary"
216+
@click="disableVideoSearchMode"
217+
/>
218+
</div>
189219
</div>
190220
</template>
191221

src/renderer/views/Playlist/Playlist.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ export default defineComponent({
6060
getPlaylistInfoDebounce: function() {},
6161
playlistInEditMode: false,
6262

63+
playlistInVideoSearchMode: false,
64+
videoSearchQuery: '',
65+
6366
promptOpen: false,
6467
}
6568
},
@@ -123,17 +126,29 @@ export default defineComponent({
123126
return this.selectedUserPlaylist?._id !== this.quickBookmarkPlaylistId
124127
},
125128

129+
sometimesFilteredUserPlaylistItems() {
130+
if (!this.isUserPlaylistRequested) { return this.playlistItems }
131+
if (this.processedVideoSearchQuery === '') { return this.playlistItems }
132+
133+
return this.playlistItems.filter((v) => {
134+
return v.title.toLowerCase().includes(this.processedVideoSearchQuery)
135+
})
136+
},
126137
visiblePlaylistItems: function () {
127138
if (!this.isUserPlaylistRequested) {
139+
// No filtering for non user playlists yet
128140
return this.playlistItems
129141
}
130142

131143
if (this.userPlaylistVisibleLimit < this.videoCount) {
132-
return this.playlistItems.slice(0, this.userPlaylistVisibleLimit)
144+
return this.sometimesFilteredUserPlaylistItems.slice(0, this.userPlaylistVisibleLimit)
133145
} else {
134-
return this.playlistItems
146+
return this.sometimesFilteredUserPlaylistItems
135147
}
136-
}
148+
},
149+
processedVideoSearchQuery() {
150+
return this.videoSearchQuery.trim().toLowerCase()
151+
},
137152
},
138153
watch: {
139154
$route () {

src/renderer/views/Playlist/Playlist.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
}"
2929
@enter-edit-mode="playlistInEditMode = true"
3030
@exit-edit-mode="playlistInEditMode = false"
31+
@search-video-mode-on="playlistInVideoSearchMode = true"
32+
@search-video-mode-off="playlistInVideoSearchMode = false"
33+
@search-video-query-change="(v) => videoSearchQuery = v"
3134
@prompt-open="promptOpen = true"
3235
@prompt-close="promptOpen = false"
3336
/>
@@ -55,8 +58,8 @@
5558
appearance="result"
5659
:always-show-add-to-playlist-button="true"
5760
:quick-bookmark-button-enabled="quickBookmarkButtonEnabled"
58-
:can-move-video-up="index > 0"
59-
:can-move-video-down="index < visiblePlaylistItems.length - 1"
61+
:can-move-video-up="index > 0 && !playlistInVideoSearchMode"
62+
:can-move-video-down="index < playlistItems.length - 1 && !playlistInVideoSearchMode"
6063
:can-remove-from-playlist="true"
6164
:video-index="index"
6265
:initial-visible-state="index < 10"

static/locales/en-US.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ User Playlists:
186186
EarliestPlayedFirst: 'Earliest Played'
187187

188188
SinglePlaylistView:
189+
Search for Videos: Search for Videos
190+
189191
Toast:
190192
This video cannot be moved up.: This video cannot be moved up.
191193
This video cannot be moved down.: This video cannot be moved down.

0 commit comments

Comments
 (0)