diff --git a/client/src/assets/ui/AssetContext.vue b/client/src/assets/ui/AssetContext.vue index 1455bab49..35c2751ea 100644 --- a/client/src/assets/ui/AssetContext.vue +++ b/client/src/assets/ui/AssetContext.vue @@ -44,31 +44,31 @@ const canShare = computed(() => { return data.owner === username || data.shares.some((s) => s.user === username && s.right === "edit"); }); -function rename(): void { - if (multiSelect.value) return; +function rename(): boolean { + if (multiSelect.value) return true; const asset = assetState.raw.idMap.get(assetState.raw.selected[0]!); if (asset === undefined) { console.error("Attempt to rename unknown file"); - return close(); + return true; } emit("rename", asset.id); - close(); + return true; } -function share(): void { +function share(): boolean { showAssetShare.value = true; - close(); + return true; } -async function remove(): Promise { - if (assetState.raw.selected.length === 0) return; +async function remove(): Promise { + if (assetState.raw.selected.length === 0) return false; const result = await modals.confirm(t("assetManager.AssetContextMenu.ask_remove")); if (result === true) { assetSystem.removeSelection(); } - close(); + return true; } const sections = computed(() => [ diff --git a/client/src/core/components/contextMenu/ContextMenu.vue b/client/src/core/components/contextMenu/ContextMenu.vue index 720bde345..797167b91 100644 --- a/client/src/core/components/contextMenu/ContextMenu.vue +++ b/client/src/core/components/contextMenu/ContextMenu.vue @@ -53,7 +53,7 @@ const visibleSections = computed(() => props.sections.filter((section) => isVisi @contextmenu.stop.prevent >
    - +
diff --git a/client/src/core/components/contextMenu/ContextMenuSection.vue b/client/src/core/components/contextMenu/ContextMenuSection.vue index fd14ffd6b..51c6465bf 100644 --- a/client/src/core/components/contextMenu/ContextMenuSection.vue +++ b/client/src/core/components/contextMenu/ContextMenuSection.vue @@ -1,7 +1,15 @@ diff --git a/client/src/core/components/contextMenu/types.ts b/client/src/core/components/contextMenu/types.ts index 2620eab93..f9e410a86 100644 --- a/client/src/core/components/contextMenu/types.ts +++ b/client/src/core/components/contextMenu/types.ts @@ -1,6 +1,6 @@ interface BaseSection { title: string; - action: () => void | Promise; + action: () => boolean | Promise; disabled?: boolean; selected?: boolean; } diff --git a/client/src/game/ui/contextmenu/DefaultContext.vue b/client/src/game/ui/contextmenu/DefaultContext.vue index 3dcd1b834..e68dbe1fc 100644 --- a/client/src/game/ui/contextmenu/DefaultContext.vue +++ b/client/src/game/ui/contextmenu/DefaultContext.vue @@ -33,19 +33,19 @@ function close(): void { showDefaultContextMenu.value = false; } -function bringPlayers(): void { - if (!gameState.raw.isDm) return; +function bringPlayers(): boolean { + if (!gameState.raw.isDm) return false; sendBringPlayers({ floor: floorState.currentFloor.value!.name, x: l2gx(defaultContextLeft.value), y: l2gy(defaultContextTop.value), }); - close(); + return true; } -async function createSpawnLocation(): Promise { - if (!gameState.raw.isDm) return; +async function createSpawnLocation(): Promise { + if (!gameState.raw.isDm) return false; const spawnLocations = locationSettingsState.raw.spawnLocations.value; const spawnName = await modals.prompt( @@ -61,7 +61,7 @@ async function createSpawnLocation(): Promise { return { valid: true }; }, ); - if (spawnName === undefined || spawnName === "") return; + if (spawnName === undefined || spawnName === "") return false; const uuid = uuidv4(); const src = "/static/img/spawn.png"; @@ -87,16 +87,17 @@ async function createSpawnLocation(): Promise { locationSettingsState.raw.activeLocation, true, ); + return true; } -function showInitiativeDialog(): void { +function showInitiativeDialog(): boolean { initiativeStore.show(true, true); - close(); + return true; } -function showTokenDialog(): void { +function showTokenDialog(): boolean { openCreateTokenDialog({ x: defaultContextLeft.value, y: defaultContextTop.value }); - close(); + return true; } const sections = computed(() => { diff --git a/client/src/game/ui/contextmenu/ShapeContext.vue b/client/src/game/ui/contextmenu/ShapeContext.vue index c5806bb07..f9f7612c0 100644 --- a/client/src/game/ui/contextmenu/ShapeContext.vue +++ b/client/src/game/ui/contextmenu/ShapeContext.vue @@ -65,16 +65,16 @@ function close(): void { showShapeContextMenu.value = false; } -function openEditDialog(): void { - if (selectedState.raw.selected.size !== 1) return; +function openEditDialog(): boolean { + if (selectedState.raw.selected.size !== 1) return false; activeShapeStore.setShowEditDialog(true); - close(); + return true; } -function openNotes(): void { - if (selectedState.raw.selected.size !== 1) return; +function openNotes(): boolean { + if (selectedState.raw.selected.size !== 1) return false; openNoteManager(NoteManagerMode.List, [...selectedState.raw.selected][0]); - close(); + return true; } // MARKERS @@ -85,23 +85,23 @@ const isMarker = computed(() => { return markerState.reactive.markers.has([...sel][0]!); }); -function deleteMarker(): void { +function deleteMarker(): boolean { const sel = selectedState.raw.selected; - if (sel.size !== 1) return; + if (sel.size !== 1) return false; markerSystem.removeMarker([...sel][0]!, true); - close(); + return true; } -function setMarker(): void { +function setMarker(): boolean { const sel = selectedState.raw.selected; - if (sel.size !== 1) return; + if (sel.size !== 1) return false; markerSystem.newMarker([...sel][0]!, true); - close(); + return true; } // INITIATIVE -async function addToInitiative(): Promise { +async function addToInitiative(): Promise { let groupInitiatives = false; const selection = selectedSystem.get({ includeComposites: false }); // First check if there are shapes with the same groupId @@ -115,7 +115,7 @@ async function addToInitiative(): Promise { "Some of the selected shapes belong to the same group. Do you wish to add 1 entry for these?", { no: "no, create a separate entry for each", focus: "confirm" }, ); - if (answer === undefined) return; + if (answer === undefined) return false; groupInitiatives = answer; break; } else { @@ -132,7 +132,7 @@ async function addToInitiative(): Promise { } } initiativeStore.show(true, true); - close(); + return true; } function getInitiativeWord(): string { @@ -158,35 +158,35 @@ const layers = computed(() => { return []; }); -function setLayer(newLayer: LayerName): void { +function setLayer(newLayer: LayerName): boolean { const oldSelection = [...selectedSystem.get({ includeComposites: true })]; selectedSystem.clear(); moveLayer(oldSelection, floorSystem.getLayer(floorState.currentFloor.value!, newLayer)!, true); - close(); + return true; } -function moveToBack(): void { +function moveToBack(): boolean { const layer = floorState.currentLayer.value!; for (const shape of selectedSystem.get({ includeComposites: false })) { layer.moveShapeOrder(shape, 0, SyncMode.FULL_SYNC); } - close(); + return true; } -function moveToFront(): void { +function moveToFront(): boolean { const layer = floorState.currentLayer.value!; for (const shape of selectedSystem.get({ includeComposites: false })) { layer.moveShapeOrder(shape, layer.size({ includeComposites: true, onlyInView: false }) - 1, SyncMode.FULL_SYNC); } - close(); + return true; } // FLOORS -function setFloor(floor: Floor): void { +function setFloor(floor: Floor): boolean { moveFloor([...selectedSystem.get({ includeComposites: true })], floor, true); - close(); + return true; } // LOCATIONS @@ -198,10 +198,10 @@ const locations = computed(() => { return []; }); -async function setLocation(newLocation: number): Promise { +async function setLocation(newLocation: number): Promise { const shapes = selectedSystem.get({ includeComposites: true }).filter((s) => !getProperties(s.id)!.isLocked); if (shapes.length === 0) { - return; + return false; } const spawnInfo = await requestSpawnInfo(newLocation); @@ -214,8 +214,7 @@ async function setLocation(newLocation: number): Promise { t("game.ui.selection.ShapeContext.no_spawn_set_text"), { showNo: false, yes: "Ok" }, ); - close(); - return; + return true; case 1: spawnLocation = spawnInfo[0]!; break; @@ -224,9 +223,9 @@ async function setLocation(newLocation: number): Promise { "Choose the desired spawn location", spawnInfo.map((s) => s.name), ); - if (choices === undefined) return; + if (choices === undefined) return false; const choiceShape = spawnInfo.find((s) => s.name === choices[0]); - if (choiceShape === undefined) return; + if (choiceShape === undefined) return false; spawnLocation = choiceShape; break; } @@ -251,16 +250,16 @@ async function setLocation(newLocation: number): Promise { playerSystem.updatePlayersLocation([...users], newLocation, true, { ...targetPosition }); } - close(); + return true; } // SELECTION const hasSingleSelection = computed(() => selectedState.reactive.selected.size === 1); -function deleteSelection(): void { +function deleteSelection(): boolean { deleteShapes(selectedSystem.get({ includeComposites: true }), SyncMode.FULL_SYNC); - close(); + return true; } // TEMPLATES @@ -271,9 +270,9 @@ const canBeSaved = computed(() => ), ); -async function saveTemplate(): Promise { +async function saveTemplate(): Promise { const shape = selectedSystem.get({ includeComposites: false })[0]; - if (shape === undefined) return; + if (shape === undefined) return false; let assetOptions: AssetOptions = { version: "0", @@ -285,7 +284,7 @@ async function saveTemplate(): Promise { if (response.success && response.options) assetOptions = response.options; } else { console.warn("Templates are currently only supported for shapes with existing asset relations."); - return; + return false; } const choices = Object.keys(assetOptions.templates); try { @@ -293,7 +292,7 @@ async function saveTemplate(): Promise { defaultButton: t("game.ui.templates.overwrite"), customButton: t("game.ui.templates.create_new"), }); - if (selection === undefined || selection.length === 0) return; + if (selection === undefined || selection.length === 0) return false; const notes = noteState.raw.shapeNotes.get1(shape.id); if (notes !== undefined) { shape.options.templateNoteIds = notes.map((n) => n); @@ -305,6 +304,7 @@ async function saveTemplate(): Promise { } catch { // no-op ; action cancelled } + return true; } // CHARACTER @@ -319,17 +319,17 @@ const canHaveCharacter = computed(() => { return true; }); -function createCharacter(): void { - close(); +function createCharacter(): boolean { const selectedId = [...selectedState.raw.selected].at(0); - if (selectedId === undefined) return; + if (selectedId === undefined) return false; const shape = getShape(selectedId); - if (shape === undefined || shape.character !== undefined) return; + if (shape === undefined || shape.character !== undefined) return false; const data: CharacterCreate = { shape: getGlobalId(selectedId)!, name: getProperties(selectedId)!.name, }; sendCreateCharacter(data); + return true; } // GROUPS @@ -353,21 +353,21 @@ const hasUngrouped = computed(() => [...selectedState.reactive.selected].some((s) => groupSystem.getGroupId(s) === undefined), ); -function createGroup(): void { +function createGroup(): boolean { groupSystem.createNewGroupForShapes([...selectedState.raw.selected]); - close(); + return true; } -async function splitGroup(): Promise { +async function splitGroup(): Promise { const keepBadges = await modals.confirm("Splitting group", "Do you wish to keep the original badges?", { no: "No, reset them", }); - if (keepBadges === undefined) return; + if (keepBadges === undefined) return false; groupSystem.createNewGroupForShapes([...selectedState.raw.selected], keepBadges); - close(); + return true; } -async function mergeGroups(): Promise { +async function mergeGroups(): Promise { const keepBadges = await modals.confirm( "Merging group", "Do you wish to keep the original badges? This can lead to duplicate badges!", @@ -375,7 +375,7 @@ async function mergeGroups(): Promise { no: "No, reset them", }, ); - if (keepBadges === undefined) return; + if (keepBadges === undefined) return false; let targetGroup: string | undefined; const membersToMove: { uuid: LocalId; badge?: number }[] = []; for (const shape of selectedSystem.get({ includeComposites: false })) { @@ -392,10 +392,10 @@ async function mergeGroups(): Promise { } } groupSystem.addGroupMembers(targetGroup!, membersToMove, true); - close(); + return true; } -function removeEntireGroup(): void { +function removeEntireGroup(): boolean { const shape = selectedSystem.get({ includeComposites: false })[0]; if (shape !== undefined) { const groupId = groupSystem.getGroupId(shape.id); @@ -403,10 +403,10 @@ function removeEntireGroup(): void { groupSystem.removeGroup(groupId, true); } } - close(); + return true; } -function enlargeGroup(): void { +function enlargeGroup(): boolean { const selection = selectedSystem .get({ includeComposites: false }) .map((s) => ({ id: s.id, groupId: groupSystem.getGroupId(s.id) })); @@ -418,20 +418,20 @@ function enlargeGroup(): void { true, ); } - close(); + return true; } -function _collapseSelection(): void { +function _collapseSelection(): boolean { collapseSelection(); - close(); + return true; } -async function _expandSelection(): Promise { +async function _expandSelection(): Promise { const updateList: IShape[] = []; await expandSelection(updateList); sendShapePositionUpdate(updateList, false); - close(); + return true; } const activeLayer = floorState.currentLayer as ComputedRef;