cluster: new albums layout
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/767/head
parent
eba28c3976
commit
3fec0a94bd
|
@ -8,7 +8,8 @@
|
||||||
:items="clusters"
|
:items="clusters"
|
||||||
:skipHover="true"
|
:skipHover="true"
|
||||||
:buffer="400"
|
:buffer="400"
|
||||||
:itemSize="itemSize"
|
:itemSize="height"
|
||||||
|
:itemSecondarySize="width"
|
||||||
:gridItems="gridItems"
|
:gridItems="gridItems"
|
||||||
@resize="resize"
|
@resize="resize"
|
||||||
>
|
>
|
||||||
|
@ -18,7 +19,7 @@
|
||||||
|
|
||||||
<template v-slot="{ item }">
|
<template v-slot="{ item }">
|
||||||
<div class="grid-item fill-block">
|
<div class="grid-item fill-block">
|
||||||
<Cluster :data="item" @click="click(item)" :link="link" />
|
<Cluster :data="item" :link="link" :class="clusterClasses" :counters="counters" @click="click(item)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</RecycleScroller>
|
</RecycleScroller>
|
||||||
|
@ -60,8 +61,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
itemSize: 200,
|
recyclerWidth: 300,
|
||||||
gridItems: 5,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -69,6 +69,40 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
/** Height of the cluster */
|
||||||
|
height() {
|
||||||
|
if (this.routeIsAlbums) {
|
||||||
|
// album view: add gap for text below album
|
||||||
|
return this.width + 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.width;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Width of the cluster */
|
||||||
|
width() {
|
||||||
|
// Restrict the number of columns between minCols and the size cap
|
||||||
|
return Math.floor(this.recyclerWidth / this.gridItems);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Number of items horizontally */
|
||||||
|
gridItems() {
|
||||||
|
return Math.max(Math.floor(this.recyclerWidth / this.maxSize), this.minCols);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Classes list on cluster object */
|
||||||
|
clusterClasses() {
|
||||||
|
return {
|
||||||
|
'cluster--album': this.routeIsAlbums,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Whether the clusters should show counters */
|
||||||
|
counters() {
|
||||||
|
return !this.routeIsAlbums;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** List of clusters to display */
|
||||||
clusters() {
|
clusters() {
|
||||||
const items = [...this.items];
|
const items = [...this.items];
|
||||||
|
|
||||||
|
@ -98,10 +132,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
resize() {
|
resize() {
|
||||||
// Restrict the number of columns between minCols and the size cap
|
this.recyclerWidth = (<any>this.$refs.recycler).$el.clientWidth;
|
||||||
const w = (<any>this.$refs.recycler).$el.clientWidth;
|
|
||||||
this.gridItems = Math.max(Math.floor(w / this.maxSize), this.minCols);
|
|
||||||
this.itemSize = Math.floor(w / this.gridItems);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<EmptyContent v-if="!items.length && !loading" />
|
<EmptyContent v-if="!items.length && !loading" />
|
||||||
|
|
||||||
<ClusterGrid :items="items" :minCols="minCols">
|
<ClusterGrid :items="items" :minCols="minCols" :maxSize="maxSize">
|
||||||
<template #before>
|
<template #before>
|
||||||
<DynamicTopMatter class="cv-dtm" ref="dtm" />
|
<DynamicTopMatter class="cv-dtm" ref="dtm" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -56,7 +56,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
minCols() {
|
minCols() {
|
||||||
return this.$route.name === 'albums' ? 2 : 3;
|
return this.routeIsAlbums ? 2 : 3;
|
||||||
|
},
|
||||||
|
|
||||||
|
maxSize() {
|
||||||
|
return this.routeIsAlbums ? 250 : 180;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<NcCounterBubble> {{ data.count }} </NcCounterBubble>
|
<NcCounterBubble> {{ data.count }} </NcCounterBubble>
|
||||||
</div>
|
</div>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
{{ title }}
|
<div class="title">{{ title }}</div>
|
||||||
<span class="subtitle" v-if="subtitle"> {{ subtitle }} </span>
|
<div class="subtitle" v-if="subtitle">{{ subtitle }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="previews fill-block" ref="previews">
|
<div class="previews fill-block" ref="previews">
|
||||||
|
@ -87,8 +87,23 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
subtitle() {
|
subtitle() {
|
||||||
if (this.album && this.album.user !== getCurrentUser()?.uid) {
|
if (this.album) {
|
||||||
return `(${this.album.user_display || this.album.user})`;
|
let text: string;
|
||||||
|
if (this.album.count === 0) {
|
||||||
|
text = this.t('memories', 'No items');
|
||||||
|
} else {
|
||||||
|
text = this.n('memories', '{n} item', '{n} items', this.album.count, { n: this.album.count });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.album.user !== getCurrentUser()?.uid) {
|
||||||
|
text +=
|
||||||
|
' / ' +
|
||||||
|
this.t('memories', 'Shared by {user}', {
|
||||||
|
user: this.album.user_display || this.album.user,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
|
@ -165,14 +180,6 @@ img {
|
||||||
}
|
}
|
||||||
|
|
||||||
.cluster {
|
.cluster {
|
||||||
// to use this option, the height must be set to a bit more
|
|
||||||
// than the width for the text; the image will then be forced
|
|
||||||
// to be square and the label will be outside.
|
|
||||||
&--circle {
|
|
||||||
height: unset; // from .fill-block
|
|
||||||
aspect-ratio: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of color of the bubble
|
// Get rid of color of the bubble
|
||||||
.count-bubble :deep .counter-bubble__counter {
|
.count-bubble :deep .counter-bubble__counter {
|
||||||
color: unset !important;
|
color: unset !important;
|
||||||
|
@ -187,9 +194,6 @@ $namemargin: 7px;
|
||||||
width: calc(100% - 2 * #{$namemargin});
|
width: calc(100% - 2 * #{$namemargin});
|
||||||
margin: $namemargin;
|
margin: $namemargin;
|
||||||
|
|
||||||
// 2px padding prevents the bottom of the text from being cut off
|
|
||||||
padding-bottom: 2px;
|
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
@ -198,31 +202,55 @@ $namemargin: 7px;
|
||||||
line-height: 1.1em;
|
line-height: 1.1em;
|
||||||
|
|
||||||
// multiline ellipsis
|
// multiline ellipsis
|
||||||
display: -webkit-box;
|
> .title {
|
||||||
-webkit-line-clamp: 5;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 5;
|
||||||
overflow: hidden;
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
// 2px padding prevents the bottom of the text from being cut off
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// name is below the image
|
||||||
.cluster--circle & {
|
.cluster--circle & {
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
margin: 0 $namemargin;
|
margin: 0 $namemargin;
|
||||||
min-height: 26px; // alignment
|
min-height: 26px; // alignment
|
||||||
}
|
|
||||||
|
|
||||||
> .subtitle {
|
|
||||||
font-size: 0.7em;
|
|
||||||
margin-top: 2px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster.error > &,
|
|
||||||
.cluster--circle & {
|
|
||||||
color: unset;
|
color: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cluster--circle &,
|
||||||
|
.cluster--album &,
|
||||||
|
.cluster.error & {
|
||||||
|
color: unset;
|
||||||
|
|
||||||
|
> .title {
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cluster--album & {
|
||||||
|
text-align: start;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 12px;
|
||||||
|
min-height: 50px;
|
||||||
|
|
||||||
|
> .subtitle {
|
||||||
|
color: var(--color-text-lighter);
|
||||||
|
font-size: 0.87em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .subtitle {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.count-bubble {
|
.count-bubble {
|
||||||
|
@ -239,6 +267,10 @@ $namemargin: 7px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.cluster--album & {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
> .img-outer {
|
> .img-outer {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--color-background-dark);
|
background-color: var(--color-background-dark);
|
||||||
|
@ -250,14 +282,17 @@ $namemargin: 7px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.cluster--rounded & {
|
.cluster--rounded &,
|
||||||
|
.cluster--album & {
|
||||||
border-radius: 12px; // rounded corners
|
border-radius: 12px; // rounded corners
|
||||||
}
|
}
|
||||||
|
.cluster--album &,
|
||||||
.cluster--circle & {
|
.cluster--circle & {
|
||||||
// circle image
|
|
||||||
border-radius: 50%;
|
|
||||||
height: unset;
|
height: unset;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1; // force square
|
||||||
|
}
|
||||||
|
.cluster--circle & {
|
||||||
|
border-radius: 50%; // circle image
|
||||||
}
|
}
|
||||||
|
|
||||||
&.plus {
|
&.plus {
|
||||||
|
|
Loading…
Reference in New Issue