@abraca/nuxt 2.0.0 → 2.0.3
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/dist/module.d.mts +18 -7
- package/dist/module.json +1 -1
- package/dist/module.mjs +21 -5
- package/dist/runtime/assets/aware-tokens.css +1 -0
- package/dist/runtime/components/AAccountSwitcherModal.d.vue.ts +16 -1
- package/dist/runtime/components/AAccountSwitcherModal.vue +33 -4
- package/dist/runtime/components/AAccountSwitcherModal.vue.d.ts +16 -1
- package/dist/runtime/components/AAuthLinkLanding.d.vue.ts +3 -0
- package/dist/runtime/components/AAuthLinkLanding.vue +85 -0
- package/dist/runtime/components/AAuthLinkLanding.vue.d.ts +3 -0
- package/dist/runtime/components/AClaimAccountModal.d.vue.ts +7 -1
- package/dist/runtime/components/AClaimAccountModal.vue +28 -13
- package/dist/runtime/components/AClaimAccountModal.vue.d.ts +7 -1
- package/dist/runtime/components/AEditor.vue +5 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.d.vue.ts +30 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue +100 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue.d.ts +30 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.d.vue.ts +22 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue +65 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue.d.ts +22 -0
- package/dist/runtime/components/AMnemonicLoginModal.d.vue.ts +1 -1
- package/dist/runtime/components/AMnemonicLoginModal.vue.d.ts +1 -1
- package/dist/runtime/components/ANodePanel.vue +2 -0
- package/dist/runtime/components/ANotificationBell.d.vue.ts +2 -2
- package/dist/runtime/components/ANotificationBell.vue.d.ts +2 -2
- package/dist/runtime/components/APasswordChangeModal.d.vue.ts +28 -0
- package/dist/runtime/components/APasswordChangeModal.vue +178 -0
- package/dist/runtime/components/APasswordChangeModal.vue.d.ts +28 -0
- package/dist/runtime/components/APasswordLoginModal.d.vue.ts +42 -0
- package/dist/runtime/components/APasswordLoginModal.vue +177 -0
- package/dist/runtime/components/APasswordLoginModal.vue.d.ts +42 -0
- package/dist/runtime/components/APasswordRegisterModal.d.vue.ts +49 -0
- package/dist/runtime/components/APasswordRegisterModal.vue +262 -0
- package/dist/runtime/components/APasswordRegisterModal.vue.d.ts +49 -0
- package/dist/runtime/components/APasswordResetConfirmModal.d.vue.ts +31 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue +154 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue.d.ts +31 -0
- package/dist/runtime/components/APasswordResetRequestModal.d.vue.ts +35 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue +113 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue.d.ts +35 -0
- package/dist/runtime/components/ASetPasswordCard.d.vue.ts +26 -0
- package/dist/runtime/components/ASetPasswordCard.vue +139 -0
- package/dist/runtime/components/ASetPasswordCard.vue.d.ts +26 -0
- package/dist/runtime/components/ASubPageList.d.vue.ts +66 -0
- package/dist/runtime/components/ASubPageList.vue +147 -0
- package/dist/runtime/components/ASubPageList.vue.d.ts +66 -0
- package/dist/runtime/components/aware/AAccordion.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AAccordion.vue +11 -1
- package/dist/runtime/components/aware/AAccordion.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AButton.vue +3 -3
- package/dist/runtime/components/aware/ACollapsible.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ACollapsible.vue +9 -1
- package/dist/runtime/components/aware/ACollapsible.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AGlobalFocusLayer.vue +1 -1
- package/dist/runtime/components/aware/AHoverItem.vue +28 -3
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/aware/AModal.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AModal.vue +9 -1
- package/dist/runtime/components/aware/AModal.vue.d.ts +2 -0
- package/dist/runtime/components/aware/APresenceBlobs.vue +1 -1
- package/dist/runtime/components/aware/APresenceCursors.vue +1 -1
- package/dist/runtime/components/aware/AScroll.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AScroll.vue +13 -3
- package/dist/runtime/components/aware/AScroll.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.vue +9 -1
- package/dist/runtime/components/aware/ASlideover.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlider.vue +1 -0
- package/dist/runtime/components/aware/ATabs.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ATabs.vue +9 -1
- package/dist/runtime/components/aware/ATabs.vue.d.ts +2 -0
- package/dist/runtime/components/chat/ANodeChatPanel.vue +1 -0
- package/dist/runtime/components/editor/AEditorRedoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorRedoButton.vue.d.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.d.vue.ts +4 -4
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.vue.d.ts +4 -4
- package/dist/runtime/components/renderers/media/MediaTransportBar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.vue.d.ts +2 -2
- package/dist/runtime/components/shell/AUserProfilePopover.d.vue.ts +1 -1
- package/dist/runtime/components/shell/AUserProfilePopover.vue.d.ts +1 -1
- package/dist/runtime/composables/useAAField.js +7 -4
- package/dist/runtime/composables/useAAFocus.js +10 -5
- package/dist/runtime/composables/useAAFollowAnchor.js +68 -34
- package/dist/runtime/composables/useAAFollowPeer.d.ts +7 -4
- package/dist/runtime/composables/useAAFollowPeer.js +60 -11
- package/dist/runtime/composables/useAAViewport.d.ts +1 -1
- package/dist/runtime/composables/useAbracadabraAuth.d.ts +2 -0
- package/dist/runtime/composables/useAbracadabraAuth.js +2 -0
- package/dist/runtime/composables/useEditorSuggestions.js +2 -1
- package/dist/runtime/composables/useEmailVerification.d.ts +40 -26
- package/dist/runtime/composables/useEmailVerification.js +95 -43
- package/dist/runtime/composables/usePasswordAuth.d.ts +64 -0
- package/dist/runtime/composables/usePasswordAuth.js +126 -0
- package/dist/runtime/composables/useTiptapHistory.d.ts +2 -2
- package/dist/runtime/composables/useTiptapHistory.js +5 -5
- package/dist/runtime/extensions/svg-embed.d.ts +23 -0
- package/dist/runtime/extensions/svg-embed.js +33 -0
- package/dist/runtime/extensions/views/MetaFieldView.vue +23 -6
- package/dist/runtime/extensions/views/SvgEmbedView.d.vue.ts +4 -0
- package/dist/runtime/extensions/views/SvgEmbedView.vue +120 -0
- package/dist/runtime/extensions/views/SvgEmbedView.vue.d.ts +4 -0
- package/dist/runtime/plugin-abracadabra.client.js +58 -9
- package/dist/runtime/plugin-abracadabra.server.js +2 -0
- package/dist/runtime/plugins/core.plugin.js +8 -4
- package/dist/runtime/server/plugins/abracadabra-service.js +102 -13
- package/dist/runtime/types.d.ts +11 -0
- package/dist/runtime/utils/awareRingStyle.js +1 -1
- package/dist/runtime/utils/sanitizeSvg.d.ts +19 -0
- package/dist/runtime/utils/sanitizeSvg.js +87 -0
- package/package.json +7 -8
- package/dist/runtime/components/renderers/ASpatialRenderer.d.vue.ts +0 -19
- package/dist/runtime/components/renderers/ASpatialRenderer.vue +0 -459
- package/dist/runtime/components/renderers/ASpatialRenderer.vue.d.ts +0 -19
- package/dist/runtime/components/renderers/spatial/SpatialGround.d.vue.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue +0 -26
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue.d.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialObject.d.vue.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue +0 -257
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue.d.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.d.vue.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue +0 -18
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue.d.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.d.vue.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue +0 -66
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue.d.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.d.vue.ts +0 -8
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue +0 -53
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue.d.ts +0 -8
- package/dist/runtime/composables/useSpatialCamera.d.ts +0 -16
- package/dist/runtime/composables/useSpatialCamera.js +0 -175
- package/dist/runtime/composables/useSpatialDrag.d.ts +0 -14
- package/dist/runtime/composables/useSpatialDrag.js +0 -137
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
|
|
3
|
-
import { useRuntimeConfig } from "#imports";
|
|
4
|
-
import { useRendererBase } from "../../composables/useRendererBase";
|
|
5
|
-
import { useNodePanel } from "../../composables/useNodePanel";
|
|
6
|
-
import { useSpatialCamera } from "../../composables/useSpatialCamera";
|
|
7
|
-
import { useSpatialDrag } from "../../composables/useSpatialDrag";
|
|
8
|
-
import SpatialTransformInputs from "./spatial/SpatialTransformInputs.vue";
|
|
9
|
-
const props = defineProps({
|
|
10
|
-
docId: { type: String, required: true },
|
|
11
|
-
childProvider: { type: null, required: true },
|
|
12
|
-
docLabel: { type: String, required: true },
|
|
13
|
-
pageTypes: { type: Array, required: false },
|
|
14
|
-
labels: { type: Object, required: false },
|
|
15
|
-
editable: { type: Boolean, required: false, default: true }
|
|
16
|
-
});
|
|
17
|
-
const config = useRuntimeConfig();
|
|
18
|
-
const _locale = config.public;
|
|
19
|
-
const { tree, childProviderRef, states, setLocalState, connectedUsers } = useRendererBase(props);
|
|
20
|
-
const {
|
|
21
|
-
openNodeId,
|
|
22
|
-
openNodeLabel,
|
|
23
|
-
openNodeProvider,
|
|
24
|
-
openNode,
|
|
25
|
-
closePanel
|
|
26
|
-
} = useNodePanel(childProviderRef);
|
|
27
|
-
const gridVisible = ref(true);
|
|
28
|
-
function toggleGrid() {
|
|
29
|
-
gridVisible.value = !gridVisible.value;
|
|
30
|
-
}
|
|
31
|
-
const {
|
|
32
|
-
cameraRef,
|
|
33
|
-
cameraPosition,
|
|
34
|
-
cameraTarget,
|
|
35
|
-
controlMode,
|
|
36
|
-
focusOn,
|
|
37
|
-
onCanvasPointerDown: camPointerDown,
|
|
38
|
-
onCanvasPointerMove: camPointerMove,
|
|
39
|
-
onCanvasPointerUp: camPointerUp,
|
|
40
|
-
onCanvasWheel
|
|
41
|
-
} = useSpatialCamera(setLocalState);
|
|
42
|
-
const selectedIds = ref(/* @__PURE__ */ new Set());
|
|
43
|
-
const selectedEntry = computed(() => {
|
|
44
|
-
if (selectedIds.value.size !== 1) return null;
|
|
45
|
-
const id = [...selectedIds.value][0];
|
|
46
|
-
return tree.entries.value.find((e) => e.id === id) ?? null;
|
|
47
|
-
});
|
|
48
|
-
watch(selectedIds, (ids) => {
|
|
49
|
-
setLocalState({ spatial: { selectedIds: [...ids] } });
|
|
50
|
-
}, { deep: true });
|
|
51
|
-
const sceneSettings = { data: {} };
|
|
52
|
-
const {
|
|
53
|
-
draggingId,
|
|
54
|
-
bindScene,
|
|
55
|
-
onPointerDown: dragPointerDown,
|
|
56
|
-
onPointerMove: dragPointerMove,
|
|
57
|
-
onPointerUp: dragPointerUp
|
|
58
|
-
} = useSpatialDrag(tree, selectedIds, cameraRef, setLocalState, sceneSettings);
|
|
59
|
-
const topLevelEntries = computed(() => tree.childrenOf(null));
|
|
60
|
-
const myClientId = computed(() => props.childProvider?.awareness?.clientID ?? 0);
|
|
61
|
-
const remoteUsers3D = computed(
|
|
62
|
-
() => states.value.filter((s) => s.clientId !== myClientId.value && s.spatial?.camera).map((s) => ({
|
|
63
|
-
clientId: s.clientId,
|
|
64
|
-
name: s.user?.name ?? "?",
|
|
65
|
-
color: s.user?.color ?? "#888",
|
|
66
|
-
position: s.spatial.camera.position,
|
|
67
|
-
selectedIds: s.spatial?.selectedIds ?? []
|
|
68
|
-
}))
|
|
69
|
-
);
|
|
70
|
-
const remoteSelectionMap = computed(() => {
|
|
71
|
-
const map = /* @__PURE__ */ new Map();
|
|
72
|
-
for (const u of remoteUsers3D.value) {
|
|
73
|
-
for (const id of u.selectedIds) {
|
|
74
|
-
if (!map.has(id)) map.set(id, []);
|
|
75
|
-
map.get(id).push({ color: u.color, name: u.name });
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return map;
|
|
79
|
-
});
|
|
80
|
-
const shapes = ["box", "sphere", "cylinder", "cone", "plane", "torus"];
|
|
81
|
-
const shapeIcons = {
|
|
82
|
-
box: "i-lucide-box",
|
|
83
|
-
sphere: "i-lucide-circle",
|
|
84
|
-
cylinder: "i-lucide-cylinder",
|
|
85
|
-
cone: "i-lucide-triangle",
|
|
86
|
-
plane: "i-lucide-square",
|
|
87
|
-
torus: "i-lucide-donut",
|
|
88
|
-
glb: "i-lucide-package"
|
|
89
|
-
};
|
|
90
|
-
function addObject(shape = "box") {
|
|
91
|
-
if (!props.editable) return;
|
|
92
|
-
const label = shape.charAt(0).toUpperCase() + shape.slice(1);
|
|
93
|
-
const offset = topLevelEntries.value.length * 1.5;
|
|
94
|
-
const id = tree.createChild(null, label);
|
|
95
|
-
tree.updateMeta(id, {
|
|
96
|
-
spShape: shape,
|
|
97
|
-
spX: offset,
|
|
98
|
-
spY: shape === "plane" ? 0 : 0.5,
|
|
99
|
-
spZ: 0,
|
|
100
|
-
spSX: 1,
|
|
101
|
-
spSY: 1,
|
|
102
|
-
spSZ: 1,
|
|
103
|
-
color: "#6366f1"
|
|
104
|
-
});
|
|
105
|
-
selectedIds.value = /* @__PURE__ */ new Set([id]);
|
|
106
|
-
}
|
|
107
|
-
function deleteSelected() {
|
|
108
|
-
if (!props.editable) return;
|
|
109
|
-
for (const id of selectedIds.value) tree.deleteEntry(id);
|
|
110
|
-
selectedIds.value = /* @__PURE__ */ new Set();
|
|
111
|
-
}
|
|
112
|
-
function duplicateSelected() {
|
|
113
|
-
if (!props.editable || !selectedEntry.value) return;
|
|
114
|
-
const newId = tree.duplicateEntry(selectedEntry.value.id);
|
|
115
|
-
const entry = tree.entries.value.find((e) => e.id === newId);
|
|
116
|
-
if (entry) tree.updateMeta(newId, { spX: (entry.meta?.spX ?? 0) + 1.5 });
|
|
117
|
-
selectedIds.value = /* @__PURE__ */ new Set([newId]);
|
|
118
|
-
}
|
|
119
|
-
const shapeMenuItems = computed(() => [
|
|
120
|
-
shapes.map((s) => ({
|
|
121
|
-
label: s.charAt(0).toUpperCase() + s.slice(1),
|
|
122
|
-
icon: shapeIcons[s] ?? "i-lucide-box",
|
|
123
|
-
onSelect: () => addObject(s)
|
|
124
|
-
}))
|
|
125
|
-
]);
|
|
126
|
-
function shapeIcon(shape) {
|
|
127
|
-
return shapeIcons[shape ?? "box"] ?? "i-lucide-box";
|
|
128
|
-
}
|
|
129
|
-
const contextMenuItems = computed(() => {
|
|
130
|
-
const items = [];
|
|
131
|
-
if (selectedEntry.value) {
|
|
132
|
-
items.push([
|
|
133
|
-
{ label: "Open", icon: "i-lucide-external-link", onSelect: () => openNode(selectedEntry.value.id, selectedEntry.value.label) },
|
|
134
|
-
{ label: "Duplicate", icon: "i-lucide-copy", onSelect: duplicateSelected }
|
|
135
|
-
]);
|
|
136
|
-
}
|
|
137
|
-
if (selectedIds.value.size > 0) {
|
|
138
|
-
items.push([{ label: "Delete", icon: "i-lucide-trash-2", color: "error", onSelect: deleteSelected }]);
|
|
139
|
-
}
|
|
140
|
-
items.push(shapes.map((s) => ({
|
|
141
|
-
label: `Add ${s.charAt(0).toUpperCase() + s.slice(1)}`,
|
|
142
|
-
icon: "i-lucide-plus",
|
|
143
|
-
onSelect: () => addObject(s)
|
|
144
|
-
})));
|
|
145
|
-
return items;
|
|
146
|
-
});
|
|
147
|
-
let pointerDownHitId = null;
|
|
148
|
-
let pointerDownTime = 0;
|
|
149
|
-
let isPointerActive = false;
|
|
150
|
-
function onCanvasPointerDown(ev) {
|
|
151
|
-
isPointerActive = true;
|
|
152
|
-
if (ev.button !== 0) {
|
|
153
|
-
camPointerDown(ev);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
pointerDownTime = performance.now();
|
|
157
|
-
pointerDownHitId = dragPointerDown(ev);
|
|
158
|
-
if (pointerDownHitId && !props.editable) {
|
|
159
|
-
pointerDownHitId = null;
|
|
160
|
-
camPointerDown(ev);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
if (pointerDownHitId) {
|
|
164
|
-
if (ev.shiftKey) {
|
|
165
|
-
const next = new Set(selectedIds.value);
|
|
166
|
-
if (next.has(pointerDownHitId)) next.delete(pointerDownHitId);
|
|
167
|
-
else next.add(pointerDownHitId);
|
|
168
|
-
selectedIds.value = next;
|
|
169
|
-
} else if (!selectedIds.value.has(pointerDownHitId)) {
|
|
170
|
-
selectedIds.value = /* @__PURE__ */ new Set([pointerDownHitId]);
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
camPointerDown(ev);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function onWindowPointerMove(ev) {
|
|
177
|
-
if (!isPointerActive) return;
|
|
178
|
-
if (draggingId.value) dragPointerMove(ev);
|
|
179
|
-
else camPointerMove(ev);
|
|
180
|
-
}
|
|
181
|
-
function onWindowPointerUp(ev) {
|
|
182
|
-
if (!isPointerActive) return;
|
|
183
|
-
isPointerActive = false;
|
|
184
|
-
if (draggingId.value) {
|
|
185
|
-
dragPointerUp(ev);
|
|
186
|
-
} else {
|
|
187
|
-
camPointerUp();
|
|
188
|
-
const elapsed = performance.now() - pointerDownTime;
|
|
189
|
-
if (!pointerDownHitId && ev.button === 0 && !ev.shiftKey && elapsed < 300) {
|
|
190
|
-
selectedIds.value = /* @__PURE__ */ new Set();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
pointerDownHitId = null;
|
|
194
|
-
}
|
|
195
|
-
function onCanvasDblClick(ev) {
|
|
196
|
-
const hitId = dragPointerDown(ev);
|
|
197
|
-
dragPointerUp(ev);
|
|
198
|
-
if (hitId) {
|
|
199
|
-
const entry = tree.entries.value.find((e) => e.id === hitId);
|
|
200
|
-
if (entry) {
|
|
201
|
-
focusOn([entry.meta?.spX ?? 0, entry.meta?.spY ?? 0, entry.meta?.spZ ?? 0]);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
function onKeyDown(ev) {
|
|
206
|
-
if (ev.target?.tagName === "INPUT") return;
|
|
207
|
-
if ((ev.key === "Delete" || ev.key === "Backspace") && props.editable && selectedIds.value.size > 0) {
|
|
208
|
-
ev.preventDefault();
|
|
209
|
-
deleteSelected();
|
|
210
|
-
}
|
|
211
|
-
if (ev.key === "d" && (ev.metaKey || ev.ctrlKey) && props.editable && selectedEntry.value) {
|
|
212
|
-
ev.preventDefault();
|
|
213
|
-
duplicateSelected();
|
|
214
|
-
}
|
|
215
|
-
if (ev.key === "Escape") selectedIds.value = /* @__PURE__ */ new Set();
|
|
216
|
-
}
|
|
217
|
-
onMounted(() => {
|
|
218
|
-
window.addEventListener("keydown", onKeyDown);
|
|
219
|
-
window.addEventListener("pointermove", onWindowPointerMove);
|
|
220
|
-
window.addEventListener("pointerup", onWindowPointerUp);
|
|
221
|
-
});
|
|
222
|
-
onBeforeUnmount(() => {
|
|
223
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
224
|
-
window.removeEventListener("pointermove", onWindowPointerMove);
|
|
225
|
-
window.removeEventListener("pointerup", onWindowPointerUp);
|
|
226
|
-
});
|
|
227
|
-
const isDark = computed(() => typeof document !== "undefined" && document.documentElement.classList.contains("dark"));
|
|
228
|
-
const clearColor = computed(() => isDark.value ? "#111118" : "#f0f0f4");
|
|
229
|
-
const gridColor1 = computed(() => isDark.value ? "#555" : "#ccc");
|
|
230
|
-
const gridColor2 = computed(() => isDark.value ? "#333" : "#ddd");
|
|
231
|
-
const groundColor = computed(() => isDark.value ? "#111118" : "#f0f0f4");
|
|
232
|
-
function onSceneReady({ scene: s, camera: c, canvas: cvs }) {
|
|
233
|
-
if (cvs && s && c) bindScene(cvs, s, c);
|
|
234
|
-
}
|
|
235
|
-
defineExpose({ connectedUsers });
|
|
236
|
-
</script>
|
|
237
|
-
|
|
238
|
-
<template>
|
|
239
|
-
<div class="spatial-container">
|
|
240
|
-
<ClientOnly>
|
|
241
|
-
<UContextMenu
|
|
242
|
-
:items="editable ? contextMenuItems : []"
|
|
243
|
-
class="absolute inset-0"
|
|
244
|
-
>
|
|
245
|
-
<div
|
|
246
|
-
class="spatial-canvas-wrap"
|
|
247
|
-
data-swipe-ignore
|
|
248
|
-
@pointerdown="onCanvasPointerDown"
|
|
249
|
-
@wheel.prevent="onCanvasWheel"
|
|
250
|
-
@dblclick="onCanvasDblClick"
|
|
251
|
-
>
|
|
252
|
-
<TresCanvas
|
|
253
|
-
shadows
|
|
254
|
-
:clear-color="clearColor"
|
|
255
|
-
>
|
|
256
|
-
<SpatialSceneBridge @ready="onSceneReady" />
|
|
257
|
-
<TresPerspectiveCamera
|
|
258
|
-
ref="cameraRef"
|
|
259
|
-
:position="cameraPosition"
|
|
260
|
-
:look-at="cameraTarget"
|
|
261
|
-
:fov="60"
|
|
262
|
-
:near="0.1"
|
|
263
|
-
:far="1e3"
|
|
264
|
-
/>
|
|
265
|
-
|
|
266
|
-
<TresAmbientLight :intensity="isDark ? 0.5 : 0.8" />
|
|
267
|
-
<TresDirectionalLight
|
|
268
|
-
:position="[15, 25, 15]"
|
|
269
|
-
:intensity="isDark ? 1.2 : 1"
|
|
270
|
-
cast-shadow
|
|
271
|
-
/>
|
|
272
|
-
<TresDirectionalLight
|
|
273
|
-
:position="[-10, 10, -10]"
|
|
274
|
-
:intensity="isDark ? 0.3 : 0.5"
|
|
275
|
-
/>
|
|
276
|
-
|
|
277
|
-
<SpatialGround
|
|
278
|
-
v-if="gridVisible"
|
|
279
|
-
:color1="gridColor1"
|
|
280
|
-
:color2="gridColor2"
|
|
281
|
-
:ground-color="groundColor"
|
|
282
|
-
/>
|
|
283
|
-
|
|
284
|
-
<SpatialObject
|
|
285
|
-
v-for="entry in topLevelEntries"
|
|
286
|
-
:key="entry.id"
|
|
287
|
-
:entry="entry"
|
|
288
|
-
:tree="tree"
|
|
289
|
-
:selected-ids="selectedIds"
|
|
290
|
-
:remote-selections="remoteSelectionMap"
|
|
291
|
-
:dragging-id="draggingId"
|
|
292
|
-
/>
|
|
293
|
-
|
|
294
|
-
<SpatialUserAvatar
|
|
295
|
-
v-for="u in remoteUsers3D"
|
|
296
|
-
:key="u.clientId"
|
|
297
|
-
:position="u.position"
|
|
298
|
-
:color="u.color"
|
|
299
|
-
:name="u.name"
|
|
300
|
-
/>
|
|
301
|
-
</TresCanvas>
|
|
302
|
-
</div>
|
|
303
|
-
|
|
304
|
-
<!-- Toolbar -->
|
|
305
|
-
<div class="spatial-toolbar">
|
|
306
|
-
<template v-if="editable">
|
|
307
|
-
<div class="toolbar-group">
|
|
308
|
-
<UDropdownMenu :items="shapeMenuItems">
|
|
309
|
-
<UButton
|
|
310
|
-
icon="i-lucide-plus"
|
|
311
|
-
size="sm"
|
|
312
|
-
variant="ghost"
|
|
313
|
-
color="neutral"
|
|
314
|
-
/>
|
|
315
|
-
</UDropdownMenu>
|
|
316
|
-
</div>
|
|
317
|
-
<div class="toolbar-divider" />
|
|
318
|
-
</template>
|
|
319
|
-
<div class="toolbar-group">
|
|
320
|
-
<UButton
|
|
321
|
-
icon="i-lucide-rotate-3d"
|
|
322
|
-
size="sm"
|
|
323
|
-
:color="controlMode === 'orbit' ? 'primary' : 'neutral'"
|
|
324
|
-
:variant="controlMode === 'orbit' ? 'soft' : 'ghost'"
|
|
325
|
-
@click="controlMode = 'orbit'"
|
|
326
|
-
/>
|
|
327
|
-
<UButton
|
|
328
|
-
icon="i-lucide-move-3d"
|
|
329
|
-
size="sm"
|
|
330
|
-
:color="controlMode === 'fly' ? 'primary' : 'neutral'"
|
|
331
|
-
:variant="controlMode === 'fly' ? 'soft' : 'ghost'"
|
|
332
|
-
@click="controlMode = 'fly'"
|
|
333
|
-
/>
|
|
334
|
-
</div>
|
|
335
|
-
<div class="toolbar-divider" />
|
|
336
|
-
<UButton
|
|
337
|
-
v-if="editable"
|
|
338
|
-
icon="i-lucide-grid-3x3"
|
|
339
|
-
size="sm"
|
|
340
|
-
:color="gridVisible ? 'primary' : 'neutral'"
|
|
341
|
-
:variant="gridVisible ? 'soft' : 'ghost'"
|
|
342
|
-
:class="{ 'opacity-40': !gridVisible }"
|
|
343
|
-
@click="toggleGrid"
|
|
344
|
-
/>
|
|
345
|
-
</div>
|
|
346
|
-
|
|
347
|
-
<!-- Properties panel -->
|
|
348
|
-
<div
|
|
349
|
-
v-if="selectedEntry"
|
|
350
|
-
class="spatial-properties"
|
|
351
|
-
>
|
|
352
|
-
<div class="sp-prop-header">
|
|
353
|
-
<UIcon
|
|
354
|
-
:name="shapeIcon(selectedEntry.meta?.spShape)"
|
|
355
|
-
class="size-4 shrink-0 text-(--ui-text-muted)"
|
|
356
|
-
/>
|
|
357
|
-
<span class="sp-prop-name">{{ selectedEntry.label }}</span>
|
|
358
|
-
<UButton
|
|
359
|
-
icon="i-lucide-external-link"
|
|
360
|
-
size="xs"
|
|
361
|
-
variant="ghost"
|
|
362
|
-
color="neutral"
|
|
363
|
-
@click="openNode(selectedEntry.id, selectedEntry.label)"
|
|
364
|
-
/>
|
|
365
|
-
<UButton
|
|
366
|
-
v-if="editable"
|
|
367
|
-
icon="i-lucide-trash-2"
|
|
368
|
-
size="xs"
|
|
369
|
-
variant="ghost"
|
|
370
|
-
color="error"
|
|
371
|
-
@click="deleteSelected"
|
|
372
|
-
/>
|
|
373
|
-
</div>
|
|
374
|
-
|
|
375
|
-
<!-- Shape selector (hide for GLB — shape comes from the file) -->
|
|
376
|
-
<div
|
|
377
|
-
v-if="editable && selectedEntry.meta?.spShape !== 'glb'"
|
|
378
|
-
class="sp-prop-row"
|
|
379
|
-
>
|
|
380
|
-
<span class="sp-prop-label">Shape</span>
|
|
381
|
-
<USelectMenu
|
|
382
|
-
:model-value="selectedEntry.meta?.spShape ?? 'box'"
|
|
383
|
-
:items="shapes"
|
|
384
|
-
size="xs"
|
|
385
|
-
class="flex-1"
|
|
386
|
-
@update:model-value="tree.updateMeta(selectedEntry.id, { spShape: $event })"
|
|
387
|
-
/>
|
|
388
|
-
</div>
|
|
389
|
-
|
|
390
|
-
<div
|
|
391
|
-
v-if="editable && selectedEntry.meta?.spShape !== 'glb'"
|
|
392
|
-
class="sp-prop-row"
|
|
393
|
-
>
|
|
394
|
-
<span class="sp-prop-label">Color</span>
|
|
395
|
-
<div class="flex gap-1 flex-wrap">
|
|
396
|
-
<button
|
|
397
|
-
v-for="c in ['#6366f1', '#ef4444', '#22c55e', '#3b82f6', '#f97316', '#a855f7', '#ec4899', '#14b8a6']"
|
|
398
|
-
:key="c"
|
|
399
|
-
class="size-5 rounded-full cursor-pointer border-2 transition-transform hover:scale-110"
|
|
400
|
-
:class="selectedEntry.meta?.color === c ? 'border-(--ui-text)' : 'border-transparent'"
|
|
401
|
-
:style="{ background: c }"
|
|
402
|
-
@click="tree.updateMeta(selectedEntry.id, { color: c })"
|
|
403
|
-
/>
|
|
404
|
-
</div>
|
|
405
|
-
</div>
|
|
406
|
-
|
|
407
|
-
<div
|
|
408
|
-
v-if="editable && selectedEntry.meta?.spShape !== 'glb'"
|
|
409
|
-
class="sp-prop-row"
|
|
410
|
-
>
|
|
411
|
-
<span class="sp-prop-label">Opacity</span>
|
|
412
|
-
<input
|
|
413
|
-
type="range"
|
|
414
|
-
min="0"
|
|
415
|
-
max="100"
|
|
416
|
-
:value="selectedEntry.meta?.spOpacity ?? 100"
|
|
417
|
-
class="flex-1 h-1.5 accent-(--color-primary-500)"
|
|
418
|
-
@input="tree.updateMeta(selectedEntry.id, { spOpacity: Number($event.target.value) })"
|
|
419
|
-
>
|
|
420
|
-
<span class="text-[10px] w-7 text-right text-(--ui-text-dimmed)">{{ selectedEntry.meta?.spOpacity ?? 100 }}%</span>
|
|
421
|
-
</div>
|
|
422
|
-
|
|
423
|
-
<!-- Transform inputs (Pos / Rot / Scale) -->
|
|
424
|
-
<SpatialTransformInputs
|
|
425
|
-
v-if="editable"
|
|
426
|
-
:entry="selectedEntry"
|
|
427
|
-
:tree="tree"
|
|
428
|
-
/>
|
|
429
|
-
</div>
|
|
430
|
-
|
|
431
|
-
<!-- Connected users -->
|
|
432
|
-
<div
|
|
433
|
-
v-if="connectedUsers.length > 1"
|
|
434
|
-
class="spatial-presence"
|
|
435
|
-
>
|
|
436
|
-
<UAvatar
|
|
437
|
-
v-for="u in connectedUsers"
|
|
438
|
-
:key="u.clientId"
|
|
439
|
-
:alt="u.name"
|
|
440
|
-
size="xs"
|
|
441
|
-
:style="{ border: `2px solid ${u.color}`, borderRadius: '50%' }"
|
|
442
|
-
/>
|
|
443
|
-
</div>
|
|
444
|
-
</UContextMenu>
|
|
445
|
-
</ClientOnly>
|
|
446
|
-
|
|
447
|
-
<!-- Node panel -->
|
|
448
|
-
<ANodePanel
|
|
449
|
-
:node-id="openNodeId"
|
|
450
|
-
:node-label="openNodeLabel"
|
|
451
|
-
:child-provider="openNodeProvider"
|
|
452
|
-
@close="closePanel"
|
|
453
|
-
/>
|
|
454
|
-
</div>
|
|
455
|
-
</template>
|
|
456
|
-
|
|
457
|
-
<style scoped>
|
|
458
|
-
.spatial-container{flex:1;height:100%;min-height:0;overflow:hidden;position:relative;width:100%}.spatial-canvas-wrap{inset:0;position:absolute;touch-action:none}.spatial-toolbar{align-items:center;backdrop-filter:blur(8px);background:var(--ui-bg);border:1px solid var(--ui-border);border-radius:10px;bottom:2rem;display:flex;gap:3px;left:50%;padding:3px;position:absolute;transform:translateX(-50%);z-index:20}.toolbar-group{align-items:center;display:flex;gap:1px}.toolbar-divider{background:var(--ui-border);flex-shrink:0;height:20px;margin:0 2px;width:1px}.spatial-properties{background:var(--ui-bg);border:1px solid var(--ui-border);border-radius:8px;display:flex;flex-direction:column;gap:6px;max-height:calc(100% - 24px);overflow-y:auto;padding:10px;position:absolute;right:12px;top:12px;width:260px;z-index:10}.sp-prop-header{align-items:center;display:flex;gap:6px}.sp-prop-name{flex:1;font-size:.8rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sp-prop-row{align-items:center;display:flex;gap:6px}.sp-prop-label{color:var(--ui-text-dimmed);flex-shrink:0;font-size:.7rem;font-weight:500;width:48px}.spatial-presence{bottom:12px;display:flex;gap:4px;left:12px;position:absolute;z-index:10}
|
|
459
|
-
</style>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type RendererBaseProps } from '../../composables/useRendererBase.js';
|
|
2
|
-
import type { AbracadabraLocale } from '../../locale.js';
|
|
3
|
-
type __VLS_Props = RendererBaseProps & {
|
|
4
|
-
labels?: Partial<AbracadabraLocale['renderers']>;
|
|
5
|
-
editable?: boolean;
|
|
6
|
-
};
|
|
7
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
8
|
-
connectedUsers: import("vue").ComputedRef<{
|
|
9
|
-
clientId: number;
|
|
10
|
-
name: string;
|
|
11
|
-
color: string;
|
|
12
|
-
avatar: string | undefined;
|
|
13
|
-
publicKey: any;
|
|
14
|
-
}[]>;
|
|
15
|
-
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
16
|
-
editable: boolean;
|
|
17
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
-
declare const _default: typeof __VLS_export;
|
|
19
|
-
export default _default;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ground plane with grid helper and shadow-receiving surface.
|
|
3
|
-
* Ported from cou-sh/app/components/spatial/SpatialGround.vue
|
|
4
|
-
*/
|
|
5
|
-
type __VLS_Props = {
|
|
6
|
-
gridSize?: number;
|
|
7
|
-
gridDivisions?: number;
|
|
8
|
-
color1?: string;
|
|
9
|
-
color2?: string;
|
|
10
|
-
groundColor?: string;
|
|
11
|
-
};
|
|
12
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
13
|
-
groundColor: string;
|
|
14
|
-
gridSize: number;
|
|
15
|
-
gridDivisions: number;
|
|
16
|
-
color1: string;
|
|
17
|
-
color2: string;
|
|
18
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
-
declare const _default: typeof __VLS_export;
|
|
20
|
-
export default _default;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
defineProps({
|
|
3
|
-
gridSize: { type: Number, required: false, default: 100 },
|
|
4
|
-
gridDivisions: { type: Number, required: false, default: 100 },
|
|
5
|
-
color1: { type: String, required: false, default: "#555" },
|
|
6
|
-
color2: { type: String, required: false, default: "#333" },
|
|
7
|
-
groundColor: { type: String, required: false, default: "#111118" }
|
|
8
|
-
});
|
|
9
|
-
const HALF_PI = -Math.PI / 2;
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<template>
|
|
13
|
-
<TresGridHelper :args="[gridSize, gridDivisions, color1, color2]" />
|
|
14
|
-
<TresMesh
|
|
15
|
-
:rotation-x="HALF_PI"
|
|
16
|
-
:position-y="-5e-3"
|
|
17
|
-
receive-shadow
|
|
18
|
-
>
|
|
19
|
-
<TresPlaneGeometry :args="[gridSize, gridSize]" />
|
|
20
|
-
<TresMeshStandardMaterial
|
|
21
|
-
:color="groundColor"
|
|
22
|
-
:opacity="0.3"
|
|
23
|
-
:transparent="true"
|
|
24
|
-
/>
|
|
25
|
-
</TresMesh>
|
|
26
|
-
</template>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ground plane with grid helper and shadow-receiving surface.
|
|
3
|
-
* Ported from cou-sh/app/components/spatial/SpatialGround.vue
|
|
4
|
-
*/
|
|
5
|
-
type __VLS_Props = {
|
|
6
|
-
gridSize?: number;
|
|
7
|
-
gridDivisions?: number;
|
|
8
|
-
color1?: string;
|
|
9
|
-
color2?: string;
|
|
10
|
-
groundColor?: string;
|
|
11
|
-
};
|
|
12
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
13
|
-
groundColor: string;
|
|
14
|
-
gridSize: number;
|
|
15
|
-
gridDivisions: number;
|
|
16
|
-
color1: string;
|
|
17
|
-
color2: string;
|
|
18
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
-
declare const _default: typeof __VLS_export;
|
|
20
|
-
export default _default;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { TreeEntry } from '../../../types.js';
|
|
2
|
-
type __VLS_Props = {
|
|
3
|
-
entry: TreeEntry;
|
|
4
|
-
tree: {
|
|
5
|
-
childrenOf: (parentId: string | null) => TreeEntry[];
|
|
6
|
-
updateMeta: (id: string, meta: Record<string, unknown>) => void;
|
|
7
|
-
};
|
|
8
|
-
selectedIds: Set<string>;
|
|
9
|
-
remoteSelections: Map<string, {
|
|
10
|
-
color: string;
|
|
11
|
-
name: string;
|
|
12
|
-
}[]>;
|
|
13
|
-
draggingId: string | null;
|
|
14
|
-
};
|
|
15
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
-
declare const _default: typeof __VLS_export;
|
|
17
|
-
export default _default;
|