Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -91,7 +91,7 @@ def get_current_time_str(tz='UTC'):
|
|
91 |
now_aware = datetime.now(pytz.utc)
|
92 |
return now_aware.strftime('%Y%m%d_%H%M%S')
|
93 |
|
94 |
-
def clean_filename_part(text, max_len=30):
|
95 |
if not isinstance(text, str):
|
96 |
text = "invalid_name"
|
97 |
text = re.sub(r'\s+', '_', text)
|
@@ -755,6 +755,9 @@ async def websocket_handler(websocket, path):
|
|
755 |
if tool_type in PRIMITIVE_MAP.values() or tool_type == "None":
|
756 |
st.session_state.selected_object = tool_type
|
757 |
print(f"Tool updated to {tool_type} for {sender_username}")
|
|
|
|
|
|
|
758 |
|
759 |
except json.JSONDecodeError:
|
760 |
print(f"WS Invalid JSON from {client_id}: {message[:100]}...")
|
@@ -915,8 +918,8 @@ def render_sidebar():
|
|
915 |
st.header("🏗️ Build Tools")
|
916 |
st.caption("Select an object to place.")
|
917 |
|
918 |
-
#
|
919 |
-
|
920 |
<style>
|
921 |
.tool-button {
|
922 |
width: 40px;
|
@@ -927,6 +930,9 @@ def render_sidebar():
|
|
927 |
border: 2px solid #ccc;
|
928 |
background-color: #f9f9f9;
|
929 |
}
|
|
|
|
|
|
|
930 |
.tool-button.selected {
|
931 |
border-color: #007bff;
|
932 |
background-color: #e7f3ff;
|
@@ -937,32 +943,43 @@ def render_sidebar():
|
|
937 |
gap: 2px;
|
938 |
}
|
939 |
</style>
|
940 |
-
|
941 |
-
|
|
|
|
|
|
|
|
|
942 |
for emoji, name in PRIMITIVE_MAP.items():
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
966 |
|
967 |
st.markdown("---")
|
968 |
st.header("🗣️ Voice & User")
|
|
|
91 |
now_aware = datetime.now(pytz.utc)
|
92 |
return now_aware.strftime('%Y%m%d_%H%M%S')
|
93 |
|
94 |
+
def cleanROS: clean_filename_part(text, max_len=30):
|
95 |
if not isinstance(text, str):
|
96 |
text = "invalid_name"
|
97 |
text = re.sub(r'\s+', '_', text)
|
|
|
755 |
if tool_type in PRIMITIVE_MAP.values() or tool_type == "None":
|
756 |
st.session_state.selected_object = tool_type
|
757 |
print(f"Tool updated to {tool_type} for {sender_username}")
|
758 |
+
# Broadcast tool selection to update other clients
|
759 |
+
broadcast_payload = json.dumps({"type": "tool_selected", "payload": {"tool_type": tool_type, "username": sender_username}})
|
760 |
+
await broadcast_message(broadcast_payload, exclude_id=client_id)
|
761 |
|
762 |
except json.JSONDecodeError:
|
763 |
print(f"WS Invalid JSON from {client_id}: {message[:100]}...")
|
|
|
918 |
st.header("🏗️ Build Tools")
|
919 |
st.caption("Select an object to place.")
|
920 |
|
921 |
+
# CSS for tool buttons
|
922 |
+
st.markdown("""
|
923 |
<style>
|
924 |
.tool-button {
|
925 |
width: 40px;
|
|
|
930 |
border: 2px solid #ccc;
|
931 |
background-color: #f9f9f9;
|
932 |
}
|
933 |
+
.tool-button:hover {
|
934 |
+
background-color: #e0e0e0;
|
935 |
+
}
|
936 |
.tool-button.selected {
|
937 |
border-color: #007bff;
|
938 |
background-color: #e7f3ff;
|
|
|
943 |
gap: 2px;
|
944 |
}
|
945 |
</style>
|
946 |
+
""", unsafe_allow_html=True)
|
947 |
+
|
948 |
+
# Tool buttons
|
949 |
+
current_tool = st.session_state.get('selected_object', 'None')
|
950 |
+
cols = st.columns(5)
|
951 |
+
col_idx = 0
|
952 |
for emoji, name in PRIMITIVE_MAP.items():
|
953 |
+
button_key = f"primitive_{name}"
|
954 |
+
button_type = "primary" if current_tool == name else "secondary"
|
955 |
+
if cols[col_idx % 5].button(emoji, key=button_key, help=name, type=button_type, use_container_width=True):
|
956 |
+
if st.session_state.selected_object != name:
|
957 |
+
st.session_state.selected_object = name
|
958 |
+
# Send WebSocket message to update tool selection
|
959 |
+
ws_message = json.dumps({
|
960 |
+
"type": "tool_selected",
|
961 |
+
"payload": {"tool_type": name, "username": st.session_state.username}
|
962 |
+
})
|
963 |
+
run_async(broadcast_message, ws_message)
|
964 |
+
# Update JavaScript tool state
|
965 |
+
run_async(lambda: streamlit_js_eval(
|
966 |
+
f"updateSelectedObjectType('{name}');",
|
967 |
+
key=f"update_tool_js_{name}"
|
968 |
+
))
|
969 |
+
col_idx += 1
|
970 |
+
st.markdown("---")
|
971 |
+
if st.button("🚫 Clear Tool", key="clear_tool", use_container_width=True):
|
972 |
+
if st.session_state.selected_object != 'None':
|
973 |
+
st.session_state.selected_object = 'None'
|
974 |
+
ws_message = json.dumps({
|
975 |
+
"type": "tool_selected",
|
976 |
+
"payload": {"tool_type": "None", "username": st.session_state.username}
|
977 |
+
})
|
978 |
+
run_async(broadcast_message, ws_message)
|
979 |
+
run_async(lambda: streamlit_js_eval(
|
980 |
+
"updateSelectedObjectType('None');",
|
981 |
+
key="update_tool_js_none"
|
982 |
+
))
|
983 |
|
984 |
st.markdown("---")
|
985 |
st.header("🗣️ Voice & User")
|