diff --git a/Dockerfile b/Dockerfile index 46341c9..a931468 100644 --- a/Dockerfile +++ b/Dockerfile @@ -91,7 +91,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nginx \ # Chrome headless shell dependencies wget ca-certificates openssl unzip \ - fonts-liberation fontconfig \ + fonts-liberation fonts-noto-color-emoji fonts-noto-cjk fontconfig \ libnss3 libatk-bridge2.0-0t64 libdrm2 libxkbcommon0 \ libgbm1 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \ libasound2t64 libcups2t64 libatk1.0-0t64 libnspr4 libdbus-1-3 \ @@ -104,15 +104,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ unzip /tmp/chrome.zip -d /opt/ && \ chmod +x /opt/chrome-headless-shell-linux64/chrome-headless-shell && \ rm /tmp/chrome.zip && \ - # Strip Chrome: remove GPU libs (--disable-gpu), keep only en-US locale, remove hyphen data + # Strip Chrome: remove GPU libs (--disable-gpu), keep locale packs for Unicode/CJK shaping rm -f /opt/chrome-headless-shell-linux64/libEGL.so \ /opt/chrome-headless-shell-linux64/libGLESv2.so \ /opt/chrome-headless-shell-linux64/libvk_swiftshader.so \ /opt/chrome-headless-shell-linux64/libvulkan.so.1 \ /opt/chrome-headless-shell-linux64/vk_swiftshader_icd.json \ /opt/chrome-headless-shell-linux64/LICENSE.headless_shell && \ - find /opt/chrome-headless-shell-linux64/locales -type f ! -name 'en-US.pak' -delete && \ - rm -rf /opt/chrome-headless-shell-linux64/hyphen-data && \ # Install s6-overlay wget -q "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" -O /tmp/s6-noarch.tar.xz && \ tar -C / -Jxpf /tmp/s6-noarch.tar.xz && \ @@ -133,11 +131,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ dpkg --purge --force-depends \ libllvm19 libz3-4 libperl5.40 perl perl-modules-5.40 \ libavahi-client3 libavahi-common-data libavahi-common3 \ - libelf1t64 libc-l10n locales \ + libelf1t64 \ 2>/dev/null || true && \ rm -rf /var/lib/apt/lists/* /var/log/dpkg.log /var/log/apt && \ - # Remove system locales and unused data (keep only C/POSIX and en_US) - rm -rf /usr/share/locale /usr/share/i18n /usr/share/doc /usr/share/man \ + # Remove unused data (keep locales and i18n for Unicode/CJK support) + rm -rf /usr/share/doc /usr/share/man \ /usr/share/info /usr/share/lintian /usr/share/X11/xkb \ /var/cache/debconf/*-old && \ # Remove auto-created PostgreSQL cluster (will be initialized on first run) diff --git a/README.md b/README.md index a4b1e23..5c3a431 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [](https://buymeacoffee.com/wojo_o) -# Inker v0.3.2 +# Inker v0.3.3 Self-hosted e-ink device management server built for the homelab community. Works with [TRMNL](https://usetrmnl.com/) devices (supports firmware 1.7.8) and any BYOD e-ink display. Design screens, create custom widgets with live data from your local network, and manage your displays from a modern web interface. diff --git a/backend/package.json b/backend/package.json index 8d6a820..a93be69 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "inker-backend", - "version": "0.3.2", + "version": "0.3.3", "description": "Inker Server Backend - E-ink Device Management", "main": "dist/main.js", "scripts": { diff --git a/backend/src/api/display/display.service.ts b/backend/src/api/display/display.service.ts index da345e0..835cb58 100644 --- a/backend/src/api/display/display.service.ts +++ b/backend/src/api/display/display.service.ts @@ -303,12 +303,10 @@ export class DisplayService { }); } - // For multi-screen playlists, cap refresh rate at current screen's duration - // so the device calls back in time for rotation + // Use the playlist item's configured duration as the refresh rate + // so the device checks back at the interval the user actually set const screenDuration = currentScreen.duration || 60; - const effectiveDeviceRate = device.playlist.items.length > 1 - ? Math.min(device.refreshRate, screenDuration) - : device.refreshRate; + const effectiveDeviceRate = screenDuration; // Calculate refresh rate based on current screen content // Clock widgets get minute-synced refresh; otherwise uses device's configured rate diff --git a/backend/src/main.ts b/backend/src/main.ts index cf5f291..e98dffb 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -81,7 +81,7 @@ async function bootstrap() { const config = new DocumentBuilder() .setTitle('Inker API') .setDescription('API documentation for Inker e-ink device management server') - .setVersion('0.3.2') + .setVersion('0.3.3') .addBearerAuth() .addApiKey({ type: 'apiKey', name: 'X-Device-Key', in: 'header' }, 'device-key') .build(); diff --git a/backend/src/screen-designer/services/screen-renderer.service.ts b/backend/src/screen-designer/services/screen-renderer.service.ts index d3626a6..ff7279e 100644 --- a/backend/src/screen-designer/services/screen-renderer.service.ts +++ b/backend/src/screen-designer/services/screen-renderer.service.ts @@ -1971,7 +1971,7 @@ export class ScreenRendererService implements OnModuleDestroy, OnModuleInit { // List items already have prefix (•, -, 1.) from renderList(), so no list-style needed // Use full fontSize to match frontend WidgetRenderer.tsx // Allow text wrapping (no white-space: nowrap) to match designer behavior - const listItems = renderedContent.slice(0, 10).map(item => + const listItems = renderedContent.map(item => `