Bladeren bron

增加了夜间模式

sequoia00 1 maand geleden
bovenliggende
commit
a952ee66ab
1 gewijzigde bestanden met toevoegingen van 129 en 37 verwijderingen
  1. 129 37
      static/web/viewer.html

+ 129 - 37
static/web/viewer.html

@@ -6,10 +6,30 @@
     <meta name="google" content="notranslate">
     <title>PDF.js viewer</title>
 
-    <link rel="resource" type="application/l10n" href="locale/locale.json">
-    <script src="../build/pdf.mjs" type="module"></script>
-    <link rel="stylesheet" href="viewer.css">
-    <script src="viewer.mjs" type="module"></script>
+    <link rel="resource" type="application/l10n" href="locale/locale.json">
+    <script src="../build/pdf.mjs" type="module"></script>
+    <link rel="stylesheet" href="viewer.css">
+    <script>
+        (function () {
+            const NIGHT_MODE_STORAGE_KEY = 'reader_pro.night_mode';
+            const PDFJS_PREFERENCES_KEY = 'pdfjs.preferences';
+            const nightModeEnabled = localStorage.getItem(NIGHT_MODE_STORAGE_KEY) === '1';
+            let preferences = {};
+
+            try {
+                preferences = JSON.parse(localStorage.getItem(PDFJS_PREFERENCES_KEY)) || {};
+            } catch (e) {
+                preferences = {};
+            }
+
+            preferences.forcePageColors = nightModeEnabled;
+            preferences.pageColorsBackground = '#0b0b0b';
+            preferences.pageColorsForeground = '#f5f5f5';
+
+            localStorage.setItem(PDFJS_PREFERENCES_KEY, JSON.stringify(preferences));
+        })();
+    </script>
+    <script src="viewer.mjs" type="module"></script>
 
     <style>
         /* 模态窗口样式 */
@@ -78,9 +98,14 @@
             color: black;
         }
 
-        .button-stop {
-            background-color: #dc3545;
-        }
+        .button-stop {
+            background-color: #dc3545;
+        }
+
+        .button-night {
+            background-color: #1f2937;
+            color: #f9fafb;
+        }
 
         /* 底部按钮栏 */
         .bottom-bar {
@@ -198,10 +223,34 @@
             font-size: 14px;
         }
 
