Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions src/js/logic/bmp-to-pdf-page.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { showLoader, hideLoader, showAlert } from '../ui.js';
import { downloadFile, formatBytes } from '../utils/helpers.js';
import { createIcons, icons } from 'lucide';
import Sortable from 'sortablejs';
import { PDFDocument as PDFLibDocument } from 'pdf-lib';

let files: File[] = [];
Expand Down Expand Up @@ -54,7 +55,8 @@ const updateUI = () => {

files.forEach((file, index) => {
const fileDiv = document.createElement('div');
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm';
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm draggable-file';
fileDiv.setAttribute('data-index', index.toString());

const infoContainer = document.createElement('div');
infoContainer.className = 'flex items-center gap-2 overflow-hidden';
Expand All @@ -69,24 +71,55 @@ const updateUI = () => {

infoContainer.append(nameSpan, sizeSpan);

const rightGroup = document.createElement('div');
rightGroup.className = 'flex items-center gap-1 ml-4';

const dragHandle = document.createElement('div');
dragHandle.className = 'drag-handle cursor-move text-gray-400 hover:text-white p-1 rounded transition-colors';
dragHandle.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="5" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="19" r="1"/></svg>`;

const removeBtn = document.createElement('button');
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.className = 'text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.innerHTML = '<i data-lucide="trash-2" class="w-4 h-4"></i>';
removeBtn.onclick = () => {
files = files.filter((_, i) => i !== index);
updateUI();
};

fileDiv.append(infoContainer, removeBtn);
rightGroup.append(dragHandle, removeBtn);
fileDiv.append(infoContainer, rightGroup);
fileDisplayArea.appendChild(fileDiv);
});
createIcons({ icons });
initializeFileListSortable();
} else {
fileControls.classList.add('hidden');
processBtn.classList.add('hidden');
}
};

function initializeFileListSortable() {
const fileDisplayArea = document.getElementById('file-display-area');
if (!fileDisplayArea) return;
if ((fileDisplayArea as any)._sortableInstance) {
(fileDisplayArea as any)._sortableInstance.destroy();
}
(fileDisplayArea as any)._sortableInstance = Sortable.create(fileDisplayArea, {
handle: '.drag-handle',
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: function (evt: any) {
if (evt.oldIndex !== evt.newIndex) {
const moved = files.splice(evt.oldIndex, 1)[0];
files.splice(evt.newIndex, 0, moved);
updateUI();
}
},
});
}

const resetState = () => {
files = [];
updateUI();
Expand Down Expand Up @@ -201,4 +234,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (processBtn) {
processBtn.addEventListener('click', convert);
}
setTimeout(() => {
initializeFileListSortable();
}, 0);
});
40 changes: 37 additions & 3 deletions src/js/logic/csv-to-pdf-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
formatBytes,
} from '../utils/helpers.js';
import { state } from '../state.js';
import Sortable from 'sortablejs';
import { createIcons, icons } from 'lucide';

document.addEventListener('DOMContentLoaded', () => {
Expand Down Expand Up @@ -33,10 +34,12 @@ document.addEventListener('DOMContentLoaded', () => {
if (fileDisplayArea) {
fileDisplayArea.innerHTML = '';


for (let index = 0; index < state.files.length; index++) {
const file = state.files[index];
const fileDiv = document.createElement('div');
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm';
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm draggable-file';
fileDiv.setAttribute('data-index', index.toString());

const infoContainer = document.createElement('div');
infoContainer.className = 'flex flex-col overflow-hidden';
Expand All @@ -51,19 +54,28 @@ document.addEventListener('DOMContentLoaded', () => {

infoContainer.append(nameSpan, metaSpan);

const rightGroup = document.createElement('div');
rightGroup.className = 'flex items-center gap-1 ml-4';

const dragHandle = document.createElement('div');
dragHandle.className = 'drag-handle cursor-move text-gray-400 hover:text-white p-1 rounded transition-colors';
dragHandle.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="5" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="19" r="1"/></svg>`;

const removeBtn = document.createElement('button');
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.className = 'text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.innerHTML = '<i data-lucide="trash-2" class="w-4 h-4"></i>';
removeBtn.onclick = () => {
state.files = state.files.filter((_, i) => i !== index);
updateUI();
};

fileDiv.append(infoContainer, removeBtn);
rightGroup.append(dragHandle, removeBtn);
fileDiv.append(infoContainer, rightGroup);
fileDisplayArea.appendChild(fileDiv);
}

createIcons({ icons });
initializeFileListSortable();
}
if (fileControls) fileControls.classList.remove('hidden');
convertOptions.classList.remove('hidden');
Expand Down Expand Up @@ -228,4 +240,26 @@ document.addEventListener('DOMContentLoaded', () => {
}

updateUI();

function initializeFileListSortable() {
const fileDisplayArea = document.getElementById('file-display-area');
if (!fileDisplayArea) return;
if ((fileDisplayArea as any)._sortableInstance) {
(fileDisplayArea as any)._sortableInstance.destroy();
}
(fileDisplayArea as any)._sortableInstance = Sortable.create(fileDisplayArea, {
handle: '.drag-handle',
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: function (evt: any) {
if (evt.oldIndex !== evt.newIndex) {
const moved = state.files.splice(evt.oldIndex, 1)[0];
state.files.splice(evt.newIndex, 0, moved);
updateUI();
}
},
});
}
});
41 changes: 38 additions & 3 deletions src/js/logic/excel-to-pdf-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { state } from '../state.js';
import { createIcons, icons } from 'lucide';
import { getLibreOfficeConverter, type LoadProgress } from '../utils/libreoffice-loader.js';
import Sortable from 'sortablejs';

document.addEventListener('DOMContentLoaded', () => {
state.files = [];
Expand Down Expand Up @@ -37,7 +38,8 @@ document.addEventListener('DOMContentLoaded', () => {
for (let index = 0; index < state.files.length; index++) {
const file = state.files[index];
const fileDiv = document.createElement('div');
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm';
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm draggable-file';
fileDiv.setAttribute('data-index', index.toString());

const infoContainer = document.createElement('div');
infoContainer.className = 'flex flex-col overflow-hidden';
Expand All @@ -52,15 +54,23 @@ document.addEventListener('DOMContentLoaded', () => {

infoContainer.append(nameSpan, metaSpan);

const rightGroup = document.createElement('div');
rightGroup.className = 'flex items-center gap-1 ml-4';

const dragHandle = document.createElement('div');
dragHandle.className = 'drag-handle cursor-move text-gray-400 hover:text-white p-1 rounded transition-colors';
dragHandle.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="5" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="19" r="1"/></svg>`;

const removeBtn = document.createElement('button');
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.className = 'text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.innerHTML = '<i data-lucide="trash-2" class="w-4 h-4"></i>';
removeBtn.onclick = () => {
state.files = state.files.filter((_, i) => i !== index);
updateUI();
};

fileDiv.append(infoContainer, removeBtn);
rightGroup.append(dragHandle, removeBtn);
fileDiv.append(infoContainer, rightGroup);
fileDisplayArea.appendChild(fileDiv);
}

Expand Down Expand Up @@ -213,4 +223,29 @@ document.addEventListener('DOMContentLoaded', () => {
if (processBtn) {
processBtn.addEventListener('click', convertToPdf);
}
setTimeout(() => {
initializeFileListSortable();
}, 0);

function initializeFileListSortable() {
const fileDisplayArea = document.getElementById('file-display-area');
if (!fileDisplayArea) return;
if ((fileDisplayArea as any)._sortableInstance) {
(fileDisplayArea as any)._sortableInstance.destroy();
}
(fileDisplayArea as any)._sortableInstance = Sortable.create(fileDisplayArea, {
handle: '.drag-handle',
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: function (evt: any) {
if (evt.oldIndex !== evt.newIndex) {
const moved = state.files.splice(evt.oldIndex, 1)[0];
state.files.splice(evt.newIndex, 0, moved);
updateUI();
}
},
});
}
});
42 changes: 39 additions & 3 deletions src/js/logic/heic-to-pdf-page.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { showLoader, hideLoader, showAlert } from '../ui.js';
import { downloadFile, formatBytes } from '../utils/helpers.js';
import { createIcons, icons } from 'lucide';
import Sortable from 'sortablejs';
import heic2any from 'heic2any';
import { PDFDocument as PDFLibDocument } from 'pdf-lib';

Expand All @@ -21,7 +22,8 @@ const updateUI = () => {

files.forEach((file, index) => {
const fileDiv = document.createElement('div');
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm';
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg text-sm draggable-file';
fileDiv.setAttribute('data-index', index.toString());

const infoContainer = document.createElement('div');
infoContainer.className = 'flex items-center gap-2 overflow-hidden';
Expand All @@ -36,24 +38,55 @@ const updateUI = () => {

infoContainer.append(nameSpan, sizeSpan);

const rightGroup = document.createElement('div');
rightGroup.className = 'flex items-center gap-1 ml-4';

const dragHandle = document.createElement('div');
dragHandle.className = 'drag-handle cursor-move text-gray-400 hover:text-white p-1 rounded transition-colors';
dragHandle.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="5" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="19" r="1"/></svg>`;

const removeBtn = document.createElement('button');
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.className = 'text-red-400 hover:text-red-300 flex-shrink-0';
removeBtn.innerHTML = '<i data-lucide="trash-2" class="w-4 h-4"></i>';
removeBtn.onclick = () => {
files = files.filter((_, i) => i !== index);
updateUI();
};

fileDiv.append(infoContainer, removeBtn);
rightGroup.append(dragHandle, removeBtn);
fileDiv.append(infoContainer, rightGroup);
fileDisplayArea.appendChild(fileDiv);
});
createIcons({ icons });
initializeFileListSortable();
} else {
fileControls.classList.add('hidden');
processBtn.classList.add('hidden');
}
};

function initializeFileListSortable() {
const fileDisplayArea = document.getElementById('file-display-area');
if (!fileDisplayArea) return;
if ((fileDisplayArea as any)._sortableInstance) {
(fileDisplayArea as any)._sortableInstance.destroy();
}
(fileDisplayArea as any)._sortableInstance = Sortable.create(fileDisplayArea, {
handle: '.drag-handle',
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: function (evt: any) {
if (evt.oldIndex !== evt.newIndex) {
const moved = files.splice(evt.oldIndex, 1)[0];
files.splice(evt.newIndex, 0, moved);
updateUI();
}
},
});
}

const resetState = () => {
files = [];
updateUI();
Expand Down Expand Up @@ -176,4 +209,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (processBtn) {
processBtn.addEventListener('click', convert);
}
setTimeout(() => {
initializeFileListSortable();
}, 0);
});
Loading