awacke1 commited on
Commit
8e9e6a8
Β·
verified Β·
1 Parent(s): acf7e0f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -21
app.py CHANGED
@@ -30,6 +30,26 @@ QUOTE_VOTES_FILE = os.path.join(VOTE_DIR, "quote_votes.md")
30
  IMAGE_VOTES_FILE = os.path.join(VOTE_DIR, "image_votes.md")
31
  HISTORY_FILE = os.path.join(VOTE_DIR, "vote_history.md")
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  # Node name - the app’s codename generator, sneaky and slick! πŸ•΅οΈβ€β™‚οΈπŸ’Ύ
34
  def get_node_name():
35
  """🎲 Spins the wheel of fate to name our node - a random alias or user pick! 🏷️"""
@@ -206,7 +226,7 @@ async def start_websocket_server(host='0.0.0.0', port=8765):
206
 
207
  # Chat interface maker - the stage builder for our chat extravaganza! 🎭🏟️
208
  def create_streamlit_interface(initial_username):
209
- """πŸ–ŒοΈ Sets up the chat stage with live updates, timers, voting, and refresh flair! 🌟"""
210
  # Custom CSS for a sleek chat box and timer
211
  st.markdown("""
212
  <style>
@@ -220,16 +240,22 @@ def create_streamlit_interface(initial_username):
220
  overflow-y: auto;
221
  }
222
  .timer {
223
- font-size: 18px;
224
  color: #ffcc00;
225
  text-align: center;
 
 
 
 
 
 
226
  }
227
  </style>
228
  """, unsafe_allow_html=True)
229
 
230
  # Title and intro
231
  st.title(f"Chat & Quote Node: {NODE_NAME}")
232
- st.markdown("Chat, vote on messages, quotes, and images - keep the party rocking! πŸŽ‰")
233
 
234
  # Session state for username, refresh rate, and quote index
235
  if 'username' not in st.session_state:
@@ -238,6 +264,8 @@ def create_streamlit_interface(initial_username):
238
  st.session_state.refresh_rate = 5
239
  if 'last_refresh' not in st.session_state:
240
  st.session_state.last_refresh = time.time()
 
 
241
  if 'quote_index' not in st.session_state:
242
  quotes = load_quotes("famous")
243
  st.session_state.quote_index = random.randint(0, max(0, len(quotes) - 1)) if quotes else 0
@@ -257,25 +285,25 @@ def create_streamlit_interface(initial_username):
257
  if st.button(f"πŸ‘", key=f"chat_vote_{i}"):
258
  user_hash = generate_user_hash()
259
  save_vote(QUOTE_VOTES_FILE, line, user_hash)
260
- st.session_state.last_refresh = time.time()
261
  st.rerun()
262
 
263
  user_list = get_user_list(chat_content)
264
  new_username = st.selectbox("Switch User", user_list + [st.session_state.username], index=len(user_list))
265
  if new_username != st.session_state.username:
266
  st.session_state.username = new_username
 
267
 
268
  message = st.text_input("Message", placeholder="Type your epic line here! ✍️")
269
  if st.button("Send πŸš€") and message.strip():
270
  save_chat_entry(st.session_state.username, message)
271
- st.session_state.last_refresh = time.time()
272
  st.rerun()
273
 
274
  # Quote section
275
  st.subheader("Quote of the Moment πŸ“")
276
  quotes = load_quotes(st.session_state.quote_source)
277
  if quotes:
278
- # Ensure quote_index is within bounds
279
  st.session_state.quote_index = st.session_state.quote_index % len(quotes)
280
  quote = quotes[st.session_state.quote_index]
281
  col1, col2 = st.columns([5, 1])
@@ -285,12 +313,12 @@ def create_streamlit_interface(initial_username):
285
  if st.button("πŸ‘ Upvote", key="quote_vote"):
286
  user_hash = generate_user_hash()
287
  save_vote(QUOTE_VOTES_FILE, quote, user_hash)
288
- st.session_state.last_refresh = time.time()
289
  st.rerun()
290
- if time.time() - st.session_state.last_refresh > 10: # 10s quote refresh
291
  st.session_state.quote_index = (st.session_state.quote_index + 1) % len(quotes)
292
  st.session_state.quote_source = "custom" if st.session_state.quote_source == "famous" else "famous"
293
- quotes = load_quotes(st.session_state.quote_source) # Reload quotes for new source
294
  st.session_state.quote_index = st.session_state.quote_index % len(quotes) if quotes else 0
295
  st.session_state.last_refresh = time.time()
296
  st.rerun()
@@ -310,51 +338,57 @@ def create_streamlit_interface(initial_username):
310
  if st.button(f"πŸ‘ Upvote {image1}", key=f"img_vote_{image1}"):
311
  user_hash = generate_user_hash()
312
  save_vote(IMAGE_VOTES_FILE, image1, user_hash)
313
- st.session_state.last_refresh = time.time()
314
  st.rerun()
315
  with col2:
316
  st.image(os.path.join(image_dir, image2))
