Add move to top/bottom to playlist (#9463)

* Add move to top/bottom to playlist

* Format emits and wrap if statement
This commit is contained in:
Caetano
2026-07-25 21:02:43 +02:00
committed by GitHub
parent 28112e44e3
commit 2df7a20b86
7 changed files with 249 additions and 6 deletions
@@ -31,6 +31,8 @@
@drag-video-end="afterDrag"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@remove-from-playlist="removeFromPlaylist"
/>
</FtAutoGrid>
@@ -129,7 +131,16 @@ const props = defineProps({
},
})
const emit = defineEmits(['move-dragged-video', 'move-video-down', 'move-video-up', 'remove-from-playlist', 'drag-video', 'drag-video-end'])
const emit = defineEmits([
'move-dragged-video',
'move-video-down',
'move-video-up',
'move-video-to-the-top',
'move-video-to-the-bottom',
'remove-from-playlist',
'drag-video',
'drag-video-end'
])
/** @type {import('vue').ComputedRef<'grid' | 'list'>} */
const listType = computed(() => {
@@ -157,6 +168,22 @@ function moveVideoDown(videoId, playlistItemId) {
emit('move-video-down', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheTop(videoId, playlistItemId) {
emit('move-video-to-the-top', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheBottom(videoId, playlistItemId) {
emit('move-video-to-the-bottom', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
@@ -33,6 +33,8 @@
:show-grab-bar="isDraggable && layout === 'grid'"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@remove-from-playlist="removeFromPlaylist"
/>
<FtListChannel
@@ -162,7 +164,16 @@ const props = defineProps({
},
})
const emit = defineEmits(['move-dragged-video', 'move-video-down', 'move-video-up', 'remove-from-playlist', 'drag-video', 'drag-video-end'])
const emit = defineEmits([
'move-dragged-video',
'move-video-down',
'move-video-up',
'move-video-to-the-top',
'move-video-to-the-bottom',
'remove-from-playlist',
'drag-video',
'drag-video-end'
])
const inUserPlaylist = props.playlistType === 'user'
const isDraggable = computed(() => inUserPlaylist && props.isSortOrderCustom && (props.canMoveVideoUp || props.canMoveVideoDown))
@@ -328,6 +339,22 @@ function moveVideoDown(videoId, playlistItemId) {
emit('move-video-down', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheTop(videoId, playlistItemId) {
emit('move-video-to-the-top', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheBottom(videoId, playlistItemId) {
emit('move-video-to-the-bottom', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
@@ -373,7 +373,14 @@ const props = defineProps({
},
})
const emit = defineEmits(['move-video-down', 'move-video-up', 'pause-player', 'remove-from-playlist'])
const emit = defineEmits([
'move-video-down',
'move-video-up',
'move-video-to-the-top',
'move-video-to-the-bottom',
'pause-player',
'remove-from-playlist'
])
const { locale, t } = useI18n()
const route = useRoute()
@@ -486,8 +493,27 @@ const dropdownOptions = computed(() => {
? t('Video.Remove From History')
: t('Video.Mark As Watched'),
value: 'history'
}
},
]
if (inUserPlaylist.value) {
if (props.canMoveVideoUp || props.canMoveVideoDown) {
options.push({
type: 'divider'
})
}
if (props.canMoveVideoUp) {
options.push({
label: t('User Playlists.Move Video to the Top'),
value: 'moveVideoTop'
})
}
if (props.canMoveVideoDown) {
options.push({
label: t('User Playlists.Move Video to the Bottom'),
value: 'moveVideoBottom'
})
}
}
if (!hideSharingActions.value) {
options.push(
{
@@ -614,6 +640,12 @@ function handleOptionsClick(option) {
markAsWatched()
}
break
case 'moveVideoTop':
moveVideoToTheTop()
break
case 'moveVideoBottom':
moveVideoToTheBottom()
break
case 'copyYoutube': {
let videoUrl = `https://youtu.be/${id.value}`
@@ -1054,6 +1086,14 @@ function removeFromWatched() {
showToast(t('Video.Video has been removed from your history'))
}
function moveVideoToTheTop() {
emit('move-video-to-the-top', id.value, props.playlistItemId)
}
function moveVideoToTheBottom() {
emit('move-video-to-the-bottom', id.value, props.playlistItemId)
}
function togglePlaylistPrompt() {
const videoData = {
videoId: id.value,
+26 -1
View File
@@ -22,6 +22,8 @@
:can-move-video-up="canMoveVideoUp"
:can-move-video-down="canMoveVideoDown"
:can-remove-from-playlist="canRemoveFromPlaylist"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@pause-player="pausePlayer"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@@ -158,12 +160,35 @@ function onVisibilityChanged(isVisible) {
}
}
const emit = defineEmits(['pause-player', 'move-video-up', 'move-video-down', 'remove-from-playlist'])
const emit = defineEmits([
'pause-player',
'move-video-up',
'move-video-down',
'move-video-to-the-top',
'move-video-to-the-bottom',
'remove-from-playlist'
])
function pausePlayer() {
emit('pause-player')
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheTop(videoId, playlistItemId) {
emit('move-video-to-the-top', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheBottom(videoId, playlistItemId) {
emit('move-video-to-the-bottom', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
@@ -58,6 +58,8 @@
@pause-player="pausePlayer"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@remove-from-playlist="removeFromPlaylist"
/>
</template>
@@ -155,7 +157,17 @@ const props = defineProps({
}
})
const emit = defineEmits(['move-dragged-video', 'move-video-down', 'move-video-up', 'pause-player', 'remove-from-playlist', 'drag-video', 'drag-video-end'])
const emit = defineEmits([
'move-dragged-video',
'move-video-down',
'move-video-up',
'move-video-to-the-top',
'move-video-to-the-bottom',
'pause-player',
'remove-from-playlist',
'drag-video',
'drag-video-end'
])
const visible = ref(props.initialVisibleState)
const inUserPlaylist = props.playlistType === 'user'
@@ -217,6 +229,22 @@ function moveVideoDown(videoId, playlistItemId) {
emit('move-video-down', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheTop(videoId, playlistItemId) {
emit('move-video-to-the-top', videoId, playlistItemId)
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheBottom(videoId, playlistItemId) {
emit('move-video-to-the-bottom', videoId, playlistItemId)
}
function onDragVideo(event) {
// Only allow dragging via the drag bar
if (!event.target.classList.contains('draggable')) { return }
+94
View File
@@ -96,6 +96,8 @@
@move-dragged-video="moveDraggedVideoTemporarilyThrottled"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@remove-from-playlist="removeVideoFromPlaylist"
/>
<TransitionGroup
@@ -129,6 +131,8 @@
@move-dragged-video="moveDraggedVideoTemporarilyThrottled"
@move-video-up="moveVideoUp"
@move-video-down="moveVideoDown"
@move-video-to-the-top="moveVideoToTheTop"
@move-video-to-the-bottom="moveVideoToTheBottom"
@remove-from-playlist="removeVideoFromPlaylist"
/>
</TransitionGroup>
@@ -714,6 +718,10 @@ function moveVideoUp(videoId, playlistItemId) {
return video.videoId === videoId && video.playlistItemId === playlistItemId
})
if (index === -1) {
return
}
if (index === 0) {
showToast(t('User Playlists.SinglePlaylistView.Toast["This video cannot be moved up."]'))
return
@@ -749,6 +757,10 @@ function moveVideoDown(videoId, playlistItemId) {
return video.videoId === videoId && video.playlistItemId === playlistItemId
})
if (index === -1) {
return
}
if (index + 1 >= playlistItems_.length) {
showToast(t('User Playlists.SinglePlaylistView.Toast["This video cannot be moved down."]'))
return
@@ -773,6 +785,88 @@ function moveVideoDown(videoId, playlistItemId) {
}
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheTop(videoId, playlistItemId) {
const playlistItems_ = playlistItems.value.slice()
const index = playlistItems_.findIndex((video) => {
return video.videoId === videoId && video.playlistItemId === playlistItemId
})
if (index === -1) {
return
}
if (index === 0) {
showToast(t('User Playlists.SinglePlaylistView.Toast["This video cannot be moved up."]'))
return
}
const videoObject = playlistItems_[index]
playlistItems_.splice(index, 1)
playlistItems_.unshift(videoObject)
const playlist = {
playlistName: playlistTitle.value,
protected: selectedUserPlaylist.value.protected,
description: playlistDescription.value,
videos: deepCopy(playlistItems_),
_id: playlistId.value
}
try {
store.dispatch('updatePlaylist', playlist)
playlistItems.value = playlistItems_
} catch (e) {
showToast(t('User Playlists.SinglePlaylistView.Toast["There was an issue with updating this playlist."]'))
console.error(e)
}
}
/**
* @param {string} videoId
* @param {string} playlistItemId
*/
function moveVideoToTheBottom(videoId, playlistItemId) {
const playlistItems_ = playlistItems.value.slice()
const index = playlistItems_.findIndex((video) => {
return video.videoId === videoId && video.playlistItemId === playlistItemId
})
if (index === -1) {
return
}
if (index === playlistItems_.length - 1) {
showToast(t('User Playlists.SinglePlaylistView.Toast["This video cannot be moved down."]'))
return
}
const videoObject = playlistItems_[index]
playlistItems_.splice(index, 1)
playlistItems_.push(videoObject)
const playlist = {
playlistName: playlistTitle.value,
protected: selectedUserPlaylist.value.protected,
description: playlistDescription.value,
videos: deepCopy(playlistItems_),
_id: playlistId.value
}
try {
store.dispatch('updatePlaylist', playlist)
playlistItems.value = playlistItems_
} catch (e) {
showToast(t('User Playlists.SinglePlaylistView.Toast["There was an issue with updating this playlist."]'))
console.error(e)
}
}
/**
* @param {VideoData} video
*/
+2
View File
@@ -164,6 +164,8 @@ User Playlists:
Add to Favorites: Add to {playlistName}
Remove from Favorites: Remove from {playlistName}
Move Video to the Top: Move Video to the Top
Move Video to the Bottom: Move Video to the Bottom
Move Video Up: Move Video Up
Move Video Down: Move Video Down
Remove from Playlist: Remove from Playlist