Sfoglia il codice sorgente

Clicking on album title takes you to the album now

Pitu 6 anni fa
parent
commit
f11cb56db8

+ 55 - 0
src/api/routes/albums/albumFullGET.js

@@ -0,0 +1,55 @@
+const Route = require('../../structures/Route');
+const Util = require('../../utils/Util');
+
+class albumGET extends Route {
+	constructor() {
+		super('/album/:id/full', 'get');
+	}
+
+	async run(req, res, db) {
+		const { id } = req.params;
+		if (!id) return res.status(400).json({ message: 'Invalid id supplied' });
+
+		const album = await db.table('albums').where({ id, userId: user.id }).first();
+		if (!album) return res.status(404).json({ message: 'Album not found' });
+
+		/*
+			Grab the files in a very unoptimized way. (This should be a join between both tables)
+		*/
+		const fileList = await db.table('albumsFiles').where('albumId', id).select('fileId');
+		const fileIds = fileList.map(el => el.fileId);
+		const files = await db.table('files')
+			.whereIn('id', fileIds)
+			.orderBy('id', 'desc');
+
+		for (const file of files) {
+			file.albums = [];
+			const albumFiles = await db.table('albumsFiles')
+				.where('fileId', file.id);
+			if (!albumFiles.length) continue;
+
+			for (const albumFile of albumFiles) {
+				const album = await db.table('albums')
+					.where('id', albumFile.albumId)
+					.select('id', 'name')
+					.first();
+				if (!album) continue;
+				file.albums.push(album);
+			}
+		}
+		/*
+			For each file, create the public link to be able to display the file
+		*/
+		for (let file of files) {
+			file = Util.constructFilePublicLink(file);
+		}
+
+		return res.json({
+			message: 'Successfully retrieved album',
+			name: album.name,
+			files
+		});
+	}
+}
+
+module.exports = albumGET;

+ 126 - 0
src/site/pages/dashboard/albums/_id.vue

@@ -0,0 +1,126 @@
+<style lang="scss" scoped>
+	@import '~/assets/styles/_colors.scss';
+	section { background-color: $backgroundLight1 !important; }
+	section.hero div.hero-body {
+		align-items: baseline;
+	}
+
+	.albumsModal .columns .column { padding: .25rem; }
+</style>
+
+<template>
+	<section class="hero is-fullheight">
+		<div class="hero-body">
+			<div class="container">
+				<div class="columns">
+					<div class="column is-narrow">
+						<Sidebar />
+					</div>
+					<div class="column">
+						<h2 class="subtitle">Files</h2>
+						<hr>
+						<!-- TODO: Add a list view so the user can see the files that don't have thumbnails, like text documents -->
+						<Grid v-if="files.length"
+							:files="files" />
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<b-modal :active.sync="isAlbumsModalActive"
+			:width="640"
+			scroll="keep">
+			<div class="card albumsModal">
+				<div class="card-content">
+					<div class="content">
+						<h3 class="subtitle">Select the albums this file should be a part of</h3>
+						<hr>
+						<div class="columns is-multiline">
+							<div v-for="(album, index) in albums"
+								:key="index"
+								class="column is-3">
+								<div class="field">
+									<b-checkbox :value="isAlbumSelected(album.id)"
+										@input="albumCheckboxClicked($event, album.id)">{{ album.name }}</b-checkbox>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</b-modal>
+	</section>
+</template>
+
+<script>
+import Sidebar from '~/components/sidebar/Sidebar.vue';
+import Grid from '~/components/grid/Grid.vue';
+
+export default {
+	components: {
+		Sidebar,
+		Grid
+	},
+	data() {
+		return {
+			name: null,
+			files: [],
+			albums: [],
+			isAlbumsModalActive: false,
+			showingModalForFile: null
+		};
+	},
+	computed: {
+		config() {
+			return this.$store.state.config;
+		}
+	},
+	metaInfo() {
+		return { title: 'Album' };
+	},
+	mounted() {
+		this.getFiles();
+		this.getAlbums();
+	},
+	methods: {
+		isAlbumSelected(id) {
+			if (!this.showingModalForFile) return;
+			const found = this.showingModalForFile.albums.find(el => el.id === id);
+			return found ? found.id ? true : false : false;
+		},
+		openAlbumModal(file) {
+			this.showingModalForFile = file;
+			this.isAlbumsModalActive = true;
+		},
+		async albumCheckboxClicked(value, id) {
+			try {
+				const response = await this.axios.post(`${this.config.baseURL}/file/album/${value ? 'add' : 'del'}`, {
+					albumId: id,
+					fileId: this.showingModalForFile.id
+				});
+				this.$toast.open(response.data.message);
+				this.getFiles();
+			} catch (error) {
+				this.$onPromiseError(error);
+			}
+		},
+		async getFiles() {
+			// TODO: Make this think SSR with AsyncData
+			try {
+				const response = await this.axios.get(`${this.config.baseURL}/album/${this.$route.params.id}/full`);
+				this.files = response.data.files;
+			} catch (error) {
+				console.error(error);
+			}
+		},
+		async getAlbums() {
+			try {
+				const response = await this.axios.get(`${this.config.baseURL}/albums/dropdown`);
+				this.albums = response.data.albums;
+			} catch (error) {
+				this.$onPromiseError(error);
+			}
+		}
+	}
+};
+</script>

+ 0 - 13
src/site/pages/dashboard/albums.vue

@@ -233,19 +233,6 @@
 												<button class="button is-danger"
 													@click="promptDeleteAlbumLink(props.row.identifier)">Delete link</button>
 											</b-table-column>
-
-											<!--
-												Until it's decided if we want to delete links or just hide them from the list
-												this setting will be hidden. Discussion about it is encouraged on Discord.
-											-->
-											<!--
-											<b-table-column field="actions"
-												label="Actions"
-												centered>
-												<button class="button is-danger"
-													@click="deleteLink(props.row.identifier)">Delete link</button>
-											</b-table-column>
-											-->
 										</template>
 										<template slot="empty">
 											<div class="has-text-centered">

+ 1 - 4
src/site/pages/dashboard/index.vue

@@ -7,10 +7,6 @@
 
 	.albumsModal .columns .column { padding: .25rem; }
 </style>
-<style lang="scss">
-	@import '~/assets/styles/_colors.scss';
-</style>
-
 
 <template>
 	<section class="hero is-fullheight">
@@ -23,6 +19,7 @@
 					<div class="column">
 						<h2 class="subtitle">Your uploaded files</h2>
 						<hr>
+						<!-- TODO: Add a list view so the user can see the files that don't have thumbnails, like text documents -->
 						<Grid v-if="files.length"
 							:files="files" />
 					</div>