aboutsummaryrefslogtreecommitdiff
path: root/viewer
diff options
context:
space:
mode:
authorpacien2022-10-30 17:40:33 +0100
committerpacien2022-10-30 21:15:01 +0100
commit12eb302bcc93405f81b676b1a29a9731a5fec9be (patch)
treea99329c14eda80e6262464bd6bb9c570e85b8941 /viewer
parentf864eeca506331c1dee2cd3f5f0df4fe806f303a (diff)
downloadldgallery-12eb302bcc93405f81b676b1a29a9731a5fec9be.tar.gz
viewer/command: add item download button
This adds a download button which allows the user to save the current item as a file. This is necessary because some item viewers do not expose a download option on their own. The download icon appears together with the other command buttons at the top-left corner of the screen, replacing the listing sorting menu which is only relevant for item lists (directory and search views). GitHub: closes #308
Diffstat (limited to 'viewer')
-rw-r--r--viewer/ldgallery-viewer.7.md1
-rw-r--r--viewer/src/locales/en.yml1
-rw-r--r--viewer/src/views/layout/top/LayoutCommand.vue46
-rw-r--r--viewer/src/views/layout/top/LayoutTop.vue5
4 files changed, 48 insertions, 5 deletions
diff --git a/viewer/ldgallery-viewer.7.md b/viewer/ldgallery-viewer.7.md
index 736f61f..46509fb 100644
--- a/viewer/ldgallery-viewer.7.md
+++ b/viewer/ldgallery-viewer.7.md
@@ -41,6 +41,7 @@ Items of the following formats can be opened and visualised within the web appli
41* PDFs 41* PDFs
42 42
43Formats which are not listed above or which are not supported by the user's web browser are offered for download instead of being directly displayed in the same window. 43Formats which are not listed above or which are not supported by the user's web browser are offered for download instead of being directly displayed in the same window.
44The item being visualised can be downloaded using the download button at the top-left corner.
44 45
45 46
46# KEYBOARD SHORTCUTS 47# KEYBOARD SHORTCUTS
diff --git a/viewer/src/locales/en.yml b/viewer/src/locales/en.yml
index acbe24b..86ecd49 100644
--- a/viewer/src/locales/en.yml
+++ b/viewer/src/locales/en.yml
@@ -1,6 +1,7 @@
1command: 1command:
2 back: Go back 2 back: Go back
3 parent: Go to parent directory 3 parent: Go to parent directory
4 download: Download
4 search: 5 search:
5 clear: Clear 6 clear: Clear
6 search: Search 7 search: Search
diff --git a/viewer/src/views/layout/top/LayoutCommand.vue b/viewer/src/views/layout/top/LayoutCommand.vue
index 8919da3..d930fd2 100644
--- a/viewer/src/views/layout/top/LayoutCommand.vue
+++ b/viewer/src/views/layout/top/LayoutCommand.vue
@@ -2,7 +2,7 @@
2-- pictures into a searchable web gallery. 2-- pictures into a searchable web gallery.
3-- 3--
4-- Copyright (C) 2019-2022 Guillaume FOUET 4-- Copyright (C) 2019-2022 Guillaume FOUET
5-- 2020 Pacien TRAN-GIRARD 5-- 2020-2022 Pacien TRAN-GIRARD
6-- 6--
7-- This program is free software: you can redistribute it and/or modify 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 8-- it under the terms of the GNU Affero General Public License as
@@ -33,7 +33,24 @@
33 size="lg" 33 size="lg"
34 /> 34 />
35 </LdLink> 35 </LdLink>
36 <LayoutCommandSort :tabindex="20" /> 36
37 <LayoutCommandSort
38 v-if="isListing"
39 :tabindex="20"
40 />
41 <a
42 v-else
43 :title="t('command.download')"
44 :download="itemFileName"
45 :href="itemResourceUrl"
46 :tabindex="20"
47 >
48 <fa-icon
49 :icon="faFileDownload"
50 size="lg"
51 />
52 </a>
53
37 <LdLink 54 <LdLink
38 :class="{ disabled: isEntryPoint(), [$style.commandSecondary]: true }" 55 :class="{ disabled: isEntryPoint(), [$style.commandSecondary]: true }"
39 :title="t('command.back')" 56 :title="t('command.back')"
@@ -67,21 +84,42 @@
67import { Item } from '@/@types/gallery'; 84import { Item } from '@/@types/gallery';
68import LdLink from '@/components/LdLink.vue'; 85import LdLink from '@/components/LdLink.vue';
69import { useUiStore } from '@/store/uiStore'; 86import { useUiStore } from '@/store/uiStore';
70import { faAngleDoubleLeft, faArrowLeft, faFolder, faLevelUpAlt, faSearch } from '@fortawesome/free-solid-svg-icons'; 87import { useGalleryStore } from '@/store/galleryStore';
88import { useNavigation } from '@/services/navigation';
89import { isDirectory, isDownloadableItem } from '@/services/itemGuards';
90import {
91 faAngleDoubleLeft,
92 faArrowLeft,
93 faFolder,
94 faLevelUpAlt,
95 faSearch,
96 faFileDownload,
97} from '@fortawesome/free-solid-svg-icons';
71import { computedEager } from '@vueuse/shared'; 98import { computedEager } from '@vueuse/shared';
72import { computed } from 'vue'; 99import { computed, PropType } from 'vue';
73import { useI18n } from 'vue-i18n'; 100import { useI18n } from 'vue-i18n';
74import { useRoute, useRouter } from 'vue-router'; 101import { useRoute, useRouter } from 'vue-router';
75import LayoutCommandSort from './LayoutCommandSort.vue'; 102import LayoutCommandSort from './LayoutCommandSort.vue';
76 103
77const props = defineProps({ 104const props = defineProps({
78 currentItemPath: { type: Array<Item>, required: true }, 105 currentItemPath: { type: Array<Item>, required: true },
106 item: { type: Object as PropType<Item>, required: true },
79}); 107});
80 108
81const { t } = useI18n(); 109const { t } = useI18n();
82const route = useRoute(); 110const route = useRoute();
83const router = useRouter(); 111const router = useRouter();
84const uiStore = useUiStore(); 112const uiStore = useUiStore();
113const galleryStore = useGalleryStore();
114const navigation = useNavigation();
115
116const isListing = computedEager(() => !props.item || isDirectory(props.item));
117const itemFileName = computed(() => navigation.getFileName(props.item));
118const itemResourceUrl = computed(() =>
119 isDownloadableItem(props.item)
120 ? galleryStore.resourceRoot + props.item.properties.resource
121 : '',
122);
85 123
86const commandToggleSearchPanelIcon = computed(() => uiStore.fullWidth ? faSearch : faAngleDoubleLeft); 124const commandToggleSearchPanelIcon = computed(() => uiStore.fullWidth ? faSearch : faAngleDoubleLeft);
87const isRoot = computedEager(() => props.currentItemPath.length <= 1 && !uiStore.searchMode); 125const isRoot = computedEager(() => props.currentItemPath.length <= 1 && !uiStore.searchMode);
diff --git a/viewer/src/views/layout/top/LayoutTop.vue b/viewer/src/views/layout/top/LayoutTop.vue
index b755c42..0362840 100644
--- a/viewer/src/views/layout/top/LayoutTop.vue
+++ b/viewer/src/views/layout/top/LayoutTop.vue
@@ -19,7 +19,10 @@
19 19
20<template> 20<template>
21 <div class="flex"> 21 <div class="flex">
22 <LayoutCommand :current-item-path="galleryStore.currentItemPath" /> 22 <LayoutCommand
23 :current-item-path="galleryStore.currentItemPath"
24 :item="galleryStore.currentItem"
25 />
23 <LayoutBreadcrumb 26 <LayoutBreadcrumb
24 :current-item-path="galleryStore.currentItemPath" 27 :current-item-path="galleryStore.currentItemPath"
25 :search-mode="uiStore.searchMode" 28 :search-mode="uiStore.searchMode"