Update app.py
Browse files
app.py
CHANGED
@@ -38,7 +38,7 @@ UNICODE_DIGITS = {
|
|
38 |
|
39 |
# Unicode font examples - the stylish wardrobe of text flair! ππ
|
40 |
UNICODE_FONTS = [
|
41 |
-
("Normal", lambda x: x),
|
42 |
("Bold", lambda x: "".join(chr(ord(c) + 0x1D400 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D41A - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
43 |
("Italic", lambda x: "".join(chr(ord(c) + 0x1D434 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D44E - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
44 |
("Script", lambda x: "".join(chr(ord(c) + 0x1D49C - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D4B6 - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
@@ -77,7 +77,7 @@ def load_chat():
|
|
77 |
"""π Digs up the chat treasure from the filesystem - tales of old and new! π°"""
|
78 |
if not os.path.exists(CHAT_FILE):
|
79 |
with open(CHAT_FILE, 'w') as f:
|
80 |
-
f.write("#
|
81 |
try:
|
82 |
with open(CHAT_FILE, 'r') as f:
|
83 |
content = f.read()
|
@@ -185,6 +185,9 @@ async def websocket_handler(websocket, path):
|
|
185 |
room_id = "chat"
|
186 |
active_connections.setdefault(room_id, {})[client_id] = websocket
|
187 |
print(f"Client {client_id} joined the chat party!")
|
|
|
|
|
|
|
188 |
|
189 |
async for message in websocket:
|
190 |
try:
|
@@ -255,11 +258,12 @@ def create_streamlit_interface(initial_username):
|
|
255 |
|
256 |
# Title and intro
|
257 |
st.title(f"Chat & Quote Node: {NODE_NAME}")
|
258 |
-
st.markdown("
|
259 |
|
260 |
-
# Session state
|
261 |
if 'username' not in st.session_state:
|
262 |
st.session_state.username = initial_username
|
|
|
263 |
if 'refresh_rate' not in st.session_state:
|
264 |
st.session_state.refresh_rate = 5
|
265 |
if 'last_refresh' not in st.session_state:
|
@@ -273,7 +277,7 @@ def create_streamlit_interface(initial_username):
|
|
273 |
st.session_state.quote_source = "famous"
|
274 |
|
275 |
# Chat section
|
276 |
-
st.subheader("Chat
|
277 |
chat_content = load_chat()
|
278 |
chat_lines = chat_content.split('\n')
|
279 |
for i, line in enumerate(chat_lines):
|
@@ -291,6 +295,7 @@ def create_streamlit_interface(initial_username):
|
|
291 |
user_list = get_user_list(chat_content)
|
292 |
new_username = st.selectbox("Switch User", user_list + [st.session_state.username], index=len(user_list))
|
293 |
if new_username != st.session_state.username:
|
|
|
294 |
st.session_state.username = new_username
|
295 |
st.session_state.timer_start = time.time()
|
296 |
|
@@ -355,40 +360,38 @@ def create_streamlit_interface(initial_username):
|
|
355 |
refresh_rate = st.slider("Refresh Rate (seconds)", min_value=1, max_value=300, value=st.session_state.refresh_rate, step=1)
|
356 |
if refresh_rate != st.session_state.refresh_rate:
|
357 |
st.session_state.refresh_rate = refresh_rate
|
358 |
-
st.session_state.timer_start = time.time()
|
359 |
|
360 |
col1, col2, col3 = st.columns(3)
|
361 |
with col1:
|
362 |
if st.button("π Small (1s)"):
|
363 |
st.session_state.refresh_rate = 1
|
364 |
st.session_state.timer_start = time.time()
|
365 |
-
st.rerun()
|
366 |
with col2:
|
367 |
if st.button("π’ Medium (5s)"):
|
368 |
st.session_state.refresh_rate = 5
|
369 |
st.session_state.timer_start = time.time()
|
370 |
-
st.rerun()
|
371 |
with col3:
|
372 |
if st.button("π Large (5m)"):
|
373 |
st.session_state.refresh_rate = 300
|
374 |
st.session_state.timer_start = time.time()
|
375 |
-
st.rerun()
|
376 |
|
377 |
# Pulsing countdown timer with emoji digits and random Unicode font
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
|
|
392 |
|
393 |
# Sidebar vote stats
|
394 |
st.sidebar.subheader("Vote Totals")
|
|
|
38 |
|
39 |
# Unicode font examples - the stylish wardrobe of text flair! ππ
|
40 |
UNICODE_FONTS = [
|
41 |
+
("Normal", lambda x: x),
|
42 |
("Bold", lambda x: "".join(chr(ord(c) + 0x1D400 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D41A - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
43 |
("Italic", lambda x: "".join(chr(ord(c) + 0x1D434 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D44E - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
44 |
("Script", lambda x: "".join(chr(ord(c) + 0x1D49C - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D4B6 - 0x61) if 'a' <= c <= 'z' else c for c in x)),
|
|
|
77 |
"""π Digs up the chat treasure from the filesystem - tales of old and new! π°"""
|
78 |
if not os.path.exists(CHAT_FILE):
|
79 |
with open(CHAT_FILE, 'w') as f:
|
80 |
+
f.write("# Sector Chat π\n\nWelcome to the cosmic hub - start chatting! π€\n")
|
81 |
try:
|
82 |
with open(CHAT_FILE, 'r') as f:
|
83 |
content = f.read()
|
|
|
185 |
room_id = "chat"
|
186 |
active_connections.setdefault(room_id, {})[client_id] = websocket
|
187 |
print(f"Client {client_id} joined the chat party!")
|
188 |
+
# Auto-join message
|
189 |
+
username = st.session_state.username if 'username' in st.session_state else random.choice(FUN_USERNAMES)
|
190 |
+
save_chat_entry("System π", f"{username} has joined Sector π!")
|
191 |
|
192 |
async for message in websocket:
|
193 |
try:
|
|
|
258 |
|
259 |
# Title and intro
|
260 |
st.title(f"Chat & Quote Node: {NODE_NAME}")
|
261 |
+
st.markdown("Welcome to Sector π - chat, vote, and watch the timer pulse! π")
|
262 |
|
263 |
+
# Session state initialization
|
264 |
if 'username' not in st.session_state:
|
265 |
st.session_state.username = initial_username
|
266 |
+
save_chat_entry("System π", f"{initial_username} has joined Sector π!")
|
267 |
if 'refresh_rate' not in st.session_state:
|
268 |
st.session_state.refresh_rate = 5
|
269 |
if 'last_refresh' not in st.session_state:
|
|
|
277 |
st.session_state.quote_source = "famous"
|
278 |
|
279 |
# Chat section
|
280 |
+
st.subheader("Sector Chat π")
|
281 |
chat_content = load_chat()
|
282 |
chat_lines = chat_content.split('\n')
|
283 |
for i, line in enumerate(chat_lines):
|
|
|
295 |
user_list = get_user_list(chat_content)
|
296 |
new_username = st.selectbox("Switch User", user_list + [st.session_state.username], index=len(user_list))
|
297 |
if new_username != st.session_state.username:
|
298 |
+
save_chat_entry("System π", f"{st.session_state.username} switched to {new_username} in Sector π!")
|
299 |
st.session_state.username = new_username
|
300 |
st.session_state.timer_start = time.time()
|
301 |
|
|
|
360 |
refresh_rate = st.slider("Refresh Rate (seconds)", min_value=1, max_value=300, value=st.session_state.refresh_rate, step=1)
|
361 |
if refresh_rate != st.session_state.refresh_rate:
|
362 |
st.session_state.refresh_rate = refresh_rate
|
363 |
+
st.session_state.timer_start = time.time()
|
364 |
|
365 |
col1, col2, col3 = st.columns(3)
|
366 |
with col1:
|
367 |
if st.button("π Small (1s)"):
|
368 |
st.session_state.refresh_rate = 1
|
369 |
st.session_state.timer_start = time.time()
|
|
|
370 |
with col2:
|
371 |
if st.button("π’ Medium (5s)"):
|
372 |
st.session_state.refresh_rate = 5
|
373 |
st.session_state.timer_start = time.time()
|
|
|
374 |
with col3:
|
375 |
if st.button("π Large (5m)"):
|
376 |
st.session_state.refresh_rate = 300
|
377 |
st.session_state.timer_start = time.time()
|
|
|
378 |
|
379 |
# Pulsing countdown timer with emoji digits and random Unicode font
|
380 |
+
timer_placeholder = st.empty()
|
381 |
+
start_time = st.session_state.timer_start
|
382 |
+
while True:
|
383 |
+
elapsed = int(time.time() - start_time)
|
384 |
+
remaining = max(0, st.session_state.refresh_rate - elapsed)
|
385 |
+
font_name, font_func = random.choice(UNICODE_FONTS)
|
386 |
+
countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(remaining)) if remaining < 10 else font_func(str(remaining))
|
387 |
+
timer_emoji = "β³" if elapsed % 2 == 0 else "π" # Pulse effect
|
388 |
+
timer_placeholder.markdown(f"<p class='timer'>{timer_emoji} {font_func('Next refresh in:')} {countdown_str} {font_func('seconds')}</p>", unsafe_allow_html=True)
|
389 |
+
if remaining == 0:
|
390 |
+
st.session_state.last_refresh = time.time()
|
391 |
+
st.session_state.timer_start = time.time()
|
392 |
+
st.rerun()
|
393 |
+
break
|
394 |
+
time.sleep(1) # Pulse every second
|
395 |
|
396 |
# Sidebar vote stats
|
397 |
st.sidebar.subheader("Vote Totals")
|