Spaces:
Running
Running
Update app.py
#90
by
Muthuraja18
- opened
app.py
CHANGED
|
@@ -982,27 +982,26 @@ def play_page():
|
|
| 982 |
st.session_state['question_started_at'] = time.time()
|
| 983 |
st.rerun()
|
| 984 |
|
|
|
|
| 985 |
# ---------------- SUBMIT ----------------
|
| 986 |
with col2:
|
| 987 |
if idx == len(questions) - 1:
|
| 988 |
if st.button("Submit All Answers", key=f"submit_{gid}_{idx}"):
|
| 989 |
-
|
| 990 |
answers = st.session_state['answers']
|
| 991 |
times = st.session_state['answer_times']
|
| 992 |
-
|
| 993 |
answers[idx] = choice
|
| 994 |
times[idx] = time.time() - st.session_state['question_started_at']
|
| 995 |
|
| 996 |
-
#
|
| 997 |
score, flags = compute_score(
|
| 998 |
questions,
|
| 999 |
answers,
|
| 1000 |
times
|
| 1001 |
)
|
| 1002 |
-
|
| 1003 |
percentage = int(score / (len(questions) * 15) * 100)
|
| 1004 |
-
|
| 1005 |
-
# Update players
|
| 1006 |
players = unified_get("players") or {}
|
| 1007 |
players.setdefault(gid, {})
|
| 1008 |
players[gid][uname] = {
|
|
@@ -1014,8 +1013,22 @@ def play_page():
|
|
| 1014 |
"timestamp": now_iso()
|
| 1015 |
}
|
| 1016 |
unified_set("players", players)
|
| 1017 |
-
|
| 1018 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1019 |
if game.get('auto_close', True):
|
| 1020 |
games[gid]['closed'] = True
|
| 1021 |
games[gid]['closed_at'] = now_iso()
|
|
@@ -1025,12 +1038,11 @@ def play_page():
|
|
| 1025 |
f"Submitted! Score: {score} / {len(questions) * 15} ({percentage}%)"
|
| 1026 |
)
|
| 1027 |
st.balloons()
|
| 1028 |
-
|
| 1029 |
st.session_state['last_score'] = score
|
| 1030 |
st.session_state['last_game'] = gid
|
| 1031 |
st.session_state['current_index'] = 0
|
| 1032 |
-
|
| 1033 |
-
|
| 1034 |
# Join game
|
| 1035 |
def join_game_page():
|
| 1036 |
st.header("Join Game")
|
|
@@ -1072,12 +1084,8 @@ def join_game_page():
|
|
| 1072 |
else:
|
| 1073 |
st.error(msg)
|
| 1074 |
|
| 1075 |
-
|
| 1076 |
-
|
| 1077 |
# Play page
|
| 1078 |
# ----------------- Create Game -----------------
|
| 1079 |
-
|
| 1080 |
-
|
| 1081 |
|
| 1082 |
# Friends page
|
| 1083 |
def friends_page():
|
|
@@ -1175,66 +1183,60 @@ def inbox_page():
|
|
| 1175 |
st.error(msg)
|
| 1176 |
|
| 1177 |
# Leaderboard page
|
|
|
|
| 1178 |
def leaderboard_page():
|
| 1179 |
-
st.header("Leaderboard")
|
| 1180 |
-
|
| 1181 |
-
# โ
Correct source (Online + Offline safe)
|
| 1182 |
-
rows = unified_get("/leaderboard") or []
|
| 1183 |
-
|
| 1184 |
-
if isinstance(rows, list) and rows:
|
| 1185 |
-
df = pd.DataFrame(rows)
|
| 1186 |
-
else:
|
| 1187 |
-
try:
|
| 1188 |
-
df = pd.read_csv(LEADERBOARD_FILE)
|
| 1189 |
-
except Exception:
|
| 1190 |
-
df = pd.DataFrame()
|
| 1191 |
|
| 1192 |
-
|
| 1193 |
-
|
|
|
|
| 1194 |
return
|
| 1195 |
|
| 1196 |
-
#
|
| 1197 |
-
|
| 1198 |
-
df["score"] = pd.to_numeric(df["score"], errors="coerce").fillna(0)
|
| 1199 |
-
|
| 1200 |
-
# ๐ Stable sorting
|
| 1201 |
-
sort_cols = ["score"]
|
| 1202 |
-
asc = [False]
|
| 1203 |
|
| 1204 |
-
|
| 1205 |
-
|
| 1206 |
-
|
|
|
|
| 1207 |
|
| 1208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1209 |
|
| 1210 |
-
|
| 1211 |
-
|
| 1212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1213 |
|
| 1214 |
-
st.markdown(
|
| 1215 |
-
st.markdown(f"**๐ฎ Total Games:** {total_games}")
|
| 1216 |
|
| 1217 |
-
#
|
| 1218 |
-
st.
|
| 1219 |
-
|
| 1220 |
-
for
|
| 1221 |
-
st.
|
| 1222 |
-
|
| 1223 |
-
f"{row.get('score',0)} pts"
|
| 1224 |
-
)
|
| 1225 |
|
| 1226 |
st.markdown("---")
|
| 1227 |
|
| 1228 |
-
#
|
| 1229 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1230 |
|
| 1231 |
-
# Existing chart (unchanged)
|
| 1232 |
-
fig = px.bar(
|
| 1233 |
-
df_sorted.head(10),
|
| 1234 |
-
x="name",
|
| 1235 |
-
y="score"
|
| 1236 |
-
)
|
| 1237 |
-
st.plotly_chart(fig, use_container_width=True)
|
| 1238 |
|
| 1239 |
|
| 1240 |
|
|
|
|
| 982 |
st.session_state['question_started_at'] = time.time()
|
| 983 |
st.rerun()
|
| 984 |
|
| 985 |
+
# ---------------- SUBMIT ----------------
|
| 986 |
# ---------------- SUBMIT ----------------
|
| 987 |
with col2:
|
| 988 |
if idx == len(questions) - 1:
|
| 989 |
if st.button("Submit All Answers", key=f"submit_{gid}_{idx}"):
|
|
|
|
| 990 |
answers = st.session_state['answers']
|
| 991 |
times = st.session_state['answer_times']
|
| 992 |
+
|
| 993 |
answers[idx] = choice
|
| 994 |
times[idx] = time.time() - st.session_state['question_started_at']
|
| 995 |
|
| 996 |
+
# Compute score
|
| 997 |
score, flags = compute_score(
|
| 998 |
questions,
|
| 999 |
answers,
|
| 1000 |
times
|
| 1001 |
)
|
|
|
|
| 1002 |
percentage = int(score / (len(questions) * 15) * 100)
|
| 1003 |
+
|
| 1004 |
+
# Update players dict
|
| 1005 |
players = unified_get("players") or {}
|
| 1006 |
players.setdefault(gid, {})
|
| 1007 |
players[gid][uname] = {
|
|
|
|
| 1013 |
"timestamp": now_iso()
|
| 1014 |
}
|
| 1015 |
unified_set("players", players)
|
| 1016 |
+
# Push to leaderboard CSV / Firebase
|
| 1017 |
+
row = {
|
| 1018 |
+
"name": uname,
|
| 1019 |
+
"avatar": st.session_state.get("avatar", "๐ฎ"),
|
| 1020 |
+
"score": score,
|
| 1021 |
+
"percentage": percentage,
|
| 1022 |
+
"game_id": gid,
|
| 1023 |
+
"topics": game.get("topics", []),
|
| 1024 |
+
"timestamp": now_iso(),
|
| 1025 |
+
"questions": len(questions),
|
| 1026 |
+
"answers": answers,
|
| 1027 |
+
"correct_flags": flags
|
| 1028 |
+
}
|
| 1029 |
+
unified_push_leaderboard(row) # <--- THIS IS KEY
|
| 1030 |
+
|
| 1031 |
+
# Auto-close game if needed
|
| 1032 |
if game.get('auto_close', True):
|
| 1033 |
games[gid]['closed'] = True
|
| 1034 |
games[gid]['closed_at'] = now_iso()
|
|
|
|
| 1038 |
f"Submitted! Score: {score} / {len(questions) * 15} ({percentage}%)"
|
| 1039 |
)
|
| 1040 |
st.balloons()
|
|
|
|
| 1041 |
st.session_state['last_score'] = score
|
| 1042 |
st.session_state['last_game'] = gid
|
| 1043 |
st.session_state['current_index'] = 0
|
| 1044 |
+
st.rerun()
|
| 1045 |
+
|
| 1046 |
# Join game
|
| 1047 |
def join_game_page():
|
| 1048 |
st.header("Join Game")
|
|
|
|
| 1084 |
else:
|
| 1085 |
st.error(msg)
|
| 1086 |
|
|
|
|
|
|
|
| 1087 |
# Play page
|
| 1088 |
# ----------------- Create Game -----------------
|
|
|
|
|
|
|
| 1089 |
|
| 1090 |
# Friends page
|
| 1091 |
def friends_page():
|
|
|
|
| 1183 |
st.error(msg)
|
| 1184 |
|
| 1185 |
# Leaderboard page
|
| 1186 |
+
# ----------------- Leaderboard Page -----------------
|
| 1187 |
def leaderboard_page():
|
| 1188 |
+
st.header("๐ Leaderboard")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1189 |
|
| 1190 |
+
rows = unified_get("leaderboard") or []
|
| 1191 |
+
if not rows:
|
| 1192 |
+
st.info("No scores yet. Play some games first!")
|
| 1193 |
return
|
| 1194 |
|
| 1195 |
+
# Convert to DataFrame
|
| 1196 |
+
df = pd.DataFrame(rows)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1197 |
|
| 1198 |
+
# Ensure columns exist
|
| 1199 |
+
for col in ["name", "score", "game_id", "avatar", "timestamp"]:
|
| 1200 |
+
if col not in df.columns:
|
| 1201 |
+
df[col] = ""
|
| 1202 |
|
| 1203 |
+
# ---------------- Weekly Leaderboard ----------------
|
| 1204 |
+
st.subheader("This Week โ Top 10")
|
| 1205 |
+
now = datetime.utcnow()
|
| 1206 |
+
start_of_week = now - timedelta(days=now.weekday())
|
| 1207 |
+
df['ts'] = pd.to_datetime(df['timestamp'], errors='coerce')
|
| 1208 |
+
weekly_df = df[df['ts'] >= start_of_week].copy()
|
| 1209 |
|
| 1210 |
+
if weekly_df.empty:
|
| 1211 |
+
st.info("No scores recorded this week.")
|
| 1212 |
+
else:
|
| 1213 |
+
weekly_df = weekly_df.sort_values(by='score', ascending=False).head(10)
|
| 1214 |
+
for i, row in weekly_df.iterrows():
|
| 1215 |
+
user_marker = "๐ You" if row['name'] == st.session_state.get('username') else ""
|
| 1216 |
+
st.write(f"{i+1}. {row.get('avatar','๐ฎ')} **{row['name']}** (Game {row['game_id']}) โ {row['score']} pts {user_marker}")
|
| 1217 |
|
| 1218 |
+
st.markdown("---")
|
|
|
|
| 1219 |
|
| 1220 |
+
# ---------------- All-time Leaderboard ----------------
|
| 1221 |
+
st.subheader("All-Time Top 10")
|
| 1222 |
+
alltime_df = df.sort_values(by='score', ascending=False).head(10)
|
| 1223 |
+
for i, row in alltime_df.iterrows():
|
| 1224 |
+
user_marker = "๐ You" if row['name'] == st.session_state.get('username') else ""
|
| 1225 |
+
st.write(f"{i+1}. {row.get('avatar','๐ฎ')} **{row['name']}** (Game {row['game_id']}) โ {row['score']} pts {user_marker}")
|
|
|
|
|
|
|
| 1226 |
|
| 1227 |
st.markdown("---")
|
| 1228 |
|
| 1229 |
+
# Optional: allow search by username
|
| 1230 |
+
search_user = st.text_input("Search leaderboard by username")
|
| 1231 |
+
if search_user:
|
| 1232 |
+
search_df = df[df['name'].str.lower() == search_user.lower()]
|
| 1233 |
+
if search_df.empty:
|
| 1234 |
+
st.info(f"No scores found for {search_user}.")
|
| 1235 |
+
else:
|
| 1236 |
+
st.subheader(f"Scores for {search_user}")
|
| 1237 |
+
for i, row in search_df.iterrows():
|
| 1238 |
+
st.write(f"Game {row['game_id']} โ {row['score']} pts โ {row.get('avatar','๐ฎ')} โ {row['timestamp']}")
|
| 1239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
|
| 1241 |
|
| 1242 |
|