retold-remote 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.
Files changed (63) hide show
  1. package/docs/README.md +181 -0
  2. package/docs/_cover.md +14 -0
  3. package/docs/_sidebar.md +10 -0
  4. package/docs/_topbar.md +3 -0
  5. package/docs/audio-viewer.md +133 -0
  6. package/docs/ebook-reader.md +90 -0
  7. package/docs/image-viewer.md +90 -0
  8. package/docs/server-setup.md +262 -0
  9. package/docs/video-viewer.md +134 -0
  10. package/html/docs.html +59 -0
  11. package/package.json +21 -7
  12. package/source/Pict-Application-RetoldRemote.js +143 -2
  13. package/source/RetoldRemote-ExtensionMaps.js +33 -0
  14. package/source/cli/RetoldRemote-Server-Setup.js +82 -67
  15. package/source/cli/commands/RetoldRemote-Command-Serve.js +5 -26
  16. package/source/providers/Pict-Provider-CollectionManager.js +934 -0
  17. package/source/providers/Pict-Provider-FormattingUtilities.js +109 -0
  18. package/source/providers/Pict-Provider-GalleryFilterSort.js +2 -11
  19. package/source/providers/Pict-Provider-GalleryNavigation.js +270 -353
  20. package/source/providers/Pict-Provider-RetoldRemoteIcons.js +52 -0
  21. package/source/providers/Pict-Provider-ToastNotification.js +96 -0
  22. package/source/providers/keyboard-handlers/KeyHandler-AudioExplorer.js +88 -0
  23. package/source/providers/keyboard-handlers/KeyHandler-Gallery.js +190 -0
  24. package/source/providers/keyboard-handlers/KeyHandler-Sidebar.js +65 -0
  25. package/source/providers/keyboard-handlers/KeyHandler-VideoExplorer.js +57 -0
  26. package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +197 -0
  27. package/source/server/RetoldRemote-ArchiveService.js +2 -12
  28. package/source/server/RetoldRemote-AudioWaveformService.js +7 -16
  29. package/source/server/RetoldRemote-CollectionService.js +684 -0
  30. package/source/server/RetoldRemote-EbookService.js +7 -16
  31. package/source/server/RetoldRemote-MediaService.js +3 -14
  32. package/source/server/RetoldRemote-ParimeCache.js +349 -0
  33. package/source/server/RetoldRemote-ThumbnailCache.js +52 -20
  34. package/source/server/RetoldRemote-VideoFrameService.js +7 -15
  35. package/source/views/PictView-Remote-AudioExplorer.js +10 -43
  36. package/source/views/PictView-Remote-CollectionsPanel.js +1087 -0
  37. package/source/views/PictView-Remote-Gallery.js +237 -44
  38. package/source/views/PictView-Remote-ImageViewer.js +1 -34
  39. package/source/views/PictView-Remote-Layout.js +410 -20
  40. package/source/views/PictView-Remote-MediaViewer.js +338 -51
  41. package/source/views/PictView-Remote-SettingsPanel.js +155 -138
  42. package/source/views/PictView-Remote-TopBar.js +615 -14
  43. package/source/views/PictView-Remote-VLCSetup.js +766 -0
  44. package/source/views/PictView-Remote-VideoExplorer.js +20 -54
  45. package/web-application/css/docuserve.css +73 -0
  46. package/web-application/docs/README.md +181 -0
  47. package/web-application/docs/_cover.md +14 -0
  48. package/web-application/docs/_sidebar.md +10 -0
  49. package/web-application/docs/_topbar.md +3 -0
  50. package/web-application/docs/audio-viewer.md +133 -0
  51. package/web-application/docs/ebook-reader.md +90 -0
  52. package/web-application/docs/image-viewer.md +90 -0
  53. package/web-application/docs/server-setup.md +262 -0
  54. package/web-application/docs/video-viewer.md +134 -0
  55. package/web-application/docs.html +59 -0
  56. package/web-application/js/pict-docuserve.min.js +58 -0
  57. package/web-application/js/pict.min.js +2 -2
  58. package/web-application/js/pict.min.js.map +1 -1
  59. package/web-application/retold-remote.js +2558 -439
  60. package/web-application/retold-remote.js.map +1 -1
  61. package/web-application/retold-remote.min.js +41 -11
  62. package/web-application/retold-remote.min.js.map +1 -1
  63. package/server.js +0 -43
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Viewer mode keyboard handler.
3
+ *
4
+ * @param {GalleryNavigationProvider} pGalleryNav - The provider instance
5
+ * @param {KeyboardEvent} pEvent - The keyboard event
6
+ */
7
+ function handleViewerKey(pGalleryNav, pEvent)
8
+ {
9
+ let tmpRemote = pGalleryNav.pict.AppData.RetoldRemote;
10
+
11
+ // Video action menu mode — intercept keys for menu options
12
+ if (tmpRemote.VideoMenuActive && tmpRemote.CurrentViewerMediaType === 'video')
13
+ {
14
+ switch (pEvent.key)
15
+ {
16
+ case 'Escape':
17
+ pEvent.preventDefault();
18
+ pGalleryNav.closeViewer();
19
+ return;
20
+
21
+ case 'ArrowRight':
22
+ case 'j':
23
+ pEvent.preventDefault();
24
+ pGalleryNav.nextFile();
25
+ return;
26
+
27
+ case 'ArrowLeft':
28
+ case 'k':
29
+ pEvent.preventDefault();
30
+ pGalleryNav.prevFile();
31
+ return;
32
+
33
+ case 'e':
34
+ pEvent.preventDefault();
35
+ let tmpVEX = pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];
36
+ if (tmpVEX)
37
+ {
38
+ tmpVEX.showExplorer(tmpRemote.CurrentViewerFile);
39
+ }
40
+ return;
41
+
42
+ case ' ':
43
+ case 'Enter':
44
+ pEvent.preventDefault();
45
+ let tmpViewer = pGalleryNav.pict.views['RetoldRemote-MediaViewer'];
46
+ if (tmpViewer)
47
+ {
48
+ tmpViewer.playVideo();
49
+ }
50
+ return;
51
+
52
+ case 't':
53
+ pEvent.preventDefault();
54
+ let tmpMediaViewer = pGalleryNav.pict.views['RetoldRemote-MediaViewer'];
55
+ if (tmpMediaViewer)
56
+ {
57
+ tmpMediaViewer.loadVideoMenuFrame();
58
+ }
59
+ return;
60
+
61
+ case 'v':
62
+ pEvent.preventDefault();
63
+ pGalleryNav._streamWithVLC();
64
+ return;
65
+ }
66
+ return;
67
+ }
68
+
69
+ switch (pEvent.key)
70
+ {
71
+ case 'Escape':
72
+ pEvent.preventDefault();
73
+ pGalleryNav.closeViewer();
74
+ break;
75
+
76
+ case 'ArrowRight':
77
+ case 'j':
78
+ pEvent.preventDefault();
79
+ pGalleryNav.nextFile();
80
+ break;
81
+
82
+ case 'ArrowLeft':
83
+ case 'k':
84
+ pEvent.preventDefault();
85
+ pGalleryNav.prevFile();
86
+ break;
87
+
88
+ case 'f':
89
+ pEvent.preventDefault();
90
+ pGalleryNav._toggleFullscreen();
91
+ break;
92
+
93
+ case 'i':
94
+ pEvent.preventDefault();
95
+ pGalleryNav._toggleFileInfo();
96
+ break;
97
+
98
+ case ' ':
99
+ pEvent.preventDefault();
100
+ pGalleryNav._togglePlayPause();
101
+ break;
102
+
103
+ case '+':
104
+ case '=':
105
+ pEvent.preventDefault();
106
+ pGalleryNav._zoomIn();
107
+ break;
108
+
109
+ case '-':
110
+ pEvent.preventDefault();
111
+ pGalleryNav._zoomOut();
112
+ break;
113
+
114
+ case '0':
115
+ pEvent.preventDefault();
116
+ pGalleryNav._zoomReset();
117
+ break;
118
+
119
+ case 'z':
120
+ pEvent.preventDefault();
121
+ pGalleryNav._cycleFitMode();
122
+ break;
123
+
124
+ case 'Enter':
125
+ pEvent.preventDefault();
126
+ pGalleryNav._streamWithVLC();
127
+ break;
128
+
129
+ case 'v':
130
+ pEvent.preventDefault();
131
+ pGalleryNav._streamWithVLC();
132
+ break;
133
+
134
+ case 'a':
135
+ pEvent.preventDefault();
136
+ {
137
+ let tmpCollMgr = pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];
138
+ if (tmpCollMgr)
139
+ {
140
+ let tmpRemote = pGalleryNav.pict.AppData.RetoldRemote;
141
+ if (tmpRemote.LastUsedCollectionGUID)
142
+ {
143
+ // Quick-add the currently viewed file
144
+ tmpCollMgr.addCurrentFileToCollection(tmpRemote.LastUsedCollectionGUID);
145
+ }
146
+ else
147
+ {
148
+ // No last-used collection — open the picker
149
+ let tmpTopBar = pGalleryNav.pict.views['ContentEditor-TopBar'];
150
+ if (tmpTopBar && typeof tmpTopBar.showAddToCollectionDropdown === 'function')
151
+ {
152
+ tmpTopBar.showAddToCollectionDropdown();
153
+ }
154
+ }
155
+ }
156
+ }
157
+ break;
158
+
159
+ case 'b':
160
+ pEvent.preventDefault();
161
+ {
162
+ let tmpCollManager = pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];
163
+ if (tmpCollManager)
164
+ {
165
+ tmpCollManager.togglePanel();
166
+ }
167
+ }
168
+ break;
169
+
170
+ case 'd':
171
+ pEvent.preventDefault();
172
+ pGalleryNav._toggleDistractionFree();
173
+ break;
174
+
175
+ case '1':
176
+ pEvent.preventDefault();
177
+ pGalleryNav.switchViewerType('image');
178
+ break;
179
+
180
+ case '2':
181
+ pEvent.preventDefault();
182
+ pGalleryNav.switchViewerType('video');
183
+ break;
184
+
185
+ case '3':
186
+ pEvent.preventDefault();
187
+ pGalleryNav.switchViewerType('audio');
188
+ break;
189
+
190
+ case '4':
191
+ pEvent.preventDefault();
192
+ pGalleryNav.switchViewerType('text');
193
+ break;
194
+ }
195
+ }
196
+
197
+ module.exports = handleViewerKey;
@@ -59,8 +59,7 @@ const _MimeTypes =
59
59
 
