aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/views/layout/top
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/views/layout/top')
-rw-r--r--viewer/src/views/layout/top/LayoutBreadcrumb.vue130
-rw-r--r--viewer/src/views/layout/top/LayoutCommand.vue127
-rw-r--r--viewer/src/views/layout/top/LayoutCommandSort.vue85
-rw-r--r--viewer/src/views/layout/top/LayoutTop.vue38
4 files changed, 380 insertions, 0 deletions
diff --git a/viewer/src/views/layout/top/LayoutBreadcrumb.vue b/viewer/src/views/layout/top/LayoutBreadcrumb.vue
new file mode 100644
index 0000000..2e70d66
--- /dev/null
+++ b/viewer/src/views/layout/top/LayoutBreadcrumb.vue
@@ -0,0 +1,130 @@
1<!-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2022 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<template>
21 <div
22 ref="breadcrumb"
23 v-dragscroll.x
24 class="flex scrollbar"
25 :class="$style.ldBreadcrumb"
26 >
27 <div
28 v-show="!arrivedState.left"
29 :class="$style.ldBreadcrumbOverflowMask"
30 />
31 <ul>
32 <li
33 v-for="(item, idx) in currentItemPath"
34 :key="item.path"
35 >
36 <fa-icon
37 v-if="idx > 0"
38 :icon="faAngleRight"
39 class="disabled"
40 />
41 <LdLink
42 :to="item.path"
43 >
44 <fa-icon
45 :icon="navigation.getIcon(item)"
46 size="lg"
47 />
48 {{ item.title }}
49 </LdLink>
50 </li>
51 <li v-if="searchMode">
52 <fa-icon
53 :icon="faAngleRight"
54 class="disabled"
55 />
56 <fa-icon
57 :icon="faSearch"
58 size="lg"
59 class="disabled"
60 />
61 </li>
62 </ul>
63 </div>
64</template>
65
66<script setup lang="ts">
67import { Item } from '@/@types/gallery';
68import LdLink from '@/components/LdLink.vue';
69import { useNavigation } from '@/services/navigation';
70import { faAngleRight, faSearch } from '@fortawesome/free-solid-svg-icons';
71import { useScroll } from '@vueuse/core';
72import { nextTick, onMounted, ref, watch } from 'vue';
73
74const props = defineProps({
75 currentItemPath: { type: Array<Item>, required: true },
76 searchMode: Boolean,
77});
78
79const breadcrumb = ref<HTMLDivElement>();
80
81const navigation = useNavigation();
82const { arrivedState } = useScroll(breadcrumb);
83
84onMounted(() =>
85 watch(() => props.currentItemPath, () => {
86 const div = breadcrumb.value;
87 if (div) nextTick(() => (div.scrollLeft = div.scrollWidth));
88 }, { immediate: true }));
89</script>
90
91<style lang="scss" module>
92@import "~@/assets/scss/theme";
93
94.ldBreadcrumbOverflowMask {
95 position: absolute;
96 width: 100%;
97 height: 100%;
98 background: linear-gradient(
99 to right,
100 rgba($panel-top-bgcolor, 1) $breadcrumb-margins,
101 rgba($panel-top-bgcolor, 0) $breadcrumb-overflow-mask-size
102 );
103 pointer-events: none;
104}
105
106.ldBreadcrumb {
107 ul {
108 display: flex;
109 white-space: nowrap;
110 list-style: none;
111 padding: 2px; // Necessary for the focus outline
112 align-items: center;
113 li {
114 > * {
115 margin-left: $breadcrumb-margins;
116 }
117 > a {
118 padding: $breadcrumb-margins 2px;
119 }
120 }
121 }
122 &:global(.scrollbar) {
123 overflow-y: hidden;
124 scrollbar-width: none;
125 &::-webkit-scrollbar {
126 height: 0;
127 }
128 }
129}
130</style>
diff --git a/viewer/src/views/layout/top/LayoutCommand.vue b/viewer/src/views/layout/top/LayoutCommand.vue
new file mode 100644
index 0000000..8919da3
--- /dev/null
+++ b/viewer/src/views/layout/top/LayoutCommand.vue
@@ -0,0 +1,127 @@
1<!-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2022 Guillaume FOUET
5-- 2020 Pacien TRAN-GIRARD
6--
7-- This program is free software: you can redistribute it and/or modify
8-- it under the terms of the GNU Affero General Public License as
9-- published by the Free Software Foundation, either version 3 of the
10-- License, or (at your option) any later version.
11--
12-- This program is distributed in the hope that it will be useful,
13-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15-- GNU Affero General Public License for more details.
16--
17-- You should have received a copy of the GNU Affero General Public License
18-- along with this program. If not, see <https://www.gnu.org/licenses/>.
19-->
20
21<template>
22 <div
23 class="flex"
24 :class="$style.commandBtns"
25 >
26 <LdLink
27 :title="t('command.search.slider')"
28 tabindex="10"
29 @click="uiStore.toggleFullWidth()"
30 >
31 <fa-icon
32 :icon="commandToggleSearchPanelIcon"
33 size="lg"
34 />
35 </LdLink>
36 <LayoutCommandSort :tabindex="20" />
37 <LdLink
38 :class="{ disabled: isEntryPoint(), [$style.commandSecondary]: true }"
39 :title="t('command.back')"
40 tabindex="30"
41 @click="isEntryPoint() || router.back()"
42 >
43 <fa-icon
44 :icon="faArrowLeft"
45 size="lg"
46 />
47 </LdLink>
48 <LdLink
49 :to="parent"
50 :class="{ disabled: isRoot }"
51 :title="t('command.parent')"
52 tabindex="40"
53 >
54 <fa-icon
55 :icon="faFolder"
56 size="xs"
57 />
58 <fa-icon
59 :icon="faLevelUpAlt"
60 size="lg"
61 />
62 </LdLink>
63 </div>
64</template>
65
66<script setup lang="ts">
67import { Item } from '@/@types/gallery';
68import LdLink from '@/components/LdLink.vue';
69import { useUiStore } from '@/store/uiStore';
70import { faAngleDoubleLeft, faArrowLeft, faFolder, faLevelUpAlt, faSearch } from '@fortawesome/free-solid-svg-icons';
71import { computedEager } from '@vueuse/shared';
72import { computed } from 'vue';
73import { useI18n } from 'vue-i18n';
74import { useRoute, useRouter } from 'vue-router';
75import LayoutCommandSort from './LayoutCommandSort.vue';
76
77const props = defineProps({
78 currentItemPath: { type: Array<Item>, required: true },
79});
80
81const { t } = useI18n();
82const route = useRoute();
83const router = useRouter();
84const uiStore = useUiStore();
85
86const commandToggleSearchPanelIcon = computed(() => uiStore.fullWidth ? faSearch : faAngleDoubleLeft);
87const isRoot = computedEager(() => props.currentItemPath.length <= 1 && !uiStore.searchMode);
88const parent = computed(() => {
89 if (uiStore.searchMode) return decodeURIComponent(route.path);
90 const ln = props.currentItemPath.length;
91 if (