aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/views
diff options
context:
space:
mode:
authorZero~Informatique2021-07-03 05:06:44 +0200
committerpacien2021-07-04 17:40:01 +0200
commit928c501dda0c3580e3cb0389efc16fc1dde16b68 (patch)
tree6425d3d394408bedd35fb663826bf20e3bf615ea /viewer/src/views
parentac160f6879f9a2c74ca77c1c34742d24e69bf570 (diff)
downloadldgallery-928c501dda0c3580e3cb0389efc16fc1dde16b68.tar.gz
viewer: optional user-defined markdown splash screen
GitHub: closes #284
Diffstat (limited to 'viewer/src/views')
-rw-r--r--viewer/src/views/MainLayout.vue46
-rw-r--r--viewer/src/views/SplashScreen.vue72
2 files changed, 100 insertions, 18 deletions
diff --git a/viewer/src/views/MainLayout.vue b/viewer/src/views/MainLayout.vue
index c54f183..2347ba7 100644
--- a/viewer/src/views/MainLayout.vue
+++ b/viewer/src/views/MainLayout.vue
@@ -22,14 +22,13 @@
22 <ld-title :gallery-title="$galleryStore.galleryTitle" :current-item="$galleryStore.currentItem" /> 22 <ld-title :gallery-title="$galleryStore.galleryTitle" :current-item="$galleryStore.currentItem" />
23 <PanelTop v-if="isReady" :class="[$style.layout, $style.layoutTop]" /> 23 <PanelTop v-if="isReady" :class="[$style.layout, $style.layoutTop]" />
24 <PanelLeft v-if="isReady" :class="[$style.layout, $style.layoutLeft]" /> 24 <PanelLeft v-if="isReady" :class="[$style.layout, $style.layoutLeft]" />
25 <router-view 25 <b-loading v-if="isLoading" active />
26 v-if="!isLoading" 26 <SplashScreen
27 ref="content" 27 v-else-if="$uiStore.splashScreenEnabled"
28 :class="[$style.layout, $style.layoutContent]" 28 :class="$style.layout"
29 class="scrollbar" 29 @validation="$uiStore.validateSpashScreen()"
30 tabindex="01"
31 /> 30 />
32 <b-loading :active="isLoading" is-full-page /> 31 <router-view v-else ref="content" :class="[$style.layout, $style.layoutContent]" class="scrollbar" tabindex="01" />
33 <ld-key-press :keycode="27" @action="$uiStore.toggleFullscreen(false)" /> 32 <ld-key-press :keycode="27" @action="$uiStore.toggleFullscreen(false)" />
34 </div> 33 </div>
35</template> 34</template>
@@ -40,18 +39,32 @@ import { Component, Ref, Vue, Watch } from "vue-property-decorator";
40import { Route } from "vue-router"; 39import { Route } from "vue-router";
41import PanelLeft from "./PanelLeft.vue"; 40import PanelLeft from "./PanelLeft.vue";
42import PanelTop from "./PanelTop.vue"; 41import PanelTop from "./PanelTop.vue";
42import SplashScreen from "./SplashScreen.vue";
43 43
44@Component({ 44@Component({
45 components: { PanelLeft, PanelTop }, 45 components: {
46 PanelLeft,
47 PanelTop,
48 SplashScreen,
49 },
46}) 50})
47export default class MainLayout extends Vue { 51export default class MainLayout extends Vue {
48 @Ref() readonly content!: Vue; 52 @Ref() readonly content?: Vue;
49 53
50 isLoading: boolean = true; 54 isLoading: boolean = true;
51 scrollPositions: ScrollPosition = {}; 55 scrollPositions: ScrollPosition = {};
52 56
53 get contentDiv() { 57 get contentDiv(): HTMLDivElement | null {
54 return this.content.$el as HTMLDivElement; 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 );
55 } 68 }
56 69
57 mounted() { 70 mounted() {
@@ -65,13 +78,14 @@ export default class MainLayout extends Vue {
65 } 78 }
66 79
67 moveFocusToContentDiv() { 80 moveFocusToContentDiv() {
68 setTimeout(() => this.contentDiv.focus()); 81 setTimeout(() => this.contentDiv?.focus());
69 } 82 }
70 83
71 @Watch("$route") 84 @Watch("$route")
72 routeChanged(newRoute: Route, oldRoute: Route) { 85 routeChanged(newRoute: Route, oldRoute: Route) {
86 if (!this.contentDiv) return;
73 this.scrollPositions[oldRoute.path] = this.contentDiv.scrollTop; 87 this.scrollPositions[oldRoute.path] = this.contentDiv.scrollTop;
74 this.$nextTick(() => (this.contentDiv.scrollTop = this.scrollPositions[newRoute.path])); 88 this.$nextTick(() => (this.contentDiv!.scrollTop = this.scrollPositions[newRoute.path]));
75 this.moveFocusToContentDiv(); 89 this.moveFocusToContentDiv();
76 } 90 }
77 91
@@ -86,14 +100,10 @@ export default class MainLayout extends Vue {
86 .catch(this.displayError); 100 .catch(this.displayError);
87 } 101 }
88 102
89 get isReady() {
90 return !this.isLoading && this.$galleryStore.config && this.$galleryStore.currentPath !== null;
91 }
92
93 displayError(reason: any) { 103 displayError(reason: any) {
94 this.$buefy.snackbar.open({ 104 this.$buefy.snackbar.open({
95 message: `${reason}`, 105 message: `${reason}`,
96 actionText: "Retry", 106 actionText: this.$t("snack.retry"),
97 position: "is-top", 107 position: "is-top",
98 type: "is-danger", 108 type: "is-danger",
99 indefinite: true, 109 indefinite: true,
diff --git a/viewer/src/views/SplashScreen.vue b/viewer/src/views/SplashScreen.vue
new file mode 100644
index 0000000..808567e
--- /dev/null
+++ b/viewer/src/views/SplashScreen.vue
@@ -0,0 +1,72 @@
1<template>
2 <b-loading v-if="isLoading" active />
3 <div v-else-if="markdown" :class="$style.splashscreen" class="scrollbar">
4 <Markdown :style="config.style" class="flex-grow-1" :markdown="markdown" />
5 <b-button size="is-large" :label="buttonAcknowledgeLabel" :class="$style.buttonAcknowledge" @click="validation" />
6 </div>
7</template>
8
9<script lang="ts">
10import { SplashScreenConfig } from "@/@types/splashscreen";
11import { Markdown } from "@/components/async";
12import FetchWithCheck from "@/services/fetchWithCheck";
13import { TranslateResult } from "vue-i18n";
14import { Component, Emit, Vue } from "vue-property-decorator";
15
16@Component({
17 components: {
18 Markdown,
19 },
20})
21export default class SplashScreen extends Vue {
22 isLoading: boolean = true;
23 markdown: string | null = null;
24
25 get config(): SplashScreenConfig {
26 return this.$uiStore.splashScreenConfig!;
27 }
28
29 created() {
30 this.fetchMarkdown();
31 }
32
33 fetchMarkdown() {
34 FetchWithCheck.get(`${process.env.VUE_APP_DATA_URL}${this.config.resource}?${this.config.dontshowagainUID ?? ""}`)
35 .then(response => response.text())
36 .then(text => (this.markdown = text))
37 .finally(() => (this.isLoading = false))
38 .catch(this.displayError);
39 }
40
41 displayError(reason: any) {
42 this.$buefy.snackbar.open({
43 message: `${reason}`,
44 actionText: this.$t("snack.retry"),
45 position: "is-top",
46 type: "is-danger",
47 indefinite: true,
48 onAction: this.fetchMarkdown,
49 });
50 }
51
52 get buttonAcknowledgeLabel(): TranslateResult {
53 return this.config.buttonAcknowledgeLabel ?? this.$t("splashScreen.button.acknowledge");
54 }
55
56 @Emit()
57 validation() {}
58}
59</script>
60
61<style lang="scss" module>
62.splashscreen {
63 display: flex;
64 flex-flow: column;
65 align-items: center;
66 padding: 32px;
67}
68.buttonAcknowledge {
69 min-width: 310px;
70 align-self: center;
71}
72</style>