Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -750,13 +750,6 @@ async def websocket_handler(websocket, path):
|
|
| 750 |
st.session_state.current_world_file = new_filename
|
| 751 |
log_action(sender_username, "delete", {"obj_id": obj_id})
|
| 752 |
|
| 753 |
-
elif msg_type == "player_position":
|
| 754 |
-
pos_data = payload.get("position")
|
| 755 |
-
rot_data = payload.get("rotation")
|
| 756 |
-
if pos_data:
|
| 757 |
-
broadcast_payload = json.dumps({"type": "player_moved", "payload": {"username": sender_username, "id": client_id, "position": pos_data, "rotation": rot_data}})
|
| 758 |
-
await broadcast_message(broadcast_payload, exclude_id=client_id)
|
| 759 |
-
|
| 760 |
elif msg_type == "tool_selected":
|
| 761 |
tool_type = payload.get("tool_type")
|
| 762 |
if tool_type in PRIMITIVE_MAP.values() or tool_type == "None":
|
|
@@ -921,47 +914,55 @@ def render_sidebar():
|
|
| 921 |
st.markdown("---")
|
| 922 |
st.header("🏗️ Build Tools")
|
| 923 |
st.caption("Select an object to place.")
|
| 924 |
-
|
| 925 |
-
|
| 926 |
-
|
| 927 |
-
|
| 928 |
-
|
| 929 |
-
|
| 930 |
-
|
| 931 |
-
|
| 932 |
-
|
| 933 |
-
|
| 934 |
-
|
| 935 |
-
|
| 936 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 937 |
for emoji, name in PRIMITIVE_MAP.items():
|
| 938 |
-
|
| 939 |
-
|
| 940 |
-
|
| 941 |
-
|
| 942 |
-
|
| 943 |
-
|
| 944 |
-
updateSelectedObjectType('{name_arg}');
|
| 945 |
-
websocket.send(JSON.stringify({{
|
| 946 |
-
type: 'tool_selected',
|
| 947 |
-
payload: {{ tool_type: '{name_arg}', username: window.USERNAME }}
|
| 948 |
-
}}));
|
| 949 |
-
""",
|
| 950 |
-
key=f"update_tool_js_{name_arg}"
|
| 951 |
-
))
|
| 952 |
-
col_idx += 1
|
| 953 |
-
st.markdown("---")
|
| 954 |
-
if st.button("🚫 Clear Tool", key="clear_tool", use_container_width=True):
|
| 955 |
-
run_async(lambda: streamlit_js_eval(
|
| 956 |
-
"""
|
| 957 |
-
updateSelectedObjectType('None');
|
| 958 |
-
websocket.send(JSON.stringify({
|
| 959 |
type: 'tool_selected',
|
| 960 |
-
payload: { tool_type: '
|
| 961 |
-
}));
|
| 962 |
-
|
| 963 |
-
|
| 964 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 965 |
|
| 966 |
st.markdown("---")
|
| 967 |
st.header("🗣�� Voice & User")
|
|
@@ -990,7 +991,7 @@ def render_main_content():
|
|
| 990 |
|
| 991 |
with tab_world:
|
| 992 |
st.header("Shared 3D World")
|
| 993 |
-
st.caption("
|
| 994 |
current_file_basename = st.session_state.get('current_world_file', None)
|
| 995 |
if current_file_basename:
|
| 996 |
parsed = parse_world_filename(os.path.join(SAVED_WORLDS_DIR, current_file_basename))
|
|
|
|
| 750 |
st.session_state.current_world_file = new_filename
|
| 751 |
log_action(sender_username, "delete", {"obj_id": obj_id})
|
| 752 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 753 |
elif msg_type == "tool_selected":
|
| 754 |
tool_type = payload.get("tool_type")
|
| 755 |
if tool_type in PRIMITIVE_MAP.values() or tool_type == "None":
|
|
|
|
| 914 |
st.markdown("---")
|
| 915 |
st.header("🏗️ Build Tools")
|
| 916 |
st.caption("Select an object to place.")
|
| 917 |
+
|
| 918 |
+
# Inject JavaScript buttons for tools
|
| 919 |
+
tool_buttons_html = """
|
| 920 |
+
<style>
|
| 921 |
+
.tool-button {
|
| 922 |
+
width: 40px;
|
| 923 |
+
height: 40px;
|
| 924 |
+
margin: 2px;
|
| 925 |
+
font-size: 20px;
|
| 926 |
+
cursor: pointer;
|
| 927 |
+
border: 2px solid #ccc;
|
| 928 |
+
background-color: #f9f9f9;
|
| 929 |
+
}
|
| 930 |
+
.tool-button.selected {
|
| 931 |
+
border-color: #007bff;
|
| 932 |
+
background-color: #e7f3ff;
|
| 933 |
+
}
|
| 934 |
+
.tool-grid {
|
| 935 |
+
display: grid;
|
| 936 |
+
grid-template-columns: repeat(5, 1fr);
|
| 937 |
+
gap: 2px;
|
| 938 |
+
}
|
| 939 |
+
</style>
|
| 940 |
+
<div class="tool-grid">
|
| 941 |
+
"""
|
| 942 |
for emoji, name in PRIMITIVE_MAP.items():
|
| 943 |
+
tool_buttons_html += f"""
|
| 944 |
+
<button class="tool-button" id="tool_{name}" onclick="
|
| 945 |
+
document.querySelectorAll('.tool-button').forEach(btn => btn.classList.remove('selected'));
|
| 946 |
+
this.classList.add('selected');
|
| 947 |
+
updateSelectedObjectType('{name}');
|
| 948 |
+
websocket.send(JSON.stringify({{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 949 |
type: 'tool_selected',
|
| 950 |
+
payload: {{ tool_type: '{name}', username: window.USERNAME }}
|
| 951 |
+
}}));
|
| 952 |
+
" title="{name}">{emoji}</button>
|
| 953 |
+
"""
|
| 954 |
+
tool_buttons_html += """
|
| 955 |
+
</div>
|
| 956 |
+
<button style="width: 100%; margin-top: 10px; padding: 5px;" onclick="
|
| 957 |
+
document.querySelectorAll('.tool-button').forEach(btn => btn.classList.remove('selected'));
|
| 958 |
+
updateSelectedObjectType('None');
|
| 959 |
+
websocket.send(JSON.stringify({
|
| 960 |
+
type: 'tool_selected',
|
| 961 |
+
payload: { tool_type: 'None', username: window.USERNAME }
|
| 962 |
+
}));
|
| 963 |
+
">🚫 Clear Tool</button>
|
| 964 |
+
"""
|
| 965 |
+
st.markdown(tool_buttons_html, unsafe_allow_html=True)
|
| 966 |
|
| 967 |
st.markdown("---")
|
| 968 |
st.header("🗣�� Voice & User")
|
|
|
|
| 991 |
|
| 992 |
with tab_world:
|
| 993 |
st.header("Shared 3D World")
|
| 994 |
+
st.caption("Click to place objects with the selected tool. Right-click to delete. Changes are shared live!")
|
| 995 |
current_file_basename = st.session_state.get('current_world_file', None)
|
| 996 |
if current_file_basename:
|
| 997 |
parsed = parse_world_filename(os.path.join(SAVED_WORLDS_DIR, current_file_basename))
|