awacke1 commited on
Commit
80d0af3
·
verified ·
1 Parent(s): dfe769e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -12
app.py CHANGED
@@ -5,8 +5,7 @@ import os
5
  import json
6
  import pandas as pd
7
  import uuid
8
- from PIL import Image, ImageDraw # For minimap (using buttons instead now)
9
- # Corrected import: removed 'sync'
10
  from streamlit_js_eval import streamlit_js_eval # For JS communication
11
 
12
  # --- Constants ---
@@ -24,7 +23,15 @@ def load_plot_metadata():
24
  """Scans save dir, sorts plots, calculates metadata."""
25
  plots = []
26
  # Ensure consistent sorting, e.g., alphabetically which often aligns with plot_001, plot_002 etc.
27
- plot_files = sorted([f for f in os.listdir(SAVE_DIR) if f.endswith(".csv")])
 
 
 
 
 
 
 
 
28
 
29
  current_x_offset = 0.0
30
  for i, filename in enumerate(plot_files):
@@ -54,11 +61,10 @@ def load_plot_objects(filename, x_offset):
54
  st.warning(f"CSV '{filename}' missing essential columns (type, pos_x/y/z). Skipping.")
55
  return []
56
  # Ensure optional columns default to something sensible if missing
57
- if 'obj_id' not in df.columns: df['obj_id'] = [str(uuid.uuid4()) for _ in range(len(df))]
58
- if 'rot_x' not in df.columns: df['rot_x'] = 0.0
59
- if 'rot_y' not in df.columns: df['rot_y'] = 0.0
60
- if 'rot_z' not in df.columns: df['rot_z'] = 0.0
61
- if 'rot_order' not in df.columns: df['rot_order'] = 'XYZ'
62
 
63
 
64
  for _, row in df.iterrows():
@@ -171,7 +177,10 @@ with st.sidebar:
171
  if cols[col_idx].button(button_label, key=f"nav_{plot['filename']}"):
172
  # Send command to JS to move the player
173
  target_x = plot['x_offset']
174
- streamlit_js_eval(js_code=f"teleportPlayer({target_x});")
 
 
 
175
  # No rerun needed here, JS handles the move instantly
176
 
177
  col_idx = (col_idx + 1) % max_cols # Cycle through columns
@@ -196,10 +205,13 @@ with st.sidebar:
196
  key="selected_object_widget" # Use a distinct key for the widget
197
  )
198
  # Update session state only if the widget's value actually changes
 
 
199
  if selected_object_type_widget != st.session_state.selected_object:
200
  st.session_state.selected_object = selected_object_type_widget
201
- # Trigger a targeted JS update if needed, or rely on injection next cycle
202
- # No rerun needed just for selection if JS reads global state on demand
 
203
 
204
 
205
  st.markdown("---")
@@ -264,7 +276,7 @@ if save_data_from_js is not None: # Process only if data is present
264
  st.session_state.new_plot_name = ""
265
  # Reset newly placed objects in JS AFTER successful save
266
  try:
267
- # This call tells JS to clear its internal 'newlyPlacedObjects' array
268
  streamlit_js_eval(js_code="resetNewlyPlacedObjects();", key="reset_js_state")
269
  except Exception as js_e:
270
  st.warning(f"Could not reset JS state after save: {js_e}")
 
5
  import json
6
  import pandas as pd
7
  import uuid
8
+ from PIL import Image, ImageDraw # Not used for minimap anymore, but kept just in case
 
9
  from streamlit_js_eval import streamlit_js_eval # For JS communication
10
 
11
  # --- Constants ---
 
23
  """Scans save dir, sorts plots, calculates metadata."""
24
  plots = []
25
  # Ensure consistent sorting, e.g., alphabetically which often aligns with plot_001, plot_002 etc.
26
+ try:
27
+ plot_files = sorted([f for f in os.listdir(SAVE_DIR) if f.endswith(".csv")])
28
+ except FileNotFoundError:
29
+ st.error(f"Save directory '{SAVE_DIR}' not found.")
30
+ return [], 0.0 # Return empty if dir doesn't exist
31
+ except Exception as e:
32
+ st.error(f"Error listing save directory '{SAVE_DIR}': {e}")
33
+ return [], 0.0
34
+
35
 
36
  current_x_offset = 0.0
37
  for i, filename in enumerate(plot_files):
 
61
  st.warning(f"CSV '{filename}' missing essential columns (type, pos_x/y/z). Skipping.")
62
  return []
63
  # Ensure optional columns default to something sensible if missing
64
+ # Use vectorized operations for defaults where possible
65
+ df['obj_id'] = df.get('obj_id', pd.Series([str(uuid.uuid4()) for _ in range(len(df))]))
66
+ for col, default in [('rot_x', 0.0), ('rot_y', 0.0), ('rot_z', 0.0), ('rot_order', 'XYZ')]:
67
+ if col not in df.columns: df[col] = default
 
68
 
69
 
70
  for _, row in df.iterrows():
 
177
  if cols[col_idx].button(button_label, key=f"nav_{plot['filename']}"):
178
  # Send command to JS to move the player
179
  target_x = plot['x_offset']
180
+ try:
181
+ streamlit_js_eval(js_code=f"teleportPlayer({target_x});", key=f"teleport_{plot['filename']}")
182
+ except Exception as e:
183
+ st.error(f"Failed to send teleport command: {e}")
184
  # No rerun needed here, JS handles the move instantly
185
 
186
  col_idx = (col_idx + 1) % max_cols # Cycle through columns
 
205
  key="selected_object_widget" # Use a distinct key for the widget
206
  )
207
  # Update session state only if the widget's value actually changes
208
+ # This change WILL trigger a rerun because Streamlit tracks widget state.
209
+ # The JS side now handles preserving its state across the resulting reload via sessionStorage.
210
  if selected_object_type_widget != st.session_state.selected_object:
211
  st.session_state.selected_object = selected_object_type_widget
212
+ # We don't *need* to force a rerun here, Streamlit handles it.
213
+ # The important part is that the NEXT run will inject the new selected type,
214
+ # and the JS will restore placed objects from sessionStorage.
215
 
216
 
217
  st.markdown("---")
 
276
  st.session_state.new_plot_name = ""
277
  # Reset newly placed objects in JS AFTER successful save
278
  try:
279
+ # This call tells JS to clear its internal 'newlyPlacedObjects' array AND sessionStorage
280
  streamlit_js_eval(js_code="resetNewlyPlacedObjects();", key="reset_js_state")
281
  except Exception as js_e:
282
  st.warning(f"Could not reset JS state after save: {js_e}")