From 92413bd360397048402735a4509edd72aa2a7717 Mon Sep 17 00:00:00 2001 From: Isaac Abadi Date: Mon, 26 Jul 2021 20:10:22 -0700 Subject: [PATCH] Added ability to add file to playlist using the context menu --- backend/app.js | 47 +++++++++++-------- backend/db.js | 23 +++++---- .../custom-playlists.component.ts | 7 +++ .../recent-videos.component.html | 2 +- .../recent-videos/recent-videos.component.ts | 38 +++++++++++++++ .../unified-file-card.component.html | 4 ++ .../unified-file-card.component.ts | 9 ++++ .../modify-playlist.component.ts | 1 + src/app/main/main.component.ts | 4 +- src/app/posts.services.ts | 21 +++++++-- 10 files changed, 119 insertions(+), 37 deletions(-) diff --git a/backend/app.js b/backend/app.js index 4b89a0ed..3ef0f3f6 100644 --- a/backend/app.js +++ b/backend/app.js @@ -754,20 +754,6 @@ function generateEnvVarConfigItem(key) { return {key: key, value: process['env'][key]}; } -function getThumbnailMp3(name) -{ - var obj = utils.getJSONMp3(name, audioFolderPath); - var thumbnailLink = obj.thumbnail; - return thumbnailLink; -} - -function getThumbnailMp4(name) -{ - var obj = utils.getJSONMp4(name, videoFolderPath); - var thumbnailLink = obj.thumbnail; - return thumbnailLink; -} - function getFileSizeMp3(name) { var jsonPath = audioFolderPath+name+".mp3.info.json"; @@ -1061,7 +1047,7 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) { // create playlist const playlist_name = file_objs.map(file_obj => file_obj.title).join(', '); const duration = file_objs.reduce((a, b) => a + utils.durationStringToNumber(b.duration), 0); - container = await db_api.createPlaylist(playlist_name, file_objs.map(file_obj => file_obj.uid), type, file_objs[0]['thumbnailURL'], options.user); + container = await db_api.createPlaylist(playlist_name, file_objs.map(file_obj => file_obj.uid), type, options.user); } else if (file_objs.length === 1) { container = file_objs[0]; } else { @@ -2181,9 +2167,8 @@ app.post('/api/createPlaylist', optionalJwt, async (req, res) => { let playlistName = req.body.playlistName; let uids = req.body.uids; let type = req.body.type; - let thumbnailURL = req.body.thumbnailURL; - const new_playlist = await db_api.createPlaylist(playlistName, uids, type, thumbnailURL, req.isAuthenticated() ? req.user.uid : null); + const new_playlist = await db_api.createPlaylist(playlistName, uids, type, req.isAuthenticated() ? req.user.uid : null); res.send({ new_playlist: new_playlist, @@ -2216,8 +2201,18 @@ app.post('/api/getPlaylist', optionalJwt, async (req, res) => { }); }); +app.post('/api/getPlaylists', optionalJwt, async (req, res) => { + const uuid = req.isAuthenticated() ? req.user.uid : null; + + const playlists = await db_api.getRecords('playlists', {user_uid: uuid}); + + res.send({ + playlists: playlists + }); +}); + app.post('/api/updatePlaylistFiles', optionalJwt, async (req, res) => { - let playlistID = req.body.playlistID; + let playlistID = req.body.playlist_id; let uids = req.body.uids; let success = false; @@ -2238,6 +2233,20 @@ app.post('/api/updatePlaylistFiles', optionalJwt, async (req, res) => { }) }); +app.post('/api/addFileToPlaylist', optionalJwt, async (req, res) => { + let playlist_id = req.body.playlist_id; + let file_uid = req.body.file_uid; + + const playlist = await db_api.getRecord('playlists', {id: playlist_id}); + + playlist.uids.push(file_uid); + + let success = await db_api.updatePlaylist(playlist); + res.send({ + success: success + }); +}); + app.post('/api/updatePlaylist', optionalJwt, async (req, res) => { let playlist = req.body.playlist; let success = await db_api.updatePlaylist(playlist, req.user && req.user.uid); @@ -2247,7 +2256,7 @@ app.post('/api/updatePlaylist', optionalJwt, async (req, res) => { }); app.post('/api/deletePlaylist', optionalJwt, async (req, res) => { - let playlistID = req.body.playlistID; + let playlistID = req.body.playlist_id; let success = null; try { diff --git a/backend/db.js b/backend/db.js index 8e510b07..47c4f008 100644 --- a/backend/db.js +++ b/backend/db.js @@ -411,23 +411,26 @@ exports.addMetadataPropertyToDB = async (property_key) => { } } -exports.createPlaylist = async (playlist_name, uids, type, thumbnail_url, user_uid = null) => { +exports.createPlaylist = async (playlist_name, uids, type, user_uid = null) => { + const first_video = await exports.getVideo(uids[0]); + const thumbnailToUse = first_video['thumbnailURL']; + let new_playlist = { name: playlist_name, uids: uids, id: uuid(), - thumbnailURL: thumbnail_url, + thumbnailURL: thumbnailToUse, type: type, registered: Date.now(), randomize_order: false }; - const duration = await exports.calculatePlaylistDuration(new_playlist, user_uid); - new_playlist.duration = duration; - new_playlist.user_uid = user_uid ? user_uid : undefined; await exports.insertRecordIntoTable('playlists', new_playlist); + + const duration = await exports.calculatePlaylistDuration(new_playlist); + await exports.updateRecord('playlists', {id: new_playlist.id}, {duration: duration}); return new_playlist; } @@ -463,10 +466,10 @@ exports.getPlaylist = async (playlist_id, user_uid = null, require_sharing = fal return playlist; } -exports.updatePlaylist = async (playlist, user_uid = null) => { +exports.updatePlaylist = async (playlist) => { let playlistID = playlist.id; - const duration = await exports.calculatePlaylistDuration(playlist, user_uid); + const duration = await exports.calculatePlaylistDuration(playlist); playlist.duration = duration; return await exports.updateRecord('playlists', {id: playlistID}, playlist); @@ -486,12 +489,12 @@ exports.setPlaylistProperty = async (playlist_id, assignment_obj, user_uid = nul return success; } -exports.calculatePlaylistDuration = async (playlist, uuid, playlist_file_objs = null) => { +exports.calculatePlaylistDuration = async (playlist, playlist_file_objs = null) => { if (!playlist_file_objs) { playlist_file_objs = []; for (let i = 0; i < playlist['uids'].length; i++) { const uid = playlist['uids'][i]; - const file_obj = await exports.getVideo(uid, uuid); + const file_obj = await exports.getVideo(uid); if (file_obj) playlist_file_objs.push(file_obj); } } @@ -588,7 +591,7 @@ exports.getVideoUIDByID = async (file_id, uuid = null) => { return file_obj ? file_obj['uid'] : null; } -exports.getVideo = async (file_uid, uuid = null, sub_id = null) => { +exports.getVideo = async (file_uid) => { return await exports.getRecord('files', {uid: file_uid}); } diff --git a/src/app/components/custom-playlists/custom-playlists.component.ts b/src/app/components/custom-playlists/custom-playlists.component.ts index 6071d3d6..98819e1f 100644 --- a/src/app/components/custom-playlists/custom-playlists.component.ts +++ b/src/app/components/custom-playlists/custom-playlists.component.ts @@ -24,10 +24,17 @@ export class CustomPlaylistsComponent implements OnInit { this.getAllPlaylists(); } }); + + this.postsService.playlists_changed.subscribe(changed => { + if (changed) { + this.getAllPlaylists(); + } + }); } getAllPlaylists() { this.playlists_received = false; + // must call getAllFiles as we need to get category playlists as well this.postsService.getAllFiles().subscribe(res => { this.playlists = res['playlists']; this.playlists_received = true; diff --git a/src/app/components/recent-videos/recent-videos.component.html b/src/app/components/recent-videos/recent-videos.component.html index ec4616ce..9b00952e 100644 --- a/src/app/components/recent-videos/recent-videos.component.html +++ b/src/app/components/recent-videos/recent-videos.component.html @@ -32,7 +32,7 @@

My videos

- +
No videos found. diff --git a/src/app/components/recent-videos/recent-videos.component.ts b/src/app/components/recent-videos/recent-videos.component.ts index 144f3bd6..d795e297 100644 --- a/src/app/components/recent-videos/recent-videos.component.ts +++ b/src/app/components/recent-videos/recent-videos.component.ts @@ -50,6 +50,8 @@ export class RecentVideosComponent implements OnInit { } }; filterProperty = this.filterProperties['upload_date']; + + playlists = null; pageSize = 10; paged_data = null; @@ -68,14 +70,27 @@ export class RecentVideosComponent implements OnInit { ngOnInit(): void { if (this.postsService.initialized) { this.getAllFiles(); + this.getAllPlaylists(); } this.postsService.service_initialized.subscribe(init => { if (init) { this.getAllFiles(); + this.getAllPlaylists(); } }); + this.postsService.files_changed.subscribe(changed => { + if (changed) { + this.getAllFiles(); + } + }); + + this.postsService.playlists_changed.subscribe(changed => { + if (changed) { + this.getAllPlaylists(); + } + }); // set filter property to cached const cached_filter_property = localStorage.getItem('filter_property'); @@ -84,6 +99,12 @@ export class RecentVideosComponent implements OnInit { } } + getAllPlaylists() { + this.postsService.getPlaylists().subscribe(res => { + this.playlists = res['playlists']; + }); + } + // search onSearchInputChanged(newvalue) { @@ -288,6 +309,23 @@ export class RecentVideosComponent implements OnInit { this.filterByProperty(this.filterProperty['property']); } + addFileToPlaylist(info_obj) { + const file = info_obj['file']; + const playlist_id = info_obj['playlist_id']; + const playlist = this.playlists.find(potential_playlist => potential_playlist['id'] === playlist_id); + this.postsService.addFileToPlaylist(playlist_id, file['uid']).subscribe(res => { + if (res['success']) { + this.postsService.openSnackBar(`Successfully added ${file.title} to ${playlist.title}!`); + this.postsService.playlists_changed.next(true); + } else { + this.postsService.openSnackBar(`Failed to add ${file.title} to ${playlist.title}! Unknown error.`); + } + }, err => { + console.error(err); + this.postsService.openSnackBar(`Failed to add ${file.title} to ${playlist.title}! See browser console for error.`); + }); + } + // sorting and filtering sortFiles(a, b) { diff --git a/src/app/components/unified-file-card/unified-file-card.component.html b/src/app/components/unified-file-card/unified-file-card.component.html index 066d78e3..287d7d4e 100644 --- a/src/app/components/unified-file-card/unified-file-card.component.html +++ b/src/app/components/unified-file-card/unified-file-card.component.html @@ -23,6 +23,10 @@ + + + +