retold-remote 0.0.1

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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/css/retold-remote.css +83 -0
  3. package/html/codejar.js +511 -0
  4. package/html/index.html +23 -0
  5. package/package.json +68 -0
  6. package/server.js +43 -0
  7. package/source/Pict-Application-RetoldRemote-Configuration.json +7 -0
  8. package/source/Pict-Application-RetoldRemote.js +622 -0
  9. package/source/Pict-RetoldRemote-Bundle.js +14 -0
  10. package/source/cli/RetoldRemote-CLI-Program.js +15 -0
  11. package/source/cli/RetoldRemote-CLI-Run.js +3 -0
  12. package/source/cli/RetoldRemote-Server-Setup.js +257 -0
  13. package/source/cli/commands/RetoldRemote-Command-Serve.js +87 -0
  14. package/source/providers/Pict-Provider-GalleryFilterSort.js +597 -0
  15. package/source/providers/Pict-Provider-GalleryNavigation.js +819 -0
  16. package/source/providers/Pict-Provider-RetoldRemote.js +273 -0
  17. package/source/providers/Pict-Provider-RetoldRemoteIcons.js +640 -0
  18. package/source/providers/Pict-Provider-RetoldRemoteTheme.js +879 -0
  19. package/source/server/RetoldRemote-MediaService.js +536 -0
  20. package/source/server/RetoldRemote-PathRegistry.js +121 -0
  21. package/source/server/RetoldRemote-ThumbnailCache.js +89 -0
  22. package/source/server/RetoldRemote-ToolDetector.js +78 -0
  23. package/source/views/PictView-Remote-Gallery.js +1437 -0
  24. package/source/views/PictView-Remote-ImageViewer.js +363 -0
  25. package/source/views/PictView-Remote-Layout.js +420 -0
  26. package/source/views/PictView-Remote-MediaViewer.js +530 -0
  27. package/source/views/PictView-Remote-SettingsPanel.js +318 -0
  28. package/source/views/PictView-Remote-TopBar.js +206 -0
  29. package/web-application/codejar.js +511 -0
  30. package/web-application/css/retold-remote.css +83 -0
  31. package/web-application/index.html +23 -0
  32. package/web-application/js/pict.min.js +12 -0
  33. package/web-application/js/pict.min.js.map +1 -0
  34. package/web-application/retold-remote.compatible.js +5764 -0
  35. package/web-application/retold-remote.compatible.js.map +1 -0
  36. package/web-application/retold-remote.compatible.min.js +120 -0
  37. package/web-application/retold-remote.compatible.min.js.map +1 -0
  38. package/web-application/retold-remote.js +5763 -0
  39. package/web-application/retold-remote.js.map +1 -0
  40. package/web-application/retold-remote.min.js +120 -0
  41. package/web-application/retold-remote.min.js.map +1 -0
