Merge branch 'feature-tabletop' into develop
This commit is contained in:
@@ -1,56 +1,134 @@
|
||||
<template lang="html">
|
||||
<v-container
|
||||
class="tabletop"
|
||||
fluid
|
||||
<div
|
||||
class="tabletop layout column"
|
||||
style="height: 100%;"
|
||||
>
|
||||
<v-row
|
||||
dense
|
||||
class="initiative-row"
|
||||
style="flex-wrap: nowrap; overflow-x: auto;"
|
||||
<tabletop-map
|
||||
class="play-area"
|
||||
style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
"
|
||||
/>
|
||||
<v-container
|
||||
fluid
|
||||
>
|
||||
<tabletop-creature-card
|
||||
v-for="creature in creatures"
|
||||
:key="creature._id"
|
||||
:model="creature"
|
||||
/>
|
||||
<v-card
|
||||
class="layout column justify-center align-center"
|
||||
style="height: 150px; min-width: 120px;"
|
||||
data-id="select-creatures"
|
||||
hover
|
||||
@click="addCreature"
|
||||
<v-row
|
||||
dense
|
||||
class="initiative-row flex-grow-0"
|
||||
style="flex-wrap: nowrap; overflow-x: auto; padding-bottom: 50px;"
|
||||
@wheel="transformScroll($event)"
|
||||
>
|
||||
<div class="flex layout justify-center align-center">
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
<tabletop-creature-card
|
||||
v-for="creature in creatures"
|
||||
:key="creature._id"
|
||||
:model="creature"
|
||||
:active="activeCreatureId === creature._id"
|
||||
:targeted="targets.includes(creature._id)"
|
||||
:show-target-btn="targets.includes(creature._id) || moreTargets"
|
||||
v-on="(!activeActionId || (targets.includes(creature._id) || moreTargets)) ? {
|
||||
click: () => {
|
||||
if (activeActionId) {
|
||||
if (targets.includes(creature._id)) {
|
||||
untarget(creature._id)
|
||||
} else {
|
||||
if (moreTargets) targets.push(creature._id);
|
||||
}
|
||||
} else {
|
||||
activeCreatureId = creature._id;
|
||||
targets = [];
|
||||
activeActionId = undefined;
|
||||
}
|
||||
}
|
||||
} : {}"
|
||||
@target="targets.push(creature._id)"
|
||||
@untarget="untarget(creature._id)"
|
||||
/>
|
||||
<div
|
||||
class="layout column ma-1 flex-grow-0"
|
||||
>
|
||||
<v-btn
|
||||
data-id="select-creatures"
|
||||
class="mb-2"
|
||||
@click="addCreature"
|
||||
>
|
||||
<v-icon left>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
Add Character
|
||||
</v-btn>
|
||||
<v-btn disabled>
|
||||
<v-icon left>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
Add Creature
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-card-title>
|
||||
Add<br>creature
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</v-row>
|
||||
<tabletop-map class="play-area" />
|
||||
<section class="action-row">
|
||||
<mini-character-sheet />
|
||||
<tabletop-action-cards />
|
||||
</section>
|
||||
</v-container>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-footer
|
||||
inset
|
||||
class="pa-0"
|
||||
style="
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom:0;
|
||||
right: 0;
|
||||
overflow-x: auto;
|
||||
"
|
||||
>
|
||||
<v-slide-y-reverse-transition mode="out-in">
|
||||
<selected-creature-bar
|
||||
:key="activeCreatureId"
|
||||
:creature-id="activeCreatureId"
|
||||
/>
|
||||
</v-slide-y-reverse-transition>
|
||||
</v-footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import addCreaturesToTabletop from '/imports/api/tabletop/methods/addCreaturesToTabletop';
|
||||
import TabletopCreatureCard from '/imports/client/ui/tabletop/TabletopCreatureCard.vue';
|
||||
import TabletopMap from '/imports/client/ui/tabletop/TabletopMap.vue';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures';
|
||||
import TabletopActionCards from '/imports/client/ui/tabletop/TabletopActionCards.vue';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import MiniCharacterSheet from '/imports/client/ui/creature/character/MiniCharacterSheet.vue';
|
||||
import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue';
|
||||
import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import ActionCard from '/imports/client/ui/tabletop/TabletopActionCard.vue';
|
||||
import SelectedCreatureBar from '/imports/client/ui/tabletop/selectedCreatureBar/SelectedCreatureBar.vue';
|
||||
|
||||
const getProperties = function (creatureId, selector = {}) {
|
||||
return CreatureProperties.find({
|
||||
'ancestors.id': {
|
||||
$eq: creatureId,
|
||||
},
|
||||
inactive: { $ne: true },
|
||||
removed: { $ne: true },
|
||||
overridden: { $ne: true },
|
||||
$nor: [
|
||||
{ hideWhenTotalZero: true, total: 0 },
|
||||
{ hideWhenValueZero: true, value: 0 },
|
||||
],
|
||||
...selector,
|
||||
}, {
|
||||
sort: { order: 1 }
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TabletopCreatureCard,
|
||||
TabletopMap,
|
||||
TabletopActionCards,
|
||||
ActionCard,
|
||||
MiniCharacterSheet,
|
||||
SelectedCreatureBar,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
@@ -58,9 +136,20 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
reactiveProvide: {
|
||||
name: 'context',
|
||||
include: ['editPermission'],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeCreature: undefined,
|
||||
activeCreatureId: undefined,
|
||||
activeActionId: undefined,
|
||||
targets: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeCreatureId(id) {
|
||||
this.$root.$emit('active-tabletop-character-change', id);
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
@@ -69,9 +158,29 @@ export default {
|
||||
return [this.model._id];
|
||||
},
|
||||
},
|
||||
creatures() {
|
||||
creatures(){
|
||||
return Creatures.find({ tabletop: this.model._id });
|
||||
},
|
||||
actions(){
|
||||
return getProperties(this.activeCreatureId, { type: 'action', actionType: { $ne: 'event'} });
|
||||
},
|
||||
moreTargets(){
|
||||
const activeAction = CreatureProperties.findOne(this.activeActionId);
|
||||
if (!activeAction) return;
|
||||
if (activeAction.target === 'singleTarget') {
|
||||
return this.targets.length === 0;
|
||||
} else if (activeAction.target === 'multipleTargets') {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
editPermission(){
|
||||
try {
|
||||
assertEditPermission(this.activeCreatureId, Meteor.userId());
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addCreature() {
|
||||
@@ -91,16 +200,53 @@ export default {
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
openCharacterSheetDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'character-sheet-dialog',
|
||||
elementId: 'mini-character-sheet',
|
||||
data: {
|
||||
creatureId: this.activeCreatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
clickProperty({_id}){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: `${_id}`,
|
||||
data: {_id},
|
||||
});
|
||||
},
|
||||
transformScroll(event) {
|
||||
if (!event.deltaY) {
|
||||
return;
|
||||
}
|
||||
event.currentTarget.scrollLeft += event.deltaY;
|
||||
event.preventDefault();
|
||||
},
|
||||
untarget(id){
|
||||
const index = this.targets.indexOf(id);
|
||||
if (index > -1) {
|
||||
this.targets.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.initiative-row>.v-card {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
height: 162px;
|
||||
width: 100px;
|
||||
margin: 4px;
|
||||
}
|
||||
.action-row > div {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
height: 120px;
|
||||
width: 200px;
|
||||
margin: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user