From 475006e91201163c76bbf2aaf4ee71d1674942f7 Mon Sep 17 00:00:00 2001 From: StillHammer Date: Fri, 19 Sep 2025 14:39:08 +0800 Subject: [PATCH] Add Word Discovery game with auto-play TTS and Settings system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New Word Discovery game with image support and practice phases - Auto-play TTS on word appearance with speed control (0.7x-1.1x) - Complete Settings page with TTS controls and debug interface - Language standardization with BCP 47 codes (en-US, zh-CN, fr-FR) - Media fallback handling for missing images and audio - Settings Manager with voice selection and debug tools 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- css/settings.css | 314 +++++++ index.html | 102 ++- js/content/chinese-long-story.js | 1 + js/content/example-minimal.js | 59 ++ js/content/example-with-images.js | 81 ++ js/content/sbs-level-7-8-new.js | 1 + js/content/story-prototype-optimized.js | 1 + js/content/test-compatibility.js | 1 + js/content/test-minimal.js | 1 + js/content/test-rich.js | 1 + js/core/content-scanner.js | 1 + js/core/game-loader.js | 3 +- js/core/navigation.js | 25 + js/core/settings-manager.js | 397 +++++++++ js/games/word-discovery.js | 1049 +++++++++++++++++++++++ 15 files changed, 2033 insertions(+), 4 deletions(-) create mode 100644 css/settings.css create mode 100644 js/content/example-minimal.js create mode 100644 js/content/example-with-images.js create mode 100644 js/core/settings-manager.js create mode 100644 js/games/word-discovery.js diff --git a/css/settings.css b/css/settings.css new file mode 100644 index 0000000..da92327 --- /dev/null +++ b/css/settings.css @@ -0,0 +1,314 @@ +/* === SETTINGS PAGE STYLES === */ + +.settings-container { + max-width: 1000px; + margin: 0 auto; + padding: 20px; + display: flex; + flex-direction: column; + gap: 30px; +} + +.settings-section { + background: var(--card-background); + border-radius: var(--border-radius); + padding: 25px; + box-shadow: var(--shadow); + border: 1px solid var(--border-color); +} + +.settings-section h3 { + font-size: 1.4em; + margin-bottom: 20px; + color: var(--text-primary); + display: flex; + align-items: center; + gap: 8px; +} + +/* === SETTING GROUPS === */ +.setting-group { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 15px; + padding: 12px 0; + border-bottom: 1px solid #f0f0f0; +} + +.setting-group:last-child { + border-bottom: none; + margin-bottom: 0; +} + +.setting-group label { + font-weight: 500; + color: var(--text-primary); + min-width: 140px; +} + +.setting-group input[type="range"] { + flex: 1; + margin: 0 15px; + accent-color: var(--primary-color); +} + +.setting-group select { + min-width: 200px; + padding: 8px 12px; + border: 1px solid var(--border-color); + border-radius: 6px; + font-size: 14px; + background: white; +} + +.setting-group span { + min-width: 40px; + text-align: center; + font-weight: 600; + color: var(--primary-color); +} + +/* === DEBUG INFO === */ +.debug-info { + background: #f8f9fa; + border-radius: 8px; + padding: 15px; + margin-bottom: 20px; +} + +.info-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; + border-bottom: 1px solid #e9ecef; +} + +.info-item:last-child { + border-bottom: none; +} + +.info-item .label { + font-weight: 500; + color: var(--text-secondary); +} + +.info-item .value { + font-weight: 600; + color: var(--text-primary); +} + +.info-item .value.small { + font-size: 0.85em; + max-width: 400px; + word-break: break-all; +} + +/* === DEBUG CONTROLS === */ +.debug-controls { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 12px; + margin-bottom: 20px; +} + +.debug-btn { + padding: 12px 16px; + border: none; + border-radius: 8px; + background: var(--primary-color); + color: white; + font-weight: 500; + cursor: pointer; + transition: var(--transition); + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.debug-btn:hover { + background: #2563eb; + transform: translateY(-2px); + box-shadow: var(--shadow); +} + +.debug-btn:active { + transform: translateY(0); +} + +/* === DEBUG OUTPUT === */ +.debug-output { + background: #1a1a1a; + border-radius: 8px; + padding: 15px; + color: #e0e0e0; +} + +.debug-output h4 { + color: #ffffff; + margin-bottom: 10px; + font-size: 1.1em; +} + +.debug-log { + min-height: 120px; + max-height: 300px; + overflow-y: auto; + font-family: 'Courier New', monospace; + font-size: 13px; + line-height: 1.4; + white-space: pre-wrap; + word-break: break-word; + background: #000000; + padding: 10px; + border-radius: 4px; + margin-bottom: 10px; +} + +.debug-log:empty::before { + content: "No debug output yet. Click test buttons above."; + color: #888; + font-style: italic; +} + +.clear-btn { + padding: 6px 12px; + border: 1px solid #555; + border-radius: 4px; + background: #333; + color: #fff; + font-size: 12px; + cursor: pointer; + transition: var(--transition); +} + +.clear-btn:hover { + background: #444; + border-color: #666; +} + +/* === VOICE LIST === */ +.voice-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 12px; + max-height: 300px; + overflow-y: auto; +} + +.voice-item { + background: #f8f9fa; + border: 1px solid var(--border-color); + border-radius: 8px; + padding: 12px; + transition: var(--transition); + cursor: pointer; +} + +.voice-item:hover { + background: #e9ecef; + border-color: var(--primary-color); +} + +.voice-item.selected { + background: var(--primary-light); + border-color: var(--primary-color); +} + +.voice-name { + font-weight: 600; + color: var(--text-primary); + margin-bottom: 4px; +} + +.voice-lang { + font-size: 0.9em; + color: var(--text-secondary); + margin-bottom: 4px; +} + +.voice-type { + font-size: 0.8em; + color: var(--accent-color); + font-weight: 500; +} + +/* === BROWSER INFO === */ +.browser-info .info-item { + align-items: flex-start; +} + +.browser-info .value { + text-align: right; + max-width: 60%; +} + +/* === LOG COLORS === */ +.debug-log .success { + color: #4ade80; +} + +.debug-log .error { + color: #f87171; +} + +.debug-log .warning { + color: #fbbf24; +} + +.debug-log .info { + color: #60a5fa; +} + +.debug-log .timestamp { + color: #9ca3af; + font-size: 0.9em; +} + +/* === RESPONSIVE === */ +@media (max-width: 768px) { + .settings-container { + padding: 15px; + gap: 20px; + } + + .settings-section { + padding: 20px; + } + + .setting-group { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + + .setting-group label { + min-width: auto; + } + + .setting-group input[type="range"] { + width: 100%; + margin: 10px 0; + } + + .setting-group select { + width: 100%; + min-width: auto; + } + + .debug-controls { + grid-template-columns: 1fr; + } + + .info-item { + flex-direction: column; + align-items: flex-start; + gap: 4px; + } + + .voice-list { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/index.html b/index.html index e4c76bd..bbaf672 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ + @@ -45,9 +46,9 @@ 📊 Statistics Coming soon - +

⚙️ Settings & Debug Tools

+ + +
+ +
+

🔊 Audio Settings

+ +
+ + + 0.8 +
+ +
+ + + 1.0 +
+ +
+ + +
+
+ + +
+

🔧 TTS Debug Tools

+ +
+
+ Browser Support: + Checking... +
+
+ Available Voices: + Loading... +
+
+ English Voices: + Loading... +
+
+ +
+ + + + +
+ +
+

Debug Output:

+
+ +
+
+ + +
+

🎤 Available Voices

+
+ Loading voices... +
+
+ + +
+

🌐 Browser Information

+
+
+ User Agent: + +
+
+ Platform: + +
+
+ Language: + +
+
+
+
+ + @@ -126,6 +221,7 @@ +