2424clicked_tiles = set ()
2525tile_buttons = {} # {(row, col): chip}
2626tile_icons = {} # {(row, col): icon reference}
27+ admin_checkboxes = {} # {(row, col): admin checkbox element}
2728
2829def split_phrase_into_lines (phrase : str ) -> list :
2930 """
@@ -78,14 +79,11 @@ def toggle_tile(row, col):
7879 if key in clicked_tiles :
7980 logging .debug (f"Tile at { key } unclicked" )
8081 clicked_tiles .remove (key )
81- tile_buttons [key ].style ("background: #facc15; border: none; color: black;" )
82- tile_icons [key ].style ("display: none;" )
8382 else :
8483 logging .debug (f"Tile at { key } clicked" )
8584 clicked_tiles .add (key )
86- tile_buttons [key ].style ("background: #22c55e; color: white; border: none;" )
87- tile_icons [key ].style ("display: block;" )
8885 check_winner ()
86+ sync_board_state ()
8987
9088# Check for Bingo win condition
9189def check_winner ():
@@ -96,16 +94,74 @@ def check_winner():
9694 if all ((i , i ) in clicked_tiles for i in range (5 )) or all ((i , 4 - i ) in clicked_tiles for i in range (5 )):
9795 ui .notify ("BINGO!" , color = "green" , duration = 5 )
9896
97+ def sync_board_state ():
98+ # Sync the styles of each tile according to the global clicked_tiles
99+ for r in range (5 ):
100+ for c in range (5 ):
101+ key = (r , c )
102+ # Skip updating the FREE MEAT cell
103+ if board [r ][c ].upper () == "FREE MEAT" :
104+ continue
105+ if key in clicked_tiles :
106+ tile_buttons [key ].style ("background: #22c55e; color: white; border: none;" )
107+ tile_icons [key ].style ("display: block;" )
108+ else :
109+ tile_buttons [key ].style ("background: #facc15; border: none; color: black;" )
110+ tile_icons [key ].style ("display: none;" )
111+ tile_buttons [key ].update ()
112+ tile_icons [key ].update ()
113+ # --- New: update admin panel checkboxes when board state syncs ---
114+ sync_admin_checkboxes ()
115+ update_admin_visibility ()
116+
117+ def sync_admin_checkboxes ():
118+ """
119+ Sync the values in both copies of each admin checkbox with the global clicked_tiles.
120+ """
121+ for key , chks in admin_checkboxes .items ():
122+ new_value = key in clicked_tiles
123+ if chks ["left" ].value != new_value :
124+ chks ["left" ].value = new_value
125+ chks ["left" ].update ()
126+ if chks ["right" ].value != new_value :
127+ chks ["right" ].value = new_value
128+ chks ["right" ].update ()
129+
130+ def update_admin_visibility ():
131+ """
132+ Bind the visibility of the admin checkboxes:
133+ - left copy is visible only when unchecked (value False)
134+ - right copy is visible only when checked (value True)
135+ """
136+ for key , chks in admin_checkboxes .items ():
137+ val = chks ["left" ].value # both copies hold the same value
138+ chks ["left" ].visible = not val # show left box only when unchecked
139+ chks ["right" ].visible = val # show right box only when checked
140+ chks ["left" ].update ()
141+ chks ["right" ].update ()
142+
143+ def admin_checkbox_change (e , key ):
144+ # When a checkbox in the admin page is toggled, update the global clicked_tiles
145+ if e .value :
146+ clicked_tiles .add (key )
147+ else :
148+ clicked_tiles .discard (key )
149+ sync_board_state ()
150+
99151# Set up NiceGUI page and head elements
100152ui .page ("/" )
101153ui .add_head_html ('<link href="https://fonts.cdnfonts.com/css/super-carnival" rel="stylesheet">' )
102154ui .add_head_html ('<script src="https://cdn.jsdelivr.net/npm/fitty@2.3.6/dist/fitty.min.js"></script>' )
155+ ui .add_head_html ('<style>body { background-color: #100079; }</style>' )
103156
104157with ui .element ("div" ).classes ("w-full max-w-3xl mx-auto" ):
105- ui .label ("COMMIT BINGO!" ).classes ("fit-header text-center" ).style ("font-family: 'Super Carnival', sans-serif;" )
158+ ui .label ("COMMIT BINGO!" ).classes ("fit-header text-center" ).style ("font-family: 'Super Carnival', sans-serif; color: #0CB2B3; " )
106159
107160create_bingo_board ()
108161
162+ # Add a timer that calls sync_board_state every 1 second to push state updates to all clients
163+ ui .timer (1 , sync_board_state )
164+
109165with ui .element ("div" ).classes ("w-full mt-4" ):
110166 ui .label (f"Seed: { today_seed } " ).classes ("text-md text-gray-300 text-center" )
111167
@@ -119,4 +175,45 @@ def check_winner():
119175 fitty('.fit-header', { multiLine: true, maxSize: 200 });
120176 });
121177</script>""" )
122- ui .run (port = 8080 , title = "Commit Bingo" , dark = True )
178+
179+ @ui .page ("/admin" )
180+ def admin_page ():
181+ with ui .column ().classes ("w-full max-w-xl mx-auto p-4" ):
182+ ui .label ("Admin Panel (Seed Phrases)" ).classes ("text-h4 text-center" )
183+
184+ # Create checkboxes for each seed phrase if not already created.
185+ for r in range (5 ):
186+ for c in range (5 ):
187+ key = (r , c )
188+ phrase = board [r ][c ]
189+ if key not in admin_checkboxes :
190+ def on_admin_checkbox_change (e , key = key ):
191+ if e .value :
192+ clicked_tiles .add (key )
193+ else :
194+ clicked_tiles .discard (key )
195+ sync_board_state ()
196+ update_admin_visibility ()
197+ left_chk = ui .checkbox (phrase , value = (key in clicked_tiles ), on_change = on_admin_checkbox_change )
198+ right_chk = ui .checkbox (phrase , value = (key in clicked_tiles ), on_change = on_admin_checkbox_change )
199+ admin_checkboxes [key ] = {"left" : left_chk , "right" : right_chk }
200+
201+
202+ left_chk .on ("change" , on_admin_checkbox_change )
203+ right_chk .on ("change" , on_admin_checkbox_change )
204+
205+ # with ui.row():
206+ # with ui.column().classes("w-1/2"):
207+ # ui.label("Uncalled").classes("text-h5 text-center")
208+ # for key in sorted(admin_checkboxes.keys(), key=lambda k: (k[0], k[1])):
209+ # # Simply calling the widget makes sure it gets rendered in this column.
210+ # admin_checkboxes[key]["left"]
211+ # with ui.column().classes("w-1/2"):
212+ # ui.label("Called").classes("text-h5 text-center")
213+ # for key in sorted(admin_checkboxes.keys(), key=lambda k: (k[0], k[1])):
214+ # admin_checkboxes[key]["right"]
215+
216+
217+ ui .timer (1 , update_admin_visibility )
218+
219+ ui .run (port = 8080 , title = "Commit Bingo" , dark = False )
0 commit comments