retold-remote 0.0.5 → 0.0.7

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 (71) hide show
  1. package/css/retold-remote.css +3 -0
  2. package/docs/README.md +181 -0
  3. package/docs/_cover.md +14 -0
  4. package/docs/_sidebar.md +10 -0
  5. package/docs/_topbar.md +3 -0
  6. package/docs/audio-viewer.md +133 -0
  7. package/docs/ebook-reader.md +90 -0
  8. package/docs/image-viewer.md +90 -0
  9. package/docs/server-setup.md +262 -0
  10. package/docs/video-viewer.md +134 -0
  11. package/html/docs.html +59 -0
  12. package/html/index.html +1 -1
  13. package/package.json +20 -6
  14. package/source/Pict-Application-RetoldRemote.js +122 -2
  15. package/source/RetoldRemote-ExtensionMaps.js +33 -0
  16. package/source/cli/RetoldRemote-Server-Setup.js +211 -67
  17. package/source/cli/commands/RetoldRemote-Command-Serve.js +5 -26
  18. package/source/providers/Pict-Provider-AISortManager.js +456 -0
  19. package/source/providers/Pict-Provider-CollectionManager.js +1200 -0
  20. package/source/providers/Pict-Provider-FormattingUtilities.js +109 -0
  21. package/source/providers/Pict-Provider-GalleryFilterSort.js +2 -11
  22. package/source/providers/Pict-Provider-GalleryNavigation.js +187 -409
  23. package/source/providers/Pict-Provider-RetoldRemoteIcons.js +52 -0
  24. package/source/providers/Pict-Provider-ToastNotification.js +96 -0
  25. package/source/providers/keyboard-handlers/KeyHandler-AudioExplorer.js +88 -0
  26. package/source/providers/keyboard-handlers/KeyHandler-Gallery.js +190 -0
  27. package/source/providers/keyboard-handlers/KeyHandler-Sidebar.js +65 -0
  28. package/source/providers/keyboard-handlers/KeyHandler-VideoExplorer.js +57 -0
  29. package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +197 -0
  30. package/source/server/RetoldRemote-AISortService.js +879 -0
  31. package/source/server/RetoldRemote-ArchiveService.js +2 -12
  32. package/source/server/RetoldRemote-AudioWaveformService.js +7 -16
  33. package/source/server/RetoldRemote-CollectionService.js +843 -0
  34. package/source/server/RetoldRemote-EbookService.js +7 -16
  35. package/source/server/RetoldRemote-FileOperationService.js +560 -0
  36. package/source/server/RetoldRemote-MediaService.js +15 -14
  37. package/source/server/RetoldRemote-MetadataCache.js +411 -0
  38. package/source/server/RetoldRemote-ParimeCache.js +349 -0
  39. package/source/server/RetoldRemote-ThumbnailCache.js +52 -20
  40. package/source/server/RetoldRemote-VideoFrameService.js +7 -15
  41. package/source/views/PictView-Remote-AudioExplorer.js +10 -43
  42. package/source/views/PictView-Remote-CollectionsPanel.js +1486 -0
  43. package/source/views/PictView-Remote-Gallery.js +237 -44
  44. package/source/views/PictView-Remote-ImageViewer.js +1 -34
  45. package/source/views/PictView-Remote-Layout.js +411 -20
  46. package/source/views/PictView-Remote-MediaViewer.js +311 -28
  47. package/source/views/PictView-Remote-SettingsPanel.js +275 -133
  48. package/source/views/PictView-Remote-TopBar.js +701 -14
  49. package/source/views/PictView-Remote-VLCSetup.js +8 -39
  50. package/source/views/PictView-Remote-VideoExplorer.js +20 -54
  51. package/web-application/css/docuserve.css +73 -0
  52. package/web-application/css/retold-remote.css +3 -0
  53. package/web-application/docs/README.md +181 -0
  54. package/web-application/docs/_cover.md +14 -0
  55. package/web-application/docs/_sidebar.md +10 -0
  56. package/web-application/docs/_topbar.md +3 -0
  57. package/web-application/docs/audio-viewer.md +133 -0
  58. package/web-application/docs/ebook-reader.md +90 -0
  59. package/web-application/docs/image-viewer.md +90 -0
  60. package/web-application/docs/server-setup.md +262 -0
  61. package/web-application/docs/video-viewer.md +134 -0
  62. package/web-application/docs.html +59 -0
  63. package/web-application/index.html +1 -1
  64. package/web-application/js/pict-docuserve.min.js +58 -0
  65. package/web-application/js/pict.min.js +2 -2
  66. package/web-application/js/pict.min.js.map +1 -1
  67. package/web-application/retold-remote.js +2652 -970
  68. package/web-application/retold-remote.js.map +1 -1
  69. package/web-application/retold-remote.min.js +60 -13
  70. package/web-application/retold-remote.min.js.map +1 -1
  71. package/server.js +0 -43
