Made folders into groups in tabletop

This commit is contained in:
ThaumRystra
2024-09-02 23:50:13 +02:00
parent 2f2a062273
commit e8c9058084
5 changed files with 61 additions and 63 deletions

View File

@@ -10,6 +10,7 @@
"EJSON",
"healthbar",
"healthbars",
"jank",
"meteortesting",
"nearley",
"ngraph",
@@ -19,6 +20,7 @@
"Spellcasting",
"uncomputed",
"vuetify",
"Vuex",
"walkdown"
]
}

View File

@@ -35,12 +35,6 @@ export type Creature = Colored & Shared & {
// Tabletop
tabletopId?: string,
initiativeRoll?: number,
tabletopSettings?: {
iconGroups: {
name?: string,
iconIds: string[],
}[],
},
settings: {
useVariantEncumbrance?: true,
@@ -131,17 +125,6 @@ const IconGroupSchema = new SimpleSchema({
},
});
const CreatureTabletopSettingsSchema = new SimpleSchema({
iconGroups: {
type: Array,
defaultValue: [],
max: 10,
},
'iconGroups.$': {
type: IconGroupSchema,
},
});
const CreatureSchema = new SimpleSchema({
// Strings
name: {
@@ -252,10 +235,6 @@ const CreatureSchema = new SimpleSchema({
type: SimpleSchema.Integer,
optional: true,
},
tabletopSettings: {
type: CreatureTabletopSettingsSchema,
optional: true,
},
// Settings
settings: {

View File

@@ -59,6 +59,7 @@ export default async function doAction(
task,
},
callback(action: EngineAction) {
if (!action) return;
resolve(callActionMethod(action, task));
return elementId;
},

View File

@@ -3,7 +3,6 @@
class="action-card overflow-y-auto"
rounded
:class="cardClasses"
:data-id="model._id"
>
<div class="layout align-center px-3">
<div
@@ -34,6 +33,7 @@
<div
class="action-header flex layout column justify-center pl-1"
style="height: 72px; cursor: pointer;"
@click="$emit('open-details')"
>
<div class="action-title my-1">
{{ model.name || propertyName }}
@@ -230,13 +230,6 @@ export default {
this.activated = undefined;
}, 150);
},
openPropertyDetails() {
this.$store.commit('pushDialogStack', {
component: 'creature-property-dialog',
elementId: `${this.model._id}`,
data: {_id: this.model._id},
});
},
}
}
</script>

View File

@@ -19,6 +19,7 @@
:close-on-click="false"
:content-class="`tabletop-prop-menu rows-${rows}`"
:close-on-content-click="false"
style="z-index: 2"
>
<tabletop-action-card
v-if="selectedProp && selectedProp.type === 'action'"
@@ -29,7 +30,10 @@
transition: 'opacity 0.2s ease',
}"
:model="selectedProp"
data-id="tabletop-action-card"
@close-menu="menuOpen = false"
@dialog-opened="menuOpen = false"
@open-details="openPropertyDetails"
/>
<v-card
v-else-if="activeIcon && activeIcon.tab"
@@ -42,6 +46,17 @@
{{ activeIcon.tabName }}
</v-card-title>
</v-card>
<v-card
v-else-if="activeIcon && activeIcon.actionName"
style="width: 300px"
>
<v-card-title>
<v-icon left>
{{ activeIcon.icon }}
</v-icon>
{{ activeIcon.actionName }}
</v-card-title>
</v-card>
</v-menu>
<v-card
class="delete-card"
@@ -178,6 +193,7 @@ export default {
rows: 2,
hoveredIcon: undefined,
selectedIcon: undefined,
lastIcon: undefined,
menuOpen: false,
menuX: 200,
menuY: window.innerHeight - 216,
@@ -227,6 +243,9 @@ export default {
this.openCharacterSheet(icon.tab, icon.standardId);
return;
}
if (icon.actionName) {
this.openStandardAction(icon.standardId)
}
if (this.selectedIcon === icon) {
this.selectedIcon = undefined;
this.menuOpen = false;
@@ -261,6 +280,22 @@ export default {
creatureId: this.creatureId,
},
});
this.menuOpen = false;
},
openStandardAction(standardId) {
// TODO standard action dialogs
this.menuOpen = false;
},
openPropertyDetails() {
const propId = this.selectedProp._id;
this.$store.commit('pushDialogStack', {
component: 'creature-property-dialog',
elementId: 'tabletop-action-card',
data: { _id: propId },
callback: () => propId
});
// Close the menu while the dialog is open
this.menuOpen = false;
},
},
meteor: {
@@ -279,9 +314,9 @@ export default {
// Get the standard icons
const standardIconsById = {
'cast-spell': {standardId: 'cast-spell', groupName: 'Standard Actions', icon: 'mdi-fire' },
'make-check': {standardId: 'make-check', groupName: 'Standard Actions', icon: 'mdi-radiobox-marked' },
'roll-dice': {standardId: 'roll-dice', groupName: 'Standard Actions', icon: 'mdi-dice-d20' },
'cast-spell': {standardId: 'cast-spell', groupName: 'Standard Actions', icon: 'mdi-fire', actionName: 'Cast Spell' },
'make-check': {standardId: 'make-check', groupName: 'Standard Actions', icon: 'mdi-radiobox-marked', actionName: 'Check' },
'roll-dice': {standardId: 'roll-dice', groupName: 'Standard Actions', icon: 'mdi-dice-d20', actionName: 'Roll' },
'tab-stats': {standardId: 'tab-stats', groupName: 'Tabs', icon: 'mdi-chart-box', tab: 'stats', tabName: 'Stats' },
'tab-actions': {standardId: 'tab-actions', groupName: 'Tabs', icon: 'mdi-lightning-bolt', tab: 'actions', tabName: 'Actions' },
'tab-spells': this.creature?.settings?.hideSpellsTab ? undefined : {standardId: 'tab-spells', groupName: 'Tabs', icon: 'mdi-fire', tab: 'spells', tabName: 'Spells' },
@@ -292,28 +327,29 @@ export default {
};
// Get the folders that could hide a property
const folderIds = CreatureProperties.find({
const folderGroupsById = {};
CreatureProperties.find({
'root.id': this.creatureId,
type: 'folder',
groupStats: true,
hideStatsGroup: true,
removed: { $ne: true },
inactive: { $ne: true },
}, { fields: { _id: 1 } }).map(folder => folder._id);
}, { fields: { _id: 1 } }).forEach(folder => {
const folderGroup = { name: folder._id, iconList: [] };
iconGroups.push(folderGroup);
folderGroupsById[folder._id] = folderGroup;
});
// Get the properties that need to be shown as an icon
const filter = {
'root.id': this.creatureId,
'parentId': {
$nin: folderIds,
},
$and: [
{
$or: [
{ type: 'action' },
{ type: 'folder', groupStats: true },
{ type: 'attribute' },
{ type: 'toggle' },
// { type: 'attribute' },
// { type: 'toggle' },
{ type: 'buff' }
],
},
@@ -335,31 +371,16 @@ export default {
const props = [];
CreatureProperties.find(filter, {
sort: { left: -1 },
fields: { _id: 1, type: 1 },
fields: { _id: 1, type: 1, parentId: 1 },
}).forEach(prop => {
props.push(prop);
propsById[prop._id] = prop;
});
// Using the creature's custom icon groups, collect the props into groups
this.creature.tabletopSettings?.iconGroups.forEach(group => {
const iconList = [];
group.iconIds?.forEach(id => {
if (propsById[id]) {
const prop = propsById[id];
// If they are in a folder, group them by that folder first
if (folderGroupsById[prop.parentId]) {
prop._placedInGroup = true;
iconList.push({ propId: prop._id });
} else if (standardIconsById[id]) {
const standardIcon = standardIconsById[id];
standardIcon._placedInGroup = true;
iconList.push(standardIcon);
folderGroupsById[prop.parentId].iconList.push({ propId: prop._id });
}
});
iconGroups.push({
name: group.name,
iconList,
});
});
// Default groups
let groupsByName = {};
@@ -413,7 +434,9 @@ export default {
iconGroups.buffs.rows = splitToNChunks(iconGroups.buffs.iconList, this.rows);
}
return iconGroups;
const filteredIconGroups = iconGroups.filter(group => group.iconList.length);
filteredIconGroups.buffs = iconGroups.buffs;
return filteredIconGroups;
}
},
}