60
60
  const _DefaultServiceConfiguration =
61
61
  {
62
- "ContentPath": ".",
63
- "CachePath": null
62
+ "ContentPath": "."
64
63
  };
65
64
 
66
65
  class RetoldRemoteArchiveService extends libFableServiceProviderBase
@@ -82,15 +81,6 @@ class RetoldRemoteArchiveService extends libFableServiceProviderBase
82
81
 
83
82
  this.contentPath = libPath.resolve(this.options.ContentPath);
84
83
 
85
- this.archiveCachePath = this.options.CachePath
86
- || libPath.join(process.cwd(), 'dist', 'retold-cache', 'archives');
87
-
88
- // Ensure cache directory exists
89
- if (!libFs.existsSync(this.archiveCachePath))
90
- {
91
- libFs.mkdirSync(this.archiveCachePath, { recursive: true });
92
- }
93
-
94
84
  // Detect 7z availability
95
85
  let tmpDetector = new libToolDetector();
96
86
  let tmpCapabilities = tmpDetector.detect();
@@ -246,7 +236,7 @@ class RetoldRemoteArchiveService extends libFableServiceProviderBase
246
236
 
247
237
  let tmpInput = `${pArchiveAbsPath}:${tmpMtime}`;
248
238
  let tmpHash = libCrypto.createHash('sha256').update(tmpInput).digest('hex').substring(0, 16);
