Merge branch 'WarehouseShippingNote/update-tablet-view' into 'master'
added new logout button and fixed pdf viewing See merge request fronk/thetool!1639
This commit is contained in:
@@ -608,7 +608,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
top: '10px',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
zIndex: '10000',
|
||||
zIndex: '98',
|
||||
padding: '8px 16px',
|
||||
backgroundColor: '#f44336',
|
||||
color: 'white',
|
||||
@@ -630,7 +630,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
console.error('Logout request failed:', error);
|
||||
window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.');
|
||||
} finally {
|
||||
setTimeout(() => window.location.reload(), 1000);
|
||||
setTimeout(() => window.location.reload(), 400);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
Vue.component('tt-fullscreen-viewer', {
|
||||
props: {
|
||||
item: {type: Object, required: true},
|
||||
url: {type: String, default: null},
|
||||
items: {type: Array, default: () => []},
|
||||
initialIndex: {type: Number, default: -1},
|
||||
item: { type: Object, required: true },
|
||||
url: { type: String, default: null },
|
||||
items: { type: Array, default: () => [] },
|
||||
initialIndex: { type: Number, default: -1 },
|
||||
},
|
||||
data: () => ({
|
||||
currentItem: null,
|
||||
currentImageIndex: -1,
|
||||
zoom: 1,
|
||||
pan: {x: 0, y: 0},
|
||||
pan: { x: 0, y: 0 },
|
||||
isPanning: false,
|
||||
panStart: {x: 0, y: 0},
|
||||
panStart: { x: 0, y: 0 },
|
||||
lastPinchDist: 0,
|
||||
// NEW: State to track if the content is loading
|
||||
isLoading: true,
|
||||
// NEW: Flag to determine if running as a PWA/standalone app
|
||||
isStandalone: false,
|
||||
}),
|
||||
computed: {
|
||||
contentSrc() {
|
||||
@@ -40,6 +41,16 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
return this.currentItem?.fileId ? `/File/download?id=${this.currentItem.fileId}` : '#';
|
||||
}
|
||||
},
|
||||
// NEW: Watcher to trigger PDF.js rendering when item changes in standalone mode
|
||||
watch: {
|
||||
currentItem(newItem) {
|
||||
if (this.isPdf(newItem) && this.isStandalone) {
|
||||
this.$nextTick(() => {
|
||||
this.renderPdfWithJs(this.contentSrc);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isImage: file => file?.mimetype?.startsWith('image/'),
|
||||
isPdf: file => file?.mimetype === 'application/pdf',
|
||||
@@ -52,7 +63,6 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
navigateImage(direction) {
|
||||
const newIndex = this.currentImageIndex + direction;
|
||||
if (newIndex >= 0 && newIndex < this.items.length) {
|
||||
// NEW: Reset loading state before loading the new image
|
||||
this.isLoading = true;
|
||||
this.currentImageIndex = newIndex;
|
||||
this.currentItem = this.items[newIndex];
|
||||
@@ -63,20 +73,14 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
e.stopPropagation();
|
||||
if (!this.currentItem) return;
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
this.closeViewer();
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
this.isViewingImage && this.navigateImage(-1);
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
this.isViewingImage && this.navigateImage(1);
|
||||
break;
|
||||
case 'Escape': this.closeViewer(); break;
|
||||
case 'ArrowLeft': this.isViewingImage && this.navigateImage(-1); break;
|
||||
case 'ArrowRight': this.isViewingImage && this.navigateImage(1); break;
|
||||
}
|
||||
},
|
||||
resetZoomAndPan() {
|
||||
this.zoom = 1;
|
||||
this.pan = {x: 0, y: 0};
|
||||
this.pan = { x: 0, y: 0 };
|
||||
this.isPanning = false;
|
||||
},
|
||||
handleWheel(e) {
|
||||
@@ -103,14 +107,86 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
onTouchStart(e) {},
|
||||
onTouchMove(e) {},
|
||||
onTouchEnd(e) {},
|
||||
|
||||
// NEW: Method to dynamically load the PDF.js library
|
||||
loadPdfJsScript() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (document.getElementById('pdfjs-script')) {
|
||||
// Script tag exists, check if library is loaded
|
||||
if (window.pdfjsLib) {
|
||||
resolve();
|
||||
} else {
|
||||
// Tag exists but script not loaded yet, wait for it
|
||||
document.getElementById('pdfjs-script').addEventListener('load', () => resolve());
|
||||
document.getElementById('pdfjs-script').addEventListener('error', (e) => reject(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.id = 'pdfjs-script';
|
||||
script.src = 'https://mozilla.github.io/pdf.js/build/pdf.js'; // CDN URL
|
||||
script.onload = () => resolve();
|
||||
script.onerror = (err) => {
|
||||
console.error("Failed to load PDF.js script.", err);
|
||||
reject(new Error("PDF.js script could not be loaded."));
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
},
|
||||
|
||||
// NEW: Method to render PDF onto a canvas using PDF.js
|
||||
async renderPdfWithJs(url) {
|
||||
if (!url) return;
|
||||
this.isLoading = true;
|
||||
|
||||
try {
|
||||
await this.loadPdfJsScript();
|
||||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.js';
|
||||
|
||||
const pdf = await pdfjsLib.getDocument(url).promise;
|
||||
// For simplicity, we render the first page. Add pagination controls as needed.
|
||||
const page = await pdf.getPage(1);
|
||||
|
||||
const canvas = this.$refs.pdfCanvas;
|
||||
if (!canvas) return; // Exit if canvas is not available
|
||||
|
||||
const context = canvas.getContext('2d');
|
||||
const viewport = page.getViewport({ scale: 1.5 });
|
||||
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
await page.render({ canvasContext: context, viewport: viewport }).promise;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error rendering PDF with PDF.js:', error);
|
||||
// Optionally show an error message to the user
|
||||
} finally {
|
||||
this.onContentLoad(); // Use existing method to hide loader
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.currentItem = this.item;
|
||||
this.currentImageIndex = this.initialIndex;
|
||||
|
||||
// NEW: Check for standalone mode on component creation
|
||||
if (typeof window !== 'undefined' && window.matchMedia) {
|
||||
this.isStandalone = window.matchMedia('(display-mode: standalone)').matches;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.body.style.overflow = 'hidden';
|
||||
this.$nextTick(() => this.$refs.viewer?.focus());
|
||||
this.$nextTick(() => {
|
||||
this.$refs.viewer?.focus();
|
||||
|
||||
// NEW: Trigger initial PDF render on mount if in standalone mode
|
||||
if (this.isPdf(this.currentItem) && this.isStandalone) {
|
||||
this.renderPdfWithJs(this.contentSrc);
|
||||
}
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.body.style.overflow = '';
|
||||
@@ -119,8 +195,7 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
template: `
|
||||
<div class="tt-fullscreen-overlay" @click.self="closeViewer" @keydown="handleKeyDown" tabindex="-1" ref="viewer">
|
||||
<div class="tt-fullscreen-toolbar">
|
||||
<a v-if="isViewingImage && currentItem.fileId" :href="downloadUrl" download class="tt-fullscreen-btn"
|
||||
title="Download">
|
||||
<a v-if="currentItem.fileId" :href="downloadUrl" download class="tt-fullscreen-btn" title="Download">
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
<button class="tt-fullscreen-btn" @click="closeViewer" title="Close"><i class="fas fa-times"></i></button>
|
||||
@@ -129,14 +204,11 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
<div class="tt-fullscreen-content" @click.self="closeViewer">
|
||||
<div v-if="isLoading" class="tt-fullscreen-loader">
|
||||
<svg version="1.1" id="L9" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve"
|
||||
style="width: 80px; height: 80px;">
|
||||
<path fill="#fff" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">
|
||||
</path>
|
||||
viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve" style="width: 80px; height: 80px;">
|
||||
<path fill="#fff" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
|
||||
<template v-if="isViewingImage">
|
||||
<div class="tt-fullscreen-image-wrapper" @wheel="handleWheel" @mousedown="onPanStart" @mousemove="onPanMove"
|
||||
@mouseup="onPanEnd" @mouseleave="onPanEnd">
|
||||
@@ -145,6 +217,10 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-else-if="isPdf(currentItem) && isStandalone" v-show="!isLoading" class="tt-fullscreen-pdf-container">
|
||||
<canvas ref="pdfCanvas" class="tt-fullscreen-pdf"></canvas>
|
||||
</div>
|
||||
|
||||
<iframe v-else-if="isPdf(currentItem)" v-show="!isLoading" :src="contentSrc" class="tt-fullscreen-pdf"
|
||||
@load="onContentLoad" @error="onContentLoad" @click.stop></iframe>
|
||||
</div>
|
||||
@@ -153,18 +229,12 @@ Vue.component('tt-fullscreen-viewer', {
|
||||
<button class="tt-fullscreen-nav-btn left" @click.stop="navigateImage(-1)" v-if="currentImageIndex > 0">
|
||||
<i class="fas fa-chevron-left"></i>
|
||||
</button>
|
||||
<button class="tt-fullscreen-nav-btn right" @click.stop="navigateImage(1)"
|
||||
v-if="currentImageIndex < items.length - 1">
|
||||
<button class="tt-fullscreen-nav-btn right" @click.stop="navigateImage(1)" v-if="currentImageIndex < items.length - 1">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</button>
|
||||
</template>
|
||||
</div>`,
|
||||
});
|
||||
|
||||
// You can add this style to your main CSS file or a <style> tag in the component file
|
||||
/*
|
||||
|
||||
*/
|
||||
})
|
||||
|
||||
Vue.component('tt-file-gallery', {
|
||||
props: {
|
||||
|
||||
Reference in New Issue
Block a user