diff options
Diffstat (limited to 'viewer/src')
-rw-r--r-- | viewer/src/@types/v-lazy-image.d.ts | 20 | ||||
-rw-r--r-- | viewer/src/assets/scss/global.scss | 36 | ||||
-rw-r--r-- | viewer/src/assets/scss/theme.scss | 4 | ||||
-rw-r--r-- | viewer/src/main.ts | 1 | ||||
-rw-r--r-- | viewer/src/plugins/lazyimage.ts | 23 | ||||
-rw-r--r-- | viewer/src/views/GalleryDirectory.vue | 15 | ||||
-rw-r--r-- | viewer/src/views/GallerySearch.vue | 5 | ||||
-rw-r--r-- | viewer/src/views/GalleryThumbnail.vue | 34 | ||||
-rw-r--r-- | viewer/src/views/MainLayout.vue | 3 |
9 files changed, 130 insertions, 11 deletions
diff --git a/viewer/src/@types/v-lazy-image.d.ts b/viewer/src/@types/v-lazy-image.d.ts new file mode 100644 index 0000000..e307751 --- /dev/null +++ b/viewer/src/@types/v-lazy-image.d.ts | |||
@@ -0,0 +1,20 @@ | |||
1 | /* ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
6 | -- This program is free software: you can redistribute it and/or modify | ||
7 | -- it under the terms of the GNU Affero General Public License as | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | declare module 'v-lazy-image'; \ No newline at end of file | ||
diff --git a/viewer/src/assets/scss/global.scss b/viewer/src/assets/scss/global.scss index 7afca8c..ff57775 100644 --- a/viewer/src/assets/scss/global.scss +++ b/viewer/src/assets/scss/global.scss | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | // Global CSS | 20 | // Global CSS |
21 | @import "@/assets/scss/theme.scss"; | ||
21 | 22 | ||
22 | // === Forms | 23 | // === Forms |
23 | 24 | ||
@@ -42,3 +43,38 @@ | |||
42 | .flex-center { | 43 | .flex-center { |
43 | align-items: center; | 44 | align-items: center; |
44 | } | 45 | } |
46 | |||
47 | // === Scrollbar styling | ||
48 | |||
49 | .scrollbar { | ||
50 | overflow-y: auto; | ||
51 | } | ||
52 | .scrollbar::-webkit-scrollbar { | ||
53 | width: 12px; | ||
54 | } | ||
55 | .scrollbar::-webkit-scrollbar-thumb { | ||
56 | box-shadow: inset 0 0 6px black; | ||
57 | background-color: $toolbar-color; | ||
58 | } | ||
59 | |||
60 | // === Thumbnail tiles alignment | ||
61 | |||
62 | .thumbnail-tiles { | ||
63 | display: flex; | ||
64 | flex-wrap: wrap; | ||
65 | align-items: center; | ||
66 | justify-content: space-between; | ||
67 | & > div { | ||
68 | margin: 1px; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | // === Effect to apply on lazy-image loading | ||
73 | |||
74 | .v-lazy-image { | ||
75 | opacity: 0; | ||
76 | transition: opacity 0.4s; | ||
77 | } | ||
78 | .v-lazy-image-loaded { | ||
79 | opacity: 1; | ||
80 | } | ||
diff --git a/viewer/src/assets/scss/theme.scss b/viewer/src/assets/scss/theme.scss index 79e14e1..efd5d79 100644 --- a/viewer/src/assets/scss/theme.scss +++ b/viewer/src/assets/scss/theme.scss | |||
@@ -27,3 +27,7 @@ $panel-top-txtcolor: white; | |||
27 | $panel-left-bgcolor: $panel-top-bgcolor; | 27 | $panel-left-bgcolor: $panel-top-bgcolor; |
28 | $panel-left-txtcolor: $panel-top-txtcolor; | 28 | $panel-left-txtcolor: $panel-top-txtcolor; |
29 | $content-bgcolor: #1e1e1e; | 29 | $content-bgcolor: #1e1e1e; |
30 | |||
31 | $toolbar-color: #d62929; | ||
32 | |||
33 | $loader-color: #119; | ||
diff --git a/viewer/src/main.ts b/viewer/src/main.ts index a5faa51..8e7716d 100644 --- a/viewer/src/main.ts +++ b/viewer/src/main.ts | |||
@@ -22,6 +22,7 @@ import "@/assets/scss/global.scss"; | |||
22 | import "@/components" | 22 | import "@/components" |
23 | import "@/plugins/fontawesome"; | 23 | import "@/plugins/fontawesome"; |
24 | import "@/plugins/buefy"; | 24 | import "@/plugins/buefy"; |
25 | import "@/plugins/lazyimage"; | ||
25 | import store from '@/store' | 26 | import store from '@/store' |
26 | import i18n from "@/plugins/i18n"; | 27 | import i18n from "@/plugins/i18n"; |
27 | import router from "@/router"; | 28 | import router from "@/router"; |
diff --git a/viewer/src/plugins/lazyimage.ts b/viewer/src/plugins/lazyimage.ts new file mode 100644 index 0000000..276c7e2 --- /dev/null +++ b/viewer/src/plugins/lazyimage.ts | |||
@@ -0,0 +1,23 @@ | |||
1 | /* ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
6 | -- This program is free software: you can redistribute it and/or modify | ||
7 | -- it under the terms of the GNU Affero General Public License as | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | import Vue from "vue"; | ||
21 | import { VLazyImagePlugin } from "v-lazy-image"; | ||
22 | |||
23 | Vue.use(VLazyImagePlugin); | ||
diff --git a/viewer/src/views/GalleryDirectory.vue b/viewer/src/views/GalleryDirectory.vue index eb98595..1df0c4d 100644 --- a/viewer/src/views/GalleryDirectory.vue +++ b/viewer/src/views/GalleryDirectory.vue | |||
@@ -18,13 +18,14 @@ | |||
18 | --> | 18 | --> |
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <div> | 21 | <div class="thumbnail-tiles"> |
22 | <div class="flex"> | 22 | <div v-for="(item) in directory.properties.items" :key="item.path"> |
23 | <div v-for="(item) in directory.properties.items" :key="item.path"> | 23 | <router-link :to="item.path"> |
24 | <router-link :to="item.path"> | 24 | <gallery-thumbnail :item="item" /> |
25 | <gallery-thumbnail :item="item" /> | 25 | </router-link> |
26 | </router-link> | 26 | </div> |
27 | </div> | 27 | <div> |
28 | <!-- Empty item for better flex layout --> | ||
28 | </div> | 29 | </div> |
29 | </div> | 30 | </div> |
30 | </template> | 31 | </template> |
diff --git a/viewer/src/views/GallerySearch.vue b/viewer/src/views/GallerySearch.vue index 7e61f89..870d3e2 100644 --- a/viewer/src/views/GallerySearch.vue +++ b/viewer/src/views/GallerySearch.vue | |||
@@ -18,13 +18,16 @@ | |||
18 | --> | 18 | --> |
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <div class="flex"> | 21 | <div class="thumbnail-tiles"> |
22 | <div v-for="(item) in items" :key="item.path"> | 22 | <div v-for="(item) in items" :key="item.path"> |
23 | <router-link :to="item.path" @click.native="$uiStore.setModeNavigation()"> | 23 | <router-link :to="item.path" @click.native="$uiStore.setModeNavigation()"> |
24 | <gallery-thumbnail :item="item" /> | 24 | <gallery-thumbnail :item="item" /> |
25 | </router-link> | 25 | </router-link> |
26 | </div> | 26 | </div> |
27 | <div v-if="items.length===0">{{$t('search.no-results')}}</div> | 27 | <div v-if="items.length===0">{{$t('search.no-results')}}</div> |
28 | <div> | ||
29 | <!-- Empty item for better flex layout --> | ||
30 | </div> | ||
28 | </div> | 31 | </div> |
29 | </template> | 32 | </template> |
30 | 33 | ||
diff --git a/viewer/src/views/GalleryThumbnail.vue b/viewer/src/views/GalleryThumbnail.vue index 4d8f604..7ceea4f 100644 --- a/viewer/src/views/GalleryThumbnail.vue +++ b/viewer/src/views/GalleryThumbnail.vue | |||
@@ -18,8 +18,15 @@ | |||
18 | --> | 18 | --> |
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <div> | 21 | <div class="forcedsize" :class="{preload: loading}"> |
22 | <img v-if="item.thumbnail" class="thumbnail" :src="pictureSrc" :title="item.path" /> | 22 | <v-lazy-image |
23 | v-if="item.thumbnail" | ||
24 | class="thumbnail" | ||
25 | :src="pictureSrc" | ||
26 | :title="item.path" | ||
27 | @intersect="loading=true" | ||
28 | @load="loading=false" | ||
29 | /> | ||
23 | <div v-else class="flex-column flex-center"> | 30 | <div v-else class="flex-column flex-center"> |
24 | <fa-icon icon="folder" class="fa-4x" /> | 31 | <fa-icon icon="folder" class="fa-4x" /> |
25 | {{item.path}} | 32 | {{item.path}} |
@@ -34,6 +41,8 @@ import { Component, Vue, Prop } from "vue-property-decorator"; | |||
34 | export default class GalleryThumbnail extends Vue { | 41 | export default class GalleryThumbnail extends Vue { |
35 | @Prop({ required: true }) readonly item!: Gallery.Item; | 42 | @Prop({ required: true }) readonly item!: Gallery.Item; |
36 | 43 | ||
44 | loading: boolean = false; | ||
45 | |||
37 | get pictureSrc() { | 46 | get pictureSrc() { |
38 | return `${process.env.VUE_APP_DATA_URL}${this.item.thumbnail}`; | 47 | return `${process.env.VUE_APP_DATA_URL}${this.item.thumbnail}`; |
39 | } | 48 | } |
@@ -41,8 +50,29 @@ export default class GalleryThumbnail extends Vue { | |||
41 | </script> | 50 | </script> |
42 | 51 | ||
43 | <style lang="scss"> | 52 | <style lang="scss"> |
53 | @import "@/assets/scss/theme.scss"; | ||
54 | |||
44 | .thumbnail { | 55 | .thumbnail { |
45 | max-width: 250px; | 56 | max-width: 250px; |
46 | max-height: 250px; | 57 | max-height: 250px; |
47 | } | 58 | } |
59 | .preload { | ||
60 | background: linear-gradient(to right, rgba(0, 0, 0, 0) 8%, $loader-color 18%, rgba(0, 0, 0, 0) 33%); | ||
61 | background-size: 200% 50px; | ||
62 | animation: preloadAnimation 2s infinite linear; | ||
63 | } | ||
64 | @keyframes preloadAnimation { | ||
65 | from { | ||
66 | background-position: -200px 0; | ||