diff options
Diffstat (limited to 'viewer/src/views')
-rw-r--r-- | viewer/src/views/GalleryNavigation.vue | 16 | ||||
-rw-r--r-- | viewer/src/views/GallerySearch.vue | 5 | ||||
-rw-r--r-- | viewer/src/views/MainLayout.vue | 93 | ||||
-rw-r--r-- | viewer/src/views/PanelLeft.vue | 14 | ||||
-rw-r--r-- | viewer/src/views/PanelTop.vue | 2 | ||||
-rw-r--r-- | viewer/src/views/SplashScreen.vue | 68 |
6 files changed, 150 insertions, 48 deletions
diff --git a/viewer/src/views/GalleryNavigation.vue b/viewer/src/views/GalleryNavigation.vue index fd1f19a..fdd3922 100644 --- a/viewer/src/views/GalleryNavigation.vue +++ b/viewer/src/views/GalleryNavigation.vue | |||
@@ -21,15 +21,15 @@ | |||
21 | <div> | 21 | <div> |
22 | <ld-error v-if="isError" icon="folder-open" :message="$t('gallery.unknown-resource')" /> | 22 | <ld-error v-if="isError" icon="folder-open" :message="$t('gallery.unknown-resource')" /> |
23 | <gallery-search v-else-if="isSearch" :path="path" /> | 23 | <gallery-search v-else-if="isSearch" :path="path" /> |
24 | <component :is="componentName" v-else :item="$galleryStore.currentItem" /> | 24 | <component :is="componentName" v-else :key="componentKey" :item="$galleryStore.currentItem" /> |
25 | </div> | 25 | </div> |
26 | </template> | 26 | </template> |
27 | 27 | ||
28 | <script lang="ts"> | 28 | <script lang="ts"> |
29 | import { Component, Vue, Prop, Watch } from "vue-property-decorator"; | ||
30 | import { ItemType } from "@/@types/ItemType"; | 29 | import { ItemType } from "@/@types/ItemType"; |
31 | import Navigation from "@/services/navigation"; | 30 | import Navigation from "@/services/navigation"; |
32 | import GallerySearch from "@/views/GallerySearch.vue"; | 31 | import GallerySearch from "@/views/GallerySearch.vue"; |
32 | import { Component, Prop, Vue, Watch } from "vue-property-decorator"; | ||
33 | 33 | ||
34 | @Component({ | 34 | @Component({ |
35 | components: { | 35 | components: { |
@@ -41,13 +41,13 @@ export default class GalleryNavigation extends Vue { | |||
41 | @Prop(Array) readonly query!: string[]; | 41 | @Prop(Array) readonly query!: string[]; |
42 | 42 | ||
43 | readonly COMPONENT_BY_TYPE: Record<ItemType, string> = { | 43 | readonly COMPONENT_BY_TYPE: Record<ItemType, string> = { |
44 | directory: "ld-directory", | 44 | directory: "ld-directory-viewer", |
45 | picture: "ld-picture", | 45 | picture: "ld-picture-viewer", |
46 | plaintext: "ld-plain-text-viewer", | 46 | plaintext: "ld-plain-text-viewer", |
47 | pdf: "ld-pdf-viewer", | 47 | pdf: "ld-pdf-viewer", |
48 | video: "ld-video-viewer", | 48 | video: "ld-video-viewer", |
49 | audio: "ld-audio-viewer", | 49 | audio: "ld-audio-viewer", |
50 | other: "ld-download", | 50 | other: "ld-download-viewer", |
51 | }; | 51 | }; |
52 | 52 | ||
53 | mounted() { | 53 | mounted() { |
@@ -66,6 +66,10 @@ export default class GalleryNavigation extends Vue { | |||
66 | return this.COMPONENT_BY_TYPE[this.$galleryStore.currentItem?.properties.type ?? ItemType.OTHER]; | 66 | return this.COMPONENT_BY_TYPE[this.$galleryStore.currentItem?.properties.type ?? ItemType.OTHER]; |
67 | } | 67 | } |
68 | 68 | ||
69 | get componentKey() { | ||
70 | return this.$galleryStore.currentItem?.path ?? ""; | ||
71 | } | ||
72 | |||
69 | @Watch("path") | 73 | @Watch("path") |
70 | pathChanged() { | 74 | pathChanged() { |
71 | this.$galleryStore.setCurrentPath(this.path); | 75 | this.$galleryStore.setCurrentPath(this.path); |
@@ -76,5 +80,3 @@ export default class GalleryNavigation extends Vue { | |||
76 | } | 80 | } |
77 | } | 81 | } |
78 | </script> | 82 | </script> |
79 | |||
80 | <style lang="scss"></style> | ||
diff --git a/viewer/src/views/GallerySearch.vue b/viewer/src/views/GallerySearch.vue index fec7216..5ab56e0 100644 --- a/viewer/src/views/GallerySearch.vue +++ b/viewer/src/views/GallerySearch.vue | |||
@@ -22,9 +22,8 @@ | |||
22 | </template> | 22 | </template> |
23 | 23 | ||
24 | <script lang="ts"> | 24 | <script lang="ts"> |
25 | import { Component, Vue, Prop } from "vue-property-decorator"; | ||
26 | import { Operation } from "@/@types/Operation"; | ||
27 | import IndexSearch from "@/services/indexsearch"; | 25 | import IndexSearch from "@/services/indexsearch"; |
26 | import { Component, Prop, Vue } from "vue-property-decorator"; | ||
28 | 27 | ||
29 | @Component | 28 | @Component |
30 | export default class GalleryPicture extends Vue { | 29 | export default class GalleryPicture extends Vue { |
@@ -53,5 +52,3 @@ export default class GalleryPicture extends Vue { | |||
53 | } | 52 | } |
54 | } | 53 | } |
55 | </script> | 54 | </script> |
56 | |||
57 | <style lang="scss"></style> | ||
diff --git a/viewer/src/views/MainLayout.vue b/viewer/src/views/MainLayout.vue index 6ef9a3b..2347ba7 100644 --- a/viewer/src/views/MainLayout.vue +++ b/viewer/src/views/MainLayout.vue | |||
@@ -18,31 +18,55 @@ | |||
18 | --> | 18 | --> |
19 | 19 | ||
20 | <template> | 20 | <template> |
21 | <div :class="{ fullscreen: $uiStore.fullscreen, fullwidth: $uiStore.fullWidth }"> | 21 | <div :class="{ [$style.fullscreen]: $uiStore.fullscreen, [$style.fullwidth]: $uiStore.fullWidth }"> |
22 | <ld-title :gallery-title="$galleryStore.galleryTitle" :current-item="$galleryStore.currentItem" /> | 22 | <ld-title :gallery-title="$galleryStore.galleryTitle" :current-item="$galleryStore.currentItem" /> |
23 | <panel-top v-if="isReady" class="layout layout-top" /> | 23 | <PanelTop v-if="isReady" :class="[$style.layout, $style.layoutTop]" /> |
24 | <panel-left v-if="isReady" class="layout layout-left" /> | 24 | <PanelLeft v-if="isReady" :class="[$style.layout, $style.layoutLeft]" /> |
25 | <router-view v-if="!isLoading" ref="content" class="layout layout-content scrollbar" /> | 25 | <b-loading v-if="isLoading" active /> |
26 | <b-loading :active="isLoading" is-full-page /> | 26 | <SplashScreen |
27 | v-else-if="$uiStore.splashScreenEnabled" | ||
28 | :class="$style.layout" | ||
29 | @validation="$uiStore.validateSpashScreen()" | ||
30 | /> | ||
31 | <router-view v-else ref="content" :class="[$style.layout, $style.layoutContent]" class="scrollbar" tabindex="01" /> | ||
27 | <ld-key-press :keycode="27" @action="$uiStore.toggleFullscreen(false)" /> | 32 | <ld-key-press :keycode="27" @action="$uiStore.toggleFullscreen(false)" /> |
28 | </div> | 33 | </div> |
29 | </template> | 34 | </template> |
30 | 35 | ||
31 | <script lang="ts"> | 36 | <script lang="ts"> |
32 | import { Component, Vue, Ref, Watch } from "vue-property-decorator"; | 37 | import { ScrollPosition } from "@/@types/scrollposition"; |
38 | import { Component, Ref, Vue, Watch } from "vue-property-decorator"; | ||
39 | import { Route } from "vue-router"; | ||
33 | import PanelLeft from "./PanelLeft.vue"; | 40 | import PanelLeft from "./PanelLeft.vue"; |
34 | import PanelTop from "./PanelTop.vue"; | 41 | import PanelTop from "./PanelTop.vue"; |
35 | import { Route } from "vue-router"; | 42 | import SplashScreen from "./SplashScreen.vue"; |
36 | 43 | ||
37 | @Component({ | 44 | @Component({ |
38 | components: { PanelLeft, PanelTop }, | 45 | components: { |
46 | PanelLeft, | ||
47 | PanelTop, | ||
48 | SplashScreen, | ||
49 | }, | ||
39 | }) | 50 | }) |
40 | export default class MainLayout extends Vue { | 51 | export default class MainLayout extends Vue { |
41 | @Ref() readonly content!: Vue; | 52 | @Ref() readonly content?: Vue; |
42 | 53 | ||
43 | isLoading: boolean = true; | 54 | isLoading: boolean = true; |
44 | scrollPositions: ScrollPosition = {}; | 55 | scrollPositions: ScrollPosition = {}; |
45 | 56 | ||
57 | get contentDiv(): HTMLDivElement | null { | ||
58 | return (this.content?.$el as HTMLDivElement) ?? null; | ||
59 | } | ||
60 | |||
61 | get isReady(): boolean { | ||
62 | return ( | ||
63 | !this.$uiStore.splashScreenEnabled && | ||
64 | !this.isLoading && | ||
65 | this.$galleryStore.config !== null && | ||
66 | this.$galleryStore.currentPath !== null | ||
67 | ); | ||
68 | } | ||
69 | |||
46 | mounted() { | 70 | mounted() { |
47 | history.replaceState({ ldgallery: "ENTRYPOINT" }, ""); | 71 | history.replaceState({ ldgallery: "ENTRYPOINT" }, ""); |
48 | this.fetchGalleryItems(); | 72 | this.fetchGalleryItems(); |
@@ -53,11 +77,16 @@ export default class MainLayout extends Vue { | |||
53 | document.body.removeEventListener("fullscreenchange", this.onFullscreenChange); | 77 | document.body.removeEventListener("fullscreenchange", this.onFullscreenChange); |
54 | } | 78 | } |
55 | 79 | ||
80 | moveFocusToContentDiv() { | ||
81 | setTimeout(() => this.contentDiv?.focus()); | ||
82 | } | ||
83 | |||
56 | @Watch("$route") | 84 | @Watch("$route") |
57 | routeChanged(newRoute: Route, oldRoute: Route) { | 85 | routeChanged(newRoute: Route, oldRoute: Route) { |
58 | const el = this.content.$el; | 86 | if (!this.contentDiv) return; |
59 | this.scrollPositions[oldRoute.path] = el.scrollTop; | 87 | this.scrollPositions[oldRoute.path] = this.contentDiv.scrollTop; |
60 | this.$nextTick(() => (el.scrollTop = this.scrollPositions[newRoute.path])); | 88 | this.$nextTick(() => (this.contentDiv!.scrollTop = this.scrollPositions[newRoute.path])); |
89 | this.moveFocusToContentDiv(); | ||
61 | } | 90 | } |
62 | 91 | ||
63 | fetchGalleryItems() { | 92 | fetchGalleryItems() { |
@@ -66,18 +95,15 @@ export default class MainLayout extends Vue { | |||
66 | .fetchConfig() | 95 | .fetchConfig() |
67 | .then(this.$uiStore.initFromConfig) | 96 | .then(this.$uiStore.initFromConfig) |
68 | .then(this.$galleryStore.fetchGalleryItems) | 97 | .then(this.$galleryStore.fetchGalleryItems) |
98 | .then(this.moveFocusToContentDiv) | ||
69 | .finally(() => (this.isLoading = false)) | 99 | .finally(() => (this.isLoading = false)) |
70 | .catch(this.displayError); | 100 | .catch(this.displayError); |
71 | } | 101 | } |
72 | 102 | ||
73 | get isReady() { | ||
74 | return !this.isLoading && this.$galleryStore.config && this.$galleryStore.currentPath !== null; | ||
75 | } | ||
76 | |||
77 | displayError(reason: any) { | 103 | displayError(reason: any) { |
78 | this.$buefy.snackbar.open({ | 104 | this.$buefy.snackbar.open({ |
79 | message: `${reason}`, | 105 | message: `${reason}`, |
80 | actionText: "Retry", | 106 | actionText: this.$t("snack.retry"), |
81 | position: "is-top", | 107 | position: "is-top", |
82 | type: "is-danger", | 108 | type: "is-danger", |
83 | indefinite: true, | 109 | indefinite: true, |
@@ -85,23 +111,28 @@ export default class MainLayout extends Vue { | |||
85 | }); | 111 | }); |
86 | } | 112 | } |
87 | 113 | ||
114 | isFullscreenActive(): boolean { | ||
115 | return Boolean(document.fullscreenElement); | ||
116 | } | ||
117 | |||
88 | @Watch("$uiStore.fullscreen") | 118 |