-        .pagination button:disabled {
-            background-color: #6c757d;
-            cursor: not-allowed;
-        }
+        .pagination button:disabled {
+            background-color: #6c757d;
+            cursor: not-allowed;
+        }
+
+        body.night-reading-mode {
+            background: #0b1220;
+        }
+
+        body.night-reading-mode #viewerContainer {
+            background: #0f172a;
+        }
+
+        body.night-reading-mode .toolbar,
+        body.night-reading-mode #loading-indicator,
+        body.night-reading-mode .user-menu-trigger,
+        body.night-reading-mode .user-menu-panel,
+        body.night-reading-mode .modal {
+            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.45);
+        }
+
+        body.night-reading-mode .bottom-bar {
+            background-color: rgba(15, 23, 42, 0.18);
+        }
+
+        body.night-reading-mode .pdfViewer .page {
+            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
+        }
 
         /* 手机端优化 */
         @media (max-width: 768px) {
@@ -240,14 +289,15 @@
 
     <audio id="audio-player" controls></audio>
 
-    <div class="bottom-bar">
-        <button id="uploadButton" class="button">上传 PDF</button>
-        <button id="openDirectoryButton" class="button">打开目录</button>
-        <button id="select-all-text" class="button button-light">阅读整页</button>
-        <button id="pause-play-button" class="button button-pause">暂停播放</button>
-        <button id="stop-play-button" class="button button-stop">停止</button>
-        <button id="toggle-text-select" class="button button-success">文本选择</button>
-    </div>
+    <div class="bottom-bar">
+        <button id="uploadButton" class="button">上传 PDF</button>
+        <button id="openDirectoryButton" class="button">打开目录</button>
+        <button id="nightModeButton" class="button button-night">夜间模式</button>
+        <button id="select-all-text" class="button button-light">阅读整页</button>
+        <button id="pause-play-button" class="button button-pause">暂停播放</button>
+        <button id="stop-play-button" class="button button-stop">停止</button>
+        <button id="toggle-text-select" class="button button-success">文本选择</button>
+    </div>
 
     <input type="file" id="pdfInput" accept="application/pdf" style="display: none;" />
 
@@ -1099,24 +1149,60 @@
                 const pdfList = document.getElementById('pdfList');
                 const prevPageButton = document.getElementById('prevPage');
                 const nextPageButton = document.getElementById('nextPage');
-                const pageInfo = document.getElementById('pageInfo');
-                const readPageButton = document.getElementById('select-all-text');
-                const pausePlayButton = document.getElementById('pause-play-button');
-                const stopPlayButton = document.getElementById('stop-play-button');
-                const bottomBar = document.querySelector('.bottom-bar');
-                const userMenu = document.getElementById('userMenu');
-                const userMenuTrigger = document.getElementById('userMenuTrigger');
-                const userMenuPanel = document.getElementById('userMenuPanel');
-                const userLogoutBtn = document.getElementById('userLogoutBtn');
+                const pageInfo = document.getElementById('pageInfo');
+                const readPageButton = document.getElementById('select-all-text');
+                const pausePlayButton = document.getElementById('pause-play-button');
+                const stopPlayButton = document.getElementById('stop-play-button');
+                const nightModeButton = document.getElementById('nightModeButton');
+                const bottomBar = document.querySelector('.bottom-bar');
+                const userMenu = document.getElementById('userMenu');
+                const userMenuTrigger = document.getElementById('userMenuTrigger');
+                const userMenuPanel = document.getElementById('userMenuPanel');
+                const userLogoutBtn = document.getElementById('userLogoutBtn');
                 const userAdminBtn = document.getElementById('userAdminBtn');
 
                 let selectedFile = null;
                 let currentPage = 1;
                 const itemsPerPage = 10;
-                let allFiles = [];
-                let selectedStartContext = null;
-                const currentFilePath = new URLSearchParams(window.location.search).get('file') || '';
-                let isRestoringProgress = false;
+                let allFiles = [];
+                let selectedStartContext = null;
+                const currentFilePath = new URLSearchParams(window.location.search).get('file') || '';
+                let isRestoringProgress = false;
+                const NIGHT_MODE_STORAGE_KEY = 'reader_pro.night_mode';
+
+                function updateNightModeButton(isEnabled) {
+                    nightModeButton.textContent = isEnabled ? '日间模式' : '夜间模式';
+                    nightModeButton.classList.toggle('button-light', isEnabled);
+                    nightModeButton.classList.toggle('button-night', !isEnabled);
+                }
+
+                function setNightMode(enabled) {
+                    document.body.classList.toggle('night-reading-mode', enabled);
+                    updateNightModeButton(enabled);
+                    localStorage.setItem(NIGHT_MODE_STORAGE_KEY, enabled ? '1' : '0');
+                    syncPdfJsNightPreferences(enabled);
+                }
+
+                function syncPdfJsNightPreferences(enabled) {
+                    const pdfjsPreferencesKey = 'pdfjs.preferences';
+                    let preferences = {};
+
+                    try {
+                        preferences = JSON.parse(localStorage.getItem(pdfjsPreferencesKey)) || {};
+                    } catch (e) {
+                        preferences = {};
+                    }
+
+                    preferences.forcePageColors = enabled;
+                    preferences.pageColorsBackground = '#0b0b0b';
+                    preferences.pageColorsForeground = '#f5f5f5';
+                    localStorage.setItem(pdfjsPreferencesKey, JSON.stringify(preferences));
+                }
+
+                function initNightMode() {
+                    const enabled = localStorage.getItem(NIGHT_MODE_STORAGE_KEY) === '1';
+                    setNightMode(enabled);
+                }
 
                 async function ensureLoggedIn() {
                     try {
@@ -1155,11 +1241,17 @@
                         window.location.href = '/login';
                     }
                 });
-                userAdminBtn.addEventListener('click', function () {
-                    window.location.href = '/admin';
-                });
-
-                function syncBottomBarToPage() {
+                userAdminBtn.addEventListener('click', function () {
+                    window.location.href = '/admin';
+                });
+                initNightMode();
+                nightModeButton.addEventListener('click', function () {
+                    const nextEnabled = !document.body.classList.contains('night-reading-mode');
+                    setNightMode(nextEnabled);
+                    window.location.reload();
+                });
+
+                function syncBottomBarToPage() {
                     if (!bottomBar) return;
 
                     const app = window.PDFViewerApplication;