diff --git a/.vscode/settings.json b/.vscode/settings.json index e211d1a5..c7852e1f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,6 +26,7 @@ "thumbhash", "uncomputed", "untarget", + "vuedraggable", "vuetify", "Vuex", "walkdown" diff --git a/app/imports/api/creature/creatureProperties/methods/equipItem.js b/app/imports/api/creature/creatureProperties/methods/equipItem.js index 27810d95..b2ea0fba 100644 --- a/app/imports/api/creature/creatureProperties/methods/equipItem.js +++ b/app/imports/api/creature/creatureProperties/methods/equipItem.js @@ -5,7 +5,7 @@ import { assertEditPermission } from '/imports/api/sharing/sharingPermissions'; import { organizeDoc } from '/imports/api/parenting/organizeMethods'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor'; import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS'; -import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag'; +import getParentRefByTag from './getParentByTag'; // Equipping or unequipping an item will also change its parent const equipItem = new ValidatedMethod({ diff --git a/app/imports/api/creature/creatureProperties/methods/getParentRefByTag.js b/app/imports/api/creature/creatureProperties/methods/getParentByTag.js similarity index 65% rename from app/imports/api/creature/creatureProperties/methods/getParentRefByTag.js rename to app/imports/api/creature/creatureProperties/methods/getParentByTag.js index cda68469..7730d169 100644 --- a/app/imports/api/creature/creatureProperties/methods/getParentRefByTag.js +++ b/app/imports/api/creature/creatureProperties/methods/getParentByTag.js @@ -1,8 +1,8 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties'; import { getFilter } from '/imports/api/parenting/parentingFunctions'; -export default function getParentRefByTag(creatureId, tag) { - let prop = CreatureProperties.findOne({ +export default function getParentByTag(creatureId, tag) { + return CreatureProperties.findOne({ ...getFilter.descendantsOfRoot(creatureId), removed: { $ne: true }, inactive: { $ne: true }, @@ -10,5 +10,4 @@ export default function getParentRefByTag(creatureId, tag) { }, { sort: { left: 1 }, }); - return prop && { id: prop._id, collection: 'creatureProperties' }; } diff --git a/app/imports/api/creature/creatureProperties/methods/insertProperty.js b/app/imports/api/creature/creatureProperties/methods/insertProperty.js index 570a301d..56512bfc 100644 --- a/app/imports/api/creature/creatureProperties/methods/insertProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/insertProperty.js @@ -5,7 +5,7 @@ import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/ge import SimpleSchema from 'simpl-schema'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions'; import { fetchDocByRef, rebuildNestedSets } from '/imports/api/parenting/parentingFunctions'; -import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag'; +import getParentRefByTag from './getParentByTag'; import { RefSchema } from '/imports/api/parenting/ChildSchema'; const insertProperty = new ValidatedMethod({ diff --git a/app/imports/client/ui/creature/character/characterSheetTabs/InventoryTab.vue b/app/imports/client/ui/creature/character/characterSheetTabs/InventoryTab.vue index 13655b90..575e3b08 100644 --- a/app/imports/client/ui/creature/character/characterSheetTabs/InventoryTab.vue +++ b/app/imports/client/ui/creature/character/characterSheetTabs/InventoryTab.vue @@ -68,8 +68,8 @@ @@ -81,8 +81,8 @@ @@ -112,7 +112,7 @@ import ColumnLayout from '/imports/client/ui/components/ColumnLayout.vue'; import ContainerCard from '/imports/client/ui/properties/components/inventory/ContainerCard.vue'; import ToolbarCard from '/imports/client/ui/components/ToolbarCard.vue'; import ItemList from '/imports/client/ui/properties/components/inventory/ItemList.vue'; -import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag'; +import getParentByTag from '/imports/api/creature/creatureProperties/methods/getParentByTag'; import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS'; import CoinValue from '/imports/client/ui/components/CoinValue.vue'; import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities'; @@ -141,7 +141,6 @@ export default { tabName: 'inventory', }; }, - // @ts-ignore Meteor isn't defined on vue meteor: { folderIds() { return CreatureProperties.find({ @@ -191,7 +190,7 @@ export default { sort: { left: 1 }, }); }, - carriedItems() { + carriedItemIds() { return CreatureProperties.find({ ...getFilter.descendantsOfRoot(this.creatureId), $nor: [getFilter.descendantsOfAll(this.containers)], @@ -205,9 +204,10 @@ export default { deactivatedByToggle: { $ne: true }, }, { sort: { left: 1 }, - }); + fields: { _id: 1 }, + }).map(prop => prop._id); }, - equippedItems() { + equippedItemIds() { return CreatureProperties.find({ ...getFilter.descendantsOfRoot(this.creatureId), type: 'item', @@ -216,27 +216,22 @@ export default { inactive: { $ne: true }, }, { sort: { left: 1 }, - }); + fields: { _id: 1 }, + }).map(prop => prop._id); }, - equipmentParentRef() { - return getParentRefByTag( + equipmentParent() { + return getParentByTag( this.creatureId, BUILT_IN_TAGS.equipment - ) || getParentRefByTag( + ) || getParentByTag( this.creatureId, BUILT_IN_TAGS.inventory - ) || { - id: this.creatureId, - collection: 'creatures' - }; + ); }, - carriedParentRef() { - return getParentRefByTag( + carriedParent() { + return getParentByTag( this.creatureId, BUILT_IN_TAGS.carried - ) || getParentRefByTag( + ) || getParentByTag( this.creatureId, BUILT_IN_TAGS.inventory - ) || { - id: this.creatureId, - collection: 'creatures' - }; + ); }, }, computed: { diff --git a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedInventory.vue b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedInventory.vue index 0540dec4..9f2696ea 100644 --- a/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedInventory.vue +++ b/app/imports/client/ui/creature/character/printedCharacterSheet/PrintedInventory.vue @@ -75,7 +75,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties'; import Creatures from '/imports/api/creature/creatures/Creatures'; import ColumnLayout from '/imports/client/ui/components/ColumnLayout.vue'; -import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag'; +import getParentRefByTag from '../../../../../api/creature/creatureProperties/methods/getParentByTag'; import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS'; import CoinValue from '/imports/client/ui/components/CoinValue.vue'; import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities'; diff --git a/app/imports/client/ui/creature/creatureList/CreatureList.vue b/app/imports/client/ui/creature/creatureList/CreatureList.vue index 45420ad2..f8869b01 100644 --- a/app/imports/client/ui/creature/creatureList/CreatureList.vue +++ b/app/imports/client/ui/creature/creatureList/CreatureList.vue @@ -7,7 +7,6 @@ ghost-class="ghost" draggable=".creature" handle=".handle" - :animation="200" @change="draggableChange" > import SharedIcon from '/imports/client/ui/components/SharedIcon.vue'; import draggable from 'vuedraggable'; -import { organizeDoc } from '/imports/api/parenting/organizeMethods'; +import { moveBetweenRoots } from '/imports/api/parenting/organizeMethods'; import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue'; export default { @@ -91,44 +90,44 @@ export default { }; }, methods: { - dropItem({ added }) { + async dropItem({ added }) { const item = added?.element; if (!item?._id) return; const docRef = { collection: 'creatureProperties', id: item._id }; - + // Create the undo function - const oldOrder = item.order; - const oldParent = item.parent; - // TODO organize doc needs to be replaced with organize between roots - const undo = () => organizeDoc.callAsync({ - docRef, - parentRef: oldParent, - order: (oldOrder || 0) - 0.5, - skipClient: true, // The client no longer has the doc subscribed, so we can't simulate - }, (error) => { - if (error) { - console.error(error); - snackbar({ text: error.reason || error.message || error.toString() }); - } - }); - - // TODO organize doc needs to be replaced with organize between roots - organizeDoc.callAsync({ - docRef, - parentRef: { collection: 'creatures', id: this.model._id }, - order: -0.5, - }, (error) => { - if (error) { - console.error(error); - snackbar({ text: error.reason || error.message || error.toString() }); - } else { - snackbar({ - text: `Moved ${item.name || 'item'} to ${this.model.name || 'another character'}`, - callbackName: 'undo', - callback: undo, + const oldRoot = item.root; + const oldOrder = item.left; + const undo = async () => { + try { + await moveBetweenRoots.callAsync({ + docRef, + newRootRef: oldRoot, + newPosition: (oldOrder || 1) - 0.5, + skipClient: true, // The client will no longer have the doc subscribed, so we can't simulate }); + } catch (e) { + console.error(e); + snackbar({ text: e.reason || e.message || e.toString() }); } - }); + } + + try { + await moveBetweenRoots.callAsync({ + docRef, + newRootRef: { collection: 'creatures', id: this.model._id }, + newPosition: 0.5, + }); + snackbar({ + text: `Moved ${item.name || 'item'} to ${this.model.name || 'another character'}`, + callbackName: 'undo', + callback: undo, + }); + } catch (e) { + console.error(e); + snackbar({ text: e.reason || e.message || e.toString() }); + } + }, } } diff --git a/app/imports/client/ui/properties/components/inventory/ContainerCard.vue b/app/imports/client/ui/properties/components/inventory/ContainerCard.vue index 734cde9b..ecb43173 100644 --- a/app/imports/client/ui/properties/components/inventory/ContainerCard.vue +++ b/app/imports/client/ui/properties/components/inventory/ContainerCard.vue @@ -35,8 +35,8 @@ @@ -92,7 +92,7 @@ export default { }, }, meteor: { - items() { + itemIds() { return CreatureProperties.find({ 'parentId': this.model._id, type: { $in: ['item', 'container'] }, @@ -102,7 +102,8 @@ export default { deactivatedByToggle: { $ne: true }, }, { sort: { left: 1 }, - }); + fields: { _id: 1 } + }).map(prop => prop._id); }, } }; diff --git a/app/imports/client/ui/properties/components/inventory/ItemList.vue b/app/imports/client/ui/properties/components/inventory/ItemList.vue index ef17094d..5575af11 100644 --- a/app/imports/client/ui/properties/components/inventory/ItemList.vue +++ b/app/imports/client/ui/properties/components/inventory/ItemList.vue @@ -11,16 +11,16 @@ ghost-class="ghost" draggable=".item" handle=".handle" - :animation="200" + :revert-on-spill="true" @change="change" > @@ -29,8 +29,10 @@ + + diff --git a/app/imports/client/ui/properties/components/inventory/ItemListTile.vue b/app/imports/client/ui/properties/components/inventory/ItemListTile.vue index f1a64bcf..c0cdd746 100644 --- a/app/imports/client/ui/properties/components/inventory/ItemListTile.vue +++ b/app/imports/client/ui/properties/components/inventory/ItemListTile.vue @@ -42,21 +42,28 @@