Merge branch '608-for-pdf-file-types-show-inline-dont-download' into 'dev'
For PDF file types, show inline, don't download in mobile or tablet See merge request keanuapp/keanuapp-weblite!359
This commit is contained in:
commit
4b1356b674
3 changed files with 359 additions and 8696 deletions
8947
package-lock.json
generated
8947
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -45,6 +45,7 @@
|
|||
"vue-3-sanitize": "^0.1.4",
|
||||
"vue-clipboard2": "^0.3.3",
|
||||
"vue-i18n": "^11.1.3",
|
||||
"vue-pdf-embed": "^2.1.3",
|
||||
"vue-router": "^4.5.1",
|
||||
"vue-swipeable-bottom-sheet": "^0.0.5",
|
||||
"vue3-emoji-picker": "^1.1.8",
|
||||
|
|
|
|||
|
|
@ -8,21 +8,47 @@
|
|||
</div>
|
||||
|
||||
<div class="message">
|
||||
<ThumbnailView class="clickable" v-on:itemclick="onDownload" :item="attachment" />
|
||||
<ThumbnailView class="clickable" v-on:itemclick="onItemClicked" :item="attachment" />
|
||||
<span class="edit-marker" v-if="event?.replacingEventId()">{{ $t("message.edited") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<v-dialog v-model="showPdfDialog" fullscreen v-if="util.isMobileOrTabletBrowser()">
|
||||
<v-card>
|
||||
<v-toolbar :elevation="2" density="compact" class="position-fixed pdf-header" color="black">
|
||||
<v-btn
|
||||
icon="arrow_back"
|
||||
@click="showPdfDialog = false"
|
||||
></v-btn>
|
||||
<v-toolbar-title>{{ attachment.name }}</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
<div class="pdf-container">
|
||||
<div
|
||||
v-for="(pageNum, index) in pageNums"
|
||||
:key="pageNum"
|
||||
:ref="(el) => { if (el) pageRefs[index] = el }"
|
||||
>
|
||||
<vue-pdf-embed
|
||||
v-if="pageVisibility[pageNum]"
|
||||
:source="doc"
|
||||
:page="pageNum"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, ref, Ref } from "vue";
|
||||
import { computed, inject, ref, Ref, nextTick, watch, onBeforeUnmount } from "vue";
|
||||
import MessageIncoming from "./MessageIncoming.vue";
|
||||
import MessageOutgoing from "./MessageOutgoing.vue";
|
||||
import ThumbnailView from "../../file_mode/ThumbnailView.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { MessageProps, useMessage } from "./useMessage";
|
||||
import { KeanuEvent } from "../../../models/eventAttachment";
|
||||
import VuePdfEmbed, { useVuePdfEmbed } from 'vue-pdf-embed'
|
||||
import util from "@/plugins/utils";
|
||||
|
||||
const { t } = useI18n();
|
||||
const $matrix: any = inject("globalMatrix");
|
||||
|
|
@ -45,11 +71,84 @@ const rootComponent = computed(() => {
|
|||
return isIncoming.value ? MessageIncoming : MessageOutgoing;
|
||||
});
|
||||
|
||||
const onDownload = () => {
|
||||
emits("download", event.value);
|
||||
const onItemClicked = () => {
|
||||
if(util.isMobileOrTabletBrowser()) {
|
||||
showPdfDialog.value = true
|
||||
} else {
|
||||
emits("download", event.value);
|
||||
}
|
||||
};
|
||||
|
||||
const showPdfDialog = ref(false)
|
||||
const pageRefs = ref([]);
|
||||
const pageVisibility = ref({});
|
||||
let pageIntersectionObserver = null;
|
||||
const pdfSource = ref(null);
|
||||
|
||||
const { doc } = useVuePdfEmbed({
|
||||
source: pdfSource,
|
||||
});
|
||||
|
||||
const pageNums = computed(() =>
|
||||
doc.value ? [...Array(doc.value.numPages + 1).keys()].slice(1) : []
|
||||
);
|
||||
|
||||
const resetPageIntersectionObserver = () => {
|
||||
if(!util.isMobileOrTabletBrowser()) return
|
||||
pageIntersectionObserver?.disconnect()
|
||||
pageIntersectionObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const index = pageRefs.value.findIndex((el) => el === entry.target)
|
||||
if (index !== -1) {
|
||||
const pageNum = pageNums.value[index]
|
||||
pageVisibility.value[pageNum] = true
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
pageRefs.value.forEach((element) => {
|
||||
if (element) pageIntersectionObserver.observe(element)
|
||||
})
|
||||
};
|
||||
|
||||
watch(pageNums, (newPageNums) => {
|
||||
if(!util.isMobileOrTabletBrowser()) return
|
||||
pageVisibility.value = { [newPageNums[0]]: true }
|
||||
pageRefs.value = []
|
||||
nextTick(resetPageIntersectionObserver)
|
||||
});
|
||||
|
||||
watch(showPdfDialog, (pdfViewerShown) => {
|
||||
if(!util.isMobileOrTabletBrowser()) return
|
||||
if(pdfViewerShown && !pdfSource.value) {
|
||||
pdfSource.value = attachment.value.src
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
pageIntersectionObserver?.disconnect()
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@/assets/css/chat.scss" as *;
|
||||
.pdf-header {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.pdf-container {
|
||||
padding: 24px 16px;
|
||||
|
||||
& > * {
|
||||
margin: 30px auto 0 auto;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.vue-pdf-embed {
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue