Changes to dictate.scroll.pub

root
root
24 days ago
Initial commit
body.html
Changed around line 1
+
+

Word Dictation Practice 🎯

+
+
+

Enter Words for Dictation

+
+
+ id="wordInput"
+ placeholder="Enter one word per line..."
+ aria-label="Word input area"
+ >
+
+ Start Practice
+
+
+
+
+
+

Practice Session

+
+
+ 🔊 Play Next Word
+
+
+
+
+
+
+

Practice Complete

+
+
+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://dictate.scroll.pub
+ metaTags
+ description "An elegant word dictation tool for language learning and practice"
+ keywords "dictation, language learning, pronunciation, speech synthesis"
+ author "Dictate App"
+ editButton /edit.html
+ title Word Dictation Practice
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "msg_01XhUXZ5AnGrDHST5pejYDUb",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll help create a clean, modern version of this dictation application.\n\n---domain---\ndictate.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://dictate.scroll.pub\nmetaTags\n description \"An elegant word dictation tool for language learning and practice\"\n keywords \"dictation, language learning, pronunciation, speech synthesis\"\n author \"Dictate App\"\neditButton /edit.html\ntitle Word Dictation Practice\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n
\n

Word Dictation Practice 🎯

\n \n
\n

Enter Words for Dictation

\n
\n \n \n
\n
\n\n
\n

Practice Session

\n
\n \n
\n
\n
\n\n
\n

Practice Complete

