Update app.py
Browse files
app.py
CHANGED
@@ -4,6 +4,17 @@ import datetime
|
|
4 |
from openai import OpenAI
|
5 |
from typing import Dict, List, Set
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
# Custom CSS for Thai-English bilingual display
|
8 |
st.markdown("""
|
9 |
<style>
|
@@ -29,16 +40,24 @@ st.markdown("""
|
|
29 |
</style>
|
30 |
""", unsafe_allow_html=True)
|
31 |
|
32 |
-
# Initialize
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
-
|
36 |
-
st.set_page_config(
|
37 |
-
page_title="JoyStory - Interactive Story Adventure",
|
38 |
-
page_icon="📖",
|
39 |
-
layout="wide",
|
40 |
-
initial_sidebar_state="collapsed",
|
41 |
-
)
|
42 |
|
43 |
def show_welcome_section():
|
44 |
st.markdown("""
|
@@ -66,25 +85,6 @@ def show_welcome_section():
|
|
66 |
</div>
|
67 |
""", unsafe_allow_html=True)
|
68 |
|
69 |
-
# Initialize session state variables
|
70 |
-
def init_session_state():
|
71 |
-
if 'story' not in st.session_state:
|
72 |
-
st.session_state.story = []
|
73 |
-
if 'feedback' not in st.session_state:
|
74 |
-
st.session_state.feedback = None
|
75 |
-
if 'level' not in st.session_state:
|
76 |
-
st.session_state.level = 'Beginner'
|
77 |
-
if 'unique_words' not in st.session_state:
|
78 |
-
st.session_state.unique_words = set()
|
79 |
-
if 'total_words' not in st.session_state:
|
80 |
-
st.session_state.total_words = 0
|
81 |
-
if 'badges' not in st.session_state:
|
82 |
-
st.session_state.badges = []
|
83 |
-
if 'should_reset' not in st.session_state:
|
84 |
-
st.session_state.should_reset = False
|
85 |
-
|
86 |
-
init_session_state()
|
87 |
-
|
88 |
def generate_story_continuation(user_input: str, level: str) -> str:
|
89 |
"""Generate AI story continuation using ChatGPT."""
|
90 |
try:
|
@@ -272,23 +272,35 @@ with st.sidebar:
|
|
272 |
🎯 เลือกระดับของน้องๆ
|
273 |
</div>
|
274 |
""", unsafe_allow_html=True)
|
|
|
275 |
level = st.radio(
|
276 |
"Select your English level:",
|
277 |
('Beginner', 'Intermediate', 'Advanced'),
|
278 |
index=['Beginner', 'Intermediate', 'Advanced'].index(st.session_state.level)
|
279 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
|
281 |
# Main content area
|
282 |
col1, col2 = st.columns([3, 1])
|
283 |
|
284 |
with col1:
|
285 |
# Story Display Box
|
286 |
-
st.
|
287 |
-
|
|
|
|
|
|
|
|
|
288 |
|
|
|
289 |
with story_display:
|
290 |
if not st.session_state.story:
|
291 |
-
st.info("Start your adventure by writing the first sentence!")
|
292 |
else:
|
293 |
for entry in st.session_state.story:
|
294 |
if entry['role'] == 'You':
|
@@ -297,62 +309,77 @@ with col1:
|
|
297 |
st.write("🤖 AI:", entry['content'])
|
298 |
|
299 |
# User Input Box
|
300 |
-
st.
|
301 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
|
303 |
-
if st.button("Submit"):
|
304 |
if user_input.strip():
|
305 |
-
# Add user's input to story
|
306 |
st.session_state.story.append({"role": "You", "content": user_input})
|
307 |
-
|
308 |
-
# Update achievements
|
309 |
update_achievements(user_input)
|
310 |
-
|
311 |
-
# Generate feedback (stored separately)
|
312 |
st.session_state.feedback = provide_feedback(user_input, st.session_state.level)
|
313 |
-
|
314 |
-
# Generate AI continuation
|
315 |
ai_response = generate_story_continuation(user_input, st.session_state.level)
|
316 |
st.session_state.story.append({"role": "AI", "content": ai_response})
|
317 |
-
|
318 |
st.rerun()
|
319 |
else:
|
320 |
-
st.warning("Please write something to continue the story.")
|
321 |
|
322 |
with col2:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
st.markdown("""
|
324 |
<div class="thai-eng">
|
325 |
-
|
326 |
-
|
327 |
</div>
|
328 |
""", unsafe_allow_html=True)
|
329 |
|
330 |
-
if st.button("Get Vocabulary Ideas"):
|
331 |
vocab_suggestions = get_vocabulary_suggestions()
|
332 |
st.markdown("#### 📚 คำศัพท์น่ารู้ | Useful Words")
|
333 |
for word in vocab_suggestions:
|
334 |
st.markdown(f"• {word}")
|
335 |
|
336 |
-
if st.button("Get
|
337 |
prompt = get_creative_prompt()
|
338 |
-
st.markdown("""
|
339 |
<div class="thai-eng">
|
340 |
-
|
341 |
-
|
342 |
</div>
|
343 |
-
"""
|
344 |
|
345 |
# Achievements Box
|
346 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
if st.session_state.badges:
|
348 |
for badge in st.session_state.badges:
|
349 |
st.success(f"🏆 {badge}")
|
350 |
else:
|
351 |
-
st.write("Keep writing to earn badges!")
|
352 |
|
353 |
# Save Story Button
|
354 |
if st.session_state.story:
|
355 |
-
if st.button("Save Story"):
|
356 |
story_data = {
|
357 |
'level': st.session_state.level,
|
358 |
'date': datetime.datetime.now().isoformat(),
|
@@ -362,7 +389,7 @@ with col2:
|
|
362 |
'unique_words': list(st.session_state.unique_words)
|
363 |
}
|
364 |
st.download_button(
|
365 |
-
label="Download Story",
|
366 |
data=json.dumps(story_data, indent=2),
|
367 |
file_name='joystory.json',
|
368 |
mime='application/json'
|
|
|
4 |
from openai import OpenAI
|
5 |
from typing import Dict, List, Set
|
6 |
|
7 |
+
# Set up Streamlit page configuration
|
8 |
+
st.set_page_config(
|
9 |
+
page_title="JoyStory - Interactive Story Adventure",
|
10 |
+
page_icon="📖",
|
11 |
+
layout="wide",
|
12 |
+
initial_sidebar_state="collapsed",
|
13 |
+
)
|
14 |
+
|
15 |
+
# Initialize OpenAI client
|
16 |
+
client = OpenAI()
|
17 |
+
|
18 |
# Custom CSS for Thai-English bilingual display
|
19 |
st.markdown("""
|
20 |
<style>
|
|
|
40 |
</style>
|
41 |
""", unsafe_allow_html=True)
|
42 |
|
43 |
+
# Initialize session state variables
|
44 |
+
def init_session_state():
|
45 |
+
if 'story' not in st.session_state:
|
46 |
+
st.session_state.story = []
|
47 |
+
if 'feedback' not in st.session_state:
|
48 |
+
st.session_state.feedback = None
|
49 |
+
if 'level' not in st.session_state:
|
50 |
+
st.session_state.level = 'Beginner'
|
51 |
+
if 'unique_words' not in st.session_state:
|
52 |
+
st.session_state.unique_words = set()
|
53 |
+
if 'total_words' not in st.session_state:
|
54 |
+
st.session_state.total_words = 0
|
55 |
+
if 'badges' not in st.session_state:
|
56 |
+
st.session_state.badges = []
|
57 |
+
if 'should_reset' not in st.session_state:
|
58 |
+
st.session_state.should_reset = False
|
59 |
|
60 |
+
init_session_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
def show_welcome_section():
|
63 |
st.markdown("""
|
|
|
85 |
</div>
|
86 |
""", unsafe_allow_html=True)
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
def generate_story_continuation(user_input: str, level: str) -> str:
|
89 |
"""Generate AI story continuation using ChatGPT."""
|
90 |
try:
|
|
|
272 |
🎯 เลือกระดับของน้องๆ
|
273 |
</div>
|
274 |
""", unsafe_allow_html=True)
|
275 |
+
|
276 |
level = st.radio(
|
277 |
"Select your English level:",
|
278 |
('Beginner', 'Intermediate', 'Advanced'),
|
279 |
index=['Beginner', 'Intermediate', 'Advanced'].index(st.session_state.level)
|
280 |
)
|
281 |
+
|
282 |
+
st.session_state.level = level
|
283 |
+
|
284 |
+
if st.button("Start New Story"):
|
285 |
+
st.session_state.should_reset = True
|
286 |
+
st.rerun()
|
287 |
|
288 |
# Main content area
|
289 |
col1, col2 = st.columns([3, 1])
|
290 |
|
291 |
with col1:
|
292 |
# Story Display Box
|
293 |
+
st.markdown("""
|
294 |
+
<div class="thai-eng">
|
295 |
+
<div class="thai">📖 เรื่องราวของคุณ</div>
|
296 |
+
<div class="eng">Your Story</div>
|
297 |
+
</div>
|
298 |
+
""", unsafe_allow_html=True)
|
299 |
|
300 |
+
story_display = st.container()
|
301 |
with story_display:
|
302 |
if not st.session_state.story:
|
303 |
+
st.info("เริ่มต้นผจญภัยด้วยการเขียนประโยคแรกกันเลย! | Start your adventure by writing the first sentence!")
|
304 |
else:
|
305 |
for entry in st.session_state.story:
|
306 |
if entry['role'] == 'You':
|
|
|
309 |
st.write("🤖 AI:", entry['content'])
|
310 |
|
311 |
# User Input Box
|
312 |
+
st.markdown("""
|
313 |
+
<div class="thai-eng">
|
314 |
+
<div class="thai">✏️ ถึงตาคุณแล้ว</div>
|
315 |
+
<div class="eng">Your Turn</div>
|
316 |
+
</div>
|
317 |
+
""", unsafe_allow_html=True)
|
318 |
+
|
319 |
+
user_input = st.text_area("เขียนต่อจากเรื่องราว | Continue the story:", height=100)
|
320 |
|
321 |
+
if st.button("ส่งคำตอบ | Submit"):
|
322 |
if user_input.strip():
|
|
|
323 |
st.session_state.story.append({"role": "You", "content": user_input})
|
|
|
|
|
324 |
update_achievements(user_input)
|
|
|
|
|
325 |
st.session_state.feedback = provide_feedback(user_input, st.session_state.level)
|
|
|
|
|
326 |
ai_response = generate_story_continuation(user_input, st.session_state.level)
|
327 |
st.session_state.story.append({"role": "AI", "content": ai_response})
|
|
|
328 |
st.rerun()
|
329 |
else:
|
330 |
+
st.warning("กรุณาเขียนเนื้อเรื่องก่อนกดส่ง | Please write something to continue the story.")
|
331 |
|
332 |
with col2:
|
333 |
+
# Feedback Display
|
334 |
+
if st.session_state.feedback:
|
335 |
+
st.markdown("""
|
336 |
+
<div class="thai-eng">
|
337 |
+
<div class="thai">📝 คำแนะนำ</div>
|
338 |
+
<div class="eng">Writing Feedback</div>
|
339 |
+
</div>
|
340 |
+
""", unsafe_allow_html=True)
|
341 |
+
st.markdown(f"*{st.session_state.feedback}*")
|
342 |
+
|
343 |
+
# Help and Suggestions Box
|
344 |
st.markdown("""
|
345 |
<div class="thai-eng">
|
346 |
+
<div class="thai">✨ เครื่องมือช่วยเขียน</div>
|
347 |
+
<div class="eng">Writing Tools</div>
|
348 |
</div>
|
349 |
""", unsafe_allow_html=True)
|
350 |
|
351 |
+
if st.button("ดูคำศัพท์แนะนำ | Get Vocabulary Ideas"):
|
352 |
vocab_suggestions = get_vocabulary_suggestions()
|
353 |
st.markdown("#### 📚 คำศัพท์น่ารู้ | Useful Words")
|
354 |
for word in vocab_suggestions:
|
355 |
st.markdown(f"• {word}")
|
356 |
|
357 |
+
if st.button("ขอคำใบ้ | Get Creative Prompt"):
|
358 |
prompt = get_creative_prompt()
|
359 |
+
st.markdown(f"""
|
360 |
<div class="thai-eng">
|
361 |
+
<div class="thai">💭 {prompt['thai']}</div>
|
362 |
+
<div class="eng">💭 {prompt['eng']}</div>
|
363 |
</div>
|
364 |
+
""", unsafe_allow_html=True)
|
365 |
|
366 |
# Achievements Box
|
367 |
+
st.markdown("""
|
368 |
+
<div class="thai-eng">
|
369 |
+
<div class="thai">🏆 ความสำเร็จ</div>
|
370 |
+
<div class="eng">Achievements</div>
|
371 |
+
</div>
|
372 |
+
""", unsafe_allow_html=True)
|
373 |
+
|
374 |
if st.session_state.badges:
|
375 |
for badge in st.session_state.badges:
|
376 |
st.success(f"🏆 {badge}")
|
377 |
else:
|
378 |
+
st.write("เขียนต่อไปเพื่อรับรางวัล | Keep writing to earn badges!")
|
379 |
|
380 |
# Save Story Button
|
381 |
if st.session_state.story:
|
382 |
+
if st.button("บันทึกเรื่องราว | Save Story"):
|
383 |
story_data = {
|
384 |
'level': st.session_state.level,
|
385 |
'date': datetime.datetime.now().isoformat(),
|
|
|
389 |
'unique_words': list(st.session_state.unique_words)
|
390 |
}
|
391 |
st.download_button(
|
392 |
+
label="ดาวน์โหลดเรื่องราว | Download Story",
|
393 |
data=json.dumps(story_data, indent=2),
|
394 |
file_name='joystory.json',
|
395 |
mime='application/json'
|