Skip to content

Commit

Permalink
Add Albums view
Browse files Browse the repository at this point in the history
Signed-off-by: Louis Chemineau <louis@chmn.me>
  • Loading branch information
artonge committed Jul 27, 2022
1 parent ae94e07 commit 545f255
Show file tree
Hide file tree
Showing 17 changed files with 956 additions and 341 deletions.
124 changes: 124 additions & 0 deletions src/components/AlbumCover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!--
- @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>
-
- @author Louis Chemineau <louis@chmn.me>
-
- @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<router-link class="album-cover" :to="`/albums/${albumId}`">
<img class="album-cover__image" :src="coverUrl">
<div class="album-cover__details">
<div class="album-cover__details__first-line">
<h2 class="album-cover__details__name">
{{ album.name || "All" }}
</h2>
<!-- TODO: uncomment when state is more specified -->
<!-- <div class="album-cover__details__state">
{{ album.state }}
</div> -->
</div>
<div class="album-cover__details__second-line">
{{ prettyCreationDate }} ⸱ {{ n('photos', '%n item', '%n items', album.itemCount,) }}
</div>
</div>
</router-link>
</template>

<script>

import { mapGetters } from 'vuex'

import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'

export default {
name: 'AlbumCover',

props: {
albumId: {
type: String,
required: true,
},
},

computed: {
...mapGetters([
'files',
'albums',
]),

/**
* @return {Album}
*/
album() {
return this.albums[this.albumId]
},

/**
* @return {string}
*/
coverUrl() {
return generateUrl(`/core/preview?fileId=${this.album.cover}&x=${512}&y=${512}&forceIcon=0&a=1`)
},

/**
* @param {string}
*/
prettyCreationDate() {
return moment.unix(this.album.creationDate).format('MMMM YYYY')
},
},

}
</script>

<style lang="scss" scoped>
.album-cover {
display: flex;
flex-direction: column;

&__image {
width: 350px;
height: 350px;
object-fit: none;
border-radius: 12px;
}

&__details {
display: flex;
flex-direction: column;

&__first-line {
display: flex;
}

&__second-line {
display: flex;
color: var(--color-text-lighter);
}

&__name {
flex-grow: 1;
margin: 0;
font-weight: normal;
}
}

}
</style>
158 changes: 158 additions & 0 deletions src/components/AlbumCreationForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<!--
- @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>
-
- @author Louis Chemineau <louis@chmn.me>
-
- @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<form v-if="!showCollaboratorView" class="album-creation-form">
<div class="form-inputs">
<input type="text"
name="name"
required
autofocus="true"
:placeholder="t('photos', 'Name of the new album')">
<label>
<MapMarker /><input type="text" name="location" :placeholder="t('photos', 'Add location')">
</label>
</div>
<div class="form-buttons">
<Button :aria-label="t('photo', 'Go to the add collaborators view.')" type="secondary" @click="showCollaboratorView = true">
<template #icon>
<AccountMultiplePlus />
</template>
{{ t('photo', 'Add collaborators') }}
</Button>
<Button :aria-label="t('photo', 'Create the album.')" type="primary" @click="createAlbum">
<template #icon>
<Send />
</template>
{{ t('photo', 'Create album') }}
</Button>
</div>
</form>
<form v-else class="add-collaborators-form">
<div class="form-title">
{{ t('photos', 'Add collaborators') }}
</div>
<div class="form-subtitle">
{{ t('photos', 'Add users who can edit your album') }}
</div>
<div class="form-subtitle">
{{ t('photos', 'Share this album via link') }}
</div>
<div class="form-inputs">
<Magnify /><input type="text" name="search" :placeholder="t('photos', 'Search users, email or federated cloud ID')">
</div>
<div class="form-buttons">
<Button :aria-label="t('photo', 'Back to the new album form.')"
type="tertiary"
@click="showCollaboratorView = false">
{{ t('photo', 'Back') }}
</Button>
<Button :aria-label="t('photo', 'Create the album.')" type="primary" @click="createAlbum">
<template #icon>
<Send />
</template>
{{ t('photo', 'Create album') }}
</Button>
</div>
</form>
</template>
<script>
import MapMarker from 'vue-material-design-icons/MapMarker'
import AccountMultiplePlus from 'vue-material-design-icons/AccountMultiplePlus'
import Send from 'vue-material-design-icons/Send'
import Magnify from 'vue-material-design-icons/Magnify'

import { Button } from '@nextcloud/vue'

export default {
name: 'AlbumCreationForm',

components: {
Button,
MapMarker,
AccountMultiplePlus,
Send,
Magnify,
},

data() {
return {
showCollaboratorView: false,
}
},

methods: {
createAlbum() {
this.$emit('album-created')
},
},
}
</script>
<style lang="scss" scoped>
.album-creation-form, .add-collaborators-form {
display: flex;
flex-direction: column;
height: 500px;
padding: 16px;

.form-title {
font-weight: bold;
}

.form-subtitle {
color: var(--color-text-lighter);
}

.form-inputs {
flex-grow: 1;
justify-items: flex-end;

input {
width: 100%;
}

label {
display: flex;
margin-top: 16px;

::v-deep svg {
margin-right: 12px;
}
}
}

.form-buttons {
display: flex;
justify-content: flex-end;

button {
margin-right: 16px;
}
}

}

.add-collaborators-form {
.form-buttons {
justify-content: space-between;
}
}
</style>
2 changes: 1 addition & 1 deletion src/components/TiledLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default {
}

.tiled-container {
height: calc(100vh - var(--header-height) - 50px - 16px * 2);
height: 100%;
margin: 0 24px;

.tiled-row {
Expand Down
4 changes: 2 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { translate, translatePlural } from '@nextcloud/l10n'
import Vue from 'vue'

import Photos from './Photos'
import router from './router'
import store from './store'
import router from './router/index.js'
import store from './store/index.js'

// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
Expand Down
Loading

0 comments on commit 545f255

Please sign in to comment.