akkoma-fe/src/components/media_modal/media_modal.vue

288 lines
6.1 KiB
Vue
Raw Normal View History

<template>
<Modal
2019-07-05 07:17:44 +00:00
v-if="showing"
class="media-modal-view"
@backdropClicked="hideIfNotSwiped"
2019-07-05 07:17:44 +00:00
>
<SwipeClick
v-if="type === 'image'"
ref="swipeClick"
class="modal-image-container"
:direction="swipeDirection"
:threshold="swipeThreshold"
@preview-requested="handleSwipePreview"
@swipe-finished="handleSwipeEnd"
@swipeless-clicked="hide"
>
<PinchZoom
ref="pinchZoom"
class="modal-image-container-inner"
selector=".modal-image"
reach-min-scale-strategy="reset"
stop-propagate-handled="stop-propgate-handled"
2021-08-02 23:21:18 +00:00
:allow-pan-min-scale="pinchZoomMinScale"
:min-scale="pinchZoomMinScale"
:reset-to-min-scale-limit="pinchZoomScaleResetLimit"
>
<img
:class="{ loading }"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
@load="onImageLoaded"
>
</PinchZoom>
</SwipeClick>
2019-07-05 07:17:44 +00:00
<VideoAttachment
v-if="type === 'video'"
2019-07-05 07:17:44 +00:00
class="modal-image"
2019-01-26 15:45:03 +00:00
:attachment="currentMedia"
:controls="true"
2019-07-05 07:17:44 +00:00
/>
<audio
v-if="type === 'audio'"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
controls
/>
<Flash
v-if="type === 'flash'"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
/>
2019-02-19 16:33:40 +00:00
<button
2019-07-05 07:17:44 +00:00
v-if="canNavigate"
2019-02-19 16:33:40 +00:00
:title="$t('media_modal.previous')"
2022-03-03 17:51:13 +00:00
class="modal-view-button modal-view-button-arrow modal-view-button-arrow--prev"
2019-02-19 16:33:40 +00:00
@click.stop.prevent="goPrev"
>
2020-10-20 21:31:16 +00:00
<FAIcon
2022-03-03 17:51:13 +00:00
class="button-icon arrow-icon"
2020-10-20 21:31:16 +00:00
icon="chevron-left"
/>
2019-02-19 16:33:40 +00:00
</button>
<button
2019-07-05 07:17:44 +00:00
v-if="canNavigate"
2019-02-19 16:33:40 +00:00
:title="$t('media_modal.next')"
2022-03-03 17:51:13 +00:00
class="modal-view-button modal-view-button-arrow modal-view-button-arrow--next"
2019-02-19 16:33:40 +00:00
@click.stop.prevent="goNext"
>
2020-10-20 21:31:16 +00:00
<FAIcon
2022-03-03 17:51:13 +00:00
class="button-icon arrow-icon"
2020-10-20 21:31:16 +00:00
icon="chevron-right"
/>
2019-02-19 16:33:40 +00:00
</button>
2022-03-03 17:51:13 +00:00
<button
class="modal-view-button modal-view-button-hide"
:title="$t('media_modal.hide')"
@click.stop.prevent="hide"
>
<FAIcon
class="button-icon"
icon="times"
/>
</button>
2021-08-15 16:45:48 +00:00
<span
v-if="description"
class="description"
>
{{ description }}
</span>
2021-08-15 22:11:16 +00:00
<span
class="counter"
>
{{ $tc('media_modal.counter', currentIndex + 1, { current: currentIndex + 1, total: media.length }) }}
2021-08-15 22:11:16 +00:00
</span>
2021-08-15 22:02:56 +00:00
<span
v-if="loading"
class="loading-spinner"
>
<FAIcon
spin
icon="circle-notch"
size="5x"
/>
</span>
</Modal>
</template>
<script src="./media_modal.js"></script>
<style lang="scss">
2022-03-06 23:38:57 +00:00
$modal-view-button-icon-height: 3em;
$modal-view-button-icon-half-height: calc(#{$modal-view-button-icon-height} / 2);
$modal-view-button-icon-width: 3em;
$modal-view-button-icon-margin: 0.5em;
2022-03-03 17:51:13 +00:00
2019-10-18 16:13:11 +00:00
.modal-view.media-modal-view {
z-index: 9000;
2021-08-15 16:45:48 +00:00
flex-direction: column;
2022-03-03 17:51:13 +00:00
.modal-view-button-arrow,
.modal-view-button-hide {
opacity: 0.75;
2019-02-10 18:26:08 +00:00
&:focus,
&:hover {
outline: none;
box-shadow: none;
}
2021-08-15 22:02:56 +00:00
&:hover {
opacity: 1;
}
2019-02-19 16:33:40 +00:00
}
overflow: hidden;
2019-02-19 16:33:40 +00:00
}
2021-08-15 16:45:48 +00:00
.media-modal-view {
@keyframes media-fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
2022-02-21 03:02:31 +00:00
.modal-image-container {
display: flex;
overflow: hidden;
align-items: center;
flex-direction: column;
2022-03-03 17:51:13 +00:00
max-width: 100%;
max-height: 100%;
width: 100%;
height: 100%;
flex-grow: 1;
justify-content: center;
2022-02-21 03:02:31 +00:00
&-inner {
width: 100%;
height: 100%;
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
2021-08-15 22:11:16 +00:00
.description,
.counter {
/* Hardcoded since background is also hardcoded */
2021-08-15 16:45:48 +00:00
color: white;
margin-top: 1em;
text-shadow: 0 0 10px black, 0 0 10px black;
2021-08-15 22:11:16 +00:00
padding: 0.2em 2em;
}
.description {
flex: 0 0 auto;
overflow-y: auto;
min-height: 1em;
2021-08-15 16:45:48 +00:00
max-width: 500px;
max-height: 9.5em;
2021-08-15 22:11:16 +00:00
word-break: break-all;
2021-08-15 16:45:48 +00:00
}
2021-08-15 16:45:48 +00:00
.modal-image {
2022-02-21 03:02:31 +00:00
max-width: 100%;
max-height: 100%;
2021-08-15 16:45:48 +00:00
image-orientation: from-image; // NOTE: only FF supports this
animation: 0.1s cubic-bezier(0.7, 0, 1, 0.6) media-fadein;
2021-08-15 22:02:56 +00:00
&.loading {
opacity: 0.5;
}
}
.loading-spinner {
width: 100%;
height: 100%;
position: absolute;
pointer-events: none;
display: flex;
justify-content: center;
align-items: center;
2021-08-15 22:11:16 +00:00
2021-08-15 22:02:56 +00:00
svg {
color: white;
}
2021-08-15 16:45:48 +00:00
}
2019-02-19 16:33:40 +00:00
2022-03-03 17:51:13 +00:00
.modal-view-button {
2021-08-15 16:45:48 +00:00
border: 0;
padding: 0;
opacity: 0;
box-shadow: none;
background: none;
appearance: none;
overflow: visible;
cursor: pointer;
transition: opacity 333ms cubic-bezier(.4,0,.22,1);
2022-03-06 23:38:57 +00:00
height: $modal-view-button-icon-height;
width: $modal-view-button-icon-width;
2019-02-19 16:33:40 +00:00
2022-03-03 17:51:13 +00:00
.button-icon {
position: absolute;
height: $modal-view-button-icon-height;
width: $modal-view-button-icon-width;
font-size: 14px;
line-height: $modal-view-button-icon-height;
color: #FFF;
text-align: center;
background-color: rgba(0,0,0,.3);
}
}
.modal-view-button-arrow {
position: absolute;
display: block;
top: 50%;
2022-03-06 23:38:57 +00:00
margin-top: $modal-view-button-icon-half-height;
width: $modal-view-button-icon-width;
height: $modal-view-button-icon-height;
2022-03-03 17:51:13 +00:00
2019-02-19 16:33:40 +00:00
.arrow-icon {
2021-08-15 16:45:48 +00:00
position: absolute;
2022-03-06 23:38:57 +00:00
top: 0;
line-height: $modal-view-button-icon-height;
2021-08-15 16:45:48 +00:00
color: #FFF;
text-align: center;
background-color: rgba(0,0,0,.3);
}
2021-08-15 16:45:48 +00:00
&--prev {
left: 0;
.arrow-icon {
2022-03-03 17:51:13 +00:00
left: $modal-view-button-icon-margin;
2021-08-15 16:45:48 +00:00
}
}
&--next {
right: 0;
.arrow-icon {
2022-03-03 17:51:13 +00:00
right: $modal-view-button-icon-margin;
2021-08-15 16:45:48 +00:00
}
}
}
2022-03-03 17:51:13 +00:00
.modal-view-button-hide {
position: absolute;
top: 0;
right: 0;
.button-icon {
top: $modal-view-button-icon-margin;
right: $modal-view-button-icon-margin;
}
}
}
</style>