Skip to content

Commit 54dab33

Browse files
committed
refactor: polish up mobile experience
1 parent 029e358 commit 54dab33

3 files changed

Lines changed: 329 additions & 78 deletions

File tree

emojistori/index.html

Lines changed: 99 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5+
<meta
6+
name="viewport"
7+
content="width=device-width, initial-scale=1.0, user-scalable=no"
8+
/>
69
<meta name="apple-mobile-web-app-capable" content="yes" />
710
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
811
<meta name="apple-mobile-web-app-title" content="EmojiStori" />
@@ -16,69 +19,75 @@
1619
/>
1720
<link
1821
rel="manifest"
19-
href="data:application/json;base64,eyJuYW1lIjoiRW1vamkgU3RvcnkgR2VuZXJhdG9yIiwic2hvcnRfbmFtZSI6IkVtb2ppIFN0b3JpZXMiLCJzdGFydF91cmwiOiIuIiwiZGlzcGxheSI6InN0YW5kYWxvbmUiLCJiYWNrZ3JvdW5kX2NvbG9yIjoiIzY2N2VlYSIsInRoZW1lX2NvbG9yIjoiIzY2N2VlYSIsImljb25zIjpbeyJzcmMiOiJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNVGd3SWlCb1pXbG5hSFE5SWpFNE1DSWlJSFpwWlhkQ2IzZzlJakFnTUNBeE9EQWdNVGd3SWlCbWFXeHNQU0p1YjI1bElpQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaVBnbzhjbVZqZENCM2FXUjBhRDBpTVRnd0lpQm9aV2xuYUhROUlqRTRNQ0lpSUhKNFBTSTBNQ0lpSUdacGJHdzlJblZ5YkNnamNYSmhaR2xsYm5Rd1gyeHBibVZoY2w5eE1qRXBJaTgrQ2p4a1pXWnpQZ285YkdsdVpXRnlSM0poWkdsbGJuUWdhV1E5SW1keVlXUnBaVzUwTUY5c2FXNWxZWEpmTVY4eElpQjRNVDBpTUNJZ2VURTlJakFpSUhneFBTSTBNQ0lpSUhreFBTSTBNQ0lnWjNKaFpHbGxiblJWYm1sMGN6MGlkWE5sY2xOd1lXTmxUMjVWYzJVaVBnbzljM1J2Y0NCemRHOXdMV052Ykc5eVBTSWpOalkzWldWaElpOCtDanh6ZEc5d0lHOW1abk5sZEQwaU1TSWdjM1J2Y0MxamIyeHZjajBpSXpjMk5HSmhNaUl2UGdvOEwyeHBibVZoY2tkeVlXUnBaVzUwUGdvOEwyUmxabk0rQ2p4MFpYaDBJSGc5SWprd0lpQjVQU0l4TVRBaUlHWnZiblF0YzJsNlpUMGlOekFpSUhSbGVIUXRZVzVqYUc5eVBTSnRhV1JrYkdVaVBqaGJhWGtiTDNSbGVIUStDand2YzNablBnbz0iLCJzaXplcyI6IjE4MHgxODAiLCJ0eXBlIjoiaW1hZ2Uvc3ZnK3htbCJ9XX0="
22+
href="data:application/json;base64,eyJuYW1lIjoiRW1vamlTdG9yaWVzIiwic2hvcnRfbmFtZSI6IkVtb2ppU3RvcmllcyIsInN0YXJ0X3VybCI6Ii4iLCJkaXNwbGF5Ijoic3RhbmRhbG9uZSIsImJhY2tncm91bmRfY29sb3IiOiIjNjY3ZWVhIiwidGhlbWVfY29sb3IiOiIjNjY3ZWVhIiwiaWNvbnMiOlt7InNyYyI6ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjNhV1IwYUQwaU1UZ3dJaUJvWldsbmFIUTlJakU0TUNJaUlIWnBaWGRDYjNnOUlqQWdNQ0F4T0RBZ01UZ3dJaUJtYVd4c1BTSnViMjVsSWlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpUGdvOGNtVmpkQ0IzYVdSMGFEMGlNVGd3SWlCb1pXbG5hSFE5SWpFNE1DSWlJSEo0UFNJME1DSWlJR1pwYkd3OUluVnliQ2dqY1hKaFpHbGxiblF3WDJ4cGJtVmhjbDl4TWpFcElpOCtDanhrWldaelBnbzliR2x1WldGeVIzSmhaR2xsYm5RZ2FXUTlJbWR5WVdScFpXNTBNRjlzYVc1bFlYSmZNVjh4SWlCNE1UMGlNQ0lnZVRFOUlqQWlJSGd4UFNJME1DSWlJSGt4UFNJME1DSWdaM0poWkdsbGJuUlZibWwwY3owaWRYTmxjbE53WVdObFQyNVZjMlVpUGdvOWMzUnZjQ0J6ZEc5d0xXTnZiRzl5UFNJak5qWTNaV1ZoSWk4K0NqeHpkRzl3SUc5bVpuTmxkRDBpTVNJZ2MzUnZjQzFqYjJ4dmNqMGlJemMyTkdKaE1pSXZQZ284TDJ4cGJtVmhja2R5WVdScFpXNTBQZ284TDJSbFpuTStDangwWlhoMElIZzlJamt3SWlCNVBTSXhNVEFpSUdadmJuUXRjMmw2WlQwaU56QWlJSFJsZUhRdFlXNWphRzl5UFNKdGFXUmtiR1VpUGpoYmFYa2JMM1JsZUhRK0Nqd3ZjM1puUGdvPSIsInNpemVzIjoiMTgweDE4MCIsInR5cGUiOiJpbWFnZS9zdmcreG1sIn1dfQ=="
2023
/>
2124
<link rel="stylesheet" href="styles.css" />
2225
</head>
2326
<body>
2427
<div class="container">
25-
<button class="settings-btn" id="settingsBtn" title="Settings">⚙️</button>
26-
27-
<h1>✨ EmojiStori Generator ✨</h1>
28+
<div class="header-area">
29+
<button class="settings-btn" id="settingsBtn" title="Settings">
30+
⚙️
31+
</button>
32+
<h1>✨ EmojiStories ✨</h1>
33+
</div>
2834

