# app.py
"""TriviaVerse Enhanced - Advanced Quiz Application"""
import streamlit as st
import time
from datetime import datetime
import random
# Removed dotenv import and os import as .env file is not persisting
# from dotenv import load_dotenv
# import os
from config.settings import (
DIFFICULTY_LEVELS,
BADGES,
RANDOM_TOPICS,
)
from config.themes import THEMES
from config.languages import SUPPORTED_LANGUAGES
from modules.mcq_generator import generate_quiz_set
from modules.flashcard_generator import generate_smart_deck
from modules.fact_game import generate_random_fact
from modules.adaptive_engine import AdaptiveEngine
from utils.ui_components import (
apply_custom_theme,
display_user_stats,
display_badges,
create_progress_chart,
animated_success,
create_quiz_card,
render_flashcard,
)
from utils.score_tracker import ScoreTracker
from utils.mobile_responsive import responsive_columns, responsive_css
from utils.user_auth import init_authentication, authenticate_user
from utils.challenge_manager import ChallengeManager
from modules.info_page import display_page_info
from utils.translator import get_translated_texts
# Removed load_dotenv() call as .env file is not persisting
# load_dotenv()
# --- Page Config ---
st.set_page_config(
page_title="TriviaVerse",
page_icon="🎯",
layout="wide",
initial_sidebar_state="expanded",
)
# --- App State Initialization ---
if "user_id" not in st.session_state:
st.session_state.user_id = st.session_state.get("username", f"user_{int(time.time())}")
if "score_tracker" not in st.session_state:
st.session_state.score_tracker = ScoreTracker(st.session_state.user_id)
if "theme" not in st.session_state:
st.session_state.theme = "default"
if "language" not in st.session_state:
st.session_state.language = "en"
if "topic" not in st.session_state:
st.session_state.topic = "Python programming"
# --- Load UI Text based on Language ---
ui = get_translated_texts(st.session_state.language)
# --- Update Page Title with Translated Text ---
st.title(f"{ui.get('app_name', 'TriviaVerse')} - {ui.get('enhanced_edition', 'Enhanced Edition')}")
# Initialize other session state variables
if "current_streak" not in st.session_state:
st.session_state.current_streak = 0
if "adaptive_engine" not in st.session_state:
st.session_state.adaptive_engine = AdaptiveEngine(st.session_state.user_id)
if "answer" not in st.session_state:
st.session_state.answer = None
if "mcq_quiz_questions" not in st.session_state:
st.session_state.mcq_quiz_questions = []
if "current_question_index" not in st.session_state:
st.session_state.current_question_index = 0
if "quiz_started" not in st.session_state:
st.session_state.quiz_started = False
if "quiz_results" not in st.session_state:
st.session_state.quiz_results = []
if "flashcard_deck" not in st.session_state:
st.session_state.flashcard_deck = []
if "current_flashcard_index" not in st.session_state:
st.session_state.current_flashcard_index = 0
if "challenge_manager" not in st.session_state:
st.session_state.challenge_manager = ChallengeManager()
if "current_challenge_id" not in st.session_state:
st.session_state.current_challenge_id = None
if "challenge_quiz_questions" not in st.session_state:
st.session_state.challenge_quiz_questions = []
if "challenge_current_question_index" not in st.session_state:
st.session_state.challenge_current_question_index = 0
if "game_state" not in st.session_state:
st.session_state.game_state = "menu"
if "challenge_created_id" not in st.session_state:
st.session_state.challenge_created_id = None
if "current_page" not in st.session_state:
st.session_state.current_page = "home"
# --- Authentication ---
init_authentication()
if not authenticate_user():
st.stop()
# --- UI Rendering ---
apply_custom_theme(st.session_state.theme)
st.markdown(responsive_css(), unsafe_allow_html=True)
def render_homepage():
st.markdown(f"""
{ui.get('app_name', 'TriviaVerse')}
{ui.get('app_description', 'A Dynamic Quiz App')}
""", unsafe_allow_html=True)
if st.button(ui.get('start_your_learning_journey', "Start Your Learning Journey"), key="start_journey"):
st.session_state.current_page = "game_modes"
st.rerun()
with st.sidebar:
st.title(f"🎯 {ui.get('app_name', 'TriviaVerse')}")
st.markdown(f"### 🎮 {ui.get('game_settings', 'Game Settings')}")
if st.button(f"🏠 {ui.get('home', 'Home')}", key="sidebar_home"):
st.session_state.current_page = "home"
st.rerun()
st.divider()
lang_choice_key = st.selectbox(
f"🌐 {ui.get('choose_language', 'Choose Language')}",
options=list(SUPPORTED_LANGUAGES.keys()),
index=list(SUPPORTED_LANGUAGES.values()).index(st.session_state.language)
)
if SUPPORTED_LANGUAGES[lang_choice_key] != st.session_state.language:
st.session_state.language = SUPPORTED_LANGUAGES[lang_choice_key]
st.rerun()
st.info(f"👤 {ui.get('welcome', 'Welcome')}, {st.session_state.get('username', 'Guest')}!")
theme_select = st.selectbox(
f"🎨 {ui.get('choose_theme', 'Choose Theme')}",
list(THEMES.keys()),
index=list(THEMES.keys()).index(st.session_state.theme),
)
if theme_select != st.session_state.theme:
st.session_state.theme = theme_select
st.rerun()
st.divider()
mode = st.radio(
f"🎲 {ui.get('select_game_mode', 'Select Game Mode')}",
[ui.get(k, k) for k in ["mcq_quiz", "flashcards", "fact_game", "challenge_mode", "page_info"]],
)
use_adaptive = st.checkbox(f"🤖 {ui.get('use_adaptive_difficulty', 'Use Adaptive Difficulty')}", value=True)
difficulty = st.session_state.adaptive_engine.get_recommended_difficulty() if use_adaptive else st.selectbox(
f"⚡ {ui.get('difficulty_level', 'Difficulty Level')}",
list(DIFFICULTY_LEVELS.keys()),
)
if use_adaptive:
st.info(f"{ui.get('recommended', 'Recommended')}: {difficulty}")
st.markdown(f"### 📖 {ui.get('choose_topic', 'Choose Topic')}")
def update_topic_text_input():
st.session_state.topic = st.session_state.topic_text_input
st.text_input(ui.get("enter_topic", "Enter topic"), value=st.session_state.topic, key="topic_text_input", on_change=update_topic_text_input)
def update_random_topic():
st.session_state.topic = random.choice(RANDOM_TOPICS)
if st.button(f"🎲 {ui.get('random_topic', 'Random')}", on_click=update_random_topic):
pass # The topic is updated by the on_click callback
st.markdown(f"### 🔥 {ui.get('trending_topics', 'Trending Topics')}")
def update_trending_topic():
if st.session_state.trending_topic_select:
st.session_state.topic = st.session_state.trending_topic_select
st.selectbox(ui.get("quick_select", "Quick select"), [""] + RANDOM_TOPICS, key="trending_topic_select", on_change=update_trending_topic)
if mode in [ui.get("mcq_quiz"), ui.get("challenge_mode")]:
st.markdown(f"### 🔢 {ui.get('number_of_questions', 'Number of Questions')}")
st.session_state.num_questions = st.selectbox(ui.get("select_number_of_questions", "Select number"), [5, 10, 15], index=1)
st.divider()
st.markdown(f"### 📊 {ui.get('your_stats', 'Your Stats')}")
stats = st.session_state.score_tracker.get_stats()
display_user_stats(stats, ui)
if st.button(f"🚪 {ui.get('logout', 'Logout')}", type="secondary", use_container_width=True):
st.session_state.clear()
st.rerun()
if st.session_state.current_page == "home":
render_homepage()
else:
# Header with user dashboard
col1, col2 = st.columns([2, 1])
with col1:
st.markdown(f"
🎮 {ui.get('app_name', 'TriviaVerse')} - {ui.get('enhanced_edition', 'Enhanced Edition')}
", unsafe_allow_html=True)
st.markdown(f"*{ui.get('app_description', 'A gamified learning platform powered by Wikimedia')}*")
with col2:
# Display current time and greeting
current_hour = datetime.now().hour
greeting = (
ui.get("good_morning", "Good morning")
if current_hour < 12
else ui.get("good_afternoon", "Good afternoon")
if current_hour < 18
else ui.get("good_evening", "Good evening")
)
st.markdown(f"### {greeting}, {st.session_state.get('username', 'Learner')}! 👋")
st.caption(f"{datetime.now().strftime('%B %d, %Y - %I:%M %p')}")
# Display user statistics dashboard
stats = st.session_state.score_tracker.get_stats()
display_user_stats(stats, ui)
# Display badges
if stats["badges"]:
st.markdown(f"### 🏅 {ui.get('your_achievements', 'Your Achievements')}")
display_badges(stats["badges"], ui)
# Progress chart
with st.expander(f"📈 {ui.get('view_detailed_progress', 'View Detailed Progress')}", expanded=False):
if stats["quizzes_completed"] > 0:
fig = create_progress_chart(stats, ui)
st.plotly_chart(fig, use_container_width=True)
else:
st.info(ui.get("complete_quizzes_prompt", "Complete some quizzes to see your progress chart!"))
st.divider()
# Main game area
if mode == ui.get("mcq_quiz"):
st.header(ui.get("mcq_quiz"))
# Initialize or reset quiz
if not st.session_state.quiz_started:
if st.button(ui.get("start_new_quiz", "Start New Quiz"), type="primary", use_container_width=True):
with st.spinner(ui.get("generating_quiz_questions", "Generating quiz questions...")):
st.session_state.mcq_quiz_questions = generate_quiz_set(
st.session_state.topic,
difficulty,
st.session_state.num_questions
)
if st.session_state.mcq_quiz_questions:
st.session_state.current_question_index = 0
st.session_state.quiz_started = True
st.session_state.answered = False
st.session_state.question_start_time = time.time()
st.session_state.hints_used = 0
st.session_state.quiz_results = [] # Reset quiz results
st.rerun()
else:
st.error(ui.get("failed_quiz_generation", "Failed to generate quiz questions. Please try a different topic."))
if st.session_state.quiz_started and st.session_state.mcq_quiz_questions:
# Display current question
current_mcq = st.session_state.mcq_quiz_questions[st.session_state.current_question_index]
question_number = st.session_state.current_question_index + 1
total_questions = len(st.session_state.mcq_quiz_questions)
st.subheader(f"{ui.get('question', 'Question')} {question_number} {ui.get('of', 'of')} {total_questions}")
col1, col2, col3 = responsive_columns([1, 1, 1], [1, 1, 1])
with col2:
time_limit = DIFFICULTY_LEVELS[difficulty]["time_limit"]
st.info(f"⏱️ {ui.get('time_limit', 'Time Limit')}: {time_limit}s")
with col3:
hints_allowed = DIFFICULTY_LEVELS[difficulty]["hints_allowed"]
st.info(f"💡 {ui.get('hints', 'Hints')}: {hints_allowed}")
# Timer
elapsed_time = int(time.time() - st.session_state.question_start_time)
remaining_time = max(0, time_limit - elapsed_time)
if remaining_time > 0 and not st.session_state.answered:
st.progress(remaining_time / time_limit)
st.caption(f"⏱️ {ui.get('time_remaining', 'Time remaining')}: {remaining_time}s")
create_quiz_card(
current_mcq["question"],
current_mcq["options"],
key="answer"
)
if hints_allowed > st.session_state.hints_used:
if st.button(f"💡 {ui.get('get_hint', 'Get Hint')} ({hints_allowed - st.session_state.hints_used} {ui.get('left', 'left')})"):
st.session_state.hints_used += 1
st.info(f"💡 {ui.get('hint', 'Hint')}: {current_mcq['explanation'][:100]}...")
col1_btn, col2_btn, col3_btn = st.columns([1, 2, 1])
with col2_btn:
if st.button(ui.get("submit_answer", "Submit Answer"), type="primary", use_container_width=True):
is_correct = st.session_state.answer == current_mcq["correct_answer"]
st.session_state.answered = True
st.session_state.quiz_results.append({
"question": current_mcq["question"],
"user_answer": st.session_state.answer,
"correct_answer": current_mcq["correct_answer"],
"is_correct": is_correct,
"explanation": current_mcq["explanation"]
})
st.session_state.adaptive_engine.update_performance(is_correct, difficulty, topic=current_mcq.get("topic"))
if is_correct:
st.session_state.current_streak += 1
points = st.session_state.score_tracker.add_quiz_result("MCQ Quiz", 1, 1, difficulty)
animated_success(f"{ui.get('correct', 'Correct')}! +{points} {ui.get('points', 'points')}")
st.balloons()
else:
st.session_state.current_streak = 0
st.error(f"❌ {ui.get('incorrect', 'Incorrect')}. {ui.get('the_answer_was', 'The answer was')}: {current_mcq['correct_answer']}")
st.info(f"📚 {current_mcq['explanation']}")
st.rerun()
elif st.session_state.answered:
if st.session_state.current_question_index < total_questions - 1:
if st.button(ui.get("next_question", "Next Question"), type="secondary", use_container_width=True):
st.session_state.current_question_index += 1
st.session_state.answered = False
st.session_state.question_start_time = time.time()
st.session_state.hints_used = 0
st.rerun()
else:
st.success(ui.get("quiz_completed", "Quiz Completed!"))
st.session_state.quiz_started = False
st.session_state.mcq_quiz_questions = []
st.session_state.current_question_index = 0
st.markdown(f"### {ui.get('quiz_results_summary', 'Quiz Results Summary')}")
for i, result in enumerate(st.session_state.quiz_results):
st.markdown(f"**{ui.get('question', 'Question')} {i+1}:** {result['question']}")
if result['is_correct']:
st.success(f"✅ {ui.get('your_answer', 'Your Answer')}: {result['user_answer']} ({ui.get('correct', 'Correct')})")
else:
st.error(f"❌ {ui.get('your_answer', 'Your Answer')}: {result['user_answer']} ({ui.get('incorrect', 'Incorrect')})")
st.info(f"{ui.get('correct_answer', 'Correct Answer')}: {result['correct_answer']}")
st.caption(f"{ui.get('explanation', 'Explanation')}: {result['explanation']}")
st.divider()
if st.button(ui.get("start_new_quiz", "Start New Quiz"), type="primary", use_container_width=True):
st.rerun()
else:
st.error(f"⏱️ {ui.get('times_up', 'Time is up!')}")
st.session_state.answered = True
st.session_state.quiz_results.append({
"question": current_mcq["question"],
"user_answer": ui.get("no_answer_timed_out", "No answer (Time's up)"),
"correct_answer": current_mcq["correct_answer"],
"is_correct": False,
"explanation": current_mcq["explanation"]
})
st.session_state.score_tracker.add_quiz_result("MCQ Quiz", 0, 1, difficulty)
st.rerun()
elif mode == ui.get("flashcards"):
st.header(ui.get("interactive_flashcards", "Interactive Flashcards"))
if st.button(ui.get("generate_flashcard", "Generate Flashcard"), type="primary"):
with st.spinner(ui.get("creating_flashcard_deck", "Creating flashcard deck...")):
st.session_state.flashcard_deck = generate_smart_deck(
st.session_state.topic,
deck_size=10,
difficulty=difficulty,
adaptive_engine=st.session_state.adaptive_engine
)
if st.session_state.flashcard_deck:
st.session_state.current_flashcard_index = 0
st.session_state.card_flipped = False
st.rerun()
else:
st.error(ui.get("failed_flashcard_generation", "Failed to generate flashcards. Please try a different topic."))
if st.session_state.flashcard_deck:
current_flashcard = st.session_state.flashcard_deck[st.session_state.current_flashcard_index]
st.subheader(f"{ui.get('flashcard', 'Flashcard')} {st.session_state.current_flashcard_index + 1} {ui.get('of', 'of')} {len(st.session_state.flashcard_deck)}")
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
render_flashcard(
current_flashcard["front"],
current_flashcard["back"],
is_flipped=st.session_state.get("card_flipped", False),
)
if not st.session_state.get("card_flipped", False):
if st.button(ui.get("flip_card", "Flip Card"), use_container_width=True):
st.session_state.card_flipped = True
st.rerun()
else:
st.write("")
btn_col1, btn_col2 = st.columns(2)
with btn_col1:
if st.button(ui.get("got_it", "Got it!"), use_container_width=True):
st.session_state.adaptive_engine.update_performance(
is_correct=True,
difficulty=current_flashcard.get("difficulty", "Medium"),
item_id=current_flashcard.get("item_id"),
topic=current_flashcard.get("topic")
)
points = st.session_state.score_tracker.add_quiz_result("Flashcards", 1, 1, current_flashcard.get("difficulty", "Medium"))
animated_success(f"{ui.get('great', 'Great')}! +{points} {ui.get('points', 'points')}")
st.session_state.card_flipped = False
if st.session_state.current_flashcard_index < len(st.session_state.flashcard_deck) - 1:
st.session_state.current_flashcard_index += 1
else:
st.success(ui.get("flashcard_deck_completed", "Flashcard Deck Completed!"))
st.session_session.flashcard_deck = []
st.session_state.current_flashcard_index = 0
st.rerun()
with btn_col2:
if st.button(ui.get("need_practice", "Need Practice"), use_container_width=True):
st.session_state.adaptive_engine.update_performance(
is_correct=False,
difficulty=current_flashcard.get("difficulty", "Medium"),
item_id=current_flashcard.get("item_id"),
topic=current_flashcard.get("topic")
)
st.session_state.score_tracker.add_quiz_result("Flashcards", 0, 1, current_flashcard.get("difficulty", "Medium"))
st.session_state.card_flipped = False
if st.session_state.current_flashcard_index < len(st.session_state.flashcard_deck) - 1:
st.session_state.current_flashcard_index += 1
else:
st.info(ui.get("flashcard_deck_completed_practice", "Flashcard Deck Completed. Keep practicing!"))
st.session_state.flashcard_deck = []
st.session_state.current_flashcard_index = 0
st.rerun()
else:
st.info(ui.get("no_flashcards_in_deck", "No flashcards in deck. Click 'Generate Flashcard' to create a new one."))
elif mode == ui.get("fact_game"):
st.header(ui.get("random_fact_game", "Random Fact Game"))
col1, col2 = st.columns([2, 1])
with col1:
if st.button(ui.get("get_random_fact", "Get Random Fact"), type="primary", use_container_width=True):
if "current_fact" in st.session_state:
del st.session_state["current_fact"]
with st.spinner(ui.get("finding_interesting_fact", "Finding an interesting fact...")):
fact = generate_random_fact()
if fact.get("status"):
st.session_state.current_fact = fact
st.session_state.fact_start_time = time.time()
else:
st.session_state.current_fact = {"status": False}
with col2:
st.info(f"⏱️ {ui.get('quick_read_challenge', 'Quick Read Challenge')}: 15s")
if "current_fact" in st.session_state:
fact = st.session_state.current_fact
if fact.get("status"):
elapsed = int(time.time() - st.session_state.get("fact_start_time", time.time()))
remaining = max(0, 15 - elapsed)
if remaining > 0:
st.progress(remaining / 15)
st.markdown(
f"""
🌟 {ui.get('did_you_know', 'Did you know?')}
{fact["fact"]}
{ui.get('topic', 'Topic')}: {fact["topic"]}
""",
unsafe_allow_html=True,
)
if st.button(ui.get("interesting_next_fact", "Interesting! Next fact")):
points = st.session_state.score_tracker.add_quiz_result("Fact Game", 1, 1, difficulty)
animated_success(f"{ui.get('knowledge_gained', 'Knowledge gained')}! +{points} {ui.get('points', 'points')}")
del st.session_state["current_fact"]
else:
st.success(ui.get("times_up_next_fact", "Time's up! Ready for the next fact?"))
if st.button(ui.get("next_fact", "Next Fact")):
del st.session_state["current_fact"]
else:
st.error(ui.get("failed_fact_generation", "Failed to generate fact. Please try again."))
elif mode == ui.get("challenge_mode"):
st.header(ui.get("challenge_mode", "Challenge Mode"))
if not st.session_state.current_challenge_id:
tab1, tab2 = st.tabs([ui.get("create_challenge", "Create Challenge"), ui.get("join_challenge", "Join Challenge")])
with tab1:
st.subheader(ui.get("create_new_challenge", "Create a New Challenge"))
with st.form("create_challenge_form"):
challenge_topic = st.text_input(ui.get("challenge_topic", "Challenge Topic"), value=st.session_state.topic)
challenge_difficulty = st.selectbox(
ui.get("challenge_difficulty", "Challenge Difficulty"),
list(DIFFICULTY_LEVELS.keys()),
index=list(DIFFICULTY_LEVELS.keys()).index(difficulty),
)
challenge_num_questions = st.selectbox(
ui.get("number_of_questions", "Number of Questions"),
[5, 10, 15],
index=[5, 10, 15].index(st.session_state.get("num_questions", 5)),
)
create_challenge_submitted = st.form_submit_button(ui.get("create_challenge", "Create Challenge"), type="primary")
if create_challenge_submitted:
new_challenge_id = st.session_state.challenge_manager.create_challenge(
creator_id=st.session_state.user_id,
topic=challenge_topic,
difficulty=challenge_difficulty,
num_questions=challenge_num_questions
)
st.session_state.challenge_created_id = new_challenge_id
st.success(f"{ui.get('challenge_created', 'Challenge created! Share this ID')}: **{new_challenge_id}**")
if st.session_state.challenge_created_id:
st.info(f"{ui.get('challenge_id', 'Challenge ID')}: **{st.session_state.challenge_created_id}**")
if st.button(ui.get("start_challenge_play", "Start Challenge Play"), key="start_created_challenge"):
st.session_state.current_challenge_id = st.session_state.challenge_created_id
st.session_state.challenge_quiz_questions = generate_quiz_set(
st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["topic"],
st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["difficulty"],
st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["num_questions"]
)
st.session_state.challenge_quiz_started = True
st.session_state.challenge_current_question_index = 0
st.session_state.answered = False
st.session_state.question_start_time = time.time()
st.session_state.hints_used = 0
st.session_state.quiz_results = []
st.session_state.challenge_created_id = None
st.rerun()
with tab2:
st.subheader(ui.get("join_existing_challenge", "Join an Existing Challenge"))
with st.form("join_challenge_form"):
join_challenge_id = st.text_input(ui.get("enter_challenge_id", "Enter Challenge ID"))
join_challenge_submitted = st.form_submit_button(ui.get("join_challenge", "Join Challenge"), type="primary")
if join_challenge_submitted:
challenge = st.session_state.challenge_manager.get_challenge(join_challenge_id)
if challenge:
st.success(f"{ui.get('joined_challenge', 'Joined challenge')}: {challenge['topic']} ({challenge['difficulty']})")
st.session_state.current_challenge_id = join_challenge_id
st.session_state.challenge_quiz_questions = generate_quiz_set(
challenge["topic"],
challenge["difficulty"],
challenge["num_questions"]
)
st.session_state.challenge_quiz_started = True
st.session_state.challenge_current_question_index = 0
st.session_state.answered = False
st.session_state.question_start_time = time.time()
st.session_state.hints_used = 0
st.session_state.quiz_results = []
st.rerun()
else:
st.error(ui.get("challenge_not_found", "Challenge not found. Please check the ID."))
if st.session_state.current_challenge_id:
current_challenge = st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)
if current_challenge:
st.markdown(f"---")
st.subheader(f"{ui.get('active_challenge', 'Active Challenge')}: {current_challenge['topic']} ({current_challenge['difficulty']})")
st.write(f"{ui.get('created_by', 'Created by')}: {current_challenge['creator_id']}")
st.write(f"{ui.get('questions', 'Questions')}: {current_challenge['num_questions']}")
st.markdown(f"#### {ui.get('participants', 'Participants')}:")
if current_challenge["participants"]:
for participant_id, p_data in current_challenge["participants"].items():
st.write(f"- {participant_id}: {ui.get('score', 'Score')} {p_data['score']} ({ui.get('completed', 'Completed')}: {p_data.get('completed_at', 'N/A')})")
else:
st.write(ui.get("no_participants_yet", "No participants yet."))
if st.session_state.challenge_quiz_started and st.session_state.challenge_quiz_questions:
current_mcq = st.session_state.challenge_quiz_questions[st.session_state.challenge_current_question_index]
question_number = st.session_state.challenge_current_question_index + 1
total_questions = len(st.session_state.challenge_quiz_questions)
st.subheader(f"{ui.get('challenge_question', 'Challenge Question')} {question_number} {ui.get('of', 'of')} {total_questions}")
col1, col2, col3 = responsive_columns([1, 1, 1], [1, 1, 1])
with col2:
time_limit = DIFFICULTY_LEVELS[current_challenge['difficulty']]["time_limit"]
st.info(f"⏱️ {ui.get('time_limit', 'Time Limit')}: {time_limit}s")
with col3:
hints_allowed = DIFFICULTY_LEVELS[current_challenge['difficulty']]["hints_allowed"]
st.info(f"💡 {ui.get('hints', 'Hints')}: {hints_allowed}")
elapsed_time = int(time.time() - st.session_state.question_start_time)
remaining_time = max(0, time_limit - elapsed_time)
if remaining_time > 0 and not st.session_state.answered:
st.progress(remaining_time / time_limit)
st.caption(f"⏱️ {ui.get('time_remaining', 'Time remaining')}: {remaining_time}s")
create_quiz_card(current_mcq["question"], current_mcq["options"], key="challenge_answer")
if hints_allowed > st.session_state.hints_used:
if st.button(f"💡 {ui.get('get_hint', 'Get Hint')} ({hints_allowed - st.session_state.hints_used} {ui.get('left', 'left')})"):
st.session_state.hints_used += 1
st.info(f"💡 {ui.get('hint', 'Hint')}: {current_mcq['explanation'][:100]}...")
col1_btn, col2_btn, col3_btn = st.columns([1, 2, 1])
with col2_btn:
if st.button(ui.get("submit_answer", "Submit Answer"), type="primary", use_container_width=True):
is_correct = st.session_state.challenge_answer == current_mcq["correct_answer"]
st.session_state.answered = True
st.session_state.quiz_results.append({
"question": current_mcq["question"],
"user_answer": st.session_state.challenge_answer,
"correct_answer": current_mcq["correct_answer"],
"is_correct": is_correct,
"explanation": current_mcq["explanation"]
})
st.session_state.adaptive_engine.update_performance(is_correct, current_challenge['difficulty'], topic=current_mcq.get("topic"))
if is_correct:
st.session_state.current_streak += 1
points = st.session_state.score_tracker.add_quiz_result("Challenge Mode", 1, 1, current_challenge['difficulty'])
animated_success(f"{ui.get('correct', 'Correct')}! +{points} {ui.get('points', 'points')}")
st.balloons()
else:
st.session_state.current_streak = 0
st.error(f"❌ {ui.get('incorrect', 'Incorrect')}. {ui.get('the_answer_was', 'The answer was')}: {current_mcq['correct_answer']}")
st.info(f"📚 {current_mcq['explanation']}")
st.rerun()
elif st.session_state.answered:
if st.session_state.challenge_current_question_index < total_questions - 1:
if st.button(ui.get("next_question", "Next Question"), type="secondary", use_container_width=True):
st.session_state.challenge_current_question_index += 1
st.session_state.answered = False
st.session_state.question_start_time = time.time()
st.session_state.hints_used = 0
st.rerun()
else:
st.success(ui.get("challenge_quiz_completed", "Challenge Quiz Completed!"))
final_score = sum(1 for r in st.session_state.quiz_results if r['is_correct'])
st.session_state.challenge_manager.update_challenge_score(
st.session_state.current_challenge_id,
st.session_state.user_id,
final_score,
st.session_state.quiz_results
)
st.session_state.challenge_quiz_started = False
st.session_state.challenge_quiz_questions = []
st.session_state.challenge_current_question_index = 0
st.session_state.current_challenge_id = None
st.rerun()
else:
st.error(f"⏱️ {ui.get('times_up', 'Time is up!')}")
st.session_state.answered = True
st.session_state.quiz_results.append({
"question": current_mcq["question"],
"user_answer": ui.get("no_answer_timed_out", "No answer (Time's up)"),
"correct_answer": current_mcq["correct_answer"],
"is_correct": False,
"explanation": current_mcq["explanation"]
})
st.session_state.score_tracker.add_quiz_result("Challenge Mode", 0, 1, difficulty)
st.rerun()
elif mode == ui.get("page_info"):
st.header(ui.get("page_information", "Page Information"))
st.write(ui.get("get_page_info_prompt", "Get detailed information and images for any topic."))
info_topic = st.text_input(ui.get("enter_topic_for_info", "Enter Topic for Information"), value=st.session_state.topic)
num_images = st.slider(ui.get("number_of_images", "Number of Images"), 0, 5, 1)
if st.button(ui.get("get_information", "Get Information"), type="primary"):
with st.spinner(f"{ui.get('fetching_information_for', 'Fetching information for')} {info_topic}..."):
display_page_info(info_topic, num_images)
st.divider()
st.markdown(f"""
{ui.get('made_with', 'Made with')} ❤️ {ui.get('using_streamlit_and_wikimedia', 'using Streamlit and Wikimedia APIs')}
{ui.get('app_name', 'TriviaVerse')} v2.0 - {ui.get('enhanced_edition', 'Enhanced Edition')}
""", unsafe_allow_html=True)