diff --git a/backend/app.js b/backend/app.js
index 50c6bb9..a508702 100644
--- a/backend/app.js
+++ b/backend/app.js
@@ -933,20 +933,13 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
else if (file_type_filter === 'video_only') filter_obj['isAudio'] = false;
files = await db_api.getRecords('files', filter_obj, false, sort, range, text_search);
- let file_count = await db_api.getRecords('files', filter_obj, true);
- playlists = await db_api.getRecords('playlists', {user_uid: uuid});
-
- const categories = await categories_api.getCategoriesAsPlaylists(files);
- if (categories) {
- playlists = playlists.concat(categories);
- }
+ const file_count = await db_api.getRecords('files', filter_obj, true);
files = JSON.parse(JSON.stringify(files));
res.send({
files: files,
file_count: file_count,
- playlists: playlists
});
});
@@ -1383,7 +1376,7 @@ app.post('/api/getPlaylists', optionalJwt, async (req, res) => {
let playlists = await db_api.getRecords('playlists', {user_uid: uuid});
if (include_categories) {
- const categories = await categories_api.getCategoriesAsPlaylists(files);
+ const categories = await categories_api.getCategoriesAsPlaylists();
if (categories) {
playlists = playlists.concat(categories);
}
diff --git a/backend/categories.js b/backend/categories.js
index 9b599cc..2faebfb 100644
--- a/backend/categories.js
+++ b/backend/categories.js
@@ -55,12 +55,12 @@ async function getCategories() {
return categories ? categories : null;
}
-async function getCategoriesAsPlaylists(files = null) {
+async function getCategoriesAsPlaylists() {
const categories_as_playlists = [];
const available_categories = await getCategories();
- if (available_categories && files) {
+ if (available_categories) {
for (let category of available_categories) {
- const files_that_match = utils.addUIDsToCategory(category, files);
+ const files_that_match = await db_api.getRecords('files', {'category.uid': category['uid']});
if (files_that_match && files_that_match.length > 0) {
category['thumbnailURL'] = files_that_match[0].thumbnailURL;
category['thumbnailPath'] = files_that_match[0].thumbnailPath;
diff --git a/backend/config.js b/backend/config.js
index 95e364c..4e208fb 100644
--- a/backend/config.js
+++ b/backend/config.js
@@ -127,7 +127,7 @@ function setConfigItem(key, value) {
success = setConfigFile(config_json);
return success;
-};
+}
function setConfigItems(items) {
let success = false;
diff --git a/backend/db.js b/backend/db.js
index d8a7b9f..73f56f1 100644
--- a/backend/db.js
+++ b/backend/db.js
@@ -387,9 +387,9 @@ exports.getPlaylist = async (playlist_id, user_uid = null, require_sharing = fal
if (!playlist) {
playlist = await exports.getRecord('categories', {uid: playlist_id});
if (playlist) {
- // category found
- const files = await exports.getFiles(user_uid);
- utils.addUIDsToCategory(playlist, files);
+ const uids = (await exports.getRecords('files', {'category.uid': playlist_id})).map(file => file.uid);
+ playlist['uids'] = uids;
+ playlist['auto'] = true;
}
}
@@ -1090,7 +1090,7 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => {
const filter_prop = filter_props[i];
const filter_prop_value = filter_obj[filter_prop];
if (filter_prop_value === undefined || filter_prop_value === null) {
- filtered &= record[filter_prop] === undefined || record[filter_prop] === null
+ filtered &= record[filter_prop] === undefined || record[filter_prop] === null;
} else {
if (typeof filter_prop_value === 'object') {
if ('$regex' in filter_prop_value) {
@@ -1099,7 +1099,11 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => {
filtered &= filter_prop in record && record[filter_prop] !== filter_prop_value['$ne'];
}
} else {
- filtered &= record[filter_prop] === filter_prop_value;
+ // handle case of nested property check
+ if (filter_prop.includes('.'))
+ filtered &= utils.searchObjectByString(record, filter_prop) === filter_prop_value;
+ else
+ filtered &= record[filter_prop] === filter_prop_value;
}
}
}
diff --git a/backend/test/tests.js b/backend/test/tests.js
index 2accc0f..448db7b 100644
--- a/backend/test/tests.js
+++ b/backend/test/tests.js
@@ -272,6 +272,11 @@ describe('Database', async function() {
const result = db_api.applyFilterLocalDB([{test: 'test'}, {test: 'test1'}], {test: filter}, 'find');
assert(result && result['test'] === 'test1');
});
+
+ it('Nested', async function() {
+ const result = db_api.applyFilterLocalDB([{test1: {test2: 'test3'}}, {test4: 'test5'}], {'test1.test2': 'test3'}, 'find');
+ assert(result && result['test1']['test2'] === 'test3');
+ });
})
});
diff --git a/backend/utils.js b/backend/utils.js
index 56f12bb..805d591 100644
--- a/backend/utils.js
+++ b/backend/utils.js
@@ -456,6 +456,21 @@ function injectArgs(original_args, new_args) {
return updated_args;
}
+const searchObjectByString = function(o, s) {
+ s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
+ s = s.replace(/^\./, ''); // strip a leading dot
+ var a = s.split('.');
+ for (var i = 0, n = a.length; i < n; ++i) {
+ var k = a[i];
+ if (k in o) {
+ o = o[k];
+ } else {
+ return;
+ }
+ }
+ return o;
+}
+
// objects
function File(id, title, thumbnailURL, isAudio, duration, url, uploader, size, path, upload_date, description, view_count, height, abr) {
@@ -489,7 +504,6 @@ module.exports = {
createContainerZipFile: createContainerZipFile,
durationStringToNumber: durationStringToNumber,
getMatchingCategoryFiles: getMatchingCategoryFiles,
- addUIDsToCategory: addUIDsToCategory,
getCurrentDownloader: getCurrentDownloader,
recFindByExt: recFindByExt,
removeFileExtension: removeFileExtension,
@@ -501,5 +515,6 @@ module.exports = {
fetchFile: fetchFile,
restartServer: restartServer,
injectArgs: injectArgs,
+ searchObjectByString: searchObjectByString,
File: File
}
diff --git a/src/app/components/custom-playlists/custom-playlists.component.ts b/src/app/components/custom-playlists/custom-playlists.component.ts
index 9654013..e659724 100644
--- a/src/app/components/custom-playlists/custom-playlists.component.ts
+++ b/src/app/components/custom-playlists/custom-playlists.component.ts
@@ -35,7 +35,7 @@ export class CustomPlaylistsComponent implements OnInit {
getAllPlaylists() {
this.playlists_received = false;
// must call getAllFiles as we need to get category playlists as well
- this.postsService.getPlaylists().subscribe(res => {
+ this.postsService.getPlaylists(true).subscribe(res => {
this.playlists = res['playlists'];
this.playlists_received = true;
});
diff --git a/src/app/dialogs/video-info-dialog/video-info-dialog.component.html b/src/app/dialogs/video-info-dialog/video-info-dialog.component.html
index c9c0cc9..8f99be9 100644
--- a/src/app/dialogs/video-info-dialog/video-info-dialog.component.html
+++ b/src/app/dialogs/video-info-dialog/video-info-dialog.component.html
@@ -28,12 +28,12 @@
-
-
+
+
N/A
-
+
{{available_category.value.name}}
diff --git a/src/app/dialogs/video-info-dialog/video-info-dialog.component.ts b/src/app/dialogs/video-info-dialog/video-info-dialog.component.ts
index 8524bca..4d9a7b6 100644
--- a/src/app/dialogs/video-info-dialog/video-info-dialog.component.ts
+++ b/src/app/dialogs/video-info-dialog/video-info-dialog.component.ts
@@ -18,6 +18,7 @@ export class VideoInfoDialogComponent implements OnInit {
upload_date: Date;
category: Category;
editing = false;
+ initialized = false;
constructor(@Inject(MAT_DIALOG_DATA) public data: any, public postsService: PostsService, private datePipe: DatePipe) { }
@@ -37,15 +38,16 @@ export class VideoInfoDialogComponent implements OnInit {
this.upload_date = new Date(this.new_file.upload_date);
this.upload_date.setMinutes( this.upload_date.getMinutes() + this.upload_date.getTimezoneOffset() );
- this.category = this.file.category ? this.category : {};
+ this.category = this.file.category ? this.file.category : {};
// we need to align whether missing category is null or undefined. this line helps with that.
if (!this.file.category) { this.new_file.category = null; this.file.category = null; }
+ this.initialized = true;
}
saveChanges(): void {
const change_obj = {};
- const keys = Object.keys(this.file);
+ const keys = Object.keys(this.new_file);
keys.forEach(key => {
if (this.file[key] !== this.new_file[key]) change_obj[key] = this.new_file[key];
});
@@ -67,7 +69,8 @@ export class VideoInfoDialogComponent implements OnInit {
}
categoryChanged(event): void {
- this.new_file.category = Object.keys(event).length ? {uid: event.uid, name: event.name} : null;
+ const new_category = event.value;
+ this.new_file.category = Object.keys(new_category).length ? {uid: new_category.uid, name: new_category.name} : null;
}
categoryComparisonFunction(option: Category, value: Category): boolean {
diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts
index c384f33..186418a 100644
--- a/src/app/posts.services.ts
+++ b/src/app/posts.services.ts
@@ -457,15 +457,15 @@ export class PostsService implements CanActivate {
return this.http.post(this.path + 'getPlaylist', body, this.httpOptions);
}
+ getPlaylists(include_categories = false) {
+ return this.http.post(this.path + 'getPlaylists', {include_categories: include_categories}, this.httpOptions);
+ }
+
incrementViewCount(file_uid, sub_id, uuid) {
const body: IncrementViewCountRequest = {file_uid: file_uid, sub_id: sub_id, uuid: uuid};
return this.http.post(this.path + 'incrementViewCount', body, this.httpOptions);
}
- getPlaylists() {
- return this.http.post(this.path + 'getPlaylists', {}, this.httpOptions);
- }
-
updatePlaylist(playlist: Playlist) {
const body: UpdatePlaylistRequest = {playlist: playlist};
return this.http.post(this.path + 'updatePlaylist', body, this.httpOptions);