29-
<div class="input-section">
30-
<label for="emojiInput">Enter your emojis:</label>
31-
<textarea
32-
id="emojiInput"
33-
placeholder="🐸🌟🏰👑..."
34-
inputmode="text"
35-
></textarea>
36-
<div class="hint">
37-
Tap here and your emoji keyboard will appear on mobile! 📱
35+
<div class="input-area">
36+
<div class="input-section">
37+
<label for="emojiInput">Enter your emojis:</label>
38+
<textarea
39+
id="emojiInput"
40+
placeholder="🐸🌟🏰👑..."
41+
inputmode="text"
42+
></textarea>
43+
<div class="hint">
44+
Tap here and your emoji keyboard will appear on mobile! 📱
45+
</div>
3846
</div>
39-
</div>
4047

41-
<button id="generateBtn">Generate Story</button>
48+
<button id="generateBtn">Generate Story</button>
4249

43-
<div class="loading" id="loading">
44-
<div>🎭 Creating your magical story...</div>
50+
<div class="loading" id="loading">
51+
<div>🎭 Creating your magical story...</div>
52+
</div>
4553
</div>
4654

47-
<div class="story-output" id="storyOutput">
48-
<h3>📚 Your Story:</h3>
49-
<div class="story-text" id="storyText"></div>
50-
<div class="story-controls">
51-
<button class="story-btn story-btn-primary" id="readAloudBtn">
52-
🔊 Read Aloud
53-
</button>
54-
<button
55-
class="story-btn story-btn-secondary"
56-
id="stopReadingBtn"
57-
style="display: none"
58-
>
59-
⏹️ Stop
60-
</button>
61-
<button class="story-btn story-btn-secondary" id="voiceSettingsBtn">
62-
🎭 Voice
63-
</button>
64-
</div>
65-
<div class="voice-controls" id="voiceControls">
66-
<label for="voiceSelect">Choose Voice:</label>
67-
<select id="voiceSelect" class="voice-select"></select>
68-
<label for="speedRange"
69-
>Speed: <span id="speedValue">1.0x</span></label
70-
>
71-
<input
72-
type="range"
73-
id="speedRange"
74-
min="0.5"
75-
max="2"
76-
step="0.1"
77-
value="1"
78-
style="width: 100%"
79-
/>
55+
<div class="story-area">
56+
<div class="story-output" id="storyOutput">
57+
<h3>📚 Your Story:</h3>
58+
<div class="story-text" id="storyText"></div>
59+
<div class="story-controls">
60+
<button class="story-btn story-btn-primary" id="readAloudBtn">
61+
🔊 Read Aloud
62+
</button>
63+
<button
64+
class="story-btn story-btn-secondary"
65+
id="stopReadingBtn"
66+
style="display: none"
67+
>
68+
⏹️ Stop
69+
</button>
70+
<button class="story-btn story-btn-secondary" id="voiceSettingsBtn">
71+
🎭 Voice
72+
</button>
73+
</div>
8074
</div>
8175
</div>
76+
77+
<div class="voice-controls" id="voiceControls">
78+
<label for="voiceSelect">Choose Voice:</label>
79+
<select id="voiceSelect" class="voice-select"></select>
80+
<label for="speedRange">Speed: <span id="speedValue">1.0x</span></label>
81+
<input
82+
type="range"
83+
id="speedRange"
84+
min="0.5"
85+
max="2"
86+
step="0.1"
87+
value="1"
88+
style="width: 100%"
89+
/>
90+
</div>
8291
</div>
8392

