iobroker.staticsfilefolder 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/io-package.json +8 -2
- package/package.json +1 -1
- package/www/app.js +121 -12
- package/www/index.html +10 -1
- package/www/style.css +34 -2
package/io-package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "staticsfilefolder",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.6",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.0.6": {
|
|
7
|
+
"en": "Changed adapter mode to daemon so the main process runs and observes files correctly."
|
|
8
|
+
},
|
|
9
|
+
"0.0.5": {
|
|
10
|
+
"en": "Added print, download, and file-navigation controls inside the file viewer modal."
|
|
11
|
+
},
|
|
6
12
|
"0.0.4": {
|
|
7
13
|
"en": "Defined latest_file_url and latest_file_path states in instanceObjects so they are created automatically upon installation."
|
|
8
14
|
},
|
|
@@ -71,7 +77,7 @@
|
|
|
71
77
|
"readme": "https://github.com/gokturk413/ioBroker.staticsfilefolder/blob/main/README.md",
|
|
72
78
|
"loglevel": "info",
|
|
73
79
|
"tier": 3,
|
|
74
|
-
"mode": "
|
|
80
|
+
"mode": "daemon",
|
|
75
81
|
"type": "utility",
|
|
76
82
|
"compact": true,
|
|
77
83
|
"webExtension": "lib/web.js",
|
package/package.json
CHANGED
package/www/app.js
CHANGED
|
@@ -23,6 +23,15 @@ const sortSelect = document.getElementById('sort-select');
|
|
|
23
23
|
const viewerModal = document.getElementById('viewer-modal');
|
|
24
24
|
const closeModal = document.getElementById('close-modal');
|
|
25
25
|
const viewerBody = document.getElementById('viewer-body');
|
|
26
|
+
const modalTitle = document.getElementById('modal-title');
|
|
27
|
+
const modalBtnPrev = document.getElementById('modal-btn-prev');
|
|
28
|
+
const modalBtnNext = document.getElementById('modal-btn-next');
|
|
29
|
+
const modalBtnPrint = document.getElementById('modal-btn-print');
|
|
30
|
+
const modalBtnDownload = document.getElementById('modal-btn-download');
|
|
31
|
+
|
|
32
|
+
// Modal Navigation State
|
|
33
|
+
let currentOpenItem = null;
|
|
34
|
+
let currentFilesList = [];
|
|
26
35
|
|
|
27
36
|
// Setup PDF.js worker
|
|
28
37
|
if (window.pdfjsLib) {
|
|
@@ -59,9 +68,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
59
68
|
typeFilter.addEventListener('change', renderItems);
|
|
60
69
|
sortSelect.addEventListener('change', renderItems);
|
|
61
70
|
|
|
71
|
+
// Modal Toolbar Event Listeners
|
|
72
|
+
modalBtnPrev.addEventListener('click', navigateModalPrev);
|
|
73
|
+
modalBtnNext.addEventListener('click', navigateModalNext);
|
|
74
|
+
modalBtnPrint.addEventListener('click', printModalContent);
|
|
75
|
+
modalBtnDownload.addEventListener('click', downloadCurrentFile);
|
|
76
|
+
|
|
62
77
|
closeModal.addEventListener('click', () => {
|
|
63
78
|
viewerModal.style.display = 'none';
|
|
64
79
|
viewerBody.innerHTML = ''; // clear memory
|
|
80
|
+
currentOpenItem = null;
|
|
65
81
|
});
|
|
66
82
|
});
|
|
67
83
|
|
|
@@ -181,6 +197,8 @@ function renderItems() {
|
|
|
181
197
|
emptyStateEl.style.display = 'none';
|
|
182
198
|
}
|
|
183
199
|
|
|
200
|
+
currentFilesList = filtered.filter(item => !item.isDirectory);
|
|
201
|
+
|
|
184
202
|
const today = new Date().setHours(0,0,0,0);
|
|
185
203
|
|
|
186
204
|
filtered.forEach(item => {
|
|
@@ -223,19 +241,110 @@ function handleItemClick(item) {
|
|
|
223
241
|
const newPath = currentPath ? `${currentPath}/${item.name}` : item.name;
|
|
224
242
|
navigateTo(newPath);
|
|
225
243
|
} else {
|
|
226
|
-
|
|
244
|
+
openFile(item);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function openFile(item) {
|
|
249
|
+
currentOpenItem = item;
|
|
250
|
+
modalTitle.textContent = item.name;
|
|
251
|
+
|
|
252
|
+
// Find index of current file in currentFilesList
|
|
253
|
+
const index = currentFilesList.findIndex(f => f.name === item.name);
|
|
254
|
+
modalBtnPrev.disabled = index <= 0;
|
|
255
|
+
modalBtnNext.disabled = index === -1 || index >= currentFilesList.length - 1;
|
|
256
|
+
|
|
257
|
+
const filePath = currentPath ? `${currentPath}/${item.name}` : item.name;
|
|
258
|
+
const fileUrl = `${FILE_URL}/${encodeURIComponent(filePath)}`;
|
|
259
|
+
|
|
260
|
+
if (item.ext === '.pdf') {
|
|
261
|
+
openPdf(fileUrl);
|
|
262
|
+
} else if (item.ext === '.xlsx' || item.ext === '.csv') {
|
|
263
|
+
openExcel(fileUrl);
|
|
264
|
+
} else if (item.ext === '.docx') {
|
|
265
|
+
openWord(fileUrl);
|
|
266
|
+
} else {
|
|
267
|
+
// Unhandled file type, just open in new tab
|
|
268
|
+
window.open(fileUrl, '_blank');
|
|
269
|
+
viewerModal.style.display = 'none';
|
|
270
|
+
currentOpenItem = null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function navigateModalPrev() {
|
|
275
|
+
if (!currentOpenItem) return;
|
|
276
|
+
const index = currentFilesList.findIndex(f => f.name === currentOpenItem.name);
|
|
277
|
+
if (index > 0) {
|
|
278
|
+
openFile(currentFilesList[index - 1]);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function navigateModalNext() {
|
|
283
|
+
if (!currentOpenItem) return;
|
|
284
|
+
const index = currentFilesList.findIndex(f => f.name === currentOpenItem.name);
|
|
285
|
+
if (index !== -1 && index < currentFilesList.length - 1) {
|
|
286
|
+
openFile(currentFilesList[index + 1]);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function printModalContent() {
|
|
291
|
+
if (!currentOpenItem) return;
|
|
292
|
+
|
|
293
|
+
const canvases = viewerBody.querySelectorAll('canvas');
|
|
294
|
+
let contentHtml = '';
|
|
295
|
+
|
|
296
|
+
if (canvases.length > 0) {
|
|
297
|
+
// PDF (which is rendered in canvases)
|
|
298
|
+
canvases.forEach(canvas => {
|
|
299
|
+
const dataUrl = canvas.toDataURL();
|
|
300
|
+
contentHtml += `<img src="${dataUrl}" style="max-width: 100%; margin-bottom: 20px; display: block;" />`;
|
|
301
|
+
});
|
|
302
|
+
} else {
|
|
303
|
+
// Excel table or Word document HTML
|
|
304
|
+
contentHtml = viewerBody.innerHTML;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const printWindow = window.open('', '_blank');
|
|
308
|
+
printWindow.document.write(`
|
|
309
|
+
<html>
|
|
310
|
+
<head>
|
|
311
|
+
<title>${currentOpenItem.name}</title>
|
|
312
|
+
<style>
|
|
313
|
+
body { margin: 20px; font-family: sans-serif; background: white; color: black; }
|
|
314
|
+
img, table { max-width: 100%; page-break-inside: avoid; }
|
|
315
|
+
table { border-collapse: collapse; width: 100%; margin-top: 10px; }
|
|
316
|
+
table th, table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
317
|
+
table th { background-color: #f2f2f2; }
|
|
318
|
+
</style>
|
|
319
|
+
</head>
|
|
320
|
+
<body>
|
|
321
|
+
<h2>${currentOpenItem.name}</h2>
|
|
322
|
+
<hr />
|
|
323
|
+
${contentHtml}
|
|
324
|
+
<script>
|
|
325
|
+
window.onload = function() {
|
|
326
|
+
setTimeout(() => {
|
|
327
|
+
window.print();
|
|
328
|
+
window.close();
|
|
329
|
+
}, 500);
|
|
330
|
+
};
|
|
331
|
+
<\/script>
|
|
332
|
+
</body>
|
|
333
|
+
</html>
|
|
334
|
+
`);
|
|
335
|
+
printWindow.document.close();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function downloadCurrentFile() {
|
|
339
|
+
if (currentOpenItem) {
|
|
340
|
+
const filePath = currentPath ? `${currentPath}/${currentOpenItem.name}` : currentOpenItem.name;
|
|
227
341
|
const fileUrl = `${FILE_URL}/${encodeURIComponent(filePath)}`;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
openWord(fileUrl);
|
|
235
|
-
} else {
|
|
236
|
-
// Unhandled file type, just open in new tab
|
|
237
|
-
window.open(fileUrl, '_blank');
|
|
238
|
-
}
|
|
342
|
+
const a = document.createElement('a');
|
|
343
|
+
a.href = fileUrl;
|
|
344
|
+
a.download = currentOpenItem.name;
|
|
345
|
+
document.body.appendChild(a);
|
|
346
|
+
a.click();
|
|
347
|
+
document.body.removeChild(a);
|
|
239
348
|
}
|
|
240
349
|
}
|
|
241
350
|
|
package/www/index.html
CHANGED
|
@@ -60,7 +60,16 @@
|
|
|
60
60
|
<!-- Viewer Modal -->
|
|
61
61
|
<div id="viewer-modal" class="modal">
|
|
62
62
|
<div class="modal-content">
|
|
63
|
-
<
|
|
63
|
+
<header class="modal-header">
|
|
64
|
+
<div class="modal-title" id="modal-title">Fayl Baxışı</div>
|
|
65
|
+
<div class="modal-toolbar">
|
|
66
|
+
<button id="modal-btn-prev" class="nav-btn" title="Əvvəlki">← Geri</button>
|
|
67
|
+
<button id="modal-btn-next" class="nav-btn" title="Növbəti">İrəli →</button>
|
|
68
|
+
<button id="modal-btn-print" class="nav-btn" title="Çap et / PDF olaraq saxla">🖨️ Çap / PDF</button>
|
|
69
|
+
<button id="modal-btn-download" class="nav-btn" title="Faylı Yüklə / Export">📥 Yüklə</button>
|
|
70
|
+
<span id="close-modal" class="close-button">×</span>
|
|
71
|
+
</div>
|
|
72
|
+
</header>
|
|
64
73
|
<div id="viewer-body">
|
|
65
74
|
<!-- Viewer content (Canvas for PDF, Table for Excel, HTML for Word) -->
|
|
66
75
|
</div>
|
package/www/style.css
CHANGED
|
@@ -218,11 +218,9 @@ body {
|
|
|
218
218
|
|
|
219
219
|
.close-button {
|
|
220
220
|
color: var(--text-muted);
|
|
221
|
-
align-self: flex-end;
|
|
222
221
|
font-size: 28px;
|
|
223
222
|
font-weight: bold;
|
|
224
223
|
cursor: pointer;
|
|
225
|
-
margin-bottom: 10px;
|
|
226
224
|
}
|
|
227
225
|
|
|
228
226
|
.close-button:hover,
|
|
@@ -264,3 +262,37 @@ table.sheetjs-table th, table.sheetjs-table td {
|
|
|
264
262
|
table.sheetjs-table th {
|
|
265
263
|
background-color: var(--hover-color);
|
|
266
264
|
}
|
|
265
|
+
|
|
266
|
+
/* Modal Header and Toolbar Styles */
|
|
267
|
+
.modal-header {
|
|
268
|
+
display: flex;
|
|
269
|
+
justify-content: space-between;
|
|
270
|
+
align-items: center;
|
|
271
|
+
padding-bottom: 15px;
|
|
272
|
+
border-bottom: 1px solid var(--border-color);
|
|
273
|
+
margin-bottom: 15px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.modal-title {
|
|
277
|
+
font-size: 1.25rem;
|
|
278
|
+
font-weight: 600;
|
|
279
|
+
color: var(--text-color);
|
|
280
|
+
white-space: nowrap;
|
|
281
|
+
overflow: hidden;
|
|
282
|
+
text-overflow: ellipsis;
|
|
283
|
+
max-width: 40%;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.modal-toolbar {
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
gap: 8px;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.modal-toolbar .close-button {
|
|
293
|
+
font-size: 32px;
|
|
294
|
+
line-height: 1;
|
|
295
|
+
margin-bottom: 0;
|
|
296
|
+
margin-left: 15px;
|
|
297
|
+
align-self: center;
|
|
298
|
+
}
|