@mml-io/3d-web-experience-client 0.0.0-experimental-c32c620-20250626 → 0.0.0-experimental-3a2278c-20250715
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/Networked3dWebExperienceClient.d.ts +10 -13
- package/build/avatar-selection-ui/AvatarSelectionUI.d.ts +21 -0
- package/build/avatar-selection-ui/AvatarType.d.ts +21 -0
- package/build/avatar-selection-ui/components/AvatarPanel/AvatarSectionUIComponent.d.ts +14 -0
- package/build/avatar-selection-ui/index.d.ts +2 -0
- package/build/chat-ui/TextChatUI.d.ts +25 -0
- package/build/chat-ui/components/ChatPanel/TextChatUIComponent.d.ts +9 -0
- package/build/chat-ui/components/Input/InputBox.d.ts +9 -0
- package/build/chat-ui/components/Message/Message.d.ts +9 -0
- package/build/chat-ui/components/Messages/Messages.d.ts +12 -0
- package/build/chat-ui/helpers.d.ts +3 -0
- package/build/chat-ui/index.d.ts +1 -0
- package/build/index.css +875 -0
- package/build/index.css.map +7 -0
- package/build/index.js +1230 -201
- package/build/index.js.map +4 -4
- package/build/src/Networked3dWebExperience.module.css.d.ts +4 -0
- package/build/src/Networked3dWebExperience.module.d.css.ts +4 -0
- package/build/src/avatar-selection-ui/components/AvatarPanel/AvatarSelectionUIComponent.module.css.d.ts +26 -0
- package/build/src/avatar-selection-ui/components/AvatarPanel/AvatarSelectionUIComponent.module.d.css.ts +26 -0
- package/build/src/chat-ui/components/ChatPanel/TextChatUIComponent.module.css.d.ts +15 -0
- package/build/src/chat-ui/components/ChatPanel/TextChatUIComponent.module.d.css.ts +15 -0
- package/build/src/chat-ui/components/Input/InputBox.module.css.d.ts +7 -0
- package/build/src/chat-ui/components/Input/InputBox.module.d.css.ts +7 -0
- package/build/src/chat-ui/components/Message/Message.module.css.d.ts +5 -0
- package/build/src/chat-ui/components/Message/Message.module.d.css.ts +5 -0
- package/build/src/chat-ui/components/Messages/Messages.module.css.d.ts +5 -0
- package/build/src/chat-ui/components/Messages/Messages.module.d.css.ts +5 -0
- package/package.json +13 -11
- package/LICENSE +0 -19
package/build/index.js
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
+
globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__']=".AvatarSelectionUIComponent-module__menuButton_VjZ7cq__0220{z-index:102;user-select:none;width:70px;min-height:70px;position:absolute;top:0;right:0}.AvatarSelectionUIComponent-module__input_VjZ7cq__0220{color:#fff;backdrop-filter:blur(10px);background-color:#0006;border:1px solid #fff3;border-radius:8px;outline:none;flex:1;margin-right:6px;padding:6px 8px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;font-weight:400;transition:all .2s ease-in-out}.AvatarSelectionUIComponent-module__input_VjZ7cq__0220:focus{background-color:#0009;border-color:#fff6;box-shadow:0 0 0 3px #ffffff26}.AvatarSelectionUIComponent-module__input_VjZ7cq__0220::placeholder{color:#ffffff80}.AvatarSelectionUIComponent-module__closeButton_VjZ7cq__0220{backdrop-filter:blur(10px);color:#fffc;cursor:pointer;user-select:none;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:44px;height:44px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:16px;font-weight:500;transition:all .2s ease-in-out;display:flex;position:absolute;top:8px;right:8px}.AvatarSelectionUIComponent-module__closeButton_VjZ7cq__0220:hover{color:#ffffffe6;background:#000c;transform:scale(1.05)}.AvatarSelectionUIComponent-module__closeButton_VjZ7cq__0220:active{transform:scale(.95)}.AvatarSelectionUIComponent-module__openTab_VjZ7cq__0220{backdrop-filter:blur(10px);cursor:pointer;user-select:none;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s ease-in-out;display:flex;position:absolute;top:8px;right:8px}.AvatarSelectionUIComponent-module__openTab_VjZ7cq__0220:hover{background:#000c;transform:scale(1.05)}.AvatarSelectionUIComponent-module__openTab_VjZ7cq__0220:active{transform:scale(.95)}.AvatarSelectionUIComponent-module__openTab_VjZ7cq__0220 img{filter:invert(80%);width:24px;height:24px;transition:all .2s ease-in-out}.AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220{backdrop-filter:blur(20px);z-index:103;user-select:none;background:#000000bf;border:1px solid #fff3;border-radius:16px;width:400px;max-width:78vw;max-height:calc(100vh - 24px);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;position:absolute;top:8px;right:60px;overflow:hidden auto;box-shadow:0 8px 32px #0006,0 0 0 1px #ffffff1a}.AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220::-webkit-scrollbar{width:8px}.AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220::-webkit-scrollbar-track{background:none}.AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220::-webkit-scrollbar-thumb{background:#fff3;border:1px solid #ffffff1a;border-radius:4px}.AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.AvatarSelectionUIComponent-module__avatarSelectionSection_VjZ7cq__0220{border-bottom:1px solid #ffffff26;padding:10px}.AvatarSelectionUIComponent-module__avatarSelectionSection_VjZ7cq__0220:last-child{border-bottom:none}.AvatarSelectionUIComponent-module__avatarSelectionUi_VjZ7cq__0220{background:#0000004d;border:1px solid #ffffff26;border-radius:12px;grid-template-columns:repeat(auto-fill,minmax(85px,1fr));gap:8px;max-height:320px;padding:10px;display:grid;overflow:hidden auto}.AvatarSelectionUIComponent-module__avatarSelectionUi_VjZ7cq__0220::-webkit-scrollbar{width:6px}.AvatarSelectionUIComponent-module__avatarSelectionUi_VjZ7cq__0220::-webkit-scrollbar-track{background:none}.AvatarSelectionUIComponent-module__avatarSelectionUi_VjZ7cq__0220::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:3px}.AvatarSelectionUIComponent-module__avatarSelectionUiHeader_VjZ7cq__0220{color:#ffffffe6;text-align:center;font-weight:600;position:relative}.AvatarSelectionUIComponent-module__avatarSelectionUiCloseButton_VjZ7cq__0220{position:absolute;top:20px;right:20px}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220{color:#ffffffe6;text-align:center;cursor:pointer;border-radius:8px;padding:4px;transition:all .2s ease-in-out}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220:hover{background:#0000004d;transform:translateY(-2px)}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImgContainer_VjZ7cq__0220{border-radius:8px;position:relative;overflow:hidden}.AvatarSelectionUIComponent-module__avatarSelectionNoImage_VjZ7cq__0220{aspect-ratio:1;box-sizing:border-box;background:#0003;border:1px solid #ffffff26;border-radius:8px;justify-content:center;align-items:center;width:100%;display:flex}.AvatarSelectionUIComponent-module__avatarSelectionNoImage_VjZ7cq__0220 img{filter:invert(70%);opacity:.7;width:40%}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220 p{text-overflow:ellipsis;white-space:nowrap;color:#fffc;margin:4px 0 0;font-size:12px;font-weight:500;position:relative;overflow:hidden}.AvatarSelectionUIComponent-module__tooltipText_VjZ7cq__0220{pointer-events:none;z-index:1000;color:#ffffffe6;backdrop-filter:blur(10px);opacity:0;visibility:hidden;white-space:nowrap;background:#000c;border-radius:8px;margin-bottom:4px;padding:4px 6px;font-size:12px;font-weight:500;transition:opacity .2s ease-in-out;position:absolute;bottom:100%;left:50%;transform:translate(-50%)}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220 p:hover+.AvatarSelectionUIComponent-module__tooltipText_VjZ7cq__0220{opacity:1;visibility:visible;transition-delay:.5s}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImgContainer_VjZ7cq__0220 .AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImage_VjZ7cq__0220{aspect-ratio:1;border-radius:8px;width:100%;transition:all .2s ease-in-out}.AvatarSelectionUIComponent-module__selectedPill_VjZ7cq__0220{color:#fff;backdrop-filter:blur(10px);background:linear-gradient(135deg,#22c55e,#16a34a);border:1px solid #fff3;border-radius:6px;padding:2px 4px;font-size:11px;font-weight:600;box-shadow:0 2px 4px #0003}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImgContainer_VjZ7cq__0220 .AvatarSelectionUIComponent-module__selectedPill_VjZ7cq__0220{z-index:2;position:absolute;top:4px;right:4px}.AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220 img:hover{opacity:.8;transform:scale(1.05)}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220{color:#ffffffe6;border-bottom:1px solid #ffffff26;padding:10px;position:relative}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220:last-child{border-bottom:none}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 .AvatarSelectionUIComponent-module__radioGroup_VjZ7cq__0220{flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:8px;display:flex}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 .AvatarSelectionUIComponent-module__radioItem_VjZ7cq__0220{white-space:nowrap;align-items:center;gap:3px;margin-right:6px;display:flex}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 label{color:#fffc;cursor:pointer;margin:0;font-size:14px;font-weight:500;transition:color .2s ease-in-out}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 label:hover{color:#fff}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio]{appearance:none;cursor:pointer;background:none;border:2px solid #ffffff4d;border-radius:50%;outline:none;width:18px;height:18px;transition:all .2s ease-in-out;position:relative}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio]:hover{border-color:#ffffff80}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio]:focus{box-shadow:0 0 0 3px #ffffff1a}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio]:checked{background:#ffffff1a;border-color:#fffc}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio]:checked:after{content:\"\";background:#ffffffe6;border-radius:50%;width:8px;height:8px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 input[type=radio][disabled]{opacity:.4;cursor:not-allowed}.AvatarSelectionUIComponent-module__customAvatarInputSection_VjZ7cq__0220{align-items:stretch;display:flex}.AvatarSelectionUIComponent-module__setButton_VjZ7cq__0220{color:#ffffffe6;backdrop-filter:blur(10px);cursor:pointer;background:linear-gradient(135deg,#0009,#0006);border:1px solid #fff3;border-radius:8px;justify-content:center;align-items:center;height:44px;padding-left:16px;padding-right:16px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;font-weight:500;transition:all .2s ease-in-out;display:flex}.AvatarSelectionUIComponent-module__setButton_VjZ7cq__0220:hover:not(:disabled){background:linear-gradient(135deg,#000c,#0009);border-color:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 8px #0000004d}.AvatarSelectionUIComponent-module__setButton_VjZ7cq__0220:active:not(:disabled){transform:translateY(0);box-shadow:0 2px 4px #0003}.AvatarSelectionUIComponent-module__setButton_VjZ7cq__0220:disabled{opacity:.5;cursor:not-allowed;transform:none}.AvatarSelectionUIComponent-module__sectionHeading_VjZ7cq__0220{color:#ffffffe6;letter-spacing:-.01em;margin-bottom:8px;font-size:18px;font-weight:600}.AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220 .AvatarSelectionUIComponent-module__selectedPill_VjZ7cq__0220{margin-left:8px;position:relative;top:-2px}.AvatarSelectionUIComponent-module__displayNameSection_VjZ7cq__0220{color:#ffffffe6;border-bottom:1px solid #ffffff26;padding:10px;position:relative}.AvatarSelectionUIComponent-module__displayNameInputSection_VjZ7cq__0220{align-items:stretch;display:flex}.InputBox-module__inputWrapper_adOgOW__0220{pointer-events:all;align-items:stretch;gap:6px;display:flex}.InputBox-module__chatInput_adOgOW__0220{color:#fff;backdrop-filter:blur(10px);box-sizing:border-box;background:#0006;border:1px solid #fff3;border-radius:8px;outline:none;flex:1;height:36px;padding:0 8px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;font-weight:400;transition:all .2s ease-in-out}.InputBox-module__chatInput_adOgOW__0220:focus{background:#0009;border-color:#fff6;box-shadow:0 0 0 3px #ffffff26}.InputBox-module__chatInput_adOgOW__0220::placeholder{color:#ffffff80}.InputBox-module__sendButton_adOgOW__0220{color:#ffffffe6;backdrop-filter:blur(10px);cursor:pointer;background:linear-gradient(135deg,#0009,#0006);border:1px solid #fff3;border-radius:8px;outline:none;justify-content:center;align-items:center;width:36px;height:36px;transition:all .2s ease-in-out;display:flex}.InputBox-module__sendButton_adOgOW__0220:hover{background:linear-gradient(135deg,#000c,#0009);border-color:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 8px #0000004d}.InputBox-module__sendButton_adOgOW__0220:active{transform:translateY(0);box-shadow:0 2px 4px #0003}.InputBox-module__sendButton_adOgOW__0220 .InputBox-module__svgIcon_adOgOW__0220 img{filter:invert(80%);width:18px;height:18px;transition:all .2s ease-in-out}.InputBox-module__sendButton_adOgOW__0220:hover .InputBox-module__svgIcon_adOgOW__0220 img{filter:invert(90%)}.Message-module__messageContainer_ikOQiq__0220{backdrop-filter:blur(8px);word-break:break-word;color:#ffffffe6;direction:ltr;background:#0000004d;border:1px solid #fff3;border-radius:8px;width:fit-content;margin:6px auto 6px 2px;padding:4px 8px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;transition:all .2s ease-in-out;overflow-x:hidden}.Message-module__messageContainer_ikOQiq__0220:hover{background:#0006;border-color:#ffffff4d}.Message-module__userName_ikOQiq__0220{color:#ffffffe6;margin-right:4px;font-weight:600}.Messages-module__messagesContainer_LXaUUW__0220{z-index:1000;max-height:inherit;scrollbar-width:thin;scrollbar-color:#fff3 transparent;pointer-events:fill;direction:rtl;position:relative;bottom:0;left:-1px;overflow-y:auto}.Messages-module__messagesContainer_LXaUUW__0220::-webkit-scrollbar{width:6px}.Messages-module__messagesContainer_LXaUUW__0220::-webkit-scrollbar-track{background:none}.Messages-module__messagesContainer_LXaUUW__0220::-webkit-scrollbar-thumb{background:#fff3;border:1px solid #ffffff1a;border-radius:3px}.Messages-module__messagesContainer_LXaUUW__0220::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.Messages-module__newMessagesButton_LXaUUW__0220{-webkit-backdrop-filter:blur(10px);color:#fff;cursor:pointer;z-index:1001;direction:ltr;background:#000000bf;border:1px solid #fff3;border-radius:20px;padding:8px 16px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;font-weight:500;transition:all .2s;position:absolute;bottom:50px;left:50%;transform:translate(-50%);box-shadow:0 4px 12px #0000004d}.Messages-module__newMessagesButton_LXaUUW__0220:hover{background:#000000d9;border-color:#ffffff4d;transform:translate(-50%)translateY(-2px);box-shadow:0 6px 16px #0006}.Messages-module__newMessagesButton_LXaUUW__0220:active{transform:translate(-50%)translateY(0);box-shadow:0 2px 8px #0000004d}.TextChatUIComponent-module__uiHover_gFDdcW__0220{z-index:102;pointer-events:all;width:58px;min-height:58px;position:absolute;bottom:0;left:0}.TextChatUIComponent-module__textChatUi_gFDdcW__0220{flex-direction:row;align-items:flex-end;width:100%;max-width:500px;height:0;display:flex;position:absolute;bottom:0;left:0}.TextChatUIComponent-module__textChat_gFDdcW__0220{z-index:-1;color:#fff;user-select:none;opacity:0;flex-direction:column;justify-content:space-between;width:100%;max-height:500px;margin-bottom:8px;margin-left:60px;padding:5px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;transition:opacity .25s ease-in-out,transform .2s ease-in-out;display:flex;transform:translate(-100%)}.TextChatUIComponent-module__fadeIn_gFDdcW__0220{opacity:1;transform:translate(0)}.TextChatUIComponent-module__fadeOut_gFDdcW__0220{opacity:.6;transform:translate(calc(-100% - 72px))}.TextChatUIComponent-module__controls_gFDdcW__0220{position:absolute;top:2px;right:0}.TextChatUIComponent-module__openTab_gFDdcW__0220{backdrop-filter:blur(10px);cursor:pointer;z-index:102;user-select:none;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s ease-in-out;display:flex;position:absolute;bottom:8px;left:8px}.TextChatUIComponent-module__openTab_gFDdcW__0220:hover{background:#000c;border-color:#ffffff4d;transform:scale(1.05)}.TextChatUIComponent-module__openTab_gFDdcW__0220:active{transform:scale(.95)}.TextChatUIComponent-module__openTab_gFDdcW__0220 img{filter:invert(80%);width:24px;height:24px;transition:all .2s ease-in-out}.TextChatUIComponent-module__stickyButton_gFDdcW__0220{z-index:103;backdrop-filter:blur(10px);cursor:pointer;user-select:none;opacity:1;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;transition:all .2s ease-in-out;display:flex;position:absolute;bottom:38px;left:38px}.TextChatUIComponent-module__stickyButton_gFDdcW__0220:hover{background:#000c;border-color:#ffffff4d;transform:scale(1.05)}.TextChatUIComponent-module__stickyButtonFadeOut_gFDdcW__0220{z-index:103;backdrop-filter:blur(10px);cursor:pointer;user-select:none;opacity:0;pointer-events:none;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;transition:all .2s ease-in-out;display:flex;position:absolute;bottom:42px;left:42px}.TextChatUIComponent-module__stickyButtonEnabled_gFDdcW__0220{z-index:103;backdrop-filter:blur(10px);cursor:pointer;user-select:none;background:#000c;border:1px solid #22c55e99;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;transition:all .2s ease-in-out;display:flex;position:absolute;bottom:42px;left:42px;box-shadow:0 0 8px #22c55e4d}.TextChatUIComponent-module__stickyButtonEnabled_gFDdcW__0220:hover{border-color:#22c55ecc;transform:scale(1.05);box-shadow:0 0 12px #22c55e66}.TextChatUIComponent-module__stickyButton_gFDdcW__0220 img,.TextChatUIComponent-module__stickyButtonFadeOut_gFDdcW__0220 img,.TextChatUIComponent-module__stickyButtonEnabled_gFDdcW__0220 img{filter:invert(70%);width:12px;height:12px;transition:all .2s ease-in-out}.TextChatUIComponent-module__stickyButton_gFDdcW__0220:hover img,.TextChatUIComponent-module__stickyButtonEnabled_gFDdcW__0220:hover img{filter:invert(90%)}.TextChatUIComponent-module__controls_gFDdcW__0220 .TextChatUIComponent-module__closeButton_gFDdcW__0220{color:#fffc;backdrop-filter:blur(10px);cursor:pointer;background:#0009;border:1px solid #fff3;border-radius:50%;justify-content:center;align-items:center;width:28px;height:28px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;font-weight:500;transition:all .2s ease-in-out;display:flex;position:absolute;top:3px;right:3px}.TextChatUIComponent-module__closeButton_gFDdcW__0220:hover{color:#ffffffe6;background:#000c;border-color:#ffffff4d;transform:scale(1.05)}.TextChatUIComponent-module__closeButton_gFDdcW__0220:active{transform:scale(.95)}.TextChatUIComponent-module__messagesWrapper_gFDdcW__0220{direction:rtl;width:fit-content;max-height:450px;margin-bottom:8px;position:relative}.Networked3dWebExperience-module__respawnButton_7g9l0W__0220{z-index:102;color:#ffffffe6;backdrop-filter:blur(10px);cursor:pointer;user-select:none;background:linear-gradient(135deg,#0009,#0006);border:1px solid #fff3;border-radius:8px;justify-content:center;align-items:center;padding:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;font-weight:500;transition:all .2s ease-in-out;display:flex;position:absolute;top:8px;left:8px}.Networked3dWebExperience-module__respawnButton_7g9l0W__0220:hover{background:linear-gradient(135deg,#000c,#0009);border-color:#ffffff4d;transform:translateY(-1px)}.Networked3dWebExperience-module__respawnButton_7g9l0W__0220:active{transform:translateY(0)}\n";globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__']="4f8287b7f1327101523ba48f76bd7efb";
|
1
2
|
// src/Networked3dWebExperienceClient.ts
|
2
|
-
import { AvatarSelectionUI } from "@mml-io/3d-web-avatar-selection-ui";
|
3
3
|
import {
|
4
4
|
CameraManager,
|
5
5
|
CharacterManager,
|
6
6
|
CharacterModelLoader,
|
7
7
|
CollisionsManager,
|
8
8
|
Composer,
|
9
|
-
decodeCharacterAndCamera,
|
10
9
|
ErrorScreen,
|
11
10
|
GroundPlane,
|
12
11
|
Key,
|
@@ -15,28 +14,1042 @@ import {
|
|
15
14
|
MMLCompositionScene,
|
16
15
|
TimeManager,
|
17
16
|
TweakPane,
|
18
|
-
|
19
|
-
|
17
|
+
Vect3,
|
18
|
+
VirtualJoystick,
|
19
|
+
Character,
|
20
|
+
Quat,
|
21
|
+
getSpawnData
|
22
|
+
} from "/Users/marcuslongmuir/mml/3d-web-experience/packages/3d-web-client-core/build/index.js";
|
20
23
|
import {
|
21
|
-
|
22
|
-
|
23
|
-
} from "@mml-io/3d-web-text-chat";
|
24
|
-
import {
|
25
|
-
USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,
|
26
|
-
USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,
|
27
|
-
USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE,
|
28
|
-
USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,
|
24
|
+
FROM_SERVER_CHAT_MESSAGE_TYPE,
|
25
|
+
FROM_CLIENT_CHAT_MESSAGE_TYPE,
|
29
26
|
UserNetworkingClient,
|
30
|
-
WebsocketStatus
|
31
|
-
|
32
|
-
|
27
|
+
WebsocketStatus,
|
28
|
+
parseServerChatMessage,
|
29
|
+
DeltaNetV01ServerErrors,
|
30
|
+
SERVER_BROADCAST_MESSAGE_TYPE,
|
31
|
+
parseServerBroadcastMessage
|
32
|
+
} from "/Users/marcuslongmuir/mml/3d-web-experience/packages/3d-web-user-networking/build/index.js";
|
33
33
|
import {
|
34
34
|
LoadingProgressManager,
|
35
35
|
registerCustomElementsToWindow,
|
36
36
|
setGlobalDocumentTimeManager,
|
37
37
|
setGlobalMMLScene
|
38
38
|
} from "@mml-io/mml-web";
|
39
|
-
import {
|
39
|
+
import { Scene, AudioListener, Vector3 } from "three";
|
40
|
+
|
41
|
+
// src/avatar-selection-ui/AvatarSelectionUI.tsx
|
42
|
+
import { createRef, forwardRef } from "react";
|
43
|
+
import { flushSync } from "react-dom";
|
44
|
+
import { createRoot } from "react-dom/client";
|
45
|
+
|
46
|
+
// src/avatar-selection-ui/components/AvatarPanel/AvatarSectionUIComponent.tsx
|
47
|
+
import {
|
48
|
+
useRef,
|
49
|
+
useState
|
50
|
+
} from "react";
|
51
|
+
|
52
|
+
// src/avatar-selection-ui/icons/Avatar.svg
|
53
|
+
var Avatar_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z"/></svg>\n';
|
54
|
+
|
55
|
+
// esbuild-css-modules-plugin-ns-js::src/avatar-selection-ui/components/AvatarPanel/AvatarSelectionUIComponent.module.css:injector.js
|
56
|
+
var content = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
57
|
+
var digest = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
58
|
+
var inject = () => {
|
59
|
+
setTimeout(() => {
|
60
|
+
if (!globalThis.document) {
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
let root = globalThis.document.querySelector("head");
|
64
|
+
if (root && root.shadowRoot) {
|
65
|
+
root = root.shadowRoot;
|
66
|
+
}
|
67
|
+
if (!root) {
|
68
|
+
root = globalThis.document.head;
|
69
|
+
}
|
70
|
+
let container = root.querySelector("#_" + digest);
|
71
|
+
if (!container) {
|
72
|
+
container = globalThis.document.createElement("style");
|
73
|
+
container.id = "_" + digest;
|
74
|
+
const text = globalThis.document.createTextNode(content);
|
75
|
+
container.appendChild(text);
|
76
|
+
root.appendChild(container);
|
77
|
+
}
|
78
|
+
}, 0);
|
79
|
+
};
|
80
|
+
|
81
|
+
// src/avatar-selection-ui/components/AvatarPanel/AvatarSelectionUIComponent.module.css
|
82
|
+
var AvatarSelectionUIComponent_default = new Proxy({
|
83
|
+
"avatarSelectionContainer": "AvatarSelectionUIComponent-module__avatarSelectionContainer_VjZ7cq__0220",
|
84
|
+
"avatarSelectionNoImage": "AvatarSelectionUIComponent-module__avatarSelectionNoImage_VjZ7cq__0220",
|
85
|
+
"avatarSelectionSection": "AvatarSelectionUIComponent-module__avatarSelectionSection_VjZ7cq__0220",
|
86
|
+
"avatarSelectionUi": "AvatarSelectionUIComponent-module__avatarSelectionUi_VjZ7cq__0220",
|
87
|
+
"avatarSelectionUiAvatar": "AvatarSelectionUIComponent-module__avatarSelectionUiAvatar_VjZ7cq__0220",
|
88
|
+
"avatarSelectionUiAvatarImage": "AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImage_VjZ7cq__0220",
|
89
|
+
"avatarSelectionUiAvatarImgContainer": "AvatarSelectionUIComponent-module__avatarSelectionUiAvatarImgContainer_VjZ7cq__0220",
|
90
|
+
"avatarSelectionUiCloseButton": "AvatarSelectionUIComponent-module__avatarSelectionUiCloseButton_VjZ7cq__0220",
|
91
|
+
"avatarSelectionUiHeader": "AvatarSelectionUIComponent-module__avatarSelectionUiHeader_VjZ7cq__0220",
|
92
|
+
"closeButton": "AvatarSelectionUIComponent-module__closeButton_VjZ7cq__0220",
|
93
|
+
"customAvatarInputSection": "AvatarSelectionUIComponent-module__customAvatarInputSection_VjZ7cq__0220",
|
94
|
+
"customAvatarSection": "AvatarSelectionUIComponent-module__customAvatarSection_VjZ7cq__0220",
|
95
|
+
"displayNameInputSection": "AvatarSelectionUIComponent-module__displayNameInputSection_VjZ7cq__0220",
|
96
|
+
"displayNameSection": "AvatarSelectionUIComponent-module__displayNameSection_VjZ7cq__0220",
|
97
|
+
"input": "AvatarSelectionUIComponent-module__input_VjZ7cq__0220",
|
98
|
+
"menuButton": "AvatarSelectionUIComponent-module__menuButton_VjZ7cq__0220",
|
99
|
+
"openTab": "AvatarSelectionUIComponent-module__openTab_VjZ7cq__0220",
|
100
|
+
"radioGroup": "AvatarSelectionUIComponent-module__radioGroup_VjZ7cq__0220",
|
101
|
+
"radioItem": "AvatarSelectionUIComponent-module__radioItem_VjZ7cq__0220",
|
102
|
+
"sectionHeading": "AvatarSelectionUIComponent-module__sectionHeading_VjZ7cq__0220",
|
103
|
+
"selectedPill": "AvatarSelectionUIComponent-module__selectedPill_VjZ7cq__0220",
|
104
|
+
"setButton": "AvatarSelectionUIComponent-module__setButton_VjZ7cq__0220",
|
105
|
+
"tooltipText": "AvatarSelectionUIComponent-module__tooltipText_VjZ7cq__0220"
|
106
|
+
}, {
|
107
|
+
get: function(source, key) {
|
108
|
+
inject();
|
109
|
+
return source[key];
|
110
|
+
}
|
111
|
+
});
|
112
|
+
|
113
|
+
// src/avatar-selection-ui/components/AvatarPanel/AvatarSectionUIComponent.tsx
|
114
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
115
|
+
function SelectedPill() {
|
116
|
+
return /* @__PURE__ */ jsx("span", { className: AvatarSelectionUIComponent_default.selectedPill, children: "Selected" });
|
117
|
+
}
|
118
|
+
var AvatarSelectionUIComponent = (props, ref) => {
|
119
|
+
const visibleByDefault = props.visibleByDefault ?? false;
|
120
|
+
const [isVisible, setIsVisible] = useState(visibleByDefault);
|
121
|
+
const [selectedAvatar, setSelectedAvatar] = useState(
|
122
|
+
props.characterDescription
|
123
|
+
);
|
124
|
+
const [customAvatarType, setCustomAvatarType] = useState(
|
125
|
+
1 /* mmlUrl */
|
126
|
+
);
|
127
|
+
const [customAvatarValue, setCustomAvatarValue] = useState("");
|
128
|
+
const inputRef = useRef(null);
|
129
|
+
const textareaRef = useRef(null);
|
130
|
+
const [displayNameValue, setDisplayNameValue] = useState(props.displayName);
|
131
|
+
const displayNameRef = useRef(null);
|
132
|
+
const handleRootClick = (e) => {
|
133
|
+
e.stopPropagation();
|
134
|
+
};
|
135
|
+
const selectAvatar = (avatar) => {
|
136
|
+
setSelectedAvatar(avatar);
|
137
|
+
props.onUpdateUserAvatar(avatar);
|
138
|
+
};
|
139
|
+
const handleInputChange = (e) => {
|
140
|
+
setCustomAvatarValue(e.target.value);
|
141
|
+
};
|
142
|
+
const handleDisplayNameChange = (e) => {
|
143
|
+
setDisplayNameValue(e.target.value);
|
144
|
+
};
|
145
|
+
const setDisplayName = () => {
|
146
|
+
if (!displayNameValue) {
|
147
|
+
return;
|
148
|
+
}
|
149
|
+
props.onUpdateDisplayName(displayNameValue);
|
150
|
+
};
|
151
|
+
const addCustomAvatar = () => {
|
152
|
+
if (!customAvatarValue) {
|
153
|
+
return;
|
154
|
+
}
|
155
|
+
let newSelectedAvatar;
|
156
|
+
switch (customAvatarType) {
|
157
|
+
case 2 /* mml */:
|
158
|
+
newSelectedAvatar = {
|
159
|
+
mmlCharacterString: customAvatarValue
|
160
|
+
};
|
161
|
+
break;
|
162
|
+
case 1 /* mmlUrl */:
|
163
|
+
newSelectedAvatar = {
|
164
|
+
mmlCharacterUrl: customAvatarValue
|
165
|
+
};
|
166
|
+
break;
|
167
|
+
case 0 /* meshFileUrl */:
|
168
|
+
newSelectedAvatar = {
|
169
|
+
meshFileUrl: customAvatarValue
|
170
|
+
};
|
171
|
+
break;
|
172
|
+
}
|
173
|
+
setSelectedAvatar(newSelectedAvatar);
|
174
|
+
props.onUpdateUserAvatar(newSelectedAvatar);
|
175
|
+
};
|
176
|
+
const handleKeyPress = (e) => {
|
177
|
+
e.stopPropagation();
|
178
|
+
};
|
179
|
+
const handleAvatarInputKeyPress = (e) => {
|
180
|
+
e.stopPropagation();
|
181
|
+
if (e.key === "Enter") {
|
182
|
+
addCustomAvatar();
|
183
|
+
}
|
184
|
+
};
|
185
|
+
const handleDisplayNameKeyPress = (e) => {
|
186
|
+
e.stopPropagation();
|
187
|
+
if (e.key === "Enter") {
|
188
|
+
setDisplayName();
|
189
|
+
}
|
190
|
+
};
|
191
|
+
const handleTypeSwitch = (type) => {
|
192
|
+
setCustomAvatarType(type);
|
193
|
+
setCustomAvatarValue("");
|
194
|
+
};
|
195
|
+
const getPlaceholderByType = (type) => {
|
196
|
+
switch (type) {
|
197
|
+
case 0 /* meshFileUrl */:
|
198
|
+
return "https://.../avatar.glb";
|
199
|
+
case 1 /* mmlUrl */:
|
200
|
+
return "https://.../avatar.html";
|
201
|
+
case 2 /* mml */:
|
202
|
+
return '<m-character src="https://link-to-avatar">\n</m-character';
|
203
|
+
}
|
204
|
+
};
|
205
|
+
if (!props.availableAvatars.length && !props.allowCustomAvatars && !props.allowCustomDisplayName) {
|
206
|
+
return null;
|
207
|
+
}
|
208
|
+
let recognizedAvatar = false;
|
209
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
210
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.menuButton, onClick: handleRootClick, children: [
|
211
|
+
!isVisible && /* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.openTab, onClick: () => setIsVisible(true), children: /* @__PURE__ */ jsx("img", { src: `data:image/svg+xml;utf8,${encodeURIComponent(Avatar_default)}` }) }),
|
212
|
+
isVisible && /* @__PURE__ */ jsx("button", { className: AvatarSelectionUIComponent_default.closeButton, onClick: (e) => setIsVisible(false), children: "X" })
|
213
|
+
] }),
|
214
|
+
isVisible && /* @__PURE__ */ jsxs("div", { className: `${AvatarSelectionUIComponent_default.avatarSelectionContainer}`, children: [
|
215
|
+
props.allowCustomDisplayName && /* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.displayNameSection, children: [
|
216
|
+
/* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.sectionHeading, children: "Display Name" }),
|
217
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.displayNameInputSection, children: [
|
218
|
+
/* @__PURE__ */ jsx(
|
219
|
+
"input",
|
220
|
+
{
|
221
|
+
ref: displayNameRef,
|
222
|
+
className: AvatarSelectionUIComponent_default.input,
|
223
|
+
value: displayNameValue,
|
224
|
+
onKeyDown: handleDisplayNameKeyPress,
|
225
|
+
onChange: handleDisplayNameChange,
|
226
|
+
placeholder: "Enter your display name"
|
227
|
+
}
|
228
|
+
),
|
229
|
+
/* @__PURE__ */ jsx(
|
230
|
+
"button",
|
231
|
+
{
|
232
|
+
className: AvatarSelectionUIComponent_default.setButton,
|
233
|
+
disabled: !displayNameValue,
|
234
|
+
type: "button",
|
235
|
+
onClick: setDisplayName,
|
236
|
+
children: "Set"
|
237
|
+
}
|
238
|
+
)
|
239
|
+
] })
|
240
|
+
] }),
|
241
|
+
!!props.availableAvatars.length && /* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.avatarSelectionSection, children: [
|
242
|
+
/* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.sectionHeading, children: "Choose your Avatar" }),
|
243
|
+
/* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.avatarSelectionUi, children: props.availableAvatars.map((avatar, index) => {
|
244
|
+
const isSelected = (selectedAvatar == null ? void 0 : selectedAvatar.meshFileUrl) && (selectedAvatar == null ? void 0 : selectedAvatar.meshFileUrl) === avatar.meshFileUrl || (selectedAvatar == null ? void 0 : selectedAvatar.mmlCharacterUrl) && (selectedAvatar == null ? void 0 : selectedAvatar.mmlCharacterUrl) === avatar.mmlCharacterUrl || (selectedAvatar == null ? void 0 : selectedAvatar.mmlCharacterString) && (selectedAvatar == null ? void 0 : selectedAvatar.mmlCharacterString) === avatar.mmlCharacterString;
|
245
|
+
if (isSelected) {
|
246
|
+
recognizedAvatar = true;
|
247
|
+
}
|
248
|
+
return /* @__PURE__ */ jsx(
|
249
|
+
"div",
|
250
|
+
{
|
251
|
+
className: AvatarSelectionUIComponent_default.avatarSelectionUiAvatar,
|
252
|
+
onClick: () => selectAvatar(avatar),
|
253
|
+
children: /* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.avatarSelectionUiAvatarImgContainer, children: [
|
254
|
+
isSelected && /* @__PURE__ */ jsx(SelectedPill, {}),
|
255
|
+
avatar.thumbnailUrl ? /* @__PURE__ */ jsx(
|
256
|
+
"img",
|
257
|
+
{
|
258
|
+
className: AvatarSelectionUIComponent_default.avatarSelectionUiAvatarImage,
|
259
|
+
src: avatar.thumbnailUrl,
|
260
|
+
alt: avatar.name
|
261
|
+
}
|
262
|
+
) : /* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.avatarSelectionNoImage, children: /* @__PURE__ */ jsx(
|
263
|
+
"img",
|
264
|
+
{
|
265
|
+
alt: avatar.name,
|
266
|
+
src: `data:image/svg+xml;utf8,${encodeURIComponent(Avatar_default)}`
|
267
|
+
}
|
268
|
+
) }),
|
269
|
+
/* @__PURE__ */ jsx("p", { children: avatar.name }),
|
270
|
+
/* @__PURE__ */ jsx("span", { className: AvatarSelectionUIComponent_default.tooltipText, children: avatar.name })
|
271
|
+
] })
|
272
|
+
},
|
273
|
+
index
|
274
|
+
);
|
275
|
+
}) })
|
276
|
+
] }),
|
277
|
+
props.allowCustomAvatars && /* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.customAvatarSection, children: [
|
278
|
+
/* @__PURE__ */ jsx("div", { className: AvatarSelectionUIComponent_default.sectionHeading, children: "Custom Avatar" }),
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.radioGroup, children: [
|
280
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.radioItem, children: [
|
281
|
+
/* @__PURE__ */ jsx(
|
282
|
+
"input",
|
283
|
+
{
|
284
|
+
type: "radio",
|
285
|
+
id: "html",
|
286
|
+
name: "customAvatarType",
|
287
|
+
onChange: () => handleTypeSwitch(1 /* mmlUrl */),
|
288
|
+
checked: customAvatarType === 1 /* mmlUrl */
|
289
|
+
}
|
290
|
+
),
|
291
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "html", children: "MML URL" })
|
292
|
+
] }),
|
293
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.radioItem, children: [
|
294
|
+
/* @__PURE__ */ jsx(
|
295
|
+
"input",
|
296
|
+
{
|
297
|
+
type: "radio",
|
298
|
+
id: "mml",
|
299
|
+
name: "customAvatarType",
|
300
|
+
onChange: () => handleTypeSwitch(2 /* mml */),
|
301
|
+
checked: customAvatarType === 2 /* mml */
|
302
|
+
}
|
303
|
+
),
|
304
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "mml", children: "MML" })
|
305
|
+
] }),
|
306
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.radioItem, children: [
|
307
|
+
/* @__PURE__ */ jsx(
|
308
|
+
"input",
|
309
|
+
{
|
310
|
+
type: "radio",
|
311
|
+
id: "glb",
|
312
|
+
name: "customAvatarType",
|
313
|
+
onChange: () => handleTypeSwitch(0 /* meshFileUrl */),
|
314
|
+
checked: customAvatarType === 0 /* meshFileUrl */
|
315
|
+
}
|
316
|
+
),
|
317
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "glb", children: "Mesh URL" })
|
318
|
+
] }),
|
319
|
+
!recognizedAvatar && /* @__PURE__ */ jsx(SelectedPill, {})
|
320
|
+
] }),
|
321
|
+
/* @__PURE__ */ jsxs("div", { className: AvatarSelectionUIComponent_default.customAvatarInputSection, children: [
|
322
|
+
customAvatarType === 2 /* mml */ ? /* @__PURE__ */ jsx(
|
323
|
+
"textarea",
|
324
|
+
{
|
325
|
+
ref: textareaRef,
|
326
|
+
className: AvatarSelectionUIComponent_default.input,
|
327
|
+
value: customAvatarValue,
|
328
|
+
onChange: handleInputChange,
|
329
|
+
onKeyDown: handleKeyPress,
|
330
|
+
placeholder: getPlaceholderByType(customAvatarType),
|
331
|
+
rows: 4
|
332
|
+
}
|
333
|
+
) : /* @__PURE__ */ jsx(
|
334
|
+
"input",
|
335
|
+
{
|
336
|
+
ref: inputRef,
|
337
|
+
className: AvatarSelectionUIComponent_default.input,
|
338
|
+
value: customAvatarValue,
|
339
|
+
onKeyDown: handleAvatarInputKeyPress,
|
340
|
+
onChange: handleInputChange,
|
341
|
+
placeholder: getPlaceholderByType(customAvatarType)
|
342
|
+
}
|
343
|
+
),
|
344
|
+
/* @__PURE__ */ jsx(
|
345
|
+
"button",
|
346
|
+
{
|
347
|
+
className: AvatarSelectionUIComponent_default.setButton,
|
348
|
+
disabled: !customAvatarValue,
|
349
|
+
type: "button",
|
350
|
+
onClick: addCustomAvatar,
|
351
|
+
children: "Set"
|
352
|
+
}
|
353
|
+
)
|
354
|
+
] })
|
355
|
+
] })
|
356
|
+
] })
|
357
|
+
] });
|
358
|
+
};
|
359
|
+
|
360
|
+
// src/avatar-selection-ui/AvatarSelectionUI.tsx
|
361
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
362
|
+
var ForwardedAvatarSelectionUIComponent = forwardRef(AvatarSelectionUIComponent);
|
363
|
+
var AvatarSelectionUI = class {
|
364
|
+
constructor(config) {
|
365
|
+
this.config = config;
|
366
|
+
this.appRef = createRef();
|
367
|
+
this.wrapper = document.createElement("div");
|
368
|
+
this.onUpdateUserAvatar = (avatar) => {
|
369
|
+
this.config.characterDescription = avatar;
|
370
|
+
this.config.sendIdentityUpdateToServer(this.config.displayName, avatar);
|
371
|
+
};
|
372
|
+
this.onUpdateDisplayName = (displayName) => {
|
373
|
+
this.config.displayName = displayName;
|
374
|
+
this.config.sendIdentityUpdateToServer(displayName, this.config.characterDescription);
|
375
|
+
};
|
376
|
+
this.config.holderElement.appendChild(this.wrapper);
|
377
|
+
this.root = createRoot(this.wrapper);
|
378
|
+
}
|
379
|
+
updateAvatarConfig(avatarConfig) {
|
380
|
+
this.config = {
|
381
|
+
...this.config,
|
382
|
+
...avatarConfig
|
383
|
+
};
|
384
|
+
this.init();
|
385
|
+
}
|
386
|
+
updateAllowCustomDisplayName(allowCustomDisplayName) {
|
387
|
+
this.config = {
|
388
|
+
...this.config,
|
389
|
+
allowCustomDisplayName
|
390
|
+
};
|
391
|
+
this.init();
|
392
|
+
}
|
393
|
+
init() {
|
394
|
+
flushSync(
|
395
|
+
() => this.root.render(
|
396
|
+
/* @__PURE__ */ jsx2(
|
397
|
+
ForwardedAvatarSelectionUIComponent,
|
398
|
+
{
|
399
|
+
ref: this.appRef,
|
400
|
+
onUpdateUserAvatar: this.onUpdateUserAvatar,
|
401
|
+
onUpdateDisplayName: this.onUpdateDisplayName,
|
402
|
+
visibleByDefault: this.config.visibleByDefault,
|
403
|
+
displayName: this.config.displayName,
|
404
|
+
characterDescription: this.config.characterDescription,
|
405
|
+
availableAvatars: this.config.availableAvatars,
|
406
|
+
allowCustomAvatars: this.config.allowCustomAvatars || false,
|
407
|
+
allowCustomDisplayName: this.config.allowCustomDisplayName || false
|
408
|
+
}
|
409
|
+
)
|
410
|
+
)
|
411
|
+
);
|
412
|
+
}
|
413
|
+
};
|
414
|
+
|
415
|
+
// src/chat-ui/TextChatUI.tsx
|
416
|
+
import { createRef as createRef2, forwardRef as forwardRef3 } from "react";
|
417
|
+
import { flushSync as flushSync2 } from "react-dom";
|
418
|
+
import { createRoot as createRoot2 } from "react-dom/client";
|
419
|
+
|
420
|
+
// src/chat-ui/components/ChatPanel/TextChatUIComponent.tsx
|
421
|
+
import {
|
422
|
+
useCallback as useCallback2,
|
423
|
+
useEffect as useEffect4,
|
424
|
+
useImperativeHandle as useImperativeHandle2,
|
425
|
+
useRef as useRef5,
|
426
|
+
useState as useState5
|
427
|
+
} from "react";
|
428
|
+
|
429
|
+
// src/chat-ui/helpers.tsx
|
430
|
+
import { useEffect, useLayoutEffect, useRef as useRef2 } from "react";
|
431
|
+
function useClickOutside(cb) {
|
432
|
+
const ref = useRef2(null);
|
433
|
+
const refCb = useRef2(cb);
|
434
|
+
useLayoutEffect(() => {
|
435
|
+
refCb.current = cb;
|
436
|
+
});
|
437
|
+
useEffect(() => {
|
438
|
+
const handler = (e) => {
|
439
|
+
const element = ref.current;
|
440
|
+
if (element && !element.contains(e.target)) {
|
441
|
+
refCb.current(e);
|
442
|
+
}
|
443
|
+
};
|
444
|
+
document.addEventListener("mousedown", handler);
|
445
|
+
document.addEventListener("touchstart", handler);
|
446
|
+
return () => {
|
447
|
+
document.removeEventListener("mousedown", handler);
|
448
|
+
document.removeEventListener("touchstart", handler);
|
449
|
+
};
|
450
|
+
}, []);
|
451
|
+
return ref;
|
452
|
+
}
|
453
|
+
|
454
|
+
// src/chat-ui/icons/Chat.svg
|
455
|
+
var Chat_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M88.2 309.1c9.8-18.3 6.8-40.8-7.5-55.8C59.4 230.9 48 204 48 176c0-63.5 63.8-128 160-128s160 64.5 160 128s-63.8 128-160 128c-13.1 0-25.8-1.3-37.8-3.6c-10.4-2-21.2-.6-30.7 4.2c-4.1 2.1-8.3 4.1-12.6 6c-16 7.2-32.9 13.5-49.9 18c2.8-4.6 5.4-9.1 7.9-13.6c1.1-1.9 2.2-3.9 3.2-5.9zM0 176c0 41.8 17.2 80.1 45.9 110.3c-.9 1.7-1.9 3.5-2.8 5.1c-10.3 18.4-22.3 36.5-36.6 52.1c-6.6 7-8.3 17.2-4.6 25.9C5.8 378.3 14.4 384 24 384c43 0 86.5-13.3 122.7-29.7c4.8-2.2 9.6-4.5 14.2-6.8c15.1 3 30.9 4.5 47.1 4.5c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176zM432 480c16.2 0 31.9-1.6 47.1-4.5c4.6 2.3 9.4 4.6 14.2 6.8C529.5 498.7 573 512 616 512c9.6 0 18.2-5.7 22-14.5c3.8-8.8 2-19-4.6-25.9c-14.2-15.6-26.2-33.7-36.6-52.1c-.9-1.7-1.9-3.4-2.8-5.1C622.8 384.1 640 345.8 640 304c0-94.4-87.9-171.5-198.2-175.8c4.1 15.2 6.2 31.2 6.2 47.8l0 .6c87.2 6.7 144 67.5 144 127.4c0 28-11.4 54.9-32.7 77.2c-14.3 15-17.3 37.6-7.5 55.8c1.1 2 2.2 4 3.2 5.9c2.5 4.5 5.2 9 7.9 13.6c-17-4.5-33.9-10.7-49.9-18c-4.3-1.9-8.5-3.9-12.6-6c-9.5-4.8-20.3-6.2-30.7-4.2c-12.1 2.4-24.7 3.6-37.8 3.6c-61.7 0-110-26.5-136.8-62.3c-16 5.4-32.8 9.4-50 11.8C279 439.8 350 480 432 480z"/></svg>';
|
456
|
+
|
457
|
+
// src/chat-ui/icons/Pin.svg
|
458
|
+
var Pin_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M32 32C32 14.3 46.3 0 64 0H320c17.7 0 32 14.3 32 32s-14.3 32-32 32H290.5l11.4 148.2c36.7 19.9 65.7 53.2 79.5 94.7l1 3c3.3 9.8 1.6 20.5-4.4 28.8s-15.7 13.3-26 13.3H32c-10.3 0-19.9-4.9-26-13.3s-7.7-19.1-4.4-28.8l1-3c13.8-41.5 42.8-74.8 79.5-94.7L93.5 64H64C46.3 64 32 49.7 32 32zM160 384h64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384z"/></svg>';
|
459
|
+
|
460
|
+
// src/chat-ui/components/Input/InputBox.tsx
|
461
|
+
import { forwardRef as forwardRef2, useImperativeHandle, useRef as useRef3, useState as useState2 } from "react";
|
462
|
+
|
463
|
+
// src/chat-ui/icons/PaperPlane.svg
|
464
|
+
var PaperPlane_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480V396.4c0-4 1.5-7.8 4.2-10.7L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z"/></svg>';
|
465
|
+
|
466
|
+
// esbuild-css-modules-plugin-ns-js::src/chat-ui/components/Input/InputBox.module.css:injector.js
|
467
|
+
var content2 = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
468
|
+
var digest2 = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
469
|
+
var inject2 = () => {
|
470
|
+
setTimeout(() => {
|
471
|
+
if (!globalThis.document) {
|
472
|
+
return;
|
473
|
+
}
|
474
|
+
let root = globalThis.document.querySelector("head");
|
475
|
+
if (root && root.shadowRoot) {
|
476
|
+
root = root.shadowRoot;
|
477
|
+
}
|
478
|
+
if (!root) {
|
479
|
+
root = globalThis.document.head;
|
480
|
+
}
|
481
|
+
let container = root.querySelector("#_" + digest2);
|
482
|
+
if (!container) {
|
483
|
+
container = globalThis.document.createElement("style");
|
484
|
+
container.id = "_" + digest2;
|
485
|
+
const text = globalThis.document.createTextNode(content2);
|
486
|
+
container.appendChild(text);
|
487
|
+
root.appendChild(container);
|
488
|
+
}
|
489
|
+
}, 0);
|
490
|
+
};
|
491
|
+
|
492
|
+
// src/chat-ui/components/Input/InputBox.module.css
|
493
|
+
var InputBox_default = new Proxy({
|
494
|
+
"chatInput": "InputBox-module__chatInput_adOgOW__0220",
|
495
|
+
"inputWrapper": "InputBox-module__inputWrapper_adOgOW__0220",
|
496
|
+
"sendButton": "InputBox-module__sendButton_adOgOW__0220",
|
497
|
+
"svgIcon": "InputBox-module__svgIcon_adOgOW__0220"
|
498
|
+
}, {
|
499
|
+
get: function(source, key) {
|
500
|
+
inject2();
|
501
|
+
return source[key];
|
502
|
+
}
|
503
|
+
});
|
504
|
+
|
505
|
+
// src/chat-ui/components/Input/InputBox.tsx
|
506
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
507
|
+
var InputBox = forwardRef2(
|
508
|
+
({ onSendMessage, hide, setFocus }, ref) => {
|
509
|
+
const inputRef = useRef3(null);
|
510
|
+
const buttonRef = useRef3(null);
|
511
|
+
const [inputValue, setInputValue] = useState2("");
|
512
|
+
useImperativeHandle(ref, () => ({
|
513
|
+
focusInput: () => {
|
514
|
+
if (inputRef.current) inputRef.current.focus();
|
515
|
+
}
|
516
|
+
}));
|
517
|
+
const handleInputChange = (e) => {
|
518
|
+
setInputValue(e.target.value);
|
519
|
+
};
|
520
|
+
const handleSendClick = () => {
|
521
|
+
if (inputValue.trim() !== "") {
|
522
|
+
onSendMessage(inputValue.trim());
|
523
|
+
setInputValue("");
|
524
|
+
}
|
525
|
+
};
|
526
|
+
const handleKeyPress = (e) => {
|
527
|
+
var _a;
|
528
|
+
e.stopPropagation();
|
529
|
+
if (e.key === "Enter") {
|
530
|
+
if (((_a = inputRef.current) == null ? void 0 : _a.value.trim().length) === 0) {
|
531
|
+
if (buttonRef.current) buttonRef.current.focus();
|
532
|
+
hide();
|
533
|
+
return;
|
534
|
+
}
|
535
|
+
handleSendClick();
|
536
|
+
}
|
537
|
+
};
|
538
|
+
return /* @__PURE__ */ jsxs2("div", { className: InputBox_default.inputWrapper, children: [
|
539
|
+
/* @__PURE__ */ jsx3(
|
540
|
+
"input",
|
541
|
+
{
|
542
|
+
ref: inputRef,
|
543
|
+
type: "text",
|
544
|
+
placeholder: "Type your message here...",
|
545
|
+
value: inputValue,
|
546
|
+
onChange: handleInputChange,
|
547
|
+
className: InputBox_default.chatInput,
|
548
|
+
onKeyDown: handleKeyPress,
|
549
|
+
onFocus: setFocus
|
550
|
+
}
|
551
|
+
),
|
552
|
+
/* @__PURE__ */ jsx3("button", { ref: buttonRef, onClick: handleSendClick, className: InputBox_default.sendButton, children: /* @__PURE__ */ jsx3("div", { className: InputBox_default.svgIcon, children: /* @__PURE__ */ jsx3("img", { src: `data:image/svg+xml;utf8,${encodeURIComponent(PaperPlane_default)}` }) }) })
|
553
|
+
] });
|
554
|
+
}
|
555
|
+
);
|
556
|
+
InputBox.displayName = "InputBox";
|
557
|
+
|
558
|
+
// src/chat-ui/components/Messages/Messages.tsx
|
559
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
|
560
|
+
|
561
|
+
// src/chat-ui/components/Message/Message.tsx
|
562
|
+
import { useState as useState3, useEffect as useEffect2, useCallback } from "react";
|
563
|
+
|
564
|
+
// esbuild-css-modules-plugin-ns-js::src/chat-ui/components/Message/Message.module.css:injector.js
|
565
|
+
var content3 = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
566
|
+
var digest3 = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
567
|
+
var inject3 = () => {
|
568
|
+
setTimeout(() => {
|
569
|
+
if (!globalThis.document) {
|
570
|
+
return;
|
571
|
+
}
|
572
|
+
let root = globalThis.document.querySelector("head");
|
573
|
+
if (root && root.shadowRoot) {
|
574
|
+
root = root.shadowRoot;
|
575
|
+
}
|
576
|
+
if (!root) {
|
577
|
+
root = globalThis.document.head;
|
578
|
+
}
|
579
|
+
let container = root.querySelector("#_" + digest3);
|
580
|
+
if (!container) {
|
581
|
+
container = globalThis.document.createElement("style");
|
582
|
+
container.id = "_" + digest3;
|
583
|
+
const text = globalThis.document.createTextNode(content3);
|
584
|
+
container.appendChild(text);
|
585
|
+
root.appendChild(container);
|
586
|
+
}
|
587
|
+
}, 0);
|
588
|
+
};
|
589
|
+
|
590
|
+
// src/chat-ui/components/Message/Message.module.css
|
591
|
+
var Message_default = new Proxy({
|
592
|
+
"messageContainer": "Message-module__messageContainer_ikOQiq__0220",
|
593
|
+
"userName": "Message-module__userName_ikOQiq__0220"
|
594
|
+
}, {
|
595
|
+
get: function(source, key) {
|
596
|
+
inject3();
|
597
|
+
return source[key];
|
598
|
+
}
|
599
|
+
});
|
600
|
+
|
601
|
+
// src/chat-ui/components/Message/Message.tsx
|
602
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
603
|
+
function ReverseHash(input) {
|
604
|
+
const stringLength = input.length;
|
605
|
+
let hash = 5381;
|
606
|
+
for (let i = stringLength - 1; i >= 0; i--) {
|
607
|
+
hash = (hash << 5) + hash + input.charCodeAt(i);
|
608
|
+
}
|
609
|
+
return hash;
|
610
|
+
}
|
611
|
+
function generateValueFromThresholds(hash, thresholds) {
|
612
|
+
const selectedThreshold = thresholds[hash % thresholds.length];
|
613
|
+
const min = Math.min(...selectedThreshold);
|
614
|
+
const max = Math.max(...selectedThreshold);
|
615
|
+
const thresholdRange = Math.abs(max - min);
|
616
|
+
return hash % thresholdRange + min;
|
617
|
+
}
|
618
|
+
function hslForString(input, options = DEFAULT_HSL_OPTIONS) {
|
619
|
+
let hash = Math.abs(ReverseHash("lightness: " + input));
|
620
|
+
const lightness = options.lightnessThresholds ? generateValueFromThresholds(hash, options.lightnessThresholds) : generateValueFromThresholds(hash, DEFAULT_HSL_OPTIONS.lightnessThresholds);
|
621
|
+
hash = Math.abs(ReverseHash("saturation:" + input));
|
622
|
+
const saturation = options.saturationThresholds ? generateValueFromThresholds(hash, options.saturationThresholds) : generateValueFromThresholds(hash, DEFAULT_HSL_OPTIONS.saturationThresholds);
|
623
|
+
hash = Math.abs(ReverseHash("hue:" + input));
|
624
|
+
const hue = options.hueThresholds ? generateValueFromThresholds(hash, options.hueThresholds) : generateValueFromThresholds(hash, DEFAULT_HSL_OPTIONS.hueThresholds);
|
625
|
+
return [hue, saturation, lightness];
|
626
|
+
}
|
627
|
+
var Message = ({ username, message, stringToHslOptions }) => {
|
628
|
+
const [userColors, setUserColors] = useState3(/* @__PURE__ */ new Map());
|
629
|
+
const generateColorForUsername = useCallback(() => {
|
630
|
+
const [hue, saturation, lightness] = hslForString(username, stringToHslOptions);
|
631
|
+
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
632
|
+
}, [stringToHslOptions, username]);
|
633
|
+
useEffect2(() => {
|
634
|
+
if (!userColors.has(username)) {
|
635
|
+
const color = generateColorForUsername();
|
636
|
+
setUserColors(new Map(userColors).set(username, color));
|
637
|
+
}
|
638
|
+
}, [username, userColors, generateColorForUsername]);
|
639
|
+
const userColor = userColors.get(username) || "hsl(0, 0%, 0%)";
|
640
|
+
return /* @__PURE__ */ jsxs3("div", { className: Message_default.messageContainer, children: [
|
641
|
+
/* @__PURE__ */ jsx4("span", { className: Message_default.userName, style: { color: userColor }, children: username }),
|
642
|
+
": ",
|
643
|
+
message
|
644
|
+
] });
|
645
|
+
};
|
646
|
+
var Message_default2 = Message;
|
647
|
+
|
648
|
+
// esbuild-css-modules-plugin-ns-js::src/chat-ui/components/Messages/Messages.module.css:injector.js
|
649
|
+
var content4 = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
650
|
+
var digest4 = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
651
|
+
var inject4 = () => {
|
652
|
+
setTimeout(() => {
|
653
|
+
if (!globalThis.document) {
|
654
|
+
return;
|
655
|
+
}
|
656
|
+
let root = globalThis.document.querySelector("head");
|
657
|
+
if (root && root.shadowRoot) {
|
658
|
+
root = root.shadowRoot;
|
659
|
+
}
|
660
|
+
if (!root) {
|
661
|
+
root = globalThis.document.head;
|
662
|
+
}
|
663
|
+
let container = root.querySelector("#_" + digest4);
|
664
|
+
if (!container) {
|
665
|
+
container = globalThis.document.createElement("style");
|
666
|
+
container.id = "_" + digest4;
|
667
|
+
const text = globalThis.document.createTextNode(content4);
|
668
|
+
container.appendChild(text);
|
669
|
+
root.appendChild(container);
|
670
|
+
}
|
671
|
+
}, 0);
|
672
|
+
};
|
673
|
+
|
674
|
+
// src/chat-ui/components/Messages/Messages.module.css
|
675
|
+
var Messages_default = new Proxy({
|
676
|
+
"messagesContainer": "Messages-module__messagesContainer_LXaUUW__0220",
|
677
|
+
"newMessagesButton": "Messages-module__newMessagesButton_LXaUUW__0220"
|
678
|
+
}, {
|
679
|
+
get: function(source, key) {
|
680
|
+
inject4();
|
681
|
+
return source[key];
|
682
|
+
}
|
683
|
+
});
|
684
|
+
|
685
|
+
// src/chat-ui/components/Messages/Messages.tsx
|
686
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
687
|
+
var Messages = ({ messages, stringToHslOptions, shouldAutoScroll }) => {
|
688
|
+
const messagesEndRef = useRef4(null);
|
689
|
+
const containerRef = useRef4(null);
|
690
|
+
const [unreadCount, setUnreadCount] = useState4(0);
|
691
|
+
const [lastReadMessageIndex, setLastReadMessageIndex] = useState4(0);
|
692
|
+
const [wasAtBottom, setWasAtBottom] = useState4(true);
|
693
|
+
const isAtBottom = () => {
|
694
|
+
if (!containerRef.current) return true;
|
695
|
+
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
696
|
+
return Math.abs(scrollHeight - clientHeight - scrollTop) < 10;
|
697
|
+
};
|
698
|
+
const handleScroll = () => {
|
699
|
+
const atBottom = isAtBottom();
|
700
|
+
setWasAtBottom(atBottom);
|
701
|
+
if (atBottom && unreadCount > 0) {
|
702
|
+
setUnreadCount(0);
|
703
|
+
setLastReadMessageIndex(messages.length - 1);
|
704
|
+
}
|
705
|
+
};
|
706
|
+
const scrollToBottom = () => {
|
707
|
+
if (messagesEndRef.current) {
|
708
|
+
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
|
709
|
+
}
|
710
|
+
setUnreadCount(0);
|
711
|
+
setLastReadMessageIndex(messages.length - 1);
|
712
|
+
setWasAtBottom(true);
|
713
|
+
};
|
714
|
+
useEffect3(() => {
|
715
|
+
if (messages.length === 0) return;
|
716
|
+
const shouldScroll = shouldAutoScroll || wasAtBottom;
|
717
|
+
if (shouldScroll) {
|
718
|
+
setTimeout(() => {
|
719
|
+
if (!isAtBottom()) {
|
720
|
+
if (messagesEndRef.current) {
|
721
|
+
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
|
722
|
+
}
|
723
|
+
}
|
724
|
+
setWasAtBottom(true);
|
725
|
+
}, 0);
|
726
|
+
setUnreadCount(0);
|
727
|
+
setLastReadMessageIndex(messages.length - 1);
|
728
|
+
} else {
|
729
|
+
const newUnreadCount = messages.length - 1 - lastReadMessageIndex;
|
730
|
+
setUnreadCount(newUnreadCount);
|
731
|
+
}
|
732
|
+
}, [messages, shouldAutoScroll, wasAtBottom, lastReadMessageIndex]);
|
733
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
734
|
+
/* @__PURE__ */ jsxs4(
|
735
|
+
"div",
|
736
|
+
{
|
737
|
+
ref: containerRef,
|
738
|
+
className: Messages_default.messagesContainer,
|
739
|
+
onScroll: handleScroll,
|
740
|
+
children: [
|
741
|
+
messages.map((msg, index) => /* @__PURE__ */ jsx5(
|
742
|
+
Message_default2,
|
743
|
+
{
|
744
|
+
username: msg.username,
|
745
|
+
message: msg.message,
|
746
|
+
stringToHslOptions
|
747
|
+
},
|
748
|
+
index
|
749
|
+
)),
|
750
|
+
/* @__PURE__ */ jsx5("div", { ref: messagesEndRef })
|
751
|
+
]
|
752
|
+
}
|
753
|
+
),
|
754
|
+
unreadCount > 0 && /* @__PURE__ */ jsxs4(
|
755
|
+
"button",
|
756
|
+
{
|
757
|
+
className: Messages_default.newMessagesButton,
|
758
|
+
onClick: scrollToBottom,
|
759
|
+
children: [
|
760
|
+
unreadCount,
|
761
|
+
" new message",
|
762
|
+
unreadCount !== 1 ? "s" : ""
|
763
|
+
]
|
764
|
+
}
|
765
|
+
)
|
766
|
+
] });
|
767
|
+
};
|
768
|
+
|
769
|
+
// esbuild-css-modules-plugin-ns-js::src/chat-ui/components/ChatPanel/TextChatUIComponent.module.css:injector.js
|
770
|
+
var content5 = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
771
|
+
var digest5 = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
772
|
+
var inject5 = () => {
|
773
|
+
setTimeout(() => {
|
774
|
+
if (!globalThis.document) {
|
775
|
+
return;
|
776
|
+
}
|
777
|
+
let root = globalThis.document.querySelector("head");
|
778
|
+
if (root && root.shadowRoot) {
|
779
|
+
root = root.shadowRoot;
|
780
|
+
}
|
781
|
+
if (!root) {
|
782
|
+
root = globalThis.document.head;
|
783
|
+
}
|
784
|
+
let container = root.querySelector("#_" + digest5);
|
785
|
+
if (!container) {
|
786
|
+
container = globalThis.document.createElement("style");
|
787
|
+
container.id = "_" + digest5;
|
788
|
+
const text = globalThis.document.createTextNode(content5);
|
789
|
+
container.appendChild(text);
|
790
|
+
root.appendChild(container);
|
791
|
+
}
|
792
|
+
}, 0);
|
793
|
+
};
|
794
|
+
|
795
|
+
// src/chat-ui/components/ChatPanel/TextChatUIComponent.module.css
|
796
|
+
var TextChatUIComponent_default = new Proxy({
|
797
|
+
"closeButton": "TextChatUIComponent-module__closeButton_gFDdcW__0220",
|
798
|
+
"controls": "TextChatUIComponent-module__controls_gFDdcW__0220",
|
799
|
+
"fadeIn": "TextChatUIComponent-module__fadeIn_gFDdcW__0220",
|
800
|
+
"fadeOut": "TextChatUIComponent-module__fadeOut_gFDdcW__0220",
|
801
|
+
"messagesWrapper": "TextChatUIComponent-module__messagesWrapper_gFDdcW__0220",
|
802
|
+
"openTab": "TextChatUIComponent-module__openTab_gFDdcW__0220",
|
803
|
+
"stickyButton": "TextChatUIComponent-module__stickyButton_gFDdcW__0220",
|
804
|
+
"stickyButtonEnabled": "TextChatUIComponent-module__stickyButtonEnabled_gFDdcW__0220",
|
805
|
+
"stickyButtonFadeOut": "TextChatUIComponent-module__stickyButtonFadeOut_gFDdcW__0220",
|
806
|
+
"textChat": "TextChatUIComponent-module__textChat_gFDdcW__0220",
|
807
|
+
"textChatUi": "TextChatUIComponent-module__textChatUi_gFDdcW__0220",
|
808
|
+
"uiHover": "TextChatUIComponent-module__uiHover_gFDdcW__0220"
|
809
|
+
}, {
|
810
|
+
get: function(source, key) {
|
811
|
+
inject5();
|
812
|
+
return source[key];
|
813
|
+
}
|
814
|
+
});
|
815
|
+
|
816
|
+
// src/chat-ui/components/ChatPanel/TextChatUIComponent.tsx
|
817
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
818
|
+
var MAX_MESSAGES = 50;
|
819
|
+
var SECONDS_TO_FADE_OUT = 6;
|
820
|
+
var ChatUIComponent = (props, ref) => {
|
821
|
+
const visibleByDefault = props.visibleByDefault ?? true;
|
822
|
+
const [messages, setMessages] = useState5([]);
|
823
|
+
const [isVisible, setIsVisible] = useState5(visibleByDefault);
|
824
|
+
const [isSticky, setSticky] = useState5(visibleByDefault);
|
825
|
+
const [isFocused, setIsFocused] = useState5(false);
|
826
|
+
const [isOpenHovered, setOpenHovered] = useState5(false);
|
827
|
+
const [shouldAutoScroll, setShouldAutoScroll] = useState5(false);
|
828
|
+
const [panelStyle, setPanelStyle] = useState5(TextChatUIComponent_default.fadeOut);
|
829
|
+
const [stickyStyle, setStickyStyle] = useState5(TextChatUIComponent_default.stickyButton);
|
830
|
+
const stickyButtonRef = useRef5(null);
|
831
|
+
const closeButtonRef = useRef5(null);
|
832
|
+
const hideTimeoutRef = useRef5(null);
|
833
|
+
const inputBoxRef = useRef5(null);
|
834
|
+
const startHideTimeout = useCallback2(() => {
|
835
|
+
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
836
|
+
hideTimeoutRef.current = setTimeout(() => {
|
837
|
+
if (isVisible) {
|
838
|
+
setIsVisible(false);
|
839
|
+
}
|
840
|
+
}, SECONDS_TO_FADE_OUT * 1e3);
|
841
|
+
}, [isVisible]);
|
842
|
+
const handleKeyDown = useCallback2(
|
843
|
+
(e) => {
|
844
|
+
if (e.key === "Enter") {
|
845
|
+
if (!isVisible) setIsVisible(true);
|
846
|
+
setIsFocused(true);
|
847
|
+
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
848
|
+
if (inputBoxRef.current) inputBoxRef.current.focusInput();
|
849
|
+
}
|
850
|
+
},
|
851
|
+
[isVisible]
|
852
|
+
);
|
853
|
+
const handleBlur = useCallback2(() => {
|
854
|
+
if (isFocused) setIsFocused(false);
|
855
|
+
startHideTimeout();
|
856
|
+
if (closeButtonRef.current) closeButtonRef.current.focus();
|
857
|
+
}, [isFocused, startHideTimeout]);
|
858
|
+
const hide = () => {
|
859
|
+
setIsVisible(false);
|
860
|
+
setIsFocused(false);
|
861
|
+
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
862
|
+
};
|
863
|
+
const handleRootClick = (e) => {
|
864
|
+
e.stopPropagation();
|
865
|
+
setOpenHovered(true);
|
866
|
+
if (!isVisible) setIsVisible(true);
|
867
|
+
};
|
868
|
+
const handleStickyButton = (e) => {
|
869
|
+
e.stopPropagation();
|
870
|
+
setSticky(!isSticky);
|
871
|
+
};
|
872
|
+
const handleWheel = (e) => {
|
873
|
+
e.stopPropagation();
|
874
|
+
};
|
875
|
+
const handleMouseLeave = () => {
|
876
|
+
setOpenHovered(false);
|
877
|
+
if (!isFocused && !isSticky && isVisible) {
|
878
|
+
startHideTimeout();
|
879
|
+
}
|
880
|
+
};
|
881
|
+
const handleMouseEnter = () => {
|
882
|
+
setOpenHovered(true);
|
883
|
+
if (!isVisible) setIsVisible(true);
|
884
|
+
};
|
885
|
+
const chatPanelRef = useClickOutside(() => {
|
886
|
+
if (isFocused) {
|
887
|
+
setIsFocused(false);
|
888
|
+
startHideTimeout();
|
889
|
+
}
|
890
|
+
});
|
891
|
+
useEffect4(() => {
|
892
|
+
if (isVisible && isSticky) {
|
893
|
+
if (chatPanelRef.current) chatPanelRef.current.style.zIndex = "100";
|
894
|
+
}
|
895
|
+
setPanelStyle(isVisible || isFocused || isSticky ? TextChatUIComponent_default.fadeIn : TextChatUIComponent_default.fadeOut);
|
896
|
+
setStickyStyle(
|
897
|
+
isSticky ? TextChatUIComponent_default.stickyButtonEnabled : isOpenHovered ? TextChatUIComponent_default.stickyButton : TextChatUIComponent_default.stickyButtonFadeOut
|
898
|
+
);
|
899
|
+
if (chatPanelRef.current && chatPanelRef.current.style.zIndex !== "100") {
|
900
|
+
setTimeout(() => {
|
901
|
+
if (chatPanelRef.current) chatPanelRef.current.style.zIndex = "100";
|
902
|
+
}, 2e3);
|
903
|
+
}
|
904
|
+
}, [isVisible, isSticky, isFocused, chatPanelRef, isOpenHovered]);
|
905
|
+
const appendMessages = (username, message) => {
|
906
|
+
setMessages((prev) => {
|
907
|
+
const newMessages = [...prev, { username, message }];
|
908
|
+
return newMessages.length > MAX_MESSAGES ? newMessages.slice(-MAX_MESSAGES) : newMessages;
|
909
|
+
});
|
910
|
+
};
|
911
|
+
useImperativeHandle2(ref, () => ({
|
912
|
+
addMessage: (username, message) => {
|
913
|
+
appendMessages(username, message);
|
914
|
+
if (!isVisible) setIsVisible(true);
|
915
|
+
startHideTimeout();
|
916
|
+
}
|
917
|
+
}));
|
918
|
+
const handleSendMessage = (message) => {
|
919
|
+
setShouldAutoScroll(true);
|
920
|
+
props.sendMessageToServer(message);
|
921
|
+
setTimeout(() => setShouldAutoScroll(false), 100);
|
922
|
+
};
|
923
|
+
const setFocus = () => setIsFocused(true);
|
924
|
+
useEffect4(() => {
|
925
|
+
window.addEventListener("keydown", handleKeyDown, false);
|
926
|
+
window.addEventListener("blur", handleBlur, false);
|
927
|
+
return () => {
|
928
|
+
window.removeEventListener("keydown", handleKeyDown, false);
|
929
|
+
window.removeEventListener("blur", handleBlur, false);
|
930
|
+
};
|
931
|
+
}, [handleBlur, handleKeyDown]);
|
932
|
+
return /* @__PURE__ */ jsxs5("div", { className: TextChatUIComponent_default.textChatUi, children: [
|
933
|
+
/* @__PURE__ */ jsxs5(
|
934
|
+
"div",
|
935
|
+
{
|
936
|
+
className: TextChatUIComponent_default.uiHover,
|
937
|
+
onMouseEnter: handleMouseEnter,
|
938
|
+
onMouseLeave: handleMouseLeave,
|
939
|
+
onClick: handleRootClick,
|
940
|
+
children: [
|
941
|
+
/* @__PURE__ */ jsx6("div", { className: TextChatUIComponent_default.openTab, onClick: hide, children: /* @__PURE__ */ jsx6("img", { src: `data:image/svg+xml;utf8,${encodeURIComponent(Chat_default)}` }) }),
|
942
|
+
/* @__PURE__ */ jsx6("div", { ref: stickyButtonRef, className: stickyStyle, onClick: handleStickyButton, children: /* @__PURE__ */ jsx6("img", { src: `data:image/svg+xml;utf8,${encodeURIComponent(Pin_default)}` }) })
|
943
|
+
]
|
944
|
+
}
|
945
|
+
),
|
946
|
+
/* @__PURE__ */ jsxs5(
|
947
|
+
"div",
|
948
|
+
{
|
949
|
+
ref: chatPanelRef,
|
950
|
+
style: { zIndex: -1 },
|
951
|
+
id: "text-chat-wrapper",
|
952
|
+
className: `${TextChatUIComponent_default.textChat} ${panelStyle}`,
|
953
|
+
onWheel: handleWheel,
|
954
|
+
children: [
|
955
|
+
/* @__PURE__ */ jsx6("div", { className: TextChatUIComponent_default.messagesWrapper, children: /* @__PURE__ */ jsx6(Messages, { messages, stringToHslOptions: props.stringToHslOptions, shouldAutoScroll }) }),
|
956
|
+
/* @__PURE__ */ jsx6(
|
957
|
+
InputBox,
|
958
|
+
{
|
959
|
+
ref: inputBoxRef,
|
960
|
+
onSendMessage: handleSendMessage,
|
961
|
+
hide,
|
962
|
+
setFocus
|
963
|
+
}
|
964
|
+
)
|
965
|
+
]
|
966
|
+
}
|
967
|
+
)
|
968
|
+
] });
|
969
|
+
};
|
970
|
+
|
971
|
+
// src/chat-ui/TextChatUI.tsx
|
972
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
973
|
+
var DEFAULT_HUE_RANGES = [[10, 350]];
|
974
|
+
var DEFAULT_SATURATION_RANGES = [[60, 100]];
|
975
|
+
var DEFAULT_LIGHTNESS_RANGES = [[65, 75]];
|
976
|
+
var DEFAULT_HSL_OPTIONS = {
|
977
|
+
hueThresholds: DEFAULT_HUE_RANGES,
|
978
|
+
saturationThresholds: DEFAULT_SATURATION_RANGES,
|
979
|
+
lightnessThresholds: DEFAULT_LIGHTNESS_RANGES
|
980
|
+
};
|
981
|
+
var ForwardedChatUIComponent = forwardRef3(ChatUIComponent);
|
982
|
+
var TextChatUI = class {
|
983
|
+
constructor(config) {
|
984
|
+
this.config = config;
|
985
|
+
this.appRef = createRef2();
|
986
|
+
this.wrapper = document.createElement("div");
|
987
|
+
this.config.holderElement.appendChild(this.wrapper);
|
988
|
+
this.root = createRoot2(this.wrapper);
|
989
|
+
}
|
990
|
+
addTextMessage(username, message) {
|
991
|
+
if (this.appRef.current) {
|
992
|
+
this.appRef.current.addMessage(username, message);
|
993
|
+
}
|
994
|
+
}
|
995
|
+
dispose() {
|
996
|
+
this.root.unmount();
|
997
|
+
this.wrapper.remove();
|
998
|
+
}
|
999
|
+
init() {
|
1000
|
+
flushSync2(
|
1001
|
+
() => this.root.render(
|
1002
|
+
/* @__PURE__ */ jsx7(
|
1003
|
+
ForwardedChatUIComponent,
|
1004
|
+
{
|
1005
|
+
ref: this.appRef,
|
1006
|
+
sendMessageToServer: this.config.sendMessageToServerMethod,
|
1007
|
+
visibleByDefault: this.config.visibleByDefault,
|
1008
|
+
stringToHslOptions: this.config.stringToHslOptions
|
1009
|
+
}
|
1010
|
+
)
|
1011
|
+
)
|
1012
|
+
);
|
1013
|
+
}
|
1014
|
+
};
|
1015
|
+
|
1016
|
+
// esbuild-css-modules-plugin-ns-js::src/Networked3dWebExperience.module.css:injector.js
|
1017
|
+
var content6 = globalThis['__css-content-4f8287b7f1327101523ba48f76bd7efb__'];
|
1018
|
+
var digest6 = globalThis['__css-digest-4f8287b7f1327101523ba48f76bd7efb__'];
|
1019
|
+
var inject6 = () => {
|
1020
|
+
setTimeout(() => {
|
1021
|
+
if (!globalThis.document) {
|
1022
|
+
return;
|
1023
|
+
}
|
1024
|
+
let root = globalThis.document.querySelector("head");
|
1025
|
+
if (root && root.shadowRoot) {
|
1026
|
+
root = root.shadowRoot;
|
1027
|
+
}
|
1028
|
+
if (!root) {
|
1029
|
+
root = globalThis.document.head;
|
1030
|
+
}
|
1031
|
+
let container = root.querySelector("#_" + digest6);
|
1032
|
+
if (!container) {
|
1033
|
+
container = globalThis.document.createElement("style");
|
1034
|
+
container.id = "_" + digest6;
|
1035
|
+
const text = globalThis.document.createTextNode(content6);
|
1036
|
+
container.appendChild(text);
|
1037
|
+
root.appendChild(container);
|
1038
|
+
}
|
1039
|
+
}, 0);
|
1040
|
+
};
|
1041
|
+
|
1042
|
+
// src/Networked3dWebExperience.module.css
|
1043
|
+
var Networked3dWebExperience_default = new Proxy({
|
1044
|
+
"respawnButton": "Networked3dWebExperience-module__respawnButton_7g9l0W__0220"
|
1045
|
+
}, {
|
1046
|
+
get: function(source, key) {
|
1047
|
+
inject6();
|
1048
|
+
return source[key];
|
1049
|
+
}
|
1050
|
+
});
|
1051
|
+
|
1052
|
+
// src/Networked3dWebExperienceClient.ts
|
40
1053
|
function normalizeSpawnConfiguration(spawnConfig) {
|
41
1054
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
42
1055
|
return {
|
@@ -69,27 +1082,23 @@ var Networked3dWebExperienceClient = class {
|
|
69
1082
|
this.scene = new Scene();
|
70
1083
|
this.tweakPane = null;
|
71
1084
|
this.audioListener = new AudioListener();
|
72
|
-
this.collisionsManager = new CollisionsManager(this.scene);
|
73
|
-
this.characterModelLoader = new CharacterModelLoader();
|
74
1085
|
this.timeManager = new TimeManager();
|
75
1086
|
this.keyInputManager = new KeyInputManager();
|
76
1087
|
this.mmlFrames = {};
|
77
1088
|
this.clientId = null;
|
78
1089
|
this.remoteUserStates = /* @__PURE__ */ new Map();
|
79
1090
|
this.userProfiles = /* @__PURE__ */ new Map();
|
80
|
-
this.networkChat = null;
|
81
1091
|
this.textChatUI = null;
|
82
1092
|
this.avatarSelectionUI = null;
|
83
|
-
this.voiceChatManager = null;
|
84
1093
|
this.latestCharacterObject = {
|
85
1094
|
characterState: null
|
86
1095
|
};
|
87
1096
|
this.characterControllerPaneSet = false;
|
88
1097
|
this.initialLoadCompleted = false;
|
89
1098
|
this.loadingProgressManager = new LoadingProgressManager();
|
90
|
-
this.currentRequestAnimationFrame = null;
|
91
1099
|
this.groundPlane = null;
|
92
1100
|
this.respawnButton = null;
|
1101
|
+
this.currentRequestAnimationFrame = null;
|
93
1102
|
var _a;
|
94
1103
|
this.element = document.createElement("div");
|
95
1104
|
this.element.style.position = "absolute";
|
@@ -106,8 +1115,10 @@ var Networked3dWebExperienceClient = class {
|
|
106
1115
|
this.canvasHolder.style.width = "100%";
|
107
1116
|
this.canvasHolder.style.height = "100%";
|
108
1117
|
this.element.appendChild(this.canvasHolder);
|
1118
|
+
this.collisionsManager = new CollisionsManager(this.scene);
|
109
1119
|
this.cameraManager = new CameraManager(this.canvasHolder, this.collisionsManager);
|
110
1120
|
this.cameraManager.camera.add(this.audioListener);
|
1121
|
+
this.characterModelLoader = new CharacterModelLoader();
|
111
1122
|
this.virtualJoystick = new VirtualJoystick(this.element, {
|
112
1123
|
radius: 70,
|
113
1124
|
innerRadius: 20,
|
@@ -117,7 +1128,8 @@ var Networked3dWebExperienceClient = class {
|
|
117
1128
|
scene: this.scene,
|
118
1129
|
cameraManager: this.cameraManager,
|
119
1130
|
spawnSun: true,
|
120
|
-
environmentConfiguration: this.config.environmentConfiguration
|
1131
|
+
environmentConfiguration: this.config.environmentConfiguration,
|
1132
|
+
postProcessingEnabled: this.config.postProcessingEnabled
|
121
1133
|
});
|
122
1134
|
this.canvasHolder.appendChild(this.composer.renderer.domElement);
|
123
1135
|
if (this.config.enableTweakPane !== false) {
|
@@ -127,62 +1139,88 @@ var Networked3dWebExperienceClient = class {
|
|
127
1139
|
this.composer.fitContainer();
|
128
1140
|
});
|
129
1141
|
resizeObserver.observe(this.element);
|
1142
|
+
this.spawnConfiguration = normalizeSpawnConfiguration(this.config.spawnConfiguration);
|
1143
|
+
const spawnData = getSpawnData(this.spawnConfiguration, true);
|
1144
|
+
const spawnRotation = new Quat().setFromEulerXYZ(spawnData.spawnRotation);
|
130
1145
|
const initialNetworkLoadRef = {};
|
131
1146
|
this.loadingProgressManager.addLoadingAsset(initialNetworkLoadRef, "network", "network");
|
132
|
-
this.networkClient = new UserNetworkingClient(
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
this.
|
148
|
-
|
149
|
-
|
1147
|
+
this.networkClient = new UserNetworkingClient(
|
1148
|
+
{
|
1149
|
+
url: this.config.userNetworkAddress,
|
1150
|
+
sessionToken: this.config.sessionToken,
|
1151
|
+
websocketFactory: (url) => new WebSocket(url, "delta-net-v0.1"),
|
1152
|
+
statusUpdateCallback: (status) => {
|
1153
|
+
console.log(`Websocket status: ${status}`);
|
1154
|
+
if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {
|
1155
|
+
this.characterManager.clear();
|
1156
|
+
this.remoteUserStates.clear();
|
1157
|
+
this.clientId = null;
|
1158
|
+
}
|
1159
|
+
},
|
1160
|
+
assignedIdentity: (clientId) => {
|
1161
|
+
console.log(`Assigned ID: ${clientId}`);
|
1162
|
+
this.clientId = clientId;
|
1163
|
+
if (this.initialLoadCompleted) {
|
1164
|
+
const spawnData2 = getSpawnData(this.spawnConfiguration, true);
|
1165
|
+
this.spawnCharacter(spawnData2);
|
1166
|
+
} else {
|
1167
|
+
this.loadingProgressManager.completedLoadingAsset(initialNetworkLoadRef);
|
1168
|
+
}
|
1169
|
+
},
|
1170
|
+
onUpdate: (update) => {
|
1171
|
+
this.onNetworkUpdate(update);
|
1172
|
+
},
|
1173
|
+
onServerError: (error) => {
|
1174
|
+
switch (error.errorType) {
|
1175
|
+
case DeltaNetV01ServerErrors.USER_AUTHENTICATION_FAILED_ERROR_TYPE:
|
1176
|
+
this.disposeWithError(error.message);
|
1177
|
+
break;
|
1178
|
+
case DeltaNetV01ServerErrors.USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE:
|
1179
|
+
this.disposeWithError(error.message);
|
1180
|
+
break;
|
1181
|
+
case DeltaNetV01ServerErrors.USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE:
|
1182
|
+
this.disposeWithError(error.message || "Server shutdown");
|
1183
|
+
break;
|
1184
|
+
default:
|
1185
|
+
console.error(`Unhandled server error: ${error.message}`);
|
1186
|
+
this.disposeWithError(error.message);
|
1187
|
+
}
|
1188
|
+
},
|
1189
|
+
onCustomMessage: (customType, contents) => {
|
1190
|
+
var _a2, _b;
|
1191
|
+
if (customType === SERVER_BROADCAST_MESSAGE_TYPE) {
|
1192
|
+
const serverBroadcastMessage = parseServerBroadcastMessage(contents);
|
1193
|
+
if (serverBroadcastMessage instanceof Error) {
|
1194
|
+
console.error(`Invalid server broadcast message: ${contents}`);
|
1195
|
+
} else {
|
1196
|
+
(_b = (_a2 = this.config).onServerBroadcast) == null ? void 0 : _b.call(_a2, serverBroadcastMessage);
|
1197
|
+
}
|
1198
|
+
} else if (customType === FROM_SERVER_CHAT_MESSAGE_TYPE) {
|
1199
|
+
const serverChatMessage = parseServerChatMessage(contents);
|
1200
|
+
if (serverChatMessage instanceof Error) {
|
1201
|
+
console.error(`Invalid server chat message: ${contents}`);
|
1202
|
+
} else {
|
1203
|
+
this.handleChatMessage(serverChatMessage.fromUserId, serverChatMessage.message);
|
1204
|
+
}
|
1205
|
+
} else {
|
1206
|
+
console.warn(`Did not recognize custom message type ${customType}`);
|
1207
|
+
}
|
150
1208
|
}
|
151
1209
|
},
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
this.remoteUserStates.set(remoteClientId, userNetworkingClientUpdate);
|
157
|
-
}
|
1210
|
+
{
|
1211
|
+
username: null,
|
1212
|
+
characterDescription: null,
|
1213
|
+
colors: null
|
158
1214
|
},
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
switch (error.errorType) {
|
167
|
-
case USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE:
|
168
|
-
this.disposeWithError(error.message);
|
169
|
-
break;
|
170
|
-
case USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE:
|
171
|
-
this.disposeWithError(error.message);
|
172
|
-
break;
|
173
|
-
case USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE:
|
174
|
-
this.disposeWithError(error.message || "Server shutdown");
|
175
|
-
break;
|
176
|
-
default:
|
177
|
-
console.error(`Unhandled server error: ${error.message}`);
|
178
|
-
this.disposeWithError(error.message);
|
179
|
-
}
|
180
|
-
},
|
181
|
-
onServerBroadcast: (broadcast) => {
|
182
|
-
var _a2, _b;
|
183
|
-
(_b = (_a2 = this.config).onServerBroadcast) == null ? void 0 : _b.call(_a2, broadcast);
|
1215
|
+
{
|
1216
|
+
position: spawnData.spawnPosition,
|
1217
|
+
rotation: {
|
1218
|
+
quaternionY: spawnRotation.y,
|
1219
|
+
quaternionW: spawnRotation.w
|
1220
|
+
},
|
1221
|
+
state: 0
|
184
1222
|
}
|
185
|
-
|
1223
|
+
);
|
186
1224
|
if (this.config.allowOrbitalCamera) {
|
187
1225
|
this.keyInputManager.createKeyBinding(Key.C, () => {
|
188
1226
|
if (document.activeElement === document.body) {
|
@@ -191,7 +1229,10 @@ var Networked3dWebExperienceClient = class {
|
|
191
1229
|
}
|
192
1230
|
});
|
193
1231
|
}
|
194
|
-
|
1232
|
+
const animationsPromise = Character.loadAnimations(
|
1233
|
+
this.characterModelLoader,
|
1234
|
+
this.config.animationConfig
|
1235
|
+
);
|
195
1236
|
this.characterManager = new CharacterManager({
|
196
1237
|
composer: this.composer,
|
197
1238
|
characterModelLoader: this.characterModelLoader,
|
@@ -205,7 +1246,10 @@ var Networked3dWebExperienceClient = class {
|
|
205
1246
|
this.latestCharacterObject.characterState = characterState;
|
206
1247
|
this.networkClient.sendUpdate(characterState);
|
207
1248
|
},
|
208
|
-
|
1249
|
+
sendLocalCharacterColors: (colors) => {
|
1250
|
+
this.networkClient.updateColors(colors);
|
1251
|
+
},
|
1252
|
+
animationsPromise,
|
209
1253
|
spawnConfiguration: this.spawnConfiguration,
|
210
1254
|
characterResolve: (characterId) => {
|
211
1255
|
return this.resolveCharacterData(characterId);
|
@@ -214,7 +1258,8 @@ var Networked3dWebExperienceClient = class {
|
|
214
1258
|
});
|
215
1259
|
this.scene.add(this.characterManager.group);
|
216
1260
|
if (this.spawnConfiguration.enableRespawnButton) {
|
217
|
-
this.
|
1261
|
+
this.respawnButton = this.createRespawnButton();
|
1262
|
+
this.element.appendChild(this.respawnButton);
|
218
1263
|
}
|
219
1264
|
this.setGroundPlaneEnabled(((_a = this.config.environmentConfiguration) == null ? void 0 : _a.groundPlane) ?? true);
|
220
1265
|
this.setupMMLScene();
|
@@ -224,10 +1269,10 @@ var Networked3dWebExperienceClient = class {
|
|
224
1269
|
const [, completed] = this.loadingProgressManager.toRatio();
|
225
1270
|
if (completed && !this.initialLoadCompleted) {
|
226
1271
|
this.initialLoadCompleted = true;
|
227
|
-
|
1272
|
+
console.log("Initial load completed");
|
228
1273
|
this.connectToTextChat();
|
229
1274
|
this.mountAvatarSelectionUI();
|
230
|
-
this.spawnCharacter();
|
1275
|
+
this.spawnCharacter(spawnData);
|
231
1276
|
}
|
232
1277
|
});
|
233
1278
|
this.loadingProgressManager.setInitialLoad(true);
|
@@ -244,7 +1289,6 @@ var Networked3dWebExperienceClient = class {
|
|
244
1289
|
}
|
245
1290
|
}
|
246
1291
|
updateConfig(config) {
|
247
|
-
var _a;
|
248
1292
|
this.config = {
|
249
1293
|
...this.config,
|
250
1294
|
...config
|
@@ -267,6 +1311,14 @@ var Networked3dWebExperienceClient = class {
|
|
267
1311
|
this.setupTweakPane();
|
268
1312
|
}
|
269
1313
|
}
|
1314
|
+
if (this.config.postProcessingEnabled !== void 0) {
|
1315
|
+
this.composer.togglePostProcessing(this.config.postProcessingEnabled);
|
1316
|
+
if (this.tweakPane) {
|
1317
|
+
this.tweakPane.dispose();
|
1318
|
+
this.tweakPane = null;
|
1319
|
+
this.setupTweakPane();
|
1320
|
+
}
|
1321
|
+
}
|
270
1322
|
if (config.allowOrbitalCamera !== void 0) {
|
271
1323
|
if (config.allowOrbitalCamera === false) {
|
272
1324
|
this.keyInputManager.removeKeyBinding(Key.C);
|
@@ -282,11 +1334,9 @@ var Networked3dWebExperienceClient = class {
|
|
282
1334
|
});
|
283
1335
|
}
|
284
1336
|
}
|
285
|
-
if (config.
|
286
|
-
if (config.
|
287
|
-
this.
|
288
|
-
this.networkChat = null;
|
289
|
-
(_a = this.textChatUI) == null ? void 0 : _a.dispose();
|
1337
|
+
if (config.enableChat) {
|
1338
|
+
if (!config.enableChat && this.textChatUI !== null) {
|
1339
|
+
this.textChatUI.dispose();
|
290
1340
|
this.textChatUI = null;
|
291
1341
|
} else {
|
292
1342
|
this.connectToTextChat();
|
@@ -297,7 +1347,7 @@ var Networked3dWebExperienceClient = class {
|
|
297
1347
|
this.characterManager.localController.updateSpawnConfig(this.spawnConfiguration);
|
298
1348
|
}
|
299
1349
|
if (this.spawnConfiguration.enableRespawnButton && !this.respawnButton) {
|
300
|
-
this.respawnButton = this.
|
1350
|
+
this.respawnButton = this.createRespawnButton();
|
301
1351
|
this.element.appendChild(this.respawnButton);
|
302
1352
|
} else if (!this.spawnConfiguration.enableRespawnButton && this.respawnButton) {
|
303
1353
|
this.respawnButton.remove();
|
@@ -318,6 +1368,16 @@ var Networked3dWebExperienceClient = class {
|
|
318
1368
|
document.body.appendChild(holder);
|
319
1369
|
return holder;
|
320
1370
|
}
|
1371
|
+
createRespawnButton() {
|
1372
|
+
const respawnButton = document.createElement("div");
|
1373
|
+
respawnButton.className = Networked3dWebExperience_default.respawnButton;
|
1374
|
+
respawnButton.textContent = "RESPAWN";
|
1375
|
+
respawnButton.addEventListener("click", () => {
|
1376
|
+
var _a;
|
1377
|
+
(_a = this.characterManager.localController) == null ? void 0 : _a.resetPosition();
|
1378
|
+
});
|
1379
|
+
return respawnButton;
|
1380
|
+
}
|
321
1381
|
resolveCharacterData(clientId) {
|
322
1382
|
const user = this.userProfiles.get(clientId);
|
323
1383
|
if (!user) {
|
@@ -325,41 +1385,43 @@ var Networked3dWebExperienceClient = class {
|
|
325
1385
|
}
|
326
1386
|
return {
|
327
1387
|
username: user.username,
|
328
|
-
characterDescription: user.characterDescription
|
1388
|
+
characterDescription: user.characterDescription,
|
1389
|
+
colors: user.colors
|
329
1390
|
};
|
330
1391
|
}
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
this.
|
1392
|
+
onNetworkUpdate(update) {
|
1393
|
+
const { removedUserIds, addedUserIds, updatedUsers } = update;
|
1394
|
+
for (const clientId of removedUserIds) {
|
1395
|
+
this.userProfiles.delete(clientId);
|
1396
|
+
this.remoteUserStates.delete(clientId);
|
1397
|
+
}
|
1398
|
+
for (const [clientId, userData] of addedUserIds) {
|
1399
|
+
this.userProfiles.set(clientId, userData.userState);
|
1400
|
+
this.remoteUserStates.set(clientId, userData.components);
|
1401
|
+
}
|
1402
|
+
for (const [clientId, userDataUpdate] of updatedUsers) {
|
1403
|
+
const userState = userDataUpdate.userState;
|
1404
|
+
if (userState) {
|
1405
|
+
if (userState.username !== void 0) {
|
1406
|
+
this.userProfiles.get(clientId).username = userState.username;
|
1407
|
+
}
|
1408
|
+
if (userState.characterDescription !== void 0) {
|
1409
|
+
this.userProfiles.get(clientId).characterDescription = userState.characterDescription;
|
1410
|
+
}
|
1411
|
+
if (userState.colors !== void 0) {
|
1412
|
+
this.userProfiles.get(clientId).colors = userState.colors;
|
1413
|
+
}
|
1414
|
+
this.characterManager.networkCharacterInfoUpdated(clientId);
|
1415
|
+
}
|
1416
|
+
this.remoteUserStates.set(clientId, userDataUpdate.components);
|
336
1417
|
}
|
337
|
-
this.characterManager.respawnIfPresent(id);
|
338
1418
|
}
|
339
1419
|
sendIdentityUpdateToServer(displayName, characterDescription) {
|
340
1420
|
if (!this.clientId) {
|
341
1421
|
throw new Error("Client ID not set");
|
342
1422
|
}
|
343
|
-
this.networkClient.
|
344
|
-
|
345
|
-
userIdentity: {
|
346
|
-
username: displayName,
|
347
|
-
characterDescription
|
348
|
-
}
|
349
|
-
});
|
350
|
-
}
|
351
|
-
connectToVoiceChat() {
|
352
|
-
if (this.clientId === null) return;
|
353
|
-
if (this.voiceChatManager === null && this.config.voiceChatAddress) {
|
354
|
-
this.voiceChatManager = new VoiceChatManager({
|
355
|
-
url: this.config.voiceChatAddress,
|
356
|
-
holderElement: this.element,
|
357
|
-
userId: this.clientId,
|
358
|
-
remoteUserStates: this.remoteUserStates,
|
359
|
-
latestCharacterObj: this.latestCharacterObject,
|
360
|
-
autoJoin: false
|
361
|
-
});
|
362
|
-
}
|
1423
|
+
this.networkClient.updateUsername(displayName);
|
1424
|
+
this.networkClient.updateCharacterDescription(characterDescription);
|
363
1425
|
}
|
364
1426
|
setupTweakPane() {
|
365
1427
|
if (this.tweakPane) {
|
@@ -369,57 +1431,53 @@ var Networked3dWebExperienceClient = class {
|
|
369
1431
|
this.element,
|
370
1432
|
this.composer.renderer,
|
371
1433
|
this.scene,
|
372
|
-
this.composer
|
1434
|
+
this.composer,
|
1435
|
+
this.config.postProcessingEnabled
|
373
1436
|
);
|
374
1437
|
this.cameraManager.setupTweakPane(this.tweakPane);
|
375
1438
|
this.composer.setupTweakPane(this.tweakPane);
|
376
1439
|
}
|
1440
|
+
handleChatMessage(fromUserId, message) {
|
1441
|
+
if (this.textChatUI === null) {
|
1442
|
+
return;
|
1443
|
+
}
|
1444
|
+
if (fromUserId === 0) {
|
1445
|
+
this.textChatUI.addTextMessage("System", message);
|
1446
|
+
} else {
|
1447
|
+
const user = this.userProfiles.get(fromUserId);
|
1448
|
+
if (!user) {
|
1449
|
+
console.error(`User not found for clientId ${fromUserId}`);
|
1450
|
+
return;
|
1451
|
+
}
|
1452
|
+
const username = user.username ?? `Unknown User ${fromUserId}`;
|
1453
|
+
this.textChatUI.addTextMessage(username, message);
|
1454
|
+
this.characterManager.addChatBubble(fromUserId, message);
|
1455
|
+
}
|
1456
|
+
}
|
377
1457
|
connectToTextChat() {
|
378
1458
|
if (this.clientId === null) {
|
379
1459
|
return;
|
380
1460
|
}
|
381
|
-
if (this.
|
1461
|
+
if (this.config.enableChat && this.textChatUI === null) {
|
382
1462
|
const user = this.userProfiles.get(this.clientId);
|
383
1463
|
if (!user) {
|
384
1464
|
throw new Error("User not found");
|
385
1465
|
}
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
},
|
396
|
-
visibleByDefault: this.config.chatVisibleByDefault,
|
397
|
-
stringToHslOptions: this.config.userNameToColorOptions
|
398
|
-
};
|
399
|
-
this.textChatUI = new TextChatUI(textChatUISettings);
|
400
|
-
this.textChatUI.init();
|
401
|
-
}
|
402
|
-
this.networkChat = new ChatNetworkingClient({
|
403
|
-
url: this.config.chatNetworkAddress,
|
404
|
-
sessionToken: this.config.sessionToken,
|
405
|
-
websocketFactory: (url) => new WebSocket(url),
|
406
|
-
statusUpdateCallback: (status) => {
|
407
|
-
if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {
|
408
|
-
}
|
1466
|
+
const textChatUISettings = {
|
1467
|
+
holderElement: this.canvasHolder,
|
1468
|
+
sendMessageToServerMethod: (message) => {
|
1469
|
+
this.characterManager.addSelfChatBubble(message);
|
1470
|
+
this.mmlCompositionScene.onChatMessage(message);
|
1471
|
+
this.networkClient.sendCustomMessage(
|
1472
|
+
FROM_CLIENT_CHAT_MESSAGE_TYPE,
|
1473
|
+
JSON.stringify({ message })
|
1474
|
+
);
|
409
1475
|
},
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
this.characterManager.addChatBubble(clientId, chatNetworkingUpdate.text);
|
416
|
-
}
|
417
|
-
},
|
418
|
-
onServerError: (error) => {
|
419
|
-
console.error(`Chat server error: ${error.message}. errorType: ${error.errorType}`);
|
420
|
-
this.disposeWithError(error.message);
|
421
|
-
}
|
422
|
-
});
|
1476
|
+
visibleByDefault: this.config.chatVisibleByDefault,
|
1477
|
+
stringToHslOptions: this.config.userNameToColorOptions
|
1478
|
+
};
|
1479
|
+
this.textChatUI = new TextChatUI(textChatUISettings);
|
1480
|
+
this.textChatUI.init();
|
423
1481
|
}
|
424
1482
|
}
|
425
1483
|
mountAvatarSelectionUI() {
|
@@ -434,8 +1492,10 @@ var Networked3dWebExperienceClient = class {
|
|
434
1492
|
this.avatarSelectionUI = new AvatarSelectionUI({
|
435
1493
|
holderElement: this.element,
|
436
1494
|
visibleByDefault: false,
|
437
|
-
displayName: ownIdentity.username
|
438
|
-
characterDescription: ownIdentity.characterDescription
|
1495
|
+
displayName: ownIdentity.username ?? `Unknown User ${this.clientId}`,
|
1496
|
+
characterDescription: ownIdentity.characterDescription ?? {
|
1497
|
+
meshFileUrl: ""
|
1498
|
+
},
|
439
1499
|
sendIdentityUpdateToServer: this.sendIdentityUpdateToServer.bind(this),
|
440
1500
|
availableAvatars: ((_a = this.config.avatarConfiguration) == null ? void 0 : _a.availableAvatars) ?? [],
|
441
1501
|
allowCustomAvatars: (_b = this.config.avatarConfiguration) == null ? void 0 : _b.allowCustomAvatars,
|
@@ -444,16 +1504,16 @@ var Networked3dWebExperienceClient = class {
|
|
444
1504
|
this.avatarSelectionUI.init();
|
445
1505
|
}
|
446
1506
|
update() {
|
447
|
-
var _a, _b, _c
|
1507
|
+
var _a, _b, _c;
|
448
1508
|
this.timeManager.update();
|
449
1509
|
this.characterManager.update();
|
450
|
-
(_a = this.voiceChatManager) == null ? void 0 : _a.speakingParticipants.forEach((value, id) => {
|
451
|
-
this.characterManager.setSpeakingCharacter(id, value);
|
452
|
-
});
|
453
1510
|
this.cameraManager.update();
|
454
|
-
|
1511
|
+
const characterPosition = (_a = this.characterManager.localCharacter) == null ? void 0 : _a.getPosition();
|
1512
|
+
(_b = this.composer.sun) == null ? void 0 : _b.updateCharacterPosition(
|
1513
|
+
new Vector3((characterPosition == null ? void 0 : characterPosition.x) || 0, (characterPosition == null ? void 0 : characterPosition.y) || 0, (characterPosition == null ? void 0 : characterPosition.z) || 0)
|
1514
|
+
);
|
455
1515
|
this.composer.render(this.timeManager);
|
456
|
-
if ((
|
1516
|
+
if ((_c = this.tweakPane) == null ? void 0 : _c.guiVisible) {
|
457
1517
|
this.tweakPane.updateStats(this.timeManager);
|
458
1518
|
this.tweakPane.updateCameraData(this.cameraManager);
|
459
1519
|
if (this.characterManager.localCharacter && this.characterManager.localController) {
|
@@ -469,60 +1529,29 @@ var Networked3dWebExperienceClient = class {
|
|
469
1529
|
this.update();
|
470
1530
|
});
|
471
1531
|
}
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
}
|
477
|
-
spawnCharacter() {
|
1532
|
+
spawnCharacter({
|
1533
|
+
spawnPosition,
|
1534
|
+
spawnRotation,
|
1535
|
+
cameraPosition
|
1536
|
+
}) {
|
478
1537
|
if (this.clientId === null) {
|
479
1538
|
throw new Error("Client ID not set");
|
480
1539
|
}
|
481
|
-
const spawnPosition = new Vector3();
|
482
|
-
spawnPosition.set(
|
483
|
-
this.randomWithVariance(
|
484
|
-
this.spawnConfiguration.spawnPosition.x,
|
485
|
-
this.spawnConfiguration.spawnPositionVariance.x
|
486
|
-
),
|
487
|
-
this.randomWithVariance(
|
488
|
-
this.spawnConfiguration.spawnPosition.y,
|
489
|
-
this.spawnConfiguration.spawnPositionVariance.y
|
490
|
-
),
|
491
|
-
this.randomWithVariance(
|
492
|
-
this.spawnConfiguration.spawnPosition.z,
|
493
|
-
this.spawnConfiguration.spawnPositionVariance.z
|
494
|
-
)
|
495
|
-
);
|
496
|
-
const spawnRotation = new Euler(
|
497
|
-
0,
|
498
|
-
-this.spawnConfiguration.spawnYRotation * (Math.PI / 180),
|
499
|
-
0
|
500
|
-
);
|
501
|
-
let cameraPosition = null;
|
502
|
-
const offset = new Vector3(0, 0, 3.3);
|
503
|
-
offset.applyEuler(new Euler(0, spawnRotation.y, 0));
|
504
|
-
cameraPosition = spawnPosition.clone().sub(offset).add(this.characterManager.headTargetOffset);
|
505
|
-
if (window.location.hash && window.location.hash.length > 1) {
|
506
|
-
const urlParams = decodeCharacterAndCamera(window.location.hash.substring(1));
|
507
|
-
spawnPosition.copy(urlParams.character.position);
|
508
|
-
spawnRotation.setFromQuaternion(urlParams.character.quaternion);
|
509
|
-
cameraPosition = urlParams.camera.position;
|
510
|
-
}
|
511
1540
|
const ownIdentity = this.userProfiles.get(this.clientId);
|
512
1541
|
if (!ownIdentity) {
|
513
1542
|
throw new Error("Own identity not found");
|
514
1543
|
}
|
515
1544
|
this.characterManager.spawnLocalCharacter(
|
516
1545
|
this.clientId,
|
517
|
-
ownIdentity.username
|
1546
|
+
ownIdentity.username ?? `Unknown User ${this.clientId}`,
|
518
1547
|
ownIdentity.characterDescription,
|
519
1548
|
spawnPosition,
|
520
1549
|
spawnRotation
|
521
1550
|
);
|
522
1551
|
if (cameraPosition !== null) {
|
523
|
-
this.cameraManager.camera.position.
|
1552
|
+
this.cameraManager.camera.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
524
1553
|
this.cameraManager.setTarget(
|
525
|
-
new
|
1554
|
+
new Vect3().add(spawnPosition).add(CharacterManager.headTargetOffset)
|
526
1555
|
);
|
527
1556
|
this.cameraManager.reverseUpdateFromPositions();
|
528
1557
|
}
|
@@ -533,24 +1562,24 @@ var Networked3dWebExperienceClient = class {
|
|
533
1562
|
this.element.append(this.errorScreen.element);
|
534
1563
|
}
|
535
1564
|
dispose() {
|
536
|
-
var _a, _b, _c
|
1565
|
+
var _a, _b, _c;
|
1566
|
+
this.characterManager.dispose();
|
537
1567
|
this.networkClient.stop();
|
538
|
-
(_a = this.networkChat) == null ? void 0 : _a.stop();
|
539
1568
|
for (const [key, element] of Object.entries(this.mmlFrames)) {
|
540
1569
|
element.remove();
|
541
1570
|
}
|
542
1571
|
this.mmlFrames = {};
|
543
|
-
(
|
1572
|
+
(_a = this.textChatUI) == null ? void 0 : _a.dispose();
|
544
1573
|
this.mmlCompositionScene.dispose();
|
545
1574
|
this.composer.dispose();
|
546
|
-
(
|
1575
|
+
(_b = this.tweakPane) == null ? void 0 : _b.dispose();
|
547
1576
|
if (this.currentRequestAnimationFrame !== null) {
|
548
1577
|
cancelAnimationFrame(this.currentRequestAnimationFrame);
|
549
1578
|
this.currentRequestAnimationFrame = null;
|
550
1579
|
}
|
551
1580
|
this.cameraManager.dispose();
|
552
1581
|
this.loadingScreen.dispose();
|
553
|
-
(
|
1582
|
+
(_c = this.errorScreen) == null ? void 0 : _c.dispose();
|
554
1583
|
}
|
555
1584
|
setupMMLScene() {
|
556
1585
|
registerCustomElementsToWindow(window);
|