8493
<!-- Settings Modal -->
@@ -93,11 +102,22 @@ <h2 class="modal-title">⚙️ Settings</h2>
93102
<label>Model Provider:</label>
94103
<div class="provider-selection">
95104
<label class="provider-option">
96-
<input type="radio" name="provider" value="anthropic" id="providerAnthropic" checked>
105+
<input
106+
type="radio"
107+
name="provider"
108+
value="anthropic"
109+
id="providerAnthropic"
110+
checked
111+
/>
97112
<span class="provider-label">Anthropic Claude</span>
98113
</label>
99114
<label class="provider-option">
100-
<input type="radio" name="provider" value="openai" id="providerOpenAI">
115+
<input
116+
type="radio"
117+
name="provider"
118+
value="openai"
119+
id="providerOpenAI"
120+
/>
101121
<span class="provider-label">OpenAI</span>
102122
</label>
103123
</div>
@@ -110,7 +130,10 @@ <h2 class="modal-title">⚙️ Settings</h2>
110130
</div>
111131
<p id="apiInfoText">
112132
You need an Anthropic API key to generate stories. Get yours at
113-
<a href="https://console.anthropic.com" target="_blank" id="apiInfoLink"
133+
<a
134+
href="https://console.anthropic.com"
135+
target="_blank"
136+
id="apiInfoLink"
114137
>console.anthropic.com</a
115138
>
116139
</p>
@@ -125,8 +148,8 @@ <h2 class="modal-title">⚙️ Settings</h2>
125148
autocomplete="off"
126149
/>
127150
</div>
128-
129-
<div class="input-section" id="openaiKeySection" style="display: none;">
151+
152+
<div class="input-section" id="openaiKeySection" style="display: none">
130153
<label for="openaiApiKeyInput">OpenAI API Key:</label>
131154
<input
132155
type="password"
@@ -135,16 +158,27 @@ <h2 class="modal-title">⚙️ Settings</h2>
135158
autocomplete="off"
136159
/>
137160
</div>
138-
161+
139162
<div class="input-section" id="ttsProviderSection">
140163
<label>Text-to-Speech:</label>
141164
<div class="provider-selection">
142165
<label class="provider-option">
143-
<input type="radio" name="ttsProvider" value="browser" id="ttsBrowser" checked>
166+
<input
167+
type="radio"
168+
name="ttsProvider"
169+
value="browser"
170+
id="ttsBrowser"
171+
checked
172+
/>
144173
<span class="provider-label">Browser TTS</span>
145174
</label>
146175
<label class="provider-option">
147-
<input type="radio" name="ttsProvider" value="openai" id="ttsOpenAI">
176+
<input
177+
type="radio"
178+
name="ttsProvider"
179+
value="openai"
180+
id="ttsOpenAI"
181+
/>
148182
<span class="provider-label">OpenAI TTS</span>
149183
</label>
150184
</div>
@@ -167,8 +201,12 @@ <h2 class="modal-title">⚙️ Settings</h2>
167201
</div>
168202

