Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -31,10 +31,8 @@ from PIL import Image
|
|
31 |
# Configuration & Constants
|
32 |
# ==============================================================================
|
33 |
|
34 |
-
# Patch asyncio for nesting
|
35 |
nest_asyncio.apply()
|
36 |
|
37 |
-
# Page Config
|
38 |
st.set_page_config(
|
39 |
page_title="๐ค๐๏ธ Shared World Builder ๐",
|
40 |
page_icon="๐๏ธ",
|
@@ -42,14 +40,12 @@ st.set_page_config(
|
|
42 |
initial_sidebar_state="expanded"
|
43 |
)
|
44 |
|
45 |
-
# General Constants
|
46 |
icons = '๐ค๐๏ธ๐ฃ๏ธ๐พ'
|
47 |
Site_Name = '๐ค๐๏ธ Shared World Builder ๐ฃ๏ธ'
|
48 |
START_ROOM = "World Lobby ๐"
|
49 |
MEDIA_DIR = "."
|
50 |
STATE_FILE = "user_state.txt"
|
51 |
|
52 |
-
# User/Chat Constants
|
53 |
FUN_USERNAMES = {
|
54 |
"BuilderBot ๐ค": "en-US-AriaNeural", "WorldWeaver ๐ธ๏ธ": "en-US-JennyNeural",
|
55 |
"Terraformer ๐ฑ": "en-GB-SoniaNeural", "SkyArchitect โ๏ธ": "en-AU-NatashaNeural",
|
@@ -59,22 +55,16 @@ FUN_USERNAMES = {
|
|
59 |
}
|
60 |
EDGE_TTS_VOICES = list(set(FUN_USERNAMES.values()))
|
61 |
CHAT_DIR = "chat_logs"
|
62 |
-
|
63 |
-
# Audio Constants
|
64 |
AUDIO_CACHE_DIR = "audio_cache"
|
65 |
AUDIO_DIR = "audio_logs"
|
66 |
-
|
67 |
-
# World Builder Constants
|
68 |
-
SAVED_WORLDS_DIR = "saved_worlds" # Corrected from SAVED_WORLDS0
|
69 |
HISTORY_LOG_DIR = "history_logs"
|
70 |
PLOT_WIDTH = 50.0
|
71 |
PLOT_DEPTH = 50.0
|
72 |
WORLD_STATE_FILE_MD_PREFIX = "๐_"
|
73 |
|
74 |
-
# File Emojis
|
75 |
FILE_EMOJIS = {"md": "๐", "mp3": "๐ต", "png": "๐ผ๏ธ", "mp4": "๐ฅ", "zip": "๐ฆ", "json": "๐"}
|
76 |
|
77 |
-
# Mapping Emojis to Primitive Types
|
78 |
PRIMITIVE_MAP = {
|
79 |
"๐ณ": "Tree", "๐ฟ": "Rock", "๐๏ธ": "Simple House", "๐ฒ": "Pine Tree", "๐งฑ": "Brick Wall",
|
80 |
"๐ต": "Sphere", "๐ฆ": "Cube", "๐งด": "Cylinder", "๐ฆ": "Cone", "๐ฉ": "Torus",
|
@@ -82,11 +72,9 @@ PRIMITIVE_MAP = {
|
|
82 |
"๐ผ": "Tower", "๐ง": "Barrier", "โฒ": "Fountain", "๐ฎ": "Lantern", "๐ชง": "Sign Post"
|
83 |
}
|
84 |
|
85 |
-
# Directories
|
86 |
for d in [CHAT_DIR, AUDIO_DIR, AUDIO_CACHE_DIR, SAVED_WORLDS_DIR, HISTORY_LOG_DIR]:
|
87 |
os.makedirs(d, exist_ok=True)
|
88 |
|
89 |
-
# Global State & Locks
|
90 |
world_objects_lock = threading.Lock()
|
91 |
world_objects = defaultdict(dict)
|
92 |
connected_clients = set()
|
@@ -769,6 +757,12 @@ async def websocket_handler(websocket, path):
|
|
769 |
broadcast_payload = json.dumps({"type": "player_moved", "payload": {"username": sender_username, "id": client_id, "position": pos_data, "rotation": rot_data}})
|
770 |
await broadcast_message(broadcast_payload, exclude_id=client_id)
|
771 |
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
except json.JSONDecodeError:
|
773 |
print(f"WS Invalid JSON from {client_id}: {message[:100]}...")
|
774 |
except Exception as e:
|
@@ -927,6 +921,16 @@ def render_sidebar():
|
|
927 |
st.markdown("---")
|
928 |
st.header("๐๏ธ Build Tools")
|
929 |
st.caption("Select an object to place.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
930 |
cols = st.columns(5)
|
931 |
col_idx = 0
|
932 |
current_tool = st.session_state.get('selected_object', 'None')
|
@@ -934,25 +938,30 @@ def render_sidebar():
|
|
934 |
button_key = f"primitive_{name}"
|
935 |
button_type = "primary" if current_tool == name else "secondary"
|
936 |
if cols[col_idx % 5].button(emoji, key=button_key, help=name, type=button_type, use_container_width=True):
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
|
|
|
|
|
|
945 |
col_idx += 1
|
946 |
st.markdown("---")
|
947 |
if st.button("๐ซ Clear Tool", key="clear_tool", use_container_width=True):
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
|
|
|
|
956 |
|
957 |
st.markdown("---")
|
958 |
st.header("๐ฃ๏ธ Voice & User")
|
|
|
31 |
# Configuration & Constants
|
32 |
# ==============================================================================
|
33 |
|
|
|
34 |
nest_asyncio.apply()
|
35 |
|
|
|
36 |
st.set_page_config(
|
37 |
page_title="๐ค๐๏ธ Shared World Builder ๐",
|
38 |
page_icon="๐๏ธ",
|
|
|
40 |
initial_sidebar_state="expanded"
|
41 |
)
|
42 |
|
|
|
43 |
icons = '๐ค๐๏ธ๐ฃ๏ธ๐พ'
|
44 |
Site_Name = '๐ค๐๏ธ Shared World Builder ๐ฃ๏ธ'
|
45 |
START_ROOM = "World Lobby ๐"
|
46 |
MEDIA_DIR = "."
|
47 |
STATE_FILE = "user_state.txt"
|
48 |
|
|
|
49 |
FUN_USERNAMES = {
|
50 |
"BuilderBot ๐ค": "en-US-AriaNeural", "WorldWeaver ๐ธ๏ธ": "en-US-JennyNeural",
|
51 |
"Terraformer ๐ฑ": "en-GB-SoniaNeural", "SkyArchitect โ๏ธ": "en-AU-NatashaNeural",
|
|
|
55 |
}
|
56 |
EDGE_TTS_VOICES = list(set(FUN_USERNAMES.values()))
|
57 |
CHAT_DIR = "chat_logs"
|
|
|
|
|
58 |
AUDIO_CACHE_DIR = "audio_cache"
|
59 |
AUDIO_DIR = "audio_logs"
|
60 |
+
SAVED_WORLDS_DIR = "saved_worlds"
|
|
|
|
|
61 |
HISTORY_LOG_DIR = "history_logs"
|
62 |
PLOT_WIDTH = 50.0
|
63 |
PLOT_DEPTH = 50.0
|
64 |
WORLD_STATE_FILE_MD_PREFIX = "๐_"
|
65 |
|
|
|
66 |
FILE_EMOJIS = {"md": "๐", "mp3": "๐ต", "png": "๐ผ๏ธ", "mp4": "๐ฅ", "zip": "๐ฆ", "json": "๐"}
|
67 |
|
|
|
68 |
PRIMITIVE_MAP = {
|
69 |
"๐ณ": "Tree", "๐ฟ": "Rock", "๐๏ธ": "Simple House", "๐ฒ": "Pine Tree", "๐งฑ": "Brick Wall",
|
70 |
"๐ต": "Sphere", "๐ฆ": "Cube", "๐งด": "Cylinder", "๐ฆ": "Cone", "๐ฉ": "Torus",
|
|
|
72 |
"๐ผ": "Tower", "๐ง": "Barrier", "โฒ": "Fountain", "๐ฎ": "Lantern", "๐ชง": "Sign Post"
|
73 |
}
|
74 |
|
|
|
75 |
for d in [CHAT_DIR, AUDIO_DIR, AUDIO_CACHE_DIR, SAVED_WORLDS_DIR, HISTORY_LOG_DIR]:
|
76 |
os.makedirs(d, exist_ok=True)
|
77 |
|
|
|
78 |
world_objects_lock = threading.Lock()
|
79 |
world_objects = defaultdict(dict)
|
80 |
connected_clients = set()
|
|
|
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":
|
763 |
+
st.session_state.selected_object = tool_type
|
764 |
+
print(f"Tool updated to {tool_type} for {sender_username}")
|
765 |
+
|
766 |
except json.JSONDecodeError:
|
767 |
print(f"WS Invalid JSON from {client_id}: {message[:100]}...")
|
768 |
except Exception as e:
|
|
|
921 |
st.markdown("---")
|
922 |
st.header("๐๏ธ Build Tools")
|
923 |
st.caption("Select an object to place.")
|
924 |
+
# Hidden selectbox to sync tool state
|
925 |
+
tool_options = ['None'] + list(PRIMITIVE_MAP.values())
|
926 |
+
selected_tool = st.selectbox("Selected Tool", options=tool_options, index=tool_options.index(st.session_state.get('selected_object', 'None')), key="tool_select", label_visibility="collapsed")
|
927 |
+
if selected_tool != st.session_state.selected_object:
|
928 |
+
st.session_state.selected_object = selected_tool
|
929 |
+
run_async(lambda: streamlit_js_eval(
|
930 |
+
f"updateSelectedObjectType({json.dumps(selected_tool)});",
|
931 |
+
key=f"update_tool_js_{selected_tool}"
|
932 |
+
))
|
933 |
+
|
934 |
cols = st.columns(5)
|
935 |
col_idx = 0
|
936 |
current_tool = st.session_state.get('selected_object', 'None')
|
|
|
938 |
button_key = f"primitive_{name}"
|
939 |
button_type = "primary" if current_tool == name else "secondary"
|
940 |
if cols[col_idx % 5].button(emoji, key=button_key, help=name, type=button_type, use_container_width=True):
|
941 |
+
# Update tool via JavaScript without rerun
|
942 |
+
run_async(lambda name_arg=name: streamlit_js_eval(
|
943 |
+
f"""
|
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: 'None', username: window.USERNAME }
|
961 |
+
}));
|
962 |
+
""",
|
963 |
+
key="update_tool_js_none"
|
964 |
+
))
|
965 |
|
966 |
st.markdown("---")
|
967 |
st.header("๐ฃ๏ธ Voice & User")
|