317
  if st.button(f"πŸ‘ Upvote {image2}", key=f"img_vote_{image2}"):
318
  user_hash = generate_user_hash()
319
  save_vote(IMAGE_VOTES_FILE, image2, user_hash)
320
- st.session_state.last_refresh = time.time()
321
  st.rerun()
322
  else:
323
  st.error("Need at least 2 images in the directory for voting!")
324
 
325
- # Refresh rate controls
326
  st.subheader("Set Refresh Rate ⏳")
327
  refresh_rate = st.slider("Refresh Rate (seconds)", min_value=1, max_value=300, value=st.session_state.refresh_rate, step=1)
328
- st.session_state.refresh_rate = refresh_rate
 
 
329
 
330
  col1, col2, col3 = st.columns(3)
331
  with col1:
332
  if st.button("πŸ‡ Small (1s)"):
333
  st.session_state.refresh_rate = 1
334
- st.session_state.last_refresh = time.time()
335
  st.rerun()
336
  with col2:
337
  if st.button("🐒 Medium (5s)"):
338
  st.session_state.refresh_rate = 5
339
- st.session_state.last_refresh = time.time()
340
  st.rerun()
341
  with col3:
342
  if st.button("🐘 Large (5m)"):
343
  st.session_state.refresh_rate = 300
344
- st.session_state.last_refresh = time.time()
345
  st.rerun()
346
 
347
- # Countdown timer
348
- elapsed = time.time() - st.session_state.last_refresh
349
- remaining = max(0, st.session_state.refresh_rate - int(elapsed))
350
- st.markdown(f"<p class='timer'>Next refresh in: {remaining} seconds</p>", unsafe_allow_html=True)
 
 
 
351
 
352
  # Auto-refresh logic
353
  if elapsed >= st.session_state.refresh_rate:
 
354
  st.session_state.last_refresh = time.time()
355
  st.rerun()
356
  else:
357
- st.markdown(f"<script>window.setTimeout(() => window.location.reload(), {int((st.session_state.refresh_rate - elapsed) * 1000)});</script>", unsafe_allow_html=True)
358
 
359
  # Sidebar vote stats
360
  st.sidebar.subheader("Vote Totals")
 
30
  IMAGE_VOTES_FILE = os.path.join(VOTE_DIR, "image_votes.md")
31
  HISTORY_FILE = os.path.join(VOTE_DIR, "vote_history.md")
32
 
33
+ # Unicode digit conversion table - the magic map for emoji numbers! πŸ”’βœ¨
34
+ UNICODE_DIGITS = {
35
+ 0: "0️⃣", 1: "1️⃣", 2: "2️⃣", 3: "3️⃣", 4: "4️⃣",
36
+ 5: "5️⃣", 6: "6️⃣", 7: "7️⃣", 8: "8️⃣", 9: "9️⃣"
37
+ }
38
+
39
+ # Unicode font examples - the stylish wardrobe of text flair! πŸ‘—πŸ“
40
+ UNICODE_FONTS = [
41
+ ("Normal", lambda x: x), # Plain ol’ text
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)),
45
+ ("Fraktur", lambda x: "".join(chr(ord(c) + 0x1D504 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D51E - 0x61) if 'a' <= c <= 'z' else c for c in x)),
46
+ ("Double Struck", lambda x: "".join(chr(ord(c) + 0x1D538 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D552 - 0x61) if 'a' <= c <= 'z' else c for c in x)),
47
+ ("Sans Serif", lambda x: "".join(chr(ord(c) + 0x1D5A0 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D5BA - 0x61) if 'a' <= c <= 'z' else c for c in x)),
48
+ ("Sans Bold", lambda x: "".join(chr(ord(c) + 0x1D5D4 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D5EE - 0x61) if 'a' <= c <= 'z' else c for c in x)),
49
+ ("Mono", lambda x: "".join(chr(ord(c) + 0x1D670 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x1D68A - 0x61) if 'a' <= c <= 'z' else c for c in x)),
50
+ ("Circle", lambda x: "".join(chr(ord(c) + 0x24B6 - 0x41) if 'A' <= c <= 'Z' else chr(ord(c) + 0x24D0 - 0x61) if 'a' <= c <= 'z' else c for c in x))
51
+ ]
52
+
53
  # Node name - the app’s codename generator, sneaky and slick! πŸ•΅οΈβ€β™‚οΈπŸ’Ύ
54
  def get_node_name():
55
  """🎲 Spins the wheel of fate to name our node - a random alias or user pick! 🏷️"""
 
226
 
227
  # Chat interface maker - the stage builder for our chat extravaganza! 🎭🏟️
228
  def create_streamlit_interface(initial_username):
229
+ """πŸ–ŒοΈ Sets up the chat stage with live updates, pulsing timers, voting, and refresh flair! 🌟"""
230
  # Custom CSS for a sleek chat box and timer
