diff --git a/lib/Db/TimelineQueryAlbums.php b/lib/Db/TimelineQueryAlbums.php
index b4b55164..bda3e185 100644
--- a/lib/Db/TimelineQueryAlbums.php
+++ b/lib/Db/TimelineQueryAlbums.php
@@ -37,15 +37,15 @@ trait TimelineQueryAlbums
);
// WHERE these are items with this album
- $query->innerJoin('pa', 'photos_albums_files', 'paf', $query->expr()->andX(
+ $query->leftJoin('pa', 'photos_albums_files', 'paf', $query->expr()->andX(
$query->expr()->eq('paf.album_id', 'pa.album_id'),
));
// WHERE these items are memories indexed photos
- $query->innerJoin('paf', 'memories', 'm', $query->expr()->eq('m.fileid', 'paf.file_id'));
+ $query->leftJoin('paf', 'memories', 'm', $query->expr()->eq('m.fileid', 'paf.file_id'));
// WHERE these photos are in the filecache
- $query->innerJoin('m', 'filecache', 'f', $query->expr()->eq('m.fileid', 'f.fileid'));
+ $query->leftJoin('m', 'filecache', 'f', $query->expr()->eq('m.fileid', 'f.fileid'));
// GROUP and ORDER by
$query->groupBy('pa.album_id');
diff --git a/src/components/modal/AlbumForm.vue b/src/components/modal/AlbumForm.vue
new file mode 100644
index 00000000..ecc2e1c5
--- /dev/null
+++ b/src/components/modal/AlbumForm.vue
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/modal/AlbumPicker.vue b/src/components/modal/AlbumPicker.vue
index 0aee3127..0cafcd98 100644
--- a/src/components/modal/AlbumPicker.vue
+++ b/src/components/modal/AlbumPicker.vue
@@ -56,17 +56,18 @@
-
+ @done="albumCreatedHandler" />
+
+
\ No newline at end of file
diff --git a/src/services/DavRequests.ts b/src/services/DavRequests.ts
index c01c20de..f121758c 100644
--- a/src/services/DavRequests.ts
+++ b/src/services/DavRequests.ts
@@ -654,4 +654,66 @@ export async function* removeFromAlbum(id: number, fileIds: number[]) {
});
yield* runInParallel(calls, 10);
-}
\ No newline at end of file
+}
+
+/**
+ * Create an album.
+ */
+export async function createAlbum(albumName: string) {
+ try {
+ await client.createDirectory(`/photos/${getCurrentUser()?.uid}/albums/${albumName}`)
+ } catch (error) {
+ console.error(error);
+ showError(t('photos', 'Failed to create {albumName}.', { albumName }))
+ }
+}
+
+/**
+ * Update an album's properties.
+ *
+ * @param {object} album Album to update
+ * @param {object} data destructuring object
+ * @param {string} data.albumName - The name of the album.
+ * @param {object} data.properties - The properties to update.
+ */
+export async function updateAlbum(album: any, { albumName, properties }: any) {
+ const stringifiedProperties = Object
+ .entries(properties)
+ .map(([name, value]) => {
+ switch (typeof value) {
+ case 'string':
+ return `${value}`
+ case 'object':
+ return `${JSON.stringify(value)}`
+ default:
+ return ''
+ }
+ })
+ .join()
+
+ try {
+ await client.customRequest(
+ album.filename,
+ {
+ method: 'PROPPATCH',
+ data: `
+
+
+
+ ${stringifiedProperties}
+
+
+ `,
+ }
+ );
+
+ return album;
+ } catch (error) {
+ console.error(error);
+ showError(t('photos', 'Failed to update properties of {albumName} with {properties}.', { albumName, properties: JSON.stringify(properties) }))
+ return album
+ }
+};