web/satellite/vuetify-poc: add keyboard controls for gallery view

Added mappings for left/right arrow keys and escape in gallery view.

Issue:
https://github.com/storj/storj/issues/6424

Change-Id: I995060dcee6a3c4b3f05f28415c81f83f6fe89c3
This commit is contained in:
Vitalii 2023-10-23 18:16:52 +03:00 committed by Storj Robot
parent fe9afad8cd
commit c79629e4da

View File

@ -2,7 +2,14 @@
// See LICENSE for copying information. // See LICENSE for copying information.
<template> <template>
<v-dialog v-model="model" transition="fade-transition" class="preview-dialog" fullscreen theme="dark" persistent no-click-animation> <v-dialog
v-model="model"
transition="fade-transition"
class="preview-dialog"
fullscreen
theme="dark"
no-click-animation
>
<v-card class="preview-card"> <v-card class="preview-card">
<v-toolbar <v-toolbar
color="rgba(0, 0, 0, 0.3)" color="rgba(0, 0, 0, 0.3)"
@ -60,7 +67,16 @@
</template> </template>
</v-toolbar> </v-toolbar>
<div class="flex-grow-1"> <div class="flex-grow-1">
<v-carousel v-model="constCarouselIndex" hide-delimiters show-arrows="hover" class="h-100"> <v-carousel
ref="carousel"
v-model="constCarouselIndex"
tabindex="0"
hide-delimiters
show-arrows="hover"
class="h-100 no-outline"
@keydown.right="onNext"
@keydown.left="onPrevious"
>
<template #prev> <template #prev>
<v-btn <v-btn
v-if="files.length > 1" v-if="files.length > 1"
@ -100,7 +116,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, h, ref, watch } from 'vue'; import { computed, h, nextTick, ref, watch } from 'vue';
import { import {
VBtn, VBtn,
VCard, VCard,
@ -128,6 +144,7 @@ const obStore = useObjectBrowserStore();
const bucketsStore = useBucketsStore(); const bucketsStore = useBucketsStore();
const notify = useNotify(); const notify = useNotify();
const carousel = ref<VCarousel | null>(null);
const isDownloading = ref<boolean>(false); const isDownloading = ref<boolean>(false);
const isShareDialogShown = ref<boolean>(false); const isShareDialogShown = ref<boolean>(false);
const isGeographicDistributionDialogShown = ref<boolean>(false); const isGeographicDistributionDialogShown = ref<boolean>(false);
@ -257,6 +274,14 @@ function setNewObjectPath(objectKey: string): void {
obStore.setObjectPathForModal(`${currentPath.value}${objectKey}`); obStore.setObjectPathForModal(`${currentPath.value}${objectKey}`);
} }
/**
* Sets focus on carousel so that keyboard navigation works.
*/
async function focusOnCarousel(): Promise<void> {
await nextTick();
carousel.value?.$el.focus();
}
/** /**
* Watch for changes on the filepath and changes the current carousel item accordingly. * Watch for changes on the filepath and changes the current carousel item accordingly.
*/ */
@ -266,10 +291,34 @@ watch(filePath, () => {
carouselIndex.value = fileIndex.value; carouselIndex.value = fileIndex.value;
}); });
watch(() => props.modelValue, shown => { watch(() => props.modelValue, async (shown) => {
if (!shown) { if (!shown) {
return; return;
} }
carouselIndex.value = fileIndex.value; carouselIndex.value = fileIndex.value;
await focusOnCarousel();
}, { immediate: true }); }, { immediate: true });
watch(isShareDialogShown, async () => {
if (isShareDialogShown.value) {
return;
}
await focusOnCarousel();
});
watch(isGeographicDistributionDialogShown, async () => {
if (isGeographicDistributionDialogShown.value) {
return;
}
await focusOnCarousel();
});
</script> </script>
<style scoped lang="scss">
.no-outline {
outline: none;
}
</style>