231
  st.markdown("""
232
  <style>
 
240
  overflow-y: auto;
241
  }
242
  .timer {
243
+ font-size: 24px;
244
  color: #ffcc00;
245
  text-align: center;
246
+ animation: pulse 1s infinite;
247
+ }
248
+ @keyframes pulse {
249
+ 0% { transform: scale(1); }
250
+ 50% { transform: scale(1.1); }
251
+ 100% { transform: scale(1); }
252
  }
253
  </style>
254
  """, unsafe_allow_html=True)
255
 
256
  # Title and intro
257
  st.title(f"Chat & Quote Node: {NODE_NAME}")
258
+ st.markdown("Chat, vote on messages, quotes, and images - watch the timer pulse! πŸŽ‰")
259
 
260
  # Session state for username, refresh rate, and quote index
261
  if 'username' not in st.session_state:
 
264
  st.session_state.refresh_rate = 5
265
  if 'last_refresh' not in st.session_state:
266
  st.session_state.last_refresh = time.time()
267
+ if 'timer_start' not in st.session_state:
268
+ st.session_state.timer_start = time.time() # Autostart timer
269
  if 'quote_index' not in st.session_state:
270
  quotes = load_quotes("famous")
271
  st.session_state.quote_index = random.randint(0, max(0, len(quotes) - 1)) if quotes else 0
 
285
  if st.button(f"πŸ‘", key=f"chat_vote_{i}"):
286
  user_hash = generate_user_hash()
287
  save_vote(QUOTE_VOTES_FILE, line, user_hash)
288
+ st.session_state.timer_start = time.time()
289
  st.rerun()
290
 
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
 
297
  message = st.text_input("Message", placeholder="Type your epic line here! ✍️")
298
  if st.button("Send πŸš€") and message.strip():
299
  save_chat_entry(st.session_state.username, message)
300
+ st.session_state.timer_start = time.time()
301
  st.rerun()
302
 
303
  # Quote section
304
  st.subheader("Quote of the Moment πŸ“")
305
  quotes = load_quotes(st.session_state.quote_source)
306
  if quotes:
 
307
  st.session_state.quote_index = st.session_state.quote_index % len(quotes)
308
  quote = quotes[st.session_state.quote_index]
309
  col1, col2 = st.columns([5, 1])
 
313
  if st.button("πŸ‘ Upvote", key="quote_vote"):
314
  user_hash = generate_user_hash()
315
  save_vote(QUOTE_VOTES_FILE, quote, user_hash)
316
+ st.session_state.timer_start = time.time()
317
  st.rerun()
318
+ if time.time() - st.session_state.last_refresh > 10:
319
  st.session_state.quote_index = (st.session_state.quote_index + 1) % len(quotes)
320
  st.session_state.quote_source = "custom" if st.session_state.quote_source == "famous" else "famous"
321
+ quotes = load_quotes(st.session_state.quote_source)
322
  st.session_state.quote_index = st.session_state.quote_index % len(quotes) if quotes else 0
323
  st.session_state.last_refresh = time.time()
324
  st.rerun()
 
338
  if st.button(f"πŸ‘ Upvote {image1}", key=f"img_vote_{image1}"):
339
  user_hash = generate_user_hash()
340
  save_vote(IMAGE_VOTES_FILE, image1, user_hash)
341
+ st.session_state.timer_start = time.time()
342
  st.rerun()
343
  with col2:
344
  st.image(os.path.join(image_dir, image2))
345
  if st.button(f"πŸ‘ Upvote {image2}", key=f"img_vote_{image2}"):
346
  user_hash = generate_user_hash()
347
  save_vote(IMAGE_VOTES_FILE, image2, user_hash)
348
+ st.session_state.timer_start = time.time()
349
  st.rerun()
350
  else:
351
  st.error("Need at least 2 images in the directory for voting!")
352
 
353
+ # Refresh rate controls with pulsing timer
354
  st.subheader("Set Refresh Rate ⏳")
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() # Reset timer on change
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
+ elapsed = int(time.time() - st.session_state.timer_start)
379
+ remaining = max(0, st.session_state.refresh_rate - (elapsed % st.session_state.refresh_rate))
380
+ font_name, font_func = random.choice(UNICODE_FONTS)
381
+ countdown_str = "".join(UNICODE_DIGITS[int(d)] for d in str(remaining)) if remaining < 10 else font_func(str(remaining))
382
+ timer_emoji = "⏳" if remaining % 2 == 0 else "πŸ’“" # Pulse effect
383
+ st.markdown(f"<p class='timer'>{timer_emoji} {font_func('Next refresh in:')} {countdown_str} {font_func('seconds')}</p>", unsafe_allow_html=True)
384
 
385
  # Auto-refresh logic
386
  if elapsed >= st.session_state.refresh_rate:
387
+ st.session_state.timer_start = time.time()
388
  st.session_state.last_refresh = time.time()
389
  st.rerun()
390
  else:
391
+ st.markdown(f"<script>window.setTimeout(() => window.location.reload(), 1000);</script>", unsafe_allow_html=True)
392
 
393
  # Sidebar vote stats
394
  st.sidebar.subheader("Vote Totals")