diff options
author | Zéro~Informatique | 2022-07-26 08:44:34 +0200 |
---|---|---|
committer | pacien | 2022-09-03 01:30:42 +0200 |
commit | 00510820a2794efcadbc83f7f8b54318fe198ecb (patch) | |
tree | a894d99c22a601197869c7a6928d40bb4ae2c392 /viewer/src/views | |
parent | 88aa098c07e067f9f737fbeba1f52a9bd5042e53 (diff) | |
download | ldgallery-00510820a2794efcadbc83f7f8b54318fe198ecb.tar.gz |
viewer: migrate to vue 3, general refactoring and cleanup
Non-exhaustive list of fixes and improvements done at the same time:
- html default background to grey (avoids white flash during init)
- unified links behavior
- added more theme variables
- removed the flex-expand transition (it wasn't working) and replaced it
with a slide
- fixed LdLoading not centered on the content
- title on removable tags
- fixed an issue with encoded URI from vue-router
- unified Item resource URLs
- removed the iframe for PlainTextViewer (it wasn't working properly)
and replaced it with a pre
- fixed clear and search buttons tabindex
- fixed the information panel bumping up during the fade animation of
tag's dropdown
- fixed some focus outlines not appearing correctly
- moved CSS variables to the :root context
- Code cleaning
GitHub: closes #217
GitHub: closes #300
GitHub: closes #297
GitHub: closes #105
GitHub: closes #267
GitHub: closes #275
GitHub: closes #228
GitHub: closes #215
GitHub: closes #112
Diffstat (limited to 'viewer/src/views')
25 files changed, 2046 insertions, 365 deletions
diff --git a/viewer/src/views/GalleryNavigation.vue b/viewer/src/views/GalleryNavigation.vue index 200637e..0869aaf 100644 --- a/viewer/src/views/GalleryNavigation.vue +++ b/viewer/src/views/GalleryNavigation.vue | |||
@@ -1,7 +1,7 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | 1 | <!-- ldgallery - A static generator which turns a collection of tagged |
2 | -- pictures into a searchable web gallery. | 2 | -- pictures into a searchable web gallery. |
3 | -- | 3 | -- |
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | 4 | -- Copyright (C) 2019-2022 Guillaume FOUET |
5 | -- | 5 | -- |
6 | -- This program is free software: you can redistribute it and/or modify | 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 | 7 | -- it under the terms of the GNU Affero General Public License as |
@@ -19,65 +19,63 @@ | |||
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <div> | 21 | <div> |
22 | <ld-error v-if="isError" icon="folder-open" :message="$t('gallery.unknown-resource')" /> | 22 | <LdNotice |
23 | <gallery-search v-else-if="isSearch" :path="path" /> | 23 | v-if="isError" |
24 | <component :is="componentName" v-else :key="componentKey" :item="$galleryStore.currentItem" /> | 24 | :icon="faFolderOpen" |
25 | :message="t('gallery.unknown-resource')" | ||
26 | /> | ||
27 | <GallerySearch v-else-if="isSearch" /> | ||
28 | <component | ||
29 | :is="componentName" | ||
30 | v-else | ||
31 | :key="componentKey" | ||
32 | :item="galleryStore.currentItem" | ||
33 | /> | ||
25 | </div> | 34 | </div> |
26 | </template> | 35 | </template> |
27 | 36 | ||
28 | <script lang="ts"> | 37 | <script setup lang="ts"> |
29 | import { ItemType } from "@/@types/ItemType"; | 38 | import { ItemType } from '@/@types/itemType'; |
30 | import Navigation from "@/services/navigation"; | 39 | import LdNotice from '@/components/LdNotice.vue'; |
31 | import GallerySearch from "@/views/GallerySearch.vue"; | 40 | import { isDirectory } from '@/services/itemGuards'; |
32 | import { Component, Prop, Vue, Watch } from "vue-property-decorator"; | 41 | import { useGalleryStore } from '@/store/galleryStore'; |
42 | import { faFolderOpen } from '@fortawesome/free-solid-svg-icons'; | ||
43 | import { computedEager } from '@vueuse/shared'; | ||
44 | import { computed, watchEffect } from 'vue'; | ||
45 | import { useI18n } from 'vue-i18n'; | ||
46 | import GallerySearch from './GallerySearch.vue'; | ||
47 | import AudioViewer from './item_handlers/AudioViewer.vue'; | ||
48 | import DirectoryViewer from './item_handlers/DirectoryViewer.vue'; | ||
49 | import DownloadViewer from './item_handlers/DownloadViewer.vue'; | ||
50 | import MarkdownViewer from './item_handlers/MarkdownViewer.vue'; | ||
51 | import PdfViewer from './item_handlers/PdfViewer.vue'; | ||
52 | import PictureViewer from './item_handlers/PictureViewer.vue'; | ||
53 | import PlainTextViewer from './item_handlers/PlainTextViewer.vue'; | ||
54 | import VideoViewer from './item_handlers/VideoViewer.vue'; | ||
33 | 55 | ||
34 | @Component({ | 56 | const props = defineProps({ |
35 | components: { | 57 | path: { type: String, required: true }, |
36 | GallerySearch, | 58 | query: { type: Array<string>, required: true }, |
37 | }, | 59 | }); |
38 | }) | ||
39 | export default class GalleryNavigation extends Vue { | ||
40 | @Prop(String) readonly path!: string; | ||
41 | @Prop(Array) readonly query!: string[]; | ||
42 | 60 | ||
43 | readonly COMPONENT_BY_TYPE: Record<ItemType, string> = { | 61 | const { t } = useI18n(); |
44 | directory: "ld-directory-viewer", | 62 | const galleryStore = useGalleryStore(); |
45 | picture: "ld-picture-viewer", | ||
46 | plaintext: "ld-plain-text-viewer", | ||
47 | markdown: "ld-markdown-viewer", | ||
48 | pdf: "ld-pdf-viewer", | ||
49 | video: "ld-video-viewer", | ||
50 | audio: "ld-audio-viewer", | ||
51 | other: "ld-download-viewer", | ||
52 | }; | ||
53 | 63 | ||
54 | mounted() { | 64 | const COMPONENT_BY_TYPE: Record<ItemType, unknown> = { |
55 | this.pathChanged(); | 65 | directory: DirectoryViewer, |
56 | } | 66 | picture: PictureViewer, |
67 | plaintext: PlainTextViewer, | ||
68 | markdown: MarkdownViewer, | ||
69 | pdf: PdfViewer, | ||
70 | video: VideoViewer, | ||
71 | audio: AudioViewer, | ||
72 | other: DownloadViewer, | ||
73 | }; | ||
57 | 74 | ||
58 | get isError() { | 75 | const isError = computedEager(() => !galleryStore.currentItem?.properties.type); |
59 | return this.checkType(null); | 76 | const isSearch = computedEager(() => isDirectory(galleryStore.currentItem) && props.query.length > 0); |
60 | } | 77 | const componentName = computed(() => COMPONENT_BY_TYPE[galleryStore.currentItem?.properties.type ?? ItemType.OTHER]); |
78 | const componentKey = computed(() => galleryStore.currentItem?.path ?? ''); | ||
61 | 79 | ||
62 | get isSearch() { | 80 | watchEffect(() => (galleryStore.currentPath = props.path)); |
63 | return this.checkType(ItemType.DIRECTORY) && this.query.length > 0; | ||
64 | } | ||
65 | |||
66 | get componentName() { | ||
67 | return this.COMPONENT_BY_TYPE[this.$galleryStore.currentItem?.properties.type ?? ItemType.OTHER]; | ||
68 | } | ||
69 | |||
70 | get componentKey() { | ||
71 | return this.$galleryStore.currentItem?.path ?? ""; | ||
72 | } | ||
73 | |||
74 | @Watch("path") | ||
75 | pathChanged() { | ||
76 | this.$galleryStore.setCurrentPath(this.path); | ||
77 | } | ||
78 | |||
79 | checkType(type: ItemType | null): boolean { | ||
80 | return Navigation.checkType(this.$galleryStore.currentItem, type); | ||
81 | } | ||
82 | } | ||
83 | </script> | 81 | </script> |
diff --git a/viewer/src/views/GallerySearch.vue b/viewer/src/views/GallerySearch.vue index 5ab56e0..d148b9c 100644 --- a/viewer/src/views/GallerySearch.vue +++ b/viewer/src/views/GallerySearch.vue | |||
@@ -1,7 +1,7 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | 1 | <!-- ldgallery - A static generator which turns a collection of tagged |
2 | -- pictures into a searchable web gallery. | 2 | -- pictures into a searchable web gallery. |
3 | -- | 3 | -- |
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | 4 | -- Copyright (C) 2019-2022 Guillaume FOUET |
5 | -- | 5 | -- |
6 | -- This program is free software: you can redistribute it and/or modify | 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 | 7 | -- it under the terms of the GNU Affero General Public License as |
@@ -18,37 +18,39 @@ | |||
18 | --> | 18 | --> |
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <ld-gallery :items="items" :noresult="noResult" /> | 21 | <GalleryTiles |
22 | :items="items.filteredByPath" | ||
23 | :noresult-message="noResult" | ||
24 | /> | ||
22 | </template> | 25 | </template> |
23 | 26 | ||
24 | <script lang="ts"> | 27 | <script setup lang="ts"> |
25 | import IndexSearch from "@/services/indexsearch"; | 28 | import { useIndexSearch } from '@/services/indexSearch'; |
26 | import { Component, Prop, Vue } from "vue-property-decorator"; | 29 | import { useGalleryStore } from '@/store/galleryStore'; |
30 | import { useUiStore } from '@/store/uiStore'; | ||
31 | import { computed, onUnmounted } from 'vue'; | ||
32 | import { useI18n } from 'vue-i18n'; | ||
33 | import GalleryTiles from './GalleryTiles.vue'; | ||
27 | 34 | ||
28 | @Component | 35 | const { t } = useI18n(); |
29 | export default class GalleryPicture extends Vue { | 36 | const uiStore = useUiStore(); |
30 | @Prop(String) readonly path!: string; | 37 | const galleryStore = useGalleryStore(); |
31 | otherCount: number = 0; | 38 | const indexSearch = useIndexSearch(); |
32 | 39 | ||
33 | mounted() { | 40 | uiStore.toggleFullscreen(false); |
34 | this.$uiStore.toggleFullscreen(false); | 41 | uiStore.searchMode = true; |