169203
<div class="modal-actions">
170-
<button class="btn btn-secondary" id="clearApiKeys">Clear Keys</button>
171-
<button class="btn btn-primary" id="saveApiKeys">Save Settings</button>
204+
<button class="btn btn-secondary" id="clearApiKeys">
205+
Clear Keys
206+
</button>
207+
<button class="btn btn-primary" id="saveApiKeys">
208+
Save Settings
209+
</button>
172210
</div>
173211
</div>
174212
</div>

emojistori/kimoji.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ function updateTTSButtons(state, audioElement = null) {
332332
readAloudBtn.disabled = true;
333333
readAloudBtn.style.display = "inline-flex";
334334
stopReadingBtn.style.display = "none";
335+
readAloudBtn.classList.remove('playing');
336+
stopReadingBtn.classList.remove('playing');
335337
break;
336338

337339
case 'ready':
@@ -342,12 +344,16 @@ function updateTTSButtons(state, audioElement = null) {
342344
// Store audio element for click-to-play
343345
readAloudBtn.dataset.audioReady = 'true';
344346
readAloudBtn._audioElement = audioElement;
347+
readAloudBtn.classList.remove('playing');
348+
stopReadingBtn.classList.remove('playing');
345349
break;
346350

347351
case 'playing':
348352
readAloudBtn.style.display = "none";
349353
stopReadingBtn.style.display = "inline-flex";
350354
readAloudBtn.disabled = true;
355+
readAloudBtn.classList.remove('playing');
356+
stopReadingBtn.classList.add('playing');
351357
break;
352358

353359
case 'idle':
@@ -358,6 +364,8 @@ function updateTTSButtons(state, audioElement = null) {
358364
stopReadingBtn.style.display = "none";
359365
readAloudBtn.dataset.audioReady = 'false';
360366
readAloudBtn._audioElement = null;
367+
readAloudBtn.classList.remove('playing');
368+
stopReadingBtn.classList.remove('playing');
361369
break;
362370
}
363371
}
@@ -710,8 +718,10 @@ function setLoading(isLoading) {
710718

711719
if (isLoading) {
712720
loading.classList.add("show");
721+
generateBtn.classList.add("generating");
713722
} else {
714723
loading.classList.remove("show");
724+
generateBtn.classList.remove("generating");
715725
}
716726
}
717727

@@ -786,7 +796,7 @@ readAloudBtn.addEventListener("click", function() {
786796
}
787797
});
788798
stopReadingBtn.addEventListener("click", stopReading);
789-
voiceSettingsBtn.addEventListener("click", toggleVoiceSettings);
799+
voiceSettingsBtn.addEventListener("click", showSettings);
790800

791801
// Modal click outside to close
792802
settingsModal.addEventListener("click", function (e) {

0 commit comments

Comments
 (0)