@@ -0,0 +1,133 @@
1
+ # Audio Viewer and Explorer
2
+
3
+ The audio viewer provides HTML5 audio playback with an optional waveform explorer for visualizing, selecting, and extracting audio segments.
4
+
5
+ ## Opening an Audio File
6
+
7
+ - **From the gallery**: select an audio file and press `Enter`, or double-click it
8
+ - **Force any file as audio**: press `3` in the gallery or viewer to open it in the audio viewer regardless of extension
9
+
10
+ ## Audio Player
11
+
12
+ The viewer shows a centered audio player with the filename and native HTML5 audio controls (play/pause, seek bar, volume, playback speed).
13
+
14
+ Below the player, action buttons appear:
15
+
16
+ | Button | Requires | Description |
17
+ |--------|----------|-------------|
18
+ | **Explore Audio** | ffprobe or ffmpeg | Opens the waveform explorer |
19
+ | **Stream with VLC** | -- | Sends the file to VLC on the server |
20
+
21
+ ### Autoplay
22
+
23
+ Autoplay is off by default. Enable it in Settings > Gallery > Autoplay audio. When enabled, audio begins playing as soon as the player loads.
24
+
25
+ ## Audio Explorer
26
+
27
+ The audio explorer displays a canvas-based waveform visualization with selection, zoom, and segment extraction.
28
+
29
+ ### Opening the Explorer
30
+
31
+ - From the audio player, click "Explore Audio"
32
+ - The explorer fetches 2000 peak samples from the server via ffmpeg
33
+
34
+ ### Waveform Display
35
+
36
+ The main canvas shows the audio waveform as vertical bars. The height of each bar represents the amplitude at that point. A dashed center line marks the zero crossing.
37
+
38
+ - **Unselected regions** are drawn in the secondary text color
39
+ - **Selected regions** are drawn in the accent color with a semi-transparent highlight behind them
40
+ - A **cursor line** follows the mouse position, displayed in white
41
+
42
+ ### Overview Bar
43
+
44
+ Below the main waveform, a smaller overview canvas shows the entire audio file. A highlighted viewport indicator box shows which portion of the waveform is currently visible in the main canvas.
45
+
46
+ Click anywhere on the overview to pan the main view to that position.
47
+
48
+ ### Selection
49
+
50
+ **Click and drag** on the main waveform to select a time range. The selection is highlighted in the accent color with edge markers.
51
+
52
+ - If the selection is too small (less than 0.1% of the total duration), it is automatically cleared
53
+ - The selection is shown in both the main canvas and the overview
54
+
55
+ ### Time Display Bar
56
+
57
+ A bar above the waveform shows three pieces of information:
58
+
59
+ - **View**: the time range currently visible (e.g., "0:12.3 - 0:45.7")
60
+ - **Selection**: the selected time range and its duration (e.g., "0:20.0 - 0:30.5 (10.5s)"), or "None"
61
+ - **Cursor**: the time position under the mouse, or "--"
62
+
63
+ Timestamps are formatted as `M:SS.D` (minutes, seconds, tenths of a second) or `H:MM:SS.D` for long files.
64
+
65
+ ### Zoom Controls
66
+
67
+ | Key / Button | Action |
68
+ |--------------|--------|
69
+ | `+` or `=` | Zoom in (centered) |
70
+ | `-` | Zoom out (centered) |
71
+ | `0` | Zoom to fit (show entire file) |
72
+ | `z` | Zoom to selection (with 5% margin) |
73
+ | Mouse wheel | Zoom at cursor position |
74
+
75
+ Minimum zoom level is 0.5% of the total duration.
76
+
77
+ Zooming preserves the center point -- the portion of the waveform under the mouse (for wheel zoom) or the center (for keyboard zoom) stays in place while the view range narrows or widens.
78
+
79
+ ### Playing a Selection
80
+
81
+ With a selection active, press `Space` or click the Play Selection button to extract and play that audio segment.
82
+
83
+ The server extracts the segment via ffmpeg and returns it as an MP3 file. A playback bar appears with an HTML5 audio player for the extracted segment.
84
+
85
+ The extraction endpoint is `/api/media/audio-segment` with `start` and `end` parameters in seconds.
86
+
87
+ ### Info Bar
88
+
89
+ The explorer shows an info bar with metadata from ffprobe:
90
+
91
+ | Field | Example |
92
+ |-------|---------|
93
+ | Duration | 3:42 |
94
+ | Sample Rate | 44.1 kHz |
95
+ | Channels | 2 (stereo) |
96
+ | Codec | mp3 |
97
+ | Bitrate | 320 kbps |
98
+ | File Size | 8.7 MB |
99
+ | Peaks | 2000 (ffmpeg) |
100
+
101
+ ### Keyboard Shortcuts
102
+
103
+ | Key | Action |
104
+ |-----|--------|
105
+ | `Space` | Play selection |
106
+ | `+` / `=` | Zoom in |
107
+ | `-` | Zoom out |
108
+ | `0` | Zoom to fit |
109
+ | `z` | Zoom to selection |
110
+ | `Esc` | Clear selection (if any), or go back to audio player |
111
+
112
+ ### Mouse Interactions
113
+
114
+ | Action | Effect |
115
+ |--------|--------|
116
+ | Click and drag on main waveform | Create/adjust selection |
117
+ | Mouse move on main waveform | Show cursor position in time bar |
118
+ | Mouse wheel on main waveform | Zoom in/out at cursor position |
119
+ | Click on overview bar | Pan main view to that position |
120
+
121
+ ## File Info Overlay
122
+
123
+ Press `i` while viewing audio to see metadata:
124
+
125
+ - Size, Duration, Codec, Bitrate, Format, Modified date, Path
126
+
127
+ ## Supported Formats
128
+
129
+ mp3, wav, ogg, flac, aac, m4a, wma, oga
130
+
131
+ Browser playback support varies. Most browsers play mp3, wav, ogg, and flac natively. For other formats, use VLC streaming.
132
+
133
+ Force any file as audio by pressing `3` in the gallery or viewer.
@@ -0,0 +1,90 @@
1
+ # eBook Reader
2
+
3
+ The eBook reader displays EPUB files directly in the browser using epub.js, with support for MOBI files through server-side conversion.
4
+
5
+ ## Opening an eBook
6
+
7
+ - **From the gallery**: select an `.epub` or `.mobi` file and press `Enter`, or double-click it
8
+ - eBooks are detected by the document type system (pdf, epub, mobi are all in the document category)
9
+
10
+ ## EPUB Files
11
+
12
+ EPUB files are loaded and rendered directly in the browser using the epub.js library. No server-side processing is required.
13
+
14
+ ### Reading Interface
15
+
16
+ The reader takes up the full viewer area and displays one page at a time in a single-column layout (no spread/two-page mode). Text is styled to match the active theme:
17
+
18
+ - Body text uses the theme's primary text color
19
+ - Background matches the theme's primary background
20
+ - Links use the theme's accent color
21
+ - Font: Georgia, Times New Roman, serif
22
+ - Line height: 1.6
23
+ - Padding: 20px horizontal, 40px vertical
24
+
25
+ ### Table of Contents
26
+
27
+ A sidebar on the left shows the book's table of contents. Each chapter is a clickable button. Subchapters are indented up to two levels.
28
+
29
+ | Action | Effect |
30
+ |--------|--------|
31
+ | Click a chapter | Jump to that chapter |
32
+ | Click "TOC" button | Toggle the sidebar open/closed |
33
+
34
+ The TOC sidebar starts collapsed and can be toggled with the TOC button in the controls bar.
35
+
36
+ ### Page Navigation
37
+
38
+ Controls at the bottom of the reader:
39
+
40
+ | Button | Action |
41
+ |--------|--------|
42
+ | **TOC** | Toggle table of contents sidebar |
43
+ | **Prev** | Go to previous page |
44
+ | **Next** | Go to next page |
45
+
46
+ Page navigation moves through the reflowed content. Pages are determined by the viewport size, not by the original book pagination.
47
+
48
+ ## MOBI Files
49
+
50
+ MOBI files (and AZW format) require server-side conversion to EPUB before they can be displayed. This requires **ebook-convert** from Calibre to be installed on the server.
51
+
52
+ ### Conversion Flow
53
+
54
+ 1. The client requests conversion via `/api/media/ebook-convert?path=<file>`
55
+ 2. The server runs `ebook-convert` to produce an EPUB file
56
+ 3. The converted EPUB is cached on disk
57
+ 4. The client fetches the EPUB from `/api/media/ebook/<cacheKey>/<filename>`
58
+ 5. The EPUB is rendered using the same epub.js reader
59
+
60
+ If ebook-convert is not available, MOBI files show a message explaining that conversion is needed and linking to the Calibre download page.
61
+
62
+ ### Installing Calibre (for MOBI support)
63
+
64
+ **macOS:**
65
+ ```bash
66
+ brew install calibre
67
+ ```
68
+
69
+ **Ubuntu/Debian:**
70
+ ```bash
71
+ sudo apt-get install calibre
72
+ ```
73
+
74
+ **Docker:**
75
+ The provided Dockerfile includes Calibre. If using the minimal Dockerfile, add:
76
+ ```dockerfile
77
+ RUN apt-get update && apt-get install -y calibre && rm -rf /var/lib/apt/lists/*
78
+ ```
79
+
80
+ ## PDF Files
81
+
82
+ PDF files are rendered using the browser's native PDF viewer in an iframe. No additional tools or libraries are required. The browser provides its own controls for page navigation, zoom, and search.
83
+
84
+ ## Limitations
85
+
86
+ - MOBI conversion requires Calibre's `ebook-convert` on the server
87
+ - DRM-protected ebooks cannot be read
88
+ - Complex EPUB layouts (fixed-layout EPUBs, heavy CSS) may not render perfectly
89
+ - The reader uses single-page mode only (no two-page spreads)
90
+ - Page numbers shown in the UI correspond to the reflowed content, not the original book pagination
@@ -0,0 +1,90 @@
1
+ # Image Viewer
2
+
3
+ The image viewer displays image files with three fit modes, manual zoom, and EXIF orientation support.
4
+
5
+ ## Opening an Image
6
+
7
+ - **From the gallery**: select a file and press `Enter`, or double-click a tile
8
+ - **Force any file as image**: press `1` in the gallery or viewer to open it in the image viewer regardless of extension
9
+
10
+ ## Fit Modes
11
+
12
+ Cycle through fit modes by pressing `z`.
13
+
14
+ ### Fit to Window
15
+
16
+ Scales the image to fill the viewport while preserving aspect ratio (CSS `object-fit: contain` behavior). The image is never larger than the viewport.
17
+
18
+ ### Original if Smaller (default)
19
+
20
+ Displays the image at its native resolution if it fits within the viewport. If the image is larger than the viewport, it scales down using the same logic as Fit to Window. This avoids upscaling small images.
21
+
22
+ ### Original Size
23
+
24
+ Always displays at native resolution regardless of viewport size. Large images will overflow and can be scrolled.
25
+
26
+ When the fit mode changes, a brief overlay indicator appears for 1.2 seconds showing the active mode name.
27
+
28
+ ## Zoom
29
+
30
+ | Key | Action | Range |
31
+ |-----|--------|-------|
32
+ | `+` or `=` | Zoom in | Up to 8x |
33
+ | `-` | Zoom out | Down to 0.25x |
34
+ | `0` | Reset zoom to 1x | |
35
+ | Click on image | Toggle between 1x and 2x | |
36
+
37
+ Each zoom step multiplies or divides by 1.25. The zoom level applies on top of the current fit mode calculation.
38
+
39
+ When zoomed beyond the viewport, the cursor changes to a zoom-out icon and the image can be scrolled. When the image fits, the cursor shows zoom-in.
40
+
41
+ ## Mouse Interactions
42
+
43
+ - **Click** on the image toggles between 1x and 2x zoom
44
+ - **Scroll** when zoomed to pan the image
45
+
46
+ ## Keyboard Shortcuts
47
+
48
+ These work while viewing any image:
49
+
50
+ | Key | Action |
51
+ |-----|--------|
52
+ | `z` | Cycle fit mode (Fit to Window -> Original if Smaller -> Original Size) |
53
+ | `+` / `=` | Zoom in |
54
+ | `-` | Zoom out |
55
+ | `0` | Reset zoom |
56
+ | `f` | Toggle fullscreen |
57
+ | `i` | Toggle file info overlay |
58
+ | Right / `j` | Next file |
59
+ | Left / `k` | Previous file |
60
+ | `v` | Stream with VLC |
61
+ | `d` | Distraction-free mode |
62
+ | `Esc` | Back to gallery |
63
+
64
+ ## File Info Overlay
65
+
66
+ Press `i` to show metadata about the current image:
67
+
68
+ - **Size**: file size in KB/MB
69
+ - **Dimensions**: width x height in pixels
70
+ - **Format**: image format
71
+ - **Modified**: last modification date
72
+ - **Path**: file path on the server
73
+
74
+ The overlay appears in the top-right corner and can be toggled on and off.
75
+
76
+ ## Supported Formats
77
+
78
+ png, jpg, jpeg, gif, webp, svg, bmp, ico, avif, tiff, tif, heic, heif
79
+
80
+ Animated GIFs and WebP animations play in the browser natively. SVG files render as vector graphics. HEIC/HEIF support depends on the browser.
81
+
82
+ ## EXIF Orientation
83
+
84
+ Images are displayed with `image-orientation: from-image`, meaning EXIF rotation data is respected automatically. Portrait photos taken on phones display upright without manual rotation.
85
+
86
+ ## Thumbnails
87
+
88
+ In the gallery, image thumbnails are generated server-side using sharp (preferred) or ImageMagick (fallback) at 200x200 pixels in webp format. Thumbnails are cached on disk and invalidated when the source file changes.
89
+
90
+ If no image processing tool is available, the full image is loaded directly.
@@ -0,0 +1,262 @@
1
+ # Server Setup and Docker
2
+
3
+ ## Installation
4
+
5
+ ### From npm
6
+
7
+ ```bash
8
+ npm install -g retold-remote
9
+ ```
10
+
11
+ ### From source
12
+
13
+ ```bash
14
+ git clone <repo-url>
15
+ cd retold-remote
16
+ npm install
17
+ npm run build
18
+ ```
19
+
20
+ The build step bundles the client-side JavaScript with Quackage and copies assets into `web-application/`.
21
+
22
+ ## Running the Server
23
+
24
+ ### CLI Command
25
+
26
+ ```bash
27
+ retold-remote serve [content-path] [options]
28
+ ```
29
+
30
+ Or using the short alias:
31
+
32
+ ```bash
33
+ rr serve /path/to/media
34
+ ```
35
+
36
+ If `content-path` is omitted, the current directory is served.
37
+
38
+ ### Options
39
+
40
+ | Flag | Description | Default |
41
+ |------|-------------|---------|
42
+ | `-p, --port [port]` | Port to listen on | Random 7000-7999 |
43
+ | `-H, --hashed-filenames` | Enable hashed filename mode (hides real paths from browser) | Off |
44
+ | `-c, --cache-path [path]` | Root cache directory | `./dist/retold-cache/` |
45
+ | `--cache-thumbnails [path]` | Override thumbnail cache location | `<cache-root>/thumbnails/` |
46
+ | `--cache-archives [path]` | Override archive extraction cache | `<cache-root>/archives/` |
47
+ | `--cache-video-frames [path]` | Override video frame cache | `<cache-root>/video-frames/` |
48
+ | `--cache-audio-waveforms [path]` | Override audio waveform cache | `<cache-root>/audio-waveforms/` |
49
+
50
+ ### Direct Node.js
51
+
52
+ ```bash
53
+ node server.js [content-path]
54
+ ```
55
+
56
+ Default port is `8086` when using `server.js` directly.
57
+
58
+ ### Environment Variables
59
+
60
+ | Variable | Description | Default |
61
+ |----------|-------------|---------|
62
+ | `PORT` | HTTP port | `8086` (server.js) or random (CLI) |
63
+ | `RETOLD_HASHED_FILENAMES` | Set to `true` to enable hashed filenames | `false` |
64
+
65
+ ### Examples
66
+
67
+ ```bash
68
+ # Serve current directory on port 8086
69
+ node server.js
70
+
71
+ # Serve a specific folder
72
+ node server.js /mnt/nas/media
73
+
74
+ # CLI with custom port
75
+ retold-remote serve /mnt/nas/media -p 3000
76
+
77
+ # Hashed filenames for privacy
78
+ retold-remote serve /mnt/nas/media -H
79
+
80
+ # Custom cache location (useful for Docker volumes)
81
+ retold-remote serve /media -c /cache
82
+ ```
83
+
84
+ ## Configuration
85
+
86
+ ### Settings Persistence
87
+
88
+ User preferences are stored in the browser via `localStorage` under the key `retold-remote-settings`. These include:
89
+
90
+ - Theme selection
91
+ - View mode (grid or list)
92
+ - Thumbnail size (small, medium, large)
93
+ - Gallery filter and sort preferences
94
+ - Show hidden files toggle
95
+ - Autoplay video / audio toggles
96
+ - Image fit mode
97
+ - Sidebar state
98
+ - Filter presets
99
+
100
+ Settings are loaded on page load and saved whenever a preference changes.
101
+
102
+ ### Server Capabilities
103
+
104
+ On startup the server probes for optional tools and reports availability at `GET /api/media/capabilities`. The Settings panel in the UI shows which tools are detected.
105
+
106
+ | Tool | Detection Method | Feature |
107
+ |------|-----------------|---------|
108
+ | **sharp** | `require('sharp')` | Image thumbnail generation |
109
+ | **ImageMagick** | `identify --version` | Fallback image thumbnails |
110
+ | **ffmpeg** | `ffmpeg -version` | Video thumbnails, frame extraction, audio waveforms |
111
+ | **ffprobe** | `ffprobe -version` | Media metadata (duration, dimensions, codec, bitrate) |
112
+ | **VLC** | macOS: `/Applications/VLC.app`; Linux: `vlc --version` | External video playback |
113
+ | **7-Zip** | `7z --help` | Archive browsing (rar, 7z, tar.*) |
114
+ | **ebook-convert** | `ebook-convert --version` (Calibre) | MOBI/AZW to EPUB conversion |
115
+
116
+ Without any optional tools the application still works: images are served directly (no thumbnails), videos play in the browser, and zip/cbz archives use native extraction via yauzl.
117
+
118
+ ### Thumbnail Cache
119
+
120
+ Thumbnails are cached on disk using a SHA-256 hash of `<filepath>:<mtime>:<width>x<height>`. When the source file is modified the mtime changes, invalidating the cache entry automatically.
121
+
122
+ Default location: `./dist/retold-cache/thumbnails/`
123
+
124
+ Default thumbnail size: 200x200, format: webp.
125
+
126
+ Thumbnails are served with `Cache-Control: public, max-age=86400`.
127
+
128
+ ### Hashed Filenames Mode
129
+
130
+ When enabled (`-H` flag or `RETOLD_HASHED_FILENAMES=true`), real file paths are never exposed to the browser. Instead, deterministic 10-character hex hashes derived from SHA-256 are used in URLs and API responses. The same path always produces the same hash across server restarts.
131
+
132
+ ## Docker
133
+
134
+ ### Using the Included Dockerfile
135
+
136
+ A `Dockerfile` is provided in the repository root:
137
+
138
+ ```bash
139
+ docker build -t retold-remote .
140
+ docker run -p 8086:8086 -v /path/to/media:/media retold-remote
141
+ ```
142
+
143
+ ### Inline Dockerfile
144
+
145
+ If you need to create a Dockerfile from scratch, here is a complete working version:
146
+
147
+ ```dockerfile
148
+ FROM node:20-slim
149
+
150
+ # Install optional tools for full functionality
151
+ RUN apt-get update && apt-get install -y --no-install-recommends \
152
+ ffmpeg \
153
+ imagemagick \
154
+ p7zip-full \
155
+ calibre \
156
+ && rm -rf /var/lib/apt/lists/*
157
+
158
+ WORKDIR /app
159
+
160
+ # Copy package files and install dependencies
161
+ COPY package.json package-lock.json ./
162
+ RUN npm ci --omit=dev && npm cache clean --force
163
+
164
+ # Install sharp (optional image processing)
165
+ RUN npm install sharp || true
166
+
167
+ # Copy application source and built assets
168
+ COPY source/ source/
169
+ COPY web-application/ web-application/
170
+ COPY css/ css/
171
+ COPY html/ html/
172
+ COPY server.js ./
173
+
174
+ # Create cache directory
175
+ RUN mkdir -p /cache
176
+
177
+ # Default port
178
+ ENV PORT=8086
179
+
180
+ EXPOSE 8086
181
+
182
+ # Serve /media with cache at /cache
183
+ CMD ["node", "server.js", "/media"]
184
+ ```
185
+
186
+ ### Docker Compose
187
+
188
+ ```yaml
189
+ version: "3.8"
190
+ services:
191
+ retold-remote:
192
+ build: .
193
+ ports:
194
+ - "8086:8086"
195
+ volumes:
196
+ - /path/to/media:/media:ro
197
+ - retold-cache:/cache
198
+ environment:
199
+ - PORT=8086
200
+ restart: unless-stopped
201
+
202
+ volumes:
203
+ retold-cache:
204
+ ```
205
+
206
+ ### Docker Usage Notes
207
+
208
+ - Mount your media folder to `/media` (read-only is fine with `:ro`)
209
+ - Mount a volume to `/cache` for persistent thumbnail and frame caches
210
+ - The `node:20-slim` base keeps the image small while the `apt-get` packages add full media processing
211
+ - `calibre` is the largest optional package; omit it if you do not need MOBI/AZW ebook conversion
212
+ - `sharp` is installed separately because it has native bindings that may fail on some architectures; the `|| true` ensures the build continues without it
213
+
214
+ ### Minimal Dockerfile (No Optional Tools)
215
+
216
+ If you only need basic browsing without thumbnails or media probing:
217
+
218
+ ```dockerfile
219
+ FROM node:20-slim
220
+
221
+ WORKDIR /app
222
+
223
+ COPY package.json package-lock.json ./
224
+ RUN npm ci --omit=dev && npm cache clean --force
225
+
226
+ COPY source/ source/
227
+ COPY web-application/ web-application/
228
+ COPY css/ css/
229
+ COPY html/ html/
230
+ COPY server.js ./
231
+
232
+ ENV PORT=8086
233
+ EXPOSE 8086
234
+
235
+ CMD ["node", "server.js", "/media"]
236
+ ```
237
+
238
+ This produces an image under 200MB. Images display directly (no thumbnails), videos play in the browser, and zip/cbz archives use native extraction.
239
+
240
+ ## Archive Browsing
241
+
242
+ Archives appear as navigable folders in the file browser. Clicking an archive opens it and displays its contents as if they were a regular directory.
243
+
244
+ **Supported formats:**
245
+
246
+ | Format | Tool Required |
247
+ |--------|---------------|
248
+ | `.zip`, `.cbz` | None (native yauzl) |
249
+ | `.7z`, `.rar`, `.tar`, `.tar.gz`, `.tar.bz2`, `.tar.xz`, `.tgz`, `.cbr` | 7-Zip |
250
+
251
+ Files inside archives can be viewed, thumbnailed, and probed just like regular files. Archive contents are extracted to the cache directory on demand.
252
+
253
+ ## VLC Streaming
254
+
255
+ The VLC integration allows streaming media files to a VLC player running on the server machine. Press `v` in the media viewer to send the current file to VLC.
256
+
257
+ Setup instructions for macOS, Windows, and Linux are available in the Settings panel under "VLC Protocol Setup". The setup creates a `vlc://` protocol handler that opens files in VLC when triggered from the browser.
258
+
259
+ **Platform details:**
260
+ - **macOS**: Creates an AppleScript app at `/Applications/VLCProtocol.app` and registers it as a URL handler
261
+ - **Windows**: Registry entry or batch script that maps `vlc://` to the VLC executable
262
+ - **Linux**: Desktop file at `~/.local/share/applications/vlc-protocol.desktop` registered with xdg-mime