iobroker.staticsfilefolder 0.0.18 → 0.0.19

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/README.md CHANGED
@@ -64,8 +64,8 @@ Once configured and the instance is running (green status):
64
64
  Placeholder for the next version (at the beginning of the line):
65
65
  ### **WORK IN PROGRESS**
66
66
  -->
67
- ### 0.0.18
68
- * Cleaned up npm lockfile and forced hoisting of test dependencies.
67
+ ### 0.0.19
68
+ * Fixed PDF printing layout margins to fit 1 page, removed file title header from print view, and added zoom controls to PDF viewer.
69
69
 
70
70
  ### 0.0.15
71
71
  * Reverted minimum Node.js engine requirement to 20 to support GitHub Actions runners.
package/io-package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "staticsfilefolder",
4
- "version": "0.0.18",
4
+ "version": "0.0.19",
5
5
  "news": {
6
- "0.0.18": {
7
- "en": "Cleaned up npm lockfile and forced hoisting of test dependencies.",
8
- "de": "Npm-Lockfile bereinigt und das Hosten von Test-Abhängigkeiten erzwungen.",
9
- "ru": "Очищен npm lockfile и принудительно подняты зависимости для тестирования.",
10
- "pt": "Limpo o lockfile do npm e forçado o hoisting das dependências de teste.",
11
- "nl": "Npm lockfile opgeschoond en hoisting van test-afhankelijkheden geforceerd.",
12
- "fr": "Nettoyage du fichier de verrouillage npm et forçage du hoisting des dépendances de test.",
13
- "it": "Pulito il file di blocco npm e forzato l'hoisting delle dipendenze di test.",
14
- "es": "Se limpió el archivo de bloqueo npm y se forzó la elevación de las dependencias de prueba.",
15
- "pl": "Oczyszczono plik blokady npm i wymuszono hoisting zależności testowych.",
16
- "uk": "Очищено файл блокування npm та примусово піднято залежності для тестування.",
17
- "zh-cn": "清理了npm锁文件并强制提升测试依赖项。"
6
+ "0.0.19": {
7
+ "en": "Fixed PDF printing layout margins to fit 1 page, removed file title header from print view, and added zoom controls to PDF viewer.",
8
+ "de": "Das PDF-Drucklayout-Ränder wurden auf 1 Seite angepasst, der Dateititelkopf wurde aus der Druckansicht entfernt und Zoom-Steuerelemente im PDF-Viewer hinzugefügt.",
9
+ "ru": "Исправлены поля макета печати PDF для соответствия 1 странице, удален заголовок файла из режима печати и добавлены элементы управления масштабированием в просмотрщик PDF.",
10
+ "pt": "Corrigidas as margens do layout de impressão PDF para caber em 1 página, removido o cabeçalho do título do arquivo da visualização de impressão e adicionados controles de zoom ao visualizador de PDF.",
11
+ "nl": "PDF-printlayoutmarges aangepast om op 1 pagina te passen, bestandsnaamkoptekst verwijderd uit de printweergave en zoomknoppen toegevoegd aan de PDF-viewer.",
12
+ "fr": "Correction des marges de mise en page d'impression PDF pour s'adapter à 1 page, suppression de l'en-tête du titre du fichier de la vue d'impression et ajout de commandes de zoom à la visionneuse PDF.",
13
+ "it": "Corretti i margini del layout di stampa PDF per adattarsi a 1 pagina, rimosso l'intestazione del titolo del file dalla visualizzazione di stampa e aggiunti controlli di zoom al visualizzatore di PDF.",
14
+ "es": "Se corrigieron los márgenes del diseño de impresión PDF para que quepan en 1 página, se eliminó el encabezado del título del archivo de la vista de impresión y se agregaron controles de zoom al visor de PDF.",
15
+ "pl": "Naprawiono marginesy układu wydruku PDF, aby pasowały do 1 strony, usunięto nagłówek tytułu pliku z widoku wydruku i dodano sterowanie powiększeniem do przeglądarki PDF.",
16
+ "uk": "Виправлено поля макета друку PDF для відповідності 1 сторінці, вилучено заголовок назвы файлу з режиму друку та додано елементи управління масштабуванням у переглядач PDF.",
17
+ "zh-cn": "修复了PDF打印布局页边距以适应1页,从打印视图中删除了文件标题页眉,并在PDF查看器中添加了缩放控制。"
18
18
  },
19
19
  "0.0.15": {
20
20
  "en": "Reverted minimum Node.js engine requirement to 20 to support GitHub Actions runners.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.staticsfilefolder",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Static Files Folder",
5
5
  "author": {
6
6
  "name": "gokturk413",
package/www/app.js CHANGED
@@ -28,11 +28,14 @@ const modalTitle = document.getElementById('modal-title');
28
28
  const modalBtnPrev = document.getElementById('modal-btn-prev');
29
29
  const modalBtnNext = document.getElementById('modal-btn-next');
30
30
  const modalBtnPrint = document.getElementById('modal-btn-print');
31
+ const modalPdfZoom = document.getElementById('modal-pdf-zoom');
31
32
  const modalBtnDownload = document.getElementById('modal-btn-download');
32
33
 
33
34
  // Modal Navigation State
34
35
  let currentOpenItem = null;
35
36
  let currentFilesList = [];
37
+ let currentPdfDoc = null;
38
+ let currentPdfZoom = 1.5;
36
39
 
37
40
  // Localization Settings
38
41
  const translations = {
@@ -240,12 +243,20 @@ document.addEventListener('DOMContentLoaded', () => {
240
243
  modalBtnPrev.addEventListener('click', navigateModalPrev);
241
244
  modalBtnNext.addEventListener('click', navigateModalNext);
242
245
  modalBtnPrint.addEventListener('click', printModalContent);
246
+ modalPdfZoom.addEventListener('change', (e) => {
247
+ currentPdfZoom = parseFloat(e.target.value);
248
+ renderPdfPages();
249
+ });
243
250
  modalBtnDownload.addEventListener('click', downloadCurrentFile);
244
251
 
245
252
  closeModal.addEventListener('click', () => {
246
253
  viewerModal.style.display = 'none';
247
254
  viewerBody.innerHTML = ''; // clear memory
248
255
  currentOpenItem = null;
256
+ currentPdfDoc = null;
257
+ currentPdfZoom = 1.5;
258
+ modalPdfZoom.value = '1.5';
259
+ modalPdfZoom.style.display = 'none';
249
260
  });
250
261
  });
251
262
 
@@ -420,6 +431,7 @@ function handleItemClick(item) {
420
431
  function openFile(item) {
421
432
  currentOpenItem = item;
422
433
  modalTitle.textContent = item.name;
434
+ modalPdfZoom.style.display = 'none';
423
435
 
424
436
  // Find index of current file in currentFilesList
425
437
  const index = currentFilesList.findIndex(f => f.name === item.name);
@@ -464,12 +476,13 @@ function printModalContent() {
464
476
 
465
477
  const canvases = viewerBody.querySelectorAll('canvas');
466
478
  let contentHtml = '';
479
+ let isPdf = canvases.length > 0;
467
480
 
468
- if (canvases.length > 0) {
481
+ if (isPdf) {
469
482
  // PDF (which is rendered in canvases)
470
483
  canvases.forEach(canvas => {
471
484
  const dataUrl = canvas.toDataURL();
472
- contentHtml += `<img src="${dataUrl}" style="max-width: 100%; margin-bottom: 20px; display: block;" />`;
485
+ contentHtml += `<img src="${dataUrl}" class="pdf-page-img" />`;
473
486
  });
474
487
  } else {
475
488
  // Excel table or Word document HTML
@@ -482,16 +495,34 @@ function printModalContent() {
482
495
  <head>
483
496
  <title>${currentOpenItem.name}</title>
484
497
  <style>
485
- body { margin: 20px; font-family: sans-serif; background: white; color: black; }
486
- img, table { max-width: 100%; page-break-inside: avoid; }
498
+ @page {
499
+ size: auto;
500
+ margin: 0mm;
501
+ }
502
+ body {
503
+ margin: 0;
504
+ padding: ${isPdf ? '0' : '20px'};
505
+ font-family: sans-serif;
506
+ background: white;
507
+ color: black;
508
+ }
509
+ .pdf-page-img {
510
+ width: 100%;
511
+ max-width: 100%;
512
+ height: auto;
513
+ display: block;
514
+ page-break-after: always;
515
+ }
516
+ .pdf-page-img:last-child {
517
+ page-break-after: avoid;
518
+ }
487
519
  table { border-collapse: collapse; width: 100%; margin-top: 10px; }
488
520
  table th, table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
489
521
  table th { background-color: #f2f2f2; }
522
+ img, table { page-break-inside: avoid; }
490
523
  </style>
491
524
  </head>
492
525
  <body>
493
- <h2>${currentOpenItem.name}</h2>
494
- <hr />
495
526
  ${contentHtml}
496
527
  <script>
497
528
  window.onload = function() {
@@ -525,23 +556,36 @@ function downloadCurrentFile() {
525
556
  async function openPdf(url) {
526
557
  viewerModal.style.display = 'block';
527
558
  viewerBody.innerHTML = `<h2>${translations[currentLang]?.loadingPdf || 'Loading PDF...'}</h2>`;
559
+ modalPdfZoom.style.display = 'inline-block';
528
560
 
529
561
  try {
530
562
  const loadingTask = window.pdfjsLib.getDocument({ url: url });
531
- const pdf = await loadingTask.promise;
532
- viewerBody.innerHTML = ''; // clear loading
533
-
534
- // Render all pages
535
- for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
536
- const page = await pdf.getPage(pageNum);
537
- const scale = 1.5;
538
- const viewport = page.getViewport({ scale: scale });
563
+ currentPdfDoc = await loadingTask.promise;
564
+ renderPdfPages();
565
+ } catch (e) {
566
+ const errorText = translations[currentLang]?.errorLoading || 'An error occurred: ';
567
+ viewerBody.innerHTML = `<h2 style="color:red">${errorText}${e.message}</h2>`;
568
+ }
569
+ }
570
+
571
+ async function renderPdfPages() {
572
+ if (!currentPdfDoc) return;
573
+ viewerBody.innerHTML = '';
574
+
575
+ try {
576
+ for (let pageNum = 1; pageNum <= currentPdfDoc.numPages; pageNum++) {
577
+ const page = await currentPdfDoc.getPage(pageNum);
578
+ const viewport = page.getViewport({ scale: currentPdfZoom });
539
579
 
540
580
  const canvas = document.createElement('canvas');
541
581
  const context = canvas.getContext('2d');
542
582
  canvas.height = viewport.height;
543
583
  canvas.width = viewport.width;
544
584
 
585
+ canvas.style.display = 'block';
586
+ canvas.style.margin = '10px auto';
587
+ canvas.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
588
+
545
589
  viewerBody.appendChild(canvas);
546
590
 
547
591
  const renderContext = {
@@ -551,8 +595,7 @@ async function openPdf(url) {
551
595
  await page.render(renderContext).promise;
552
596
  }
553
597
  } catch (e) {
554
- const errorText = translations[currentLang]?.errorLoading || 'An error occurred: ';
555
- viewerBody.innerHTML = `<h2 style="color:red">${errorText}${e.message}</h2>`;
598
+ console.error("Error rendering PDF pages:", e);
556
599
  }
557
600
  }
558
601
 
package/www/index.html CHANGED
@@ -67,6 +67,13 @@
67
67
  <button id="modal-btn-prev" class="nav-btn" data-i18n="modalBack" title="Previous">&larr; Back</button>
68
68
  <button id="modal-btn-next" class="nav-btn" data-i18n="modalForward" title="Next">Next &rarr;</button>
69
69
  <button id="modal-btn-print" class="nav-btn" data-i18n="modalPrint" title="Print / Save as PDF">🖨️ Print / PDF</button>
70
+ <select id="modal-pdf-zoom" class="nav-btn" title="Zoom" style="display: none; height: 32px; padding: 0 6px; margin: 0 4px; font-size: 14px; border-radius: 4px; border: 1px solid var(--border-color); background: var(--bg-card); color: var(--text-color); cursor: pointer; vertical-align: middle;">
71
+ <option value="1.0">100%</option>
72
+ <option value="1.25">125%</option>
73
+ <option value="1.5" selected>150%</option>
74
+ <option value="2.0">200%</option>
75
+ <option value="2.5">250%</option>
76
+ </select>
70
77
  <button id="modal-btn-download" class="nav-btn" data-i18n="modalDownload" title="Download File">📥 Download</button>
71
78
  <span id="close-modal" class="close-button">&times;</span>
72
79
  </div>