249
- let tmpDir = libPath.join(this.archiveCachePath, tmpHash);
239
+ let tmpDir = this.fable.ParimeBinaryStorage.resolvePath('archive-cache', tmpHash);
250
240
 
251
241
  if (!libFs.existsSync(tmpDir))
252
242
  {
@@ -23,7 +23,6 @@ const libChildProcess = require('child_process');
23
23
  const _DefaultServiceConfiguration =
24
24
  {
25
25
  "ContentPath": ".",
26
- "CachePath": null,
27
26
  "DefaultPeakCount": 2000,
28
27
  "DefaultSegmentFormat": "mp3",
29
28
  "MaxSegmentDuration": 600
@@ -48,19 +47,10 @@ class RetoldRemoteAudioWaveformService extends libFableServiceProviderBase
48
47
 
49
48
  this.contentPath = libPath.resolve(this.options.ContentPath);
50
49
 
51
- this.cachePath = this.options.CachePath
52
- || libPath.join(process.cwd(), 'dist', 'retold-cache', 'audio-waveforms');
53
-
54
- // Ensure cache directory exists
55
- if (!libFs.existsSync(this.cachePath))
56
- {
57
- libFs.mkdirSync(this.cachePath, { recursive: true });
58
- }
59
-
60
50
  // Detect audiowaveform availability
61
51
  this.hasAudiowaveform = this._detectCommand('audiowaveform --version');
62
52
 
63
- this.fable.log.info(`Audio Waveform Service: cache at ${this.cachePath}`);
53
+ this.fable.log.info('Audio Waveform Service: using ParimeBinaryStorage (categories: audio-waveforms, audio-segments)');
64
54
  this.fable.log.info(` audiowaveform tool: ${this.hasAudiowaveform ? 'available' : 'not found (using ffprobe fallback)'}`);
65
55
  }
66
56
 
@@ -95,7 +85,7 @@ class RetoldRemoteAudioWaveformService extends libFableServiceProviderBase
95
85
  {
96
86
  let tmpInput = `waveform:${pAbsPath}:${pMtimeMs}:${pPeakCount}`;
97
87
  let tmpHash = libCrypto.createHash('sha256').update(tmpInput).digest('hex').substring(0, 16);
98
- return libPath.join(this.cachePath, tmpHash);
88
+ return this.fable.ParimeBinaryStorage.resolvePath('audio-waveforms', tmpHash);
99
89
  }
100
90
 
101
91
  /**
@@ -112,7 +102,7 @@ class RetoldRemoteAudioWaveformService extends libFableServiceProviderBase
112
102
  {
113
103
  let tmpInput = `segment:${pAbsPath}:${pMtimeMs}:${pStart}:${pEnd}:${pFormat}`;
114
104
  let tmpHash = libCrypto.createHash('sha256').update(tmpInput).digest('hex').substring(0, 16);
115
- return libPath.join(this.cachePath, tmpHash);
105
+ return this.fable.ParimeBinaryStorage.resolvePath('audio-segments', tmpHash);
116
106
  }
117
107
 
118
108
  /**
@@ -652,11 +642,12 @@ class RetoldRemoteAudioWaveformService extends libFableServiceProviderBase
652
642
  return null;
653
643
  }
654
644
 
655
- let tmpPath = libPath.join(this.cachePath, pCacheKey, pFilename);
645
+ let tmpCacheDir = this.fable.ParimeBinaryStorage.resolvePath('audio-segments', pCacheKey);
646
+ let tmpPath = libPath.join(tmpCacheDir, pFilename);
656
647
 
657
- // Double-check it's under our cache dir
648
+ // Double-check it's under the storage root
658
649
  let tmpResolved = libPath.resolve(tmpPath);
659
- if (!tmpResolved.startsWith(this.cachePath))
650
+ if (!tmpResolved.startsWith(this.fable.ParimeBinaryStorage.storageRoot))
660
651
  {
661
652
  return null;
662
653
  }