retold-remote 0.0.23 → 0.0.26
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/css/retold-remote.css +343 -20
- package/docs/.nojekyll +0 -0
- package/docs/README.md +64 -12
- package/docs/_cover.md +6 -6
- package/docs/_sidebar.md +2 -0
- package/docs/_topbar.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/collections.md +30 -0
- package/docs/css/docuserve.css +327 -0
- package/docs/ebook-reader.md +75 -1
- package/docs/image-explorer.md +62 -2
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +254 -0
- package/docs/retold-keyword-index.json +31216 -0
- package/docs/server-setup.md +122 -91
- package/docs/stack-launcher.md +218 -0
- package/docs/synology.md +585 -0
- package/docs/ultravisor-configuration.md +5 -5
- package/docs/ultravisor-integration.md +4 -2
- package/package.json +20 -14
- package/source/Pict-Application-RetoldRemote.js +22 -0
- package/source/RetoldRemote-ExtensionMaps.js +1 -1
- package/source/cli/RetoldRemote-Server-Setup.js +460 -7
- package/source/cli/RetoldRemote-Stack-Launcher.js +563 -0
- package/source/cli/RetoldRemote-Stack-Run.js +41 -0
- package/source/cli/commands/RetoldRemote-Command-Serve.js +129 -54
- package/source/providers/CollectionManager-AddItems.js +166 -0
- package/source/providers/Pict-Provider-GalleryNavigation.js +55 -0
- package/source/providers/Pict-Provider-OperationStatus.js +597 -0
- package/source/providers/keyboard-handlers/KeyHandler-ImageExplorer.js +20 -1
- package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +23 -0
- package/source/server/RetoldRemote-AudioWaveformService.js +49 -3
- package/source/server/RetoldRemote-CollectionExportService.js +763 -0
- package/source/server/RetoldRemote-CollectionService.js +5 -0
- package/source/server/RetoldRemote-EbookService.js +218 -3
- package/source/server/RetoldRemote-ImageService.js +221 -46
- package/source/server/RetoldRemote-MediaService.js +63 -4
- package/source/server/RetoldRemote-MetadataCache.js +25 -5
- package/source/server/RetoldRemote-OperationBroadcaster.js +363 -0
- package/source/server/RetoldRemote-SubimageService.js +680 -0
- package/source/server/RetoldRemote-ToolDetector.js +50 -0
- package/source/server/RetoldRemote-UltravisorBeacon.js +18 -3
- package/source/server/RetoldRemote-UltravisorDispatcher.js +65 -491
- package/source/server/RetoldRemote-UltravisorOperations.js +133 -20
- package/source/server/RetoldRemote-VideoFrameService.js +302 -9
- package/source/views/MediaViewer-EbookViewer.js +419 -1
- package/source/views/MediaViewer-PdfViewer.js +1050 -0
- package/source/views/PictView-Remote-AudioExplorer.js +77 -1
- package/source/views/PictView-Remote-CollectionsPanel.js +213 -0
- package/source/views/PictView-Remote-Gallery.js +365 -64
- package/source/views/PictView-Remote-ImageExplorer.js +1529 -44
- package/source/views/PictView-Remote-ImageViewer.js +2 -2
- package/source/views/PictView-Remote-Layout.js +58 -0
- package/source/views/PictView-Remote-MediaViewer.js +100 -25
- package/source/views/PictView-Remote-RegionsBrowser.js +554 -0
- package/source/views/PictView-Remote-SubimagesPanel.js +353 -0
- package/source/views/PictView-Remote-TopBar.js +1 -0
- package/source/views/PictView-Remote-VideoExplorer.js +77 -1
- package/web-application/css/docuserve.css +277 -23
- package/web-application/css/retold-remote.css +343 -20
- package/web-application/docs/README.md +64 -12
- package/web-application/docs/_cover.md +6 -6
- package/web-application/docs/_sidebar.md +2 -0
- package/web-application/docs/_topbar.md +1 -1
- package/web-application/docs/collections.md +30 -0
- package/web-application/docs/ebook-reader.md +75 -1
- package/web-application/docs/image-explorer.md +62 -2
- package/web-application/docs/server-setup.md +122 -91
- package/web-application/docs/stack-launcher.md +218 -0
- package/web-application/docs/synology.md +585 -0
- package/web-application/docs/ultravisor-configuration.md +5 -5
- package/web-application/docs/ultravisor-integration.md +4 -2
- package/web-application/js/pict-docuserve.min.js +12 -12
- package/web-application/js/pict.min.js +2 -2
- package/web-application/js/pict.min.js.map +1 -1
- package/web-application/retold-remote.js +6596 -1784
- package/web-application/retold-remote.js.map +1 -1
- package/web-application/retold-remote.min.js +75 -23
- package/web-application/retold-remote.min.js.map +1 -1
|
@@ -68,11 +68,11 @@ class RetoldRemoteImageViewerView extends libPictView
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
* Show the explore button
|
|
71
|
+
* Show the explore button in the header nav bar.
|
|
72
72
|
*/
|
|
73
73
|
_showExploreButton()
|
|
74
74
|
{
|
|
75
|
-
let tmpBtn = document.getElementById('RetoldRemote-
|
|
75
|
+
let tmpBtn = document.getElementById('RetoldRemote-HeaderExploreBtn');
|
|
76
76
|
if (tmpBtn)
|
|
77
77
|
{
|
|
78
78
|
tmpBtn.style.display = '';
|
|
@@ -24,6 +24,7 @@ const _ViewConfiguration =
|
|
|
24
24
|
<button class="content-editor-sidebar-tab active" data-tab="files" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('files')">Files</button>
|
|
25
25
|
<button class="content-editor-sidebar-tab" data-tab="favorites" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('favorites')">Favorites</button>
|
|
26
26
|
<button class="content-editor-sidebar-tab" data-tab="info" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('info')">Info</button>
|
|
27
|
+
<button class="content-editor-sidebar-tab" data-tab="subimages" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('subimages')">Regions</button>
|
|
27
28
|
<button class="content-editor-sidebar-tab" data-tab="settings" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('settings')">Settings</button>
|
|
28
29
|
<button class="content-editor-sidebar-tab content-editor-sidebar-tab-collections" data-tab="collections" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('collections')" style="display:none;">Collections</button>
|
|
29
30
|
</div>
|
|
@@ -32,6 +33,7 @@ const _ViewConfiguration =
|
|
|
32
33
|
<div id="RetoldRemote-Favorites-Body"></div>
|
|
33
34
|
</div>
|
|
34
35
|
<div class="content-editor-sidebar-pane" data-pane="info" id="RetoldRemote-Info-Container" style="display:none"></div>
|
|
36
|
+
<div class="content-editor-sidebar-pane" data-pane="subimages" id="RetoldRemote-Subimages-Container" style="display:none"></div>
|
|
35
37
|
<div class="content-editor-sidebar-pane" data-pane="settings" id="RetoldRemote-Settings-Container" style="display:none"></div>
|
|
36
38
|
<div class="content-editor-sidebar-pane" data-pane="collections" id="RetoldRemote-Collections-MobilePane" style="display:none"></div>
|
|
37
39
|
</div>
|
|
@@ -48,6 +50,7 @@ const _ViewConfiguration =
|
|
|
48
50
|
</div>
|
|
49
51
|
</div>
|
|
50
52
|
</div>
|
|
53
|
+
<div class="retold-remote-operation-status" id="RetoldRemote-OperationStatus-Container"></div>
|
|
51
54
|
`
|
|
52
55
|
}
|
|
53
56
|
],
|
|
@@ -196,6 +199,16 @@ class RetoldRemoteLayoutView extends libPictView
|
|
|
196
199
|
pEl.style.display = (pEl.getAttribute('data-pane') === pTab) ? '' : 'none';
|
|
197
200
|
});
|
|
198
201
|
|
|
202
|
+
// Subimages tab: render the subimages panel
|
|
203
|
+
if (pTab === 'subimages')
|
|
204
|
+
{
|
|
205
|
+
let tmpSubimagesView = this.pict.views['RetoldRemote-SubimagesPanel'];
|
|
206
|
+
if (tmpSubimagesView)
|
|
207
|
+
{
|
|
208
|
+
tmpSubimagesView.render();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
199
212
|
// Render settings panel on demand
|
|
200
213
|
if (pTab === 'settings')
|
|
201
214
|
{
|
|
@@ -256,6 +269,51 @@ class RetoldRemoteLayoutView extends libPictView
|
|
|
256
269
|
|
|
257
270
|
}
|
|
258
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Notify the layout that the currently-viewed file has changed (or been
|
|
274
|
+
* cleared). This re-renders whichever sidebar panel is currently visible
|
|
275
|
+
* so stale file-scoped content (Info metadata, Regions list, etc.) gets
|
|
276
|
+
* refreshed without the user having to click the tab again.
|
|
277
|
+
*
|
|
278
|
+
* Call this from every viewer that mutates tmpRemote.CurrentViewerFile,
|
|
279
|
+
* and from the gallery clear path. Do NOT call it on intra-file navigation
|
|
280
|
+
* (PDF page changes, EPUB chapter changes) — those don't change the file.
|
|
281
|
+
*
|
|
282
|
+
* @param {string} pFilePath - The new current file path (or '' when clearing)
|
|
283
|
+
*/
|
|
284
|
+
notifyCurrentFileChanged(pFilePath)
|
|
285
|
+
{
|
|
286
|
+
// Find the currently-active sidebar tab
|
|
287
|
+
let tmpActiveTab = document.querySelector('.content-editor-sidebar-tab.active');
|
|
288
|
+
if (!tmpActiveTab)
|
|
289
|
+
{
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
let tmpTab = tmpActiveTab.getAttribute('data-tab');
|
|
293
|
+
|
|
294
|
+
// Re-render whichever panel owns file-scoped state. The panel's own
|
|
295
|
+
// render() already detects whether the file actually changed (via its
|
|
296
|
+
// internal _currentPath comparison) and re-fetches only when needed.
|
|
297
|
+
if (tmpTab === 'subimages')
|
|
298
|
+
{
|
|
299
|
+
let tmpSubimagesView = this.pict.views['RetoldRemote-SubimagesPanel'];
|
|
300
|
+
if (tmpSubimagesView)
|
|
301
|
+
{
|
|
302
|
+
tmpSubimagesView.render();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else if (tmpTab === 'info')
|
|
306
|
+
{
|
|
307
|
+
let tmpInfoView = this.pict.views['RetoldRemote-FileInfoPanel'];
|
|
308
|
+
if (tmpInfoView)
|
|
309
|
+
{
|
|
310
|
+
tmpInfoView.render();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Other tabs (files, favorites, settings, collections) are not
|
|
314
|
+
// file-scoped, so there's nothing to refresh on file change.
|
|
315
|
+
}
|
|
316
|
+
|
|
259
317
|
_setupResizeHandle()
|
|
260
318
|
{
|
|
261
319
|
let tmpSelf = this;
|
|
@@ -2,6 +2,7 @@ const libPictView = require('pict-view');
|
|
|
2
2
|
|
|
3
3
|
const _MediaViewerEbookViewer = require('./MediaViewer-EbookViewer');
|
|
4
4
|
const _MediaViewerCodeViewer = require('./MediaViewer-CodeViewer');
|
|
5
|
+
const _MediaViewerPdfViewer = require('./MediaViewer-PdfViewer');
|
|
5
6
|
|
|
6
7
|
const _ViewConfiguration =
|
|
7
8
|
{
|
|
@@ -40,6 +41,14 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
40
41
|
tmpRemote.CurrentViewerMediaType = pMediaType;
|
|
41
42
|
tmpRemote.VideoMenuActive = (pMediaType === 'video');
|
|
42
43
|
|
|
44
|
+
// Notify the layout so active sidebar panels (Info, Regions, etc.)
|
|
45
|
+
// refresh to the new file instead of keeping stale content.
|
|
46
|
+
let tmpLayout = this.pict.views['ContentEditor-Layout'];
|
|
47
|
+
if (tmpLayout && typeof tmpLayout.notifyCurrentFileChanged === 'function')
|
|
48
|
+
{
|
|
49
|
+
tmpLayout.notifyCurrentFileChanged(pFilePath);
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
// Show viewer, hide gallery
|
|
44
53
|
let tmpGalleryContainer = document.getElementById('RetoldRemote-Gallery-Container');
|
|
45
54
|
let tmpViewerContainer = document.getElementById('RetoldRemote-Viewer-Container');
|
|
@@ -59,6 +68,7 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
59
68
|
tmpHTML += '<button class="retold-remote-viewer-nav-btn" onclick="pict.providers[\'RetoldRemote-GalleryNavigation\'].closeViewer()" title="Back (Esc)">← Back</button>';
|
|
60
69
|
tmpHTML += '<button class="retold-remote-viewer-nav-btn" onclick="pict.providers[\'RetoldRemote-GalleryNavigation\'].prevFile()" title="Previous (k)">‹ Prev</button>';
|
|
61
70
|
tmpHTML += '<div class="retold-remote-viewer-title">' + this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpFileName) + '</div>';
|
|
71
|
+
tmpHTML += '<button class="retold-remote-viewer-nav-btn" id="RetoldRemote-HeaderExploreBtn" onclick="pict.views[\'RetoldRemote-ImageExplorer\'].showExplorer(pict.AppData.RetoldRemote.CurrentViewerFile)" title="Explore image (e)" style="display:none;">🔍 Explore</button>';
|
|
62
72
|
tmpHTML += '<button class="retold-remote-viewer-nav-btn" onclick="pict.providers[\'RetoldRemote-GalleryNavigation\'].nextFile()" title="Next (j)">Next ›</button>';
|
|
63
73
|
tmpHTML += '<button class="retold-remote-viewer-nav-btn" onclick="pict.providers[\'RetoldRemote-GalleryNavigation\']._toggleFileInfo()" title="Info (i)">ⓘ</button>';
|
|
64
74
|
tmpHTML += '<button class="retold-remote-viewer-nav-btn" onclick="pict.views[\'RetoldRemote-MediaViewer\'].toggleDistractionFree()" title="Distraction-Free (d)">▢</button>';
|
|
@@ -127,7 +137,7 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
127
137
|
this._loadCodeViewer(tmpContentURL, pFilePath);
|
|
128
138
|
}
|
|
129
139
|
|
|
130
|
-
// Load ebook
|
|
140
|
+
// Load document viewers: ebook for epub/mobi, PDF for pdf, convert-then-PDF for others
|
|
131
141
|
if (pMediaType === 'document')
|
|
132
142
|
{
|
|
133
143
|
let tmpExt = pFilePath.replace(/^.*\./, '').toLowerCase();
|
|
@@ -135,7 +145,15 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
135
145
|
{
|
|
136
146
|
this._loadEbookViewer(tmpContentURL, pFilePath);
|
|
137
147
|
}
|
|
138
|
-
|
|
148
|
+
else if (tmpExt === 'pdf')
|
|
149
|
+
{
|
|
150
|
+
this._loadPdfViewer(tmpContentURL, pFilePath);
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
{
|
|
154
|
+
// Convertible document types — convert to PDF first, then load PDF viewer
|
|
155
|
+
this._loadConvertedDocumentViewer(pFilePath);
|
|
156
|
+
}
|
|
139
157
|
}
|
|
140
158
|
|
|
141
159
|
// Set up swipe navigation for touch devices
|
|
@@ -169,6 +187,15 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
169
187
|
tmpRemote.CurrentViewerMediaType = 'image';
|
|
170
188
|
tmpRemote.VideoMenuActive = false;
|
|
171
189
|
|
|
190
|
+
// Notify the layout so active sidebar panels (Info, Regions, etc.)
|
|
191
|
+
// refresh. This is especially important when switching between
|
|
192
|
+
// collection items via the direct-image path.
|
|
193
|
+
let tmpLayout = this.pict.views['ContentEditor-Layout'];
|
|
194
|
+
if (tmpLayout && typeof tmpLayout.notifyCurrentFileChanged === 'function')
|
|
195
|
+
{
|
|
196
|
+
tmpLayout.notifyCurrentFileChanged(pFilePath || '');
|
|
197
|
+
}
|
|
198
|
+
|
|
172
199
|
// Show viewer, hide gallery
|
|
173
200
|
let tmpGalleryContainer = document.getElementById('RetoldRemote-Gallery-Container');
|
|
174
201
|
let tmpViewerContainer = document.getElementById('RetoldRemote-Viewer-Container');
|
|
@@ -533,19 +560,12 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
533
560
|
tmpImg.onclick = function () { pict.views['RetoldRemote-ImageViewer'].toggleZoom(); };
|
|
534
561
|
tmpFragment.appendChild(tmpImg);
|
|
535
562
|
|
|
536
|
-
// Explore button
|
|
537
|
-
let
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
tmpBtn.innerHTML = '🔍 Explore';
|
|
543
|
-
tmpBtn.onclick = function ()
|
|
544
|
-
{
|
|
545
|
-
pict.views['RetoldRemote-ImageExplorer'].showExplorer(
|
|
546
|
-
pict.AppData.RetoldRemote.CurrentViewerFile);
|
|
547
|
-
};
|
|
548
|
-
tmpFragment.appendChild(tmpBtn);
|
|
563
|
+
// Always show the Explore button in the header nav bar for images
|
|
564
|
+
let tmpHeaderExploreBtn = document.getElementById('RetoldRemote-HeaderExploreBtn');
|
|
565
|
+
if (tmpHeaderExploreBtn)
|
|
566
|
+
{
|
|
567
|
+
tmpHeaderExploreBtn.style.display = '';
|
|
568
|
+
}
|
|
549
569
|
|
|
550
570
|
// Dimension badge for large images
|
|
551
571
|
if (pShowExplore && pOrigWidth && pOrigHeight)
|
|
@@ -568,12 +588,6 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
568
588
|
+ 'id="RetoldRemote-ImageViewer-Img" '
|
|
569
589
|
+ 'onload="pict.views[\'RetoldRemote-ImageViewer\'].initImage()" '
|
|
570
590
|
+ 'onclick="pict.views[\'RetoldRemote-ImageViewer\'].toggleZoom()">';
|
|
571
|
-
// Explore button (hidden by default, shown by ImageViewer for large images)
|
|
572
|
-
tmpHTML += '<button class="retold-remote-image-explore-btn" id="RetoldRemote-ImageExploreBtn" '
|
|
573
|
-
+ 'style="display:none" '
|
|
574
|
-
+ 'onclick="pict.views[\'RetoldRemote-ImageExplorer\'].showExplorer(pict.AppData.RetoldRemote.CurrentViewerFile)" '
|
|
575
|
-
+ 'title="Open in deep-zoom explorer (e)">'
|
|
576
|
-
+ '🔍 Explore</button>';
|
|
577
591
|
return tmpHTML;
|
|
578
592
|
}
|
|
579
593
|
|
|
@@ -786,9 +800,7 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
786
800
|
|
|
787
801
|
if (tmpExtension === 'pdf')
|
|
788
802
|
{
|
|
789
|
-
return
|
|
790
|
-
+ 'style="width: 100%; height: 100%; border: none;">'
|
|
791
|
-
+ '</iframe>';
|
|
803
|
+
return this._buildPdfHTML(pURL, pFileName, pFilePath);
|
|
792
804
|
}
|
|
793
805
|
|
|
794
806
|
if (tmpExtension === 'epub' || tmpExtension === 'mobi')
|
|
@@ -796,7 +808,15 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
796
808
|
return this._buildEbookHTML(pURL, pFileName, pFilePath);
|
|
797
809
|
}
|
|
798
810
|
|
|
799
|
-
// For
|
|
811
|
+
// For convertible document types (doc, docx, rtf, odt, wpd, etc.),
|
|
812
|
+
// show the PDF viewer shell — conversion happens async in _loadDocumentViewer
|
|
813
|
+
let tmpConvertibleExts = { 'doc': true, 'docx': true, 'rtf': true, 'odt': true, 'wpd': true, 'wps': true, 'pages': true, 'odp': true, 'ppt': true, 'pptx': true, 'ods': true, 'xls': true, 'xlsx': true };
|
|
814
|
+
if (tmpConvertibleExts[tmpExtension])
|
|
815
|
+
{
|
|
816
|
+
return this._buildPdfHTML(pURL, pFileName, pFilePath);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// Unknown document types: show a download link
|
|
800
820
|
let tmpIconProvider = this.pict.providers['RetoldRemote-Icons'];
|
|
801
821
|
let tmpDocIconHTML = tmpIconProvider ? '<span class="retold-remote-icon retold-remote-icon-lg">' + tmpIconProvider.getIcon('document-large', 64) + '</span>' : '📄';
|
|
802
822
|
return '<div style="text-align: center; padding: 40px;">'
|
|
@@ -813,6 +833,60 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
813
833
|
// ebookGoToChapter, ebookPrevPage, ebookNextPage, toggleEbookTOC
|
|
814
834
|
// are in MediaViewer-EbookViewer.js (mixed in below).
|
|
815
835
|
|
|
836
|
+
/**
|
|
837
|
+
* Convert a document (doc, docx, rtf, odt, wpd, etc.) to PDF and load in the PDF viewer.
|
|
838
|
+
* Shows a converting message in the PDF content area while waiting.
|
|
839
|
+
*
|
|
840
|
+
* @param {string} pFilePath - Relative file path
|
|
841
|
+
*/
|
|
842
|
+
_loadConvertedDocumentViewer(pFilePath)
|
|
843
|
+
{
|
|
844
|
+
let tmpSelf = this;
|
|
845
|
+
let tmpProvider = this.pict.providers['RetoldRemote-Provider'];
|
|
846
|
+
let tmpPathParam = tmpProvider ? tmpProvider._getPathParam(pFilePath) : encodeURIComponent(pFilePath);
|
|
847
|
+
|
|
848
|
+
// Show converting message in the PDF content area
|
|
849
|
+
let tmpContent = document.getElementById('RetoldRemote-PdfContent');
|
|
850
|
+
if (tmpContent)
|
|
851
|
+
{
|
|
852
|
+
tmpContent.innerHTML = '<div style="text-align:center;padding:40px;color:var(--retold-text-dim);">'
|
|
853
|
+
+ '<div style="font-size:1.5rem;margin-bottom:12px;">⚙</div>'
|
|
854
|
+
+ 'Converting document to PDF\u2026'
|
|
855
|
+
+ '</div>';
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
fetch('/api/media/doc-convert?path=' + tmpPathParam)
|
|
859
|
+
.then((pResponse) => pResponse.json())
|
|
860
|
+
.then((pData) =>
|
|
861
|
+
{
|
|
862
|
+
if (!pData || !pData.Success)
|
|
863
|
+
{
|
|
864
|
+
throw new Error(pData ? pData.Error : 'Conversion failed.');
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
// Build the PDF URL from the ebook cache (same serving endpoint)
|
|
868
|
+
let tmpPdfURL = '/api/media/ebook/' + pData.CacheKey + '/' + pData.OutputFilename;
|
|
869
|
+
|
|
870
|
+
// Load the PDF viewer with the converted file
|
|
871
|
+
tmpSelf._loadPdfViewer(tmpPdfURL, pFilePath);
|
|
872
|
+
})
|
|
873
|
+
.catch((pError) =>
|
|
874
|
+
{
|
|
875
|
+
if (tmpContent)
|
|
876
|
+
{
|
|
877
|
+
let tmpFmt = tmpSelf.pict.providers['RetoldRemote-FormattingUtilities'];
|
|
878
|
+
tmpContent.innerHTML = '<div style="text-align:center;padding:40px;color:var(--retold-text-dim);">'
|
|
879
|
+
+ '<div style="margin-bottom:12px;color:#e06c75;">Conversion failed</div>'
|
|
880
|
+
+ '<div style="font-size:0.85rem;">' + tmpFmt.escapeHTML(pError.message) + '</div>'
|
|
881
|
+
+ '<div style="margin-top:16px;">'
|
|
882
|
+
+ '<a href="' + (tmpProvider ? tmpProvider.getContentURL(pFilePath) : '/content/' + encodeURIComponent(pFilePath))
|
|
883
|
+
+ '" target="_blank" style="color:var(--retold-accent);font-size:0.85rem;">Download original file</a>'
|
|
884
|
+
+ '</div>'
|
|
885
|
+
+ '</div>';
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
|
|
816
890
|
_buildFallbackHTML(pURL, pFileName)
|
|
817
891
|
{
|
|
818
892
|
let tmpIconProvider = this.pict.providers['RetoldRemote-Icons'];
|
|
@@ -942,6 +1016,7 @@ class RetoldRemoteMediaViewerView extends libPictView
|
|
|
942
1016
|
|
|
943
1017
|
Object.assign(RetoldRemoteMediaViewerView.prototype, _MediaViewerEbookViewer);
|
|
944
1018
|
Object.assign(RetoldRemoteMediaViewerView.prototype, _MediaViewerCodeViewer);
|
|
1019
|
+
Object.assign(RetoldRemoteMediaViewerView.prototype, _MediaViewerPdfViewer);
|
|
945
1020
|
|
|
946
1021
|
RetoldRemoteMediaViewerView.default_configuration = _ViewConfiguration;
|
|
947
1022
|
|