@@ -0,0 +1,420 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "ContentEditor-Layout",
6
+
7
+ DefaultRenderable: "RetoldRemote-Layout-Shell",
8
+ DefaultDestinationAddress: "#ContentEditor-Application-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ #ContentEditor-Application-Container
14
+ {
15
+ display: flex;
16
+ flex-direction: column;
17
+ height: 100vh;
18
+ background: var(--retold-bg-primary);
19
+ color: var(--retold-text-primary);
20
+ font-family: var(--retold-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
21
+ }
22
+ #ContentEditor-TopBar-Container
23
+ {
24
+ flex-shrink: 0;
25
+ }
26
+ .content-editor-body
27
+ {
28
+ display: flex;
29
+ flex: 1;
30
+ min-height: 0;
31
+ overflow: hidden;
32
+ }
33
+ /* Sidebar */
34
+ .content-editor-sidebar-wrap
35
+ {
36
+ display: flex;
37
+ flex-shrink: 0;
38
+ position: relative;
39
+ transition: width 0.2s ease;
40
+ }
41
+ .content-editor-sidebar-inner
42
+ {
43
+ display: flex;
44
+ flex-direction: column;
45
+ flex: 1;
46
+ min-width: 0;
47
+ min-height: 0;
48
+ overflow: hidden;
49
+ }
50
+ .content-editor-sidebar-tabs
51
+ {
52
+ display: flex;
53
+ flex-shrink: 0;
54
+ border-bottom: 1px solid var(--retold-border);
55
+ background: var(--retold-bg-secondary);
56
+ }
57
+ .content-editor-sidebar-tab
58
+ {
59
+ flex: 1;
60
+ padding: 7px 0;
61
+ border: none;
62
+ background: transparent;
63
+ font-size: 0.78rem;
64
+ font-weight: 600;
65
+ color: var(--retold-text-muted);
66
+ cursor: pointer;
67
+ border-bottom: 2px solid transparent;
68
+ transition: color 0.15s, border-color 0.15s;
69
+ font-family: inherit;
70
+ }
71
+ .content-editor-sidebar-tab:hover
72
+ {
73
+ color: var(--retold-text-secondary);
74
+ }
75
+ .content-editor-sidebar-tab.active
76
+ {
77
+ color: var(--retold-accent);
78
+ border-bottom-color: var(--retold-accent);
79
+ }
80
+ .content-editor-sidebar-pane
81
+ {
82
+ flex: 1;
83
+ overflow-y: auto;
84
+ overflow-x: hidden;
85
+ min-width: 0;
86
+ min-height: 0;
87
+ }
88
+ #ContentEditor-Sidebar-Container
89
+ {
90
+ background: var(--retold-bg-tertiary);
91
+ }
92
+ /* Collapsed state */
93
+ .content-editor-sidebar-wrap.collapsed
94
+ {
95
+ width: 0 !important;
96
+ }
97
+ .content-editor-sidebar-wrap.collapsed .content-editor-sidebar-inner
98
+ {
99
+ visibility: hidden;
100
+ }
101
+ .content-editor-sidebar-wrap.collapsed .content-editor-resize-handle
102
+ {
103
+ display: none;
104
+ }
105
+ /* Collapse toggle */
106
+ .content-editor-sidebar-toggle
107
+ {
108
+ position: absolute;
109
+ top: 8px;
110
+ right: -20px;
111
+ width: 20px;
112
+ height: 28px;
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: center;
116
+ background: var(--retold-bg-tertiary);
117
+ border: 1px solid var(--retold-border);
118
+ border-left: none;
119
+ border-radius: 0 4px 4px 0;
120
+ cursor: pointer;
121
+ z-index: 10;
122
+ color: var(--retold-text-muted);
123
+ font-size: 11px;
124
+ line-height: 1;
125
+ transition: color 0.15s;
126
+ }
127
+ .content-editor-sidebar-toggle:hover
128
+ {
129
+ color: var(--retold-text-primary);
130
+ }
131
+ /* Resize handle */
132
+ .content-editor-resize-handle
133
+ {
134
+ flex-shrink: 0;
135
+ width: 5px;
136
+ cursor: col-resize;
137
+ background: transparent;
138
+ border-right: 1px solid var(--retold-border);
139
+ transition: background 0.15s;
140
+ }
141
+ .content-editor-resize-handle:hover,
142
+ .content-editor-resize-handle.dragging
143
+ {
144
+ background: var(--retold-accent);
145
+ border-right-color: var(--retold-accent);
146
+ }
147
+ /* File browser overrides for sidebar */
148
+ #ContentEditor-Sidebar-Container .pict-filebrowser
149
+ {
150
+ border: none;
151
+ border-radius: 0;
152
+ background: transparent;
153
+ color: var(--retold-text-secondary);
154
+ }
155
+ #ContentEditor-Sidebar-Container .pict-filebrowser-browse-pane
156
+ {
157
+ display: none;
158
+ }
159
+ #ContentEditor-Sidebar-Container .pict-filebrowser-view-pane
160
+ {
161
+ display: none;
162
+ }
163
+ #ContentEditor-Sidebar-Container .pict-fb-detail-col-size,
164
+ #ContentEditor-Sidebar-Container .pict-fb-detail-col-modified,
165
+ #ContentEditor-Sidebar-Container .pict-fb-detail-size,
166
+ #ContentEditor-Sidebar-Container .pict-fb-detail-modified
167
+ {
168
+ display: none;
169
+ }
170
+ #ContentEditor-Sidebar-Container .pict-fb-detail-header
171
+ {
172
+ display: none;
173
+ }
174
+ #ContentEditor-Sidebar-Container .pict-fb-detail-row
175
+ {
176
+ color: var(--retold-text-secondary);
177
+ border-bottom-color: var(--retold-border);
178
+ }
179
+ #ContentEditor-Sidebar-Container .pict-fb-detail-row:hover
180
+ {
181
+ background: var(--retold-bg-hover);
182
+ color: var(--retold-text-primary);
183
+ }
184
+ #ContentEditor-Sidebar-Container .pict-fb-detail-row.selected
185
+ {
186
+ background: var(--retold-bg-selected);
187
+ color: var(--retold-accent);
188
+ }
189
+ #ContentEditor-Sidebar-Container .pict-fb-breadcrumbs
190
+ {
191
+ color: var(--retold-text-muted);
192
+ background: var(--retold-bg-secondary);
193
+ border-bottom-color: var(--retold-border);
194
+ }
195
+ #ContentEditor-Sidebar-Container .pict-fb-breadcrumb-link
196
+ {
197
+ color: var(--retold-accent);
198
+ }
199
+ /* Main content area */
200
+ #RetoldRemote-Content-Container
201
+ {
202
+ flex: 1;
203
+ overflow-y: auto;
204
+ position: relative;
205
+ }
206
+ #RetoldRemote-Gallery-Container
207
+ {
208
+ padding: 12px;
209
+ min-height: 100%;
210
+ }
211
+ #RetoldRemote-Viewer-Container
212
+ {
213
+ position: absolute;
214
+ top: 0;
215
+ left: 0;
216
+ right: 0;
217
+ bottom: 0;
218
+ background: var(--retold-bg-viewer);
219
+ display: none;
220
+ }
221
+ /* Also hide the editor container from the parent */
222
+ #ContentEditor-Editor-Container
223
+ {
224
+ display: none;
225
+ }
226
+ `,
227
+
228
+ Templates:
229
+ [
230
+ {
231
+ Hash: "RetoldRemote-Layout-Shell",
232
+ Template: /*html*/`
233
+ <div id="ContentEditor-TopBar-Container"></div>
234
+ <div class="content-editor-body">
235
+ <div class="content-editor-sidebar-wrap" style="width: 250px;">
236
+ <div class="content-editor-sidebar-toggle" onclick="pict.views['ContentEditor-Layout'].toggleSidebar()">&#9664;</div>
237
+ <div class="content-editor-sidebar-inner">
238
+ <div class="content-editor-sidebar-tabs">
239
+ <button class="content-editor-sidebar-tab active" data-tab="files" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('files')">Files</button>
240
+ <button class="content-editor-sidebar-tab" data-tab="settings" onclick="pict.views['ContentEditor-Layout'].switchSidebarTab('settings')">Settings</button>
241
+ </div>
242
+ <div class="content-editor-sidebar-pane" data-pane="files" id="ContentEditor-Sidebar-Container"></div>
243
+ <div class="content-editor-sidebar-pane" data-pane="settings" id="RetoldRemote-Settings-Container" style="display:none"></div>
244
+ </div>
245
+ <div class="content-editor-resize-handle"></div>
246
+ </div>
247
+ <div id="RetoldRemote-Content-Container">
248
+ <div id="RetoldRemote-Gallery-Container"></div>
249
+ <div id="RetoldRemote-Viewer-Container"></div>
250
+ </div>
251
+ </div>
252
+ `
253
+ }
254
+ ],
255
+
256
+ Renderables:
257
+ [
258
+ {
259
+ RenderableHash: "RetoldRemote-Layout-Shell",
260
+ TemplateHash: "RetoldRemote-Layout-Shell",
261
+ DestinationAddress: "#ContentEditor-Application-Container"
262
+ }
263
+ ]
264
+ };
265
+
266
+ class RetoldRemoteLayoutView extends libPictView
267
+ {
268
+ constructor(pFable, pOptions, pServiceHash)
269
+ {
270
+ super(pFable, pOptions, pServiceHash);
271
+
272
+ this._sidebarDragging = false;
273
+ }
274
+
275
+ onAfterRender()
276
+ {
277
+ super.onAfterRender();
278
+
279
+ // Inject all view CSS into the page
280
+ this.pict.CSSMap.injectCSS();
281
+
282
+ // Set up sidebar resize handle
283
+ this._setupResizeHandle();
284
+
285
+ // Restore sidebar state from settings
286
+ let tmpRemote = this.pict.AppData.RetoldRemote;
287
+ if (tmpRemote && tmpRemote.SidebarCollapsed)
288
+ {
289
+ let tmpWrap = document.querySelector('.content-editor-sidebar-wrap');
290
+ if (tmpWrap)
291
+ {
292
+ tmpWrap.classList.add('collapsed');
293
+ }
294
+ }
295
+ if (tmpRemote && tmpRemote.SidebarWidth)
296
+ {
297
+ let tmpWrap = document.querySelector('.content-editor-sidebar-wrap');
298
+ if (tmpWrap && !tmpWrap.classList.contains('collapsed'))
299
+ {
300
+ tmpWrap.style.width = tmpRemote.SidebarWidth + 'px';
301
+ }
302
+ }
303
+
304
+ // Listen for hash changes (browser back/forward)
305
+ let tmpSelf = this;
306
+ window.addEventListener('hashchange', () =>
307
+ {
308
+ tmpSelf.pict.PictApplication.resolveHash();
309
+ });
310
+ }
311
+
312
+ toggleSidebar()
313
+ {
314
+ let tmpWrap = document.querySelector('.content-editor-sidebar-wrap');
315
+ if (!tmpWrap)
316
+ {
317
+ return;
318
+ }
319
+
320
+ tmpWrap.classList.toggle('collapsed');
321
+
322
+ let tmpRemote = this.pict.AppData.RetoldRemote;
323
+ tmpRemote.SidebarCollapsed = tmpWrap.classList.contains('collapsed');
324
+ this.pict.PictApplication.saveSettings();
325
+
326
+ // Recalculate gallery columns after sidebar resize
327
+ let tmpNavProvider = this.pict.providers['RetoldRemote-GalleryNavigation'];
328
+ if (tmpNavProvider)
329
+ {
330
+ setTimeout(() => tmpNavProvider.recalculateColumns(), 250);
331
+ }
332
+ }
333
+
334
+ switchSidebarTab(pTab)
335
+ {
336
+ // Update tab buttons
337
+ let tmpTabs = document.querySelectorAll('.content-editor-sidebar-tab');
338
+ tmpTabs.forEach((pEl) =>
339
+ {
340
+ pEl.classList.toggle('active', pEl.getAttribute('data-tab') === pTab);
341
+ });
342
+
343
+ // Update panes
344
+ let tmpPanes = document.querySelectorAll('.content-editor-sidebar-pane');
345
+ tmpPanes.forEach((pEl) =>
346
+ {
347
+ pEl.style.display = (pEl.getAttribute('data-pane') === pTab) ? '' : 'none';
348
+ });
349
+
350
+ // Render settings panel on demand
351
+ if (pTab === 'settings')
352
+ {
353
+ let tmpSettingsView = this.pict.views['RetoldRemote-SettingsPanel'];
354
+ if (tmpSettingsView)
355
+ {
356
+ tmpSettingsView.render();
357
+ }
358
+ }
359
+ }
360
+
361
+ _setupResizeHandle()
362
+ {
363
+ let tmpSelf = this;
364
+ let tmpHandle = document.querySelector('.content-editor-resize-handle');
365
+ let tmpWrap = document.querySelector('.content-editor-sidebar-wrap');
366
+
367
+ if (!tmpHandle || !tmpWrap)
368
+ {
369
+ return;
370
+ }
371
+
372
+ let tmpStartX = 0;
373
+ let tmpStartWidth = 0;
374
+
375
+ function onMouseDown(pEvent)
376
+ {
377
+ tmpSelf._sidebarDragging = true;
378
+ tmpStartX = pEvent.clientX;
379
+ tmpStartWidth = tmpWrap.offsetWidth;
380
+ tmpHandle.classList.add('dragging');
381
+ document.addEventListener('mousemove', onMouseMove);
382
+ document.addEventListener('mouseup', onMouseUp);
383
+ pEvent.preventDefault();
384
+ }
385
+
386
+ function onMouseMove(pEvent)
387
+ {
388
+ if (!tmpSelf._sidebarDragging) return;
389
+ let tmpNewWidth = tmpStartWidth + (pEvent.clientX - tmpStartX);
390
+ tmpNewWidth = Math.max(150, Math.min(tmpNewWidth, 600));
391
+ tmpWrap.style.width = tmpNewWidth + 'px';
392
+ }
393
+
394
+ function onMouseUp()
395
+ {
396
+ tmpSelf._sidebarDragging = false;
397
+ tmpHandle.classList.remove('dragging');
398
+ document.removeEventListener('mousemove', onMouseMove);
399
+ document.removeEventListener('mouseup', onMouseUp);
400
+
401
+ // Persist width
402
+ let tmpRemote = tmpSelf.pict.AppData.RetoldRemote;
403
+ tmpRemote.SidebarWidth = tmpWrap.offsetWidth;
404
+ tmpSelf.pict.PictApplication.saveSettings();
405
+
406
+ // Recalculate gallery columns
407
+ let tmpNavProvider = tmpSelf.pict.providers['RetoldRemote-GalleryNavigation'];
408
+ if (tmpNavProvider)
409
+ {
410
+ tmpNavProvider.recalculateColumns();
411
+ }
412
+ }
413
+
414
+ tmpHandle.addEventListener('mousedown', onMouseDown);
415
+ }
416
+ }
417
+
418
+ RetoldRemoteLayoutView.default_configuration = _ViewConfiguration;
419
+
420
+ module.exports = RetoldRemoteLayoutView;