mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-05-13 17:55:56 +00:00
Reshape multitool U
Replace MultiToolFile input with common file input
This commit is contained in:
parent
99c4003b20
commit
695025ba13
@ -14,26 +14,30 @@ label {
|
|||||||
border-radius: 16px !important;
|
border-radius: 16px !important;
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
border: 1px solid var(--theme-color-outline-variant);
|
border: 1px solid var(--theme-color-outline-variant);
|
||||||
|
flex-grow: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-action-bar {
|
.mt-action-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
background-color: var(--md-sys-color-surface-5);
|
|
||||||
border: none;
|
border: none;
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
top: 10px;
|
top: 10px;
|
||||||
z-index: 10;
|
z-index: 11;
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
border-radius: 2rem;
|
border-radius: 2rem;
|
||||||
margin: 0px 25px;
|
margin: 0px 25px;
|
||||||
|
justify-content:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.mt-action-bar>* {
|
.mt-action-bar>* {
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.mt-file-uploader {
|
||||||
|
width:100%
|
||||||
|
}
|
||||||
.mt-action-bar svg,
|
.mt-action-bar svg,
|
||||||
.mt-action-btn svg {
|
.mt-action-btn svg {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
@ -42,16 +46,22 @@ label {
|
|||||||
|
|
||||||
.mt-action-bar .mt-filename {
|
.mt-action-bar .mt-filename {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-action-btn {
|
.mt-action-btn {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 8%;
|
||||||
|
background-color: var(--md-sys-color-surface-container-low) ;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
align-items: start;
|
z-index: 12;
|
||||||
top: 10px;
|
|
||||||
z-index: 10;
|
|
||||||
padding: 12px 0px 0px;
|
padding: 12px 0px 0px;
|
||||||
width: 100%;
|
width: fit-content;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 2rem;
|
||||||
|
padding: 10px 20px
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-action-btn .btn {
|
.mt-action-btn .btn {
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
class FileDragManager {
|
|
||||||
overlay;
|
|
||||||
dragCounter;
|
|
||||||
updateFilename;
|
|
||||||
|
|
||||||
constructor(cb = null) {
|
|
||||||
this.dragCounter = 0;
|
|
||||||
this.setCallback(cb);
|
|
||||||
|
|
||||||
// Prevent default behavior for drag events
|
|
||||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
|
|
||||||
document.body.addEventListener(eventName, preventDefaults, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
function preventDefaults(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dragenterListener = this.dragenterListener.bind(this);
|
|
||||||
this.dragleaveListener = this.dragleaveListener.bind(this);
|
|
||||||
this.dropListener = this.dropListener.bind(this);
|
|
||||||
|
|
||||||
document.body.addEventListener('dragenter', this.dragenterListener);
|
|
||||||
document.body.addEventListener('dragleave', this.dragleaveListener);
|
|
||||||
// Add drop event listener
|
|
||||||
document.body.addEventListener('drop', this.dropListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
setActions({updateFilename}) {
|
|
||||||
this.updateFilename = updateFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCallback(cb) {
|
|
||||||
if (cb) {
|
|
||||||
this.callback = cb;
|
|
||||||
} else {
|
|
||||||
this.callback = (files) => console.warn('FileDragManager not set');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dragenterListener() {
|
|
||||||
this.dragCounter++;
|
|
||||||
if (!this.overlay) {
|
|
||||||
// Create and show the overlay
|
|
||||||
this.overlay = document.createElement('div');
|
|
||||||
this.overlay.style.position = 'fixed';
|
|
||||||
this.overlay.style.top = 0;
|
|
||||||
this.overlay.style.left = 0;
|
|
||||||
this.overlay.style.width = '100%';
|
|
||||||
this.overlay.style.height = '100%';
|
|
||||||
this.overlay.style.background = 'rgba(0, 0, 0, 0.5)';
|
|
||||||
this.overlay.style.color = '#fff';
|
|
||||||
this.overlay.style.zIndex = '1000';
|
|
||||||
this.overlay.style.display = 'flex';
|
|
||||||
this.overlay.style.alignItems = 'center';
|
|
||||||
this.overlay.style.justifyContent = 'center';
|
|
||||||
this.overlay.style.pointerEvents = 'none';
|
|
||||||
this.overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
|
|
||||||
document.getElementById('content-wrap').appendChild(this.overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dragleaveListener() {
|
|
||||||
this.dragCounter--;
|
|
||||||
if (this.dragCounter === 0) {
|
|
||||||
// Hide and remove the overlay
|
|
||||||
if (this.overlay) {
|
|
||||||
this.overlay.remove();
|
|
||||||
this.overlay = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dropListener(e) {
|
|
||||||
const dt = e.dataTransfer;
|
|
||||||
const files = dt.files;
|
|
||||||
this.callback(files)
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
//maybe
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
// Hide and remove the overlay
|
|
||||||
if (this.overlay) {
|
|
||||||
this.overlay.remove();
|
|
||||||
this.overlay = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateFilename(files ? files[0].name : '');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async addImageFile(file, nextSiblingElement) {
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.classList.add('page-container');
|
|
||||||
|
|
||||||
var img = document.createElement('img');
|
|
||||||
img.classList.add('page-image');
|
|
||||||
img.src = URL.createObjectURL(file);
|
|
||||||
div.appendChild(img);
|
|
||||||
|
|
||||||
this.pdfAdapters.forEach((adapter) => {
|
|
||||||
adapter.adapt?.(div);
|
|
||||||
});
|
|
||||||
if (nextSiblingElement) {
|
|
||||||
this.pagesContainer.insertBefore(div, nextSiblingElement);
|
|
||||||
} else {
|
|
||||||
this.pagesContainer.appendChild(div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FileDragManager;
|
|
@ -14,22 +14,18 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="bg-card">
|
|
||||||
<div class="tool-header">
|
|
||||||
<span class="material-symbols-rounded tool-header-icon advance">construction</span>
|
|
||||||
<span class="tool-header-text" th:text="#{multiTool.header}"></span>
|
|
||||||
</div>
|
|
||||||
<div class="mt-action-bar d-flex flex-wrap">
|
|
||||||
<div class="mt-filename">
|
|
||||||
<label for="filename-input" th:text="#{multiTool.uploadPrompts}">Filename</label>
|
|
||||||
<input type="text" class="form-control" id="filename-input"
|
|
||||||
th:placeholder="#{multiTool.uploadPrompts}">
|
|
||||||
</div>
|
|
||||||
<div class="mt-action-btn">
|
<div class="mt-action-btn">
|
||||||
<button class="btn btn-primary" th:title="#{multiTool.addFile}" onclick="addFiles()">
|
<button id="undo-btn" th:title="#{multiTool.undo}" class="btn btn-secondary" onclick="undo()"
|
||||||
|
disabled>
|
||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
add
|
undo
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button id="redo-btn" class="btn btn-secondary" th:title="#{multiTool.redo}" onclick="redo()"
|
||||||
|
disabled>
|
||||||
|
<span class="material-symbols-rounded">
|
||||||
|
redo
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateLeft}"
|
<button class="btn btn-secondary enable-on-file" th:title="#{multiTool.rotateLeft}"
|
||||||
@ -56,20 +52,7 @@
|
|||||||
insert_page_break
|
insert_page_break
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button id="undo-btn" th:title="#{multiTool.undo}" class="btn btn-secondary" onclick="undo()"
|
|
||||||
disabled>
|
|
||||||
<span class="material-symbols-rounded">
|
|
||||||
undo
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="redo-btn" class="btn btn-secondary" th:title="#{multiTool.redo}" onclick="redo()"
|
|
||||||
disabled>
|
|
||||||
<span class="material-symbols-rounded">
|
|
||||||
redo
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="select-pages-container" th:title="#{multiTool.selectPages}"
|
<button id="select-pages-container" th:title="#{multiTool.selectPages}"
|
||||||
class="btn btn-secondary enable-on-file" onclick="toggleSelectPageVisibility()" disabled>
|
class="btn btn-secondary enable-on-file" onclick="toggleSelectPageVisibility()" disabled>
|
||||||
@ -91,7 +74,18 @@
|
|||||||
<span class="material-symbols-rounded">delete</span>
|
<span class="material-symbols-rounded">delete</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left:auto">
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="bg-card">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon advance">construction</span>
|
||||||
|
<span class="tool-header-text" th:text="#{multiTool.header}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-action-bar d-flex flex-wrap">
|
||||||
|
<div class="mt-filename">
|
||||||
|
<input type="text" class="form-control" id="filename-input"
|
||||||
|
th:placeholder="#{multiTool.uploadPrompts}">
|
||||||
|
|
||||||
<button id="export-selected-button" th:title="#{multiTool.downloadSelected}"
|
<button id="export-selected-button" th:title="#{multiTool.downloadSelected}"
|
||||||
style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||||
class="btn btn-primary enable-on-file hidden" onclick="exportPdf(true)" disabled>
|
class="btn btn-primary enable-on-file hidden" onclick="exportPdf(true)" disabled>
|
||||||
@ -99,6 +93,7 @@
|
|||||||
file_save
|
file_save
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
<button style="border-color: green; color:#b2e3a8; background: rgba(24, 122, 5, 1)"
|
||||||
th:title="#{multiTool.downloadAll}" id="export-button" class="btn btn-primary enable-on-file"
|
th:title="#{multiTool.downloadAll}" id="export-button" class="btn btn-primary enable-on-file"
|
||||||
onclick="exportPdf(false)" disabled>
|
onclick="exportPdf(false)" disabled>
|
||||||
@ -107,7 +102,12 @@
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-file-uploader">
|
||||||
|
<div
|
||||||
|
th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, accept='application/pdf', showUploads=false)}">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="selected-pages-display" class="selected-pages-container hidden">
|
<div id="selected-pages-display" class="selected-pages-container hidden">
|
||||||
<div style="display:flex; height:3rem; margin-right:1rem">
|
<div style="display:flex; height:3rem; margin-right:1rem">
|
||||||
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
||||||
@ -119,6 +119,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="multi-tool-container">
|
<div class="multi-tool-container">
|
||||||
<div class="d-flex flex-wrap" id="pages-container-wrapper">
|
<div class="d-flex flex-wrap" id="pages-container-wrapper">
|
||||||
<div id="pages-container">
|
<div id="pages-container">
|
||||||
@ -180,16 +181,21 @@
|
|||||||
import DragDropManager from "./js/multitool/DragDropManager.js";
|
import DragDropManager from "./js/multitool/DragDropManager.js";
|
||||||
import ImageHighlighter from "./js/multitool/ImageHighlighter.js";
|
import ImageHighlighter from "./js/multitool/ImageHighlighter.js";
|
||||||
import PdfActionsManager from './js/multitool/PdfActionsManager.js';
|
import PdfActionsManager from './js/multitool/PdfActionsManager.js';
|
||||||
import FileDragManager from './js/multitool/fileInput.js';
|
|
||||||
// enables drag and drop
|
// enables drag and drop
|
||||||
|
|
||||||
|
const pdfUpload = document.querySelector("input[name=pdf-upload]");
|
||||||
|
pdfUpload.addEventListener("change", async (e) => {
|
||||||
|
if (!e.target.files) return;
|
||||||
|
await pdfContainer.handleDroppedFiles( e.target.files);
|
||||||
|
e.target.value = null;
|
||||||
|
});
|
||||||
|
|
||||||
var undoManager = new UndoManager();
|
var undoManager = new UndoManager();
|
||||||
const dragDropManager = new DragDropManager('drag-container', 'pages-container');
|
const dragDropManager = new DragDropManager('drag-container', 'pages-container');
|
||||||
// enables image highlight on click
|
// enables image highlight on click
|
||||||
const imageHighlighter = new ImageHighlighter('image-highlighter');
|
const imageHighlighter = new ImageHighlighter('image-highlighter');
|
||||||
// enables the default action buttons on each file
|
// enables the default action buttons on each file
|
||||||
const pdfActionsManager = new PdfActionsManager('pages-container', undoManager);
|
const pdfActionsManager = new PdfActionsManager('pages-container', undoManager);
|
||||||
const fileDragManager = new FileDragManager();
|
|
||||||
// Scroll the wrapper horizontally
|
// Scroll the wrapper horizontally
|
||||||
|
|
||||||
// Automatically exposes rotateAll, addFiles and exportPdf to the window for the global buttons.
|
// Automatically exposes rotateAll, addFiles and exportPdf to the window for the global buttons.
|
||||||
@ -199,13 +205,11 @@
|
|||||||
[
|
[
|
||||||
dragDropManager,
|
dragDropManager,
|
||||||
imageHighlighter,
|
imageHighlighter,
|
||||||
pdfActionsManager,
|
pdfActionsManager
|
||||||
fileDragManager
|
|
||||||
],
|
],
|
||||||
undoManager
|
undoManager
|
||||||
)
|
)
|
||||||
|
|
||||||
fileDragManager.setCallback(async (files) => pdfContainer.handleDroppedFiles(files));
|
|
||||||
document.addEventListener('keydown', function (event) {
|
document.addEventListener('keydown', function (event) {
|
||||||
let targetElementId = event.target.id;
|
let targetElementId = event.target.id;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user