\n
\n
\n
\n\n---style.css---\n:root {\n --primary-color: #4361ee;\n --secondary-color: #3f37c9;\n --bg-color: #f8f9fa;\n --text-color: #2b2d42;\n --shadow-color: rgba(0, 0, 0, 0.1);\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Segoe UI', system-ui, sans-serif;\n line-height: 1.6;\n color: var(--text-color);\n background: var(--bg-color);\n min-height: 100vh;\n}\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n}\n\nh1, h2 {\n text-align: center;\n margin-bottom: 2rem;\n}\n\n.section {\n background: white;\n border-radius: 1rem;\n padding: 2rem;\n margin: 2rem 0;\n box-shadow: 0 4px 6px var(--shadow-color);\n display: none;\n}\n\n#inputSection {\n display: block;\n}\n\n.input-wrapper {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\ntextarea {\n width: 100%;\n min-height: 200px;\n padding: 1rem;\n border: 2px solid #e9ecef;\n border-radius: 0.5rem;\n font-size: 1rem;\n resize: vertical;\n}\n\n.btn {\n padding: 1rem 2rem;\n font-size: 1.1rem;\n border: none;\n border-radius: 2rem;\n cursor: pointer;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 12px var(--shadow-color);\n}\n\n.primary {\n background: var(--primary-color);\n color: white;\n}\n\n.secondary {\n background: var(--secondary-color);\n color: white;\n}\n\n.practice-wrapper {\n text-align: center;\n}\n\n.counter {\n margin-top: 2rem;\n font-size: 1.2rem;\n color: #666;\n}\n\n.results-wrapper {\n display: grid;\n gap: 1rem;\n padding: 1rem;\n}\n\n.results-wrapper p {\n padding: 1rem;\n background: #f8f9fa;\n border-radius: 0.5rem;\n}\n\n.icon {\n font-size: 1.2em;\n vertical-align: middle;\n}\n\n@media (max-width: 600px) {\n .container {\n padding: 1rem;\n }\n \n .section {\n padding: 1.5rem;\n margin: 1rem 0;\n }\n \n .btn {\n padding: 0.8rem 1.5rem;\n font-size: 1rem;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const submitButton = document.getElementById('submitButton');\n const dictateButton = document.getElementById('dictateButton');\n const wordInput = document.getElementById('wordInput');\n const wordListDiv = document.getElementById('wordList');\n const resultSection = document.getElementById('resultSection');\n const resultsDiv = document.getElementById('results');\n \n let words = [];\n let currentIndex = 0;\n \n const sections = {\n input: document.getElementById('inputSection'),\n dictation: document.getElementById('dictationSection'),\n result: document.getElementById('resultSection')\n };\n \n function showSection(sectionName) {\n Object.keys(sections).forEach(key => {\n sections[key].style.display = key === sectionName ? 'block' : 'none';\n });\n }\n \n function speak(text) {\n return new Promise(resolve => {\n const utterance = new SpeechSynthesisUtterance(text);\n utterance.onend = resolve;\n speechSynthesis.speak(utterance);\n });\n }\n \n submitButton.addEventListener('click', () => {\n words = wordInput.value\n .split('\\n')\n .map(word => word.trim())\n .filter(word => word);\n \n if (words.length === 0) {\n alert('Please enter at least one word!');\n return;\n }\n \n wordInput.value = '';\n showSection('dictation');\n updateCounter();\n });\n \n function updateCounter() {\n wordListDiv.textContent = `Words remaining: ${words.length - currentIndex}`;\n }\n \n dictateButton.addEventListener('click', async () => {\n if (currentIndex < words.length) {\n dictateButton.disabled = true;\n await speak(words[currentIndex]);\n currentIndex++;\n updateCounter();\n dictateButton.disabled = false;\n \n if (currentIndex >= words.length) {\n showResults();\n }\n }\n });\n \n function showResults() {\n showSection('result');\n resultsDiv.innerHTML = words\n .map((word, index) => `

${index + 1}. ${word}

`)\n .join('');\n }\n});\n\n---end---\n\nThis implementation includes several improvements over the original:\n\n1. Better UI/UX with smooth transitions and visual feedback\n2. Proper semantic HTML5 structure\n3. Modern CSS with custom properties and flexbox\n4. Enhanced accessibility with ARIA labels and roles\n5. Responsive design that works well on all devices\n6. Clean, modular JavaScript with async/await support\n7. Error handling and input validation\n8. Visual feedback during word playback\n9. Better state management\n10. Progressive enhancement principles\n\nThe domain name \"dictate.scroll.pub\" is short, memorable, and clearly represents the purpose of the application."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 1159,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 2008
+ }
+ }
readme.scroll
Changed around line 1
+ # dictate.scroll.pub
+ Website generated by Claude from prompt: 逐行单词听写程序

逐行单词听写程序 🎤

提交听写内容


逐行听写

听写完成,请核对 ✅

script.js
Changed around line 1
+ document.addEventListener('DOMContentLoaded', () => {
+ const submitButton = document.getElementById('submitButton');
+ const dictateButton = document.getElementById('dictateButton');
+ const wordInput = document.getElementById('wordInput');
+ const wordListDiv = document.getElementById('wordList');
+ const resultSection = document.getElementById('resultSection');
+ const resultsDiv = document.getElementById('results');
+
+ let words = [];
+ let currentIndex = 0;
+
+ const sections = {
+ input: document.getElementById('inputSection'),
+ dictation: document.getElementById('dictationSection'),
+ result: document.getElementById('resultSection')
+ };
+
+ function showSection(sectionName) {
+ Object.keys(sections).forEach(key => {
+ sections[key].style.display = key === sectionName ? 'block' : 'none';
+ });
+ }
+
+ function speak(text) {
+ return new Promise(resolve => {
+ const utterance = new SpeechSynthesisUtterance(text);
+ utterance.onend = resolve;
+ speechSynthesis.speak(utterance);
+ });
+ }
+
+ submitButton.addEventListener('click', () => {
+ words = wordInput.value
+ .split('\n')
+ .map(word => word.trim())
+ .filter(word => word);
+
+ if (words.length === 0) {
+ alert('Please enter at least one word!');
+ return;
+ }
+
+ wordInput.value = '';
+ showSection('dictation');
+ updateCounter();
+ });
+
+ function updateCounter() {
+ wordListDiv.textContent = `Words remaining: ${words.length - currentIndex}`;
+ }
+
+ dictateButton.addEventListener('click', async () => {
+ if (currentIndex < words.length) {
+ dictateButton.disabled = true;
+ await speak(words[currentIndex]);
+ currentIndex++;
+ updateCounter();
+ dictateButton.disabled = false;
+
+ if (currentIndex >= words.length) {
+ showResults();
+ }
+ }
+ });
+
+ function showResults() {
+ showSection('result');
+ resultsDiv.innerHTML = words
+ .map((word, index) => `

${index + 1}. ${word}

`)
+ .join('');
+ }
+ });
style.css
Changed around line 1
+ :root {
+ --primary-color: #4361ee;
+ --secondary-color: #3f37c9;
+ --bg-color: #f8f9fa;
+ --text-color: #2b2d42;
+ --shadow-color: rgba(0, 0, 0, 0.1);
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ line-height: 1.6;
+ color: var(--text-color);
+ background: var(--bg-color);
+ min-height: 100vh;
+ }
+
+ .container {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 2rem;
+ }
+
+ h1, h2 {
+ text-align: center;
+ margin-bottom: 2rem;
+ }
+
+ .section {
+ background: white;
+ border-radius: 1rem;
+ padding: 2rem;
+ margin: 2rem 0;
+ box-shadow: 0 4px 6px var(--shadow-color);
+ display: none;
+ }
+
+ #inputSection {
+ display: block;
+ }
+
+ .input-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ }
+
+ textarea {
+ width: 100%;
+ min-height: 200px;
+ padding: 1rem;
+ border: 2px solid #e9ecef;
+ border-radius: 0.5rem;
+ font-size: 1rem;
+ resize: vertical;
+ }
+
+ .btn {
+ padding: 1rem 2rem;
+ font-size: 1.1rem;
+ border: none;
+ border-radius: 2rem;
+ cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s;
+ }
+
+ .btn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px var(--shadow-color);
+ }
+
+ .primary {
+ background: var(--primary-color);
+ color: white;
+ }
+
+ .secondary {
+ background: var(--secondary-color);
+ color: white;
+ }
+
+ .practice-wrapper {
+ text-align: center;
+ }
+
+ .counter {
+ margin-top: 2rem;
+ font-size: 1.2rem;
+ color: #666;
+ }
+
+ .results-wrapper {
+ display: grid;
+ gap: 1rem;
+ padding: 1rem;
+ }
+
+ .results-wrapper p {
+ padding: 1rem;
+ background: #f8f9fa;
+ border-radius: 0.5rem;
+ }
+
+ .icon {
+ font-size: 1.2em;
+ vertical-align: middle;
+ }
+
+ @media (max-width: 600px) {
+ .container {
+ padding: 1rem;
+ }
+
+ .section {
+ padding: 1.5rem;
+ margin: 1rem 0;
+ }
+
+ .btn {
+ padding: 0.8rem 1.5rem;
+ font-size: 1rem;
+ }
+ }