Characters now start with a slot for a base. New characters start on the character tab with the build dialog open.

This commit is contained in:
Stefan Zermatten
2021-01-14 12:28:51 +02:00
parent 27f1f4e720
commit 9492b2d8b8
11 changed files with 105 additions and 306 deletions

View File

@@ -4,6 +4,7 @@ import SimpleSchema from 'simpl-schema';
import deathSaveSchema from '/imports/api/properties/subSchemas/DeathSavesSchema.js'
import ColorSchema from '/imports/api/properties/subSchemas/ColorSchema.js';
import SharingSchema from '/imports/api/sharing/SharingSchema.js';
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
import {assertEditPermission} from '/imports/api/sharing/sharingPermissions.js';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js';
@@ -160,11 +161,25 @@ const insertCreature = new ValidatedMethod({
assertUserHasPaidBenefits(this.userId);
// Create the creature document
let charId = Creatures.insert({
let creatureId = Creatures.insert({
owner: this.userId,
});
CreatureProperties.insert({
slotTags: ['base'],
quantityExpected: 1,
type: 'propertySlot',
name: 'Base',
description: 'Choose a starting point for your character, this will define the basic setup of your character sheet. Without a base, your sheet will be empty.',
hideWhenFull: true,
parent: {collection: 'creatures', id: creatureId},
ancestors: [{collection: 'creatures', id: creatureId}],
order: 0,
tags: [],
spaceLeft: 1,
totalFilled: 0,
});
this.unblock();
return charId;
return creatureId;
},
});

View File

@@ -35,7 +35,11 @@
class="fill-height"
>
<v-tabs-items
v-model="activeTab"
:value="$store.state.characterSheetTabs[$route.params.id]"
@change="e => $store.commit(
'setTabForCharacterSheet',
{id: $route.params.id, tab: e}
)"
>
<v-tab-item>
<stats-tab :creature-id="creatureId" />
@@ -87,10 +91,6 @@
creatureId: {
type: String,
required: true,
},
tabs: {
type: Number,
required: true,
},
},
reactiveProvide: {

View File

@@ -78,11 +78,14 @@
<v-tabs
v-if="creature"
slot="extension"
:value="value"
centered
grow
max="100px"
@change="e => $emit('input', e)"
:value="$store.state.characterSheetTabs[$route.params.id]"
@change="e => $store.commit(
'setTabForCharacterSheet',
{id: $route.params.id, tab: e}
)"
>
<v-tab>
Stats
@@ -118,12 +121,6 @@ import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
export default {
props: {
value: {
type: Number,
required: true,
},
},
data(){return {
theme,
}},

View File

@@ -1,55 +0,0 @@
<template lang="html">
<v-tabs
v-if="creature"
slot="extension"
color="secondary"
:value="value"
centered
grow
max="100px"
@change="e => $emit('input', e)"
>
<v-tab>
Stats
</v-tab>
<v-tab>
Features
</v-tab>
<v-tab>
Inventory
</v-tab>
<v-tab>
Spells
</v-tab>
<v-tab>
Character
</v-tab>
<v-tab>
Tree
</v-tab>
</v-tabs>
</template>
<script>
import Creatures from '/imports/api/creature/Creatures.js';
export default {
props: {
value: {
type: Number,
required: true,
},
},
meteor: {
creature(){
return Creatures.findOne(this.$route.params.id);
},
},
}
</script>
<style lang="css" scoped>
.v-tabs__container--grow .v-tabs__div {
max-width: 120px !important;
}
</style>

View File

@@ -1,159 +0,0 @@
<template lang="html">
<v-toolbar-items v-if="creature">
<v-btn
v-if="editPermission"
flat
icon
@click="recompute(creature._id)"
>
<v-icon>refresh</v-icon>
</v-btn>
<v-menu
bottom
left
transition="slide-y-transition"
data-id="creature-menu"
>
<template #activator="{ on }">
<v-btn
icon
v-on="on"
>
<v-icon>more_vert</v-icon>
</v-btn>
</template>
<v-list v-if="editPermission">
<v-list-tile @click="deleteCharacter">
<v-list-tile-title>
<v-icon>delete</v-icon> Delete
</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="showCharacterForm">
<v-list-tile-title>
<v-icon>create</v-icon> Edit details
</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="showShareDialog">
<v-list-tile-title>
<v-icon>share</v-icon> Sharing
</v-list-tile-title>
</v-list-tile>
</v-list>
<v-list v-else>
<v-list-tile @click="unshareWithMe">
<v-list-tile-title>
<v-icon>delete</v-icon> Unshare with me
</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</v-toolbar-items>
</template>
<script>
import Creatures from '/imports/api/creature/Creatures.js';
import removeCreature from '/imports/api/creature/removeCreature.js';
import { mapMutations } from 'vuex';
import { theme } from '/imports/ui/theme.js';
import { recomputeCreature } from '/imports/api/creature/computation/recomputeCreature.js';
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
export default {
data(){return {
theme,
}},
computed: {
creatureId(){
return this.$route.params.id;
},
},
methods: {
...mapMutations([
'toggleDrawer',
]),
recompute(charId){
recomputeCreature.call({charId});
},
showCharacterForm(){
this.$store.commit('pushDialogStack', {
component: 'creature-form-dialog',
elementId: 'creature-menu',
data: {
_id: this.creatureId,
},
});
},
showShareDialog(){
this.$store.commit('pushDialogStack', {
component: 'share-dialog',
elementId: 'creature-menu',
data: {
docRef: {
id: this.creatureId,
collection: 'creatures',
}
},
});
},
deleteCharacter(){
let that = this;
this.$store.commit('pushDialogStack', {
component: 'delete-confirmation-dialog',
elementId: 'creature-menu',
data: {
name: this.creature.name,
typeName: 'Character'
},
callback(confirmation){
if(!confirmation) return;
removeCreature.call({charId: that.creatureId}, (error) => {
if (error) {
console.error(error);
} else {
that.$router.push('/characterList');
}
});
}
});
},
unshareWithMe(){
updateUserSharePermissions.call({
docRef: {
collection: 'creatures',
id: this.creatureId,
},
userId: Meteor.userId(),
role: 'none',
}, (error) => {
if (error) {
console.error(error);
} else {
this.$router.push('/characterList');
}
});
},
},
meteor: {
$subscribe: {
'singleCharacter'(){
return [this.creatureId];
},
},
creature(){
return Creatures.findOne(this.creatureId);
},
editPermission(){
try {
assertEditPermission(this.creature, Meteor.userId());
return true;
} catch (e) {
return false;
}
},
},
}
</script>
<style lang="css" scoped>
</style>

View File

@@ -119,38 +119,18 @@ import Slots from '/imports/ui/creature/slots/Slots.vue';
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
export default {
components: {
ColumnLayout,
NoteCard,
components: {
ColumnLayout,
NoteCard,
Slots,
ToolbarCard,
},
props: {
creatureId: {
},
props: {
creatureId: {
type: String,
required: true,
},
},
meteor: {
notes(){
return CreatureProperties.find({
'ancestors.id': this.creatureId,
type: 'note',
removed: {$ne: true},
}, {
sort: {order: 1},
});
},
creature(){
return Creatures.findOne(this.creatureId);
},
classLevels(){
return getActiveProperties({
ancestorId: this.creatureId,
filter: {type: 'classLevel'},
});
},
},
},
computed: {
highestClassLevels(){
let highestLevels = {};
@@ -171,48 +151,74 @@ export default {
return highestLevelsList;
},
},
methods: {
showCharacterForm(){
this.$store.commit('pushDialogStack', {
component: 'creature-form-dialog',
elementId: 'creature-summary',
data: {
_id: this.creatureId,
},
});
},
mounted(){
if (this.$store.state.showBuildDialog){
this.$store.commit('setShowBuildDialog', false);
this.showSlotDialog();
}
},
meteor: {
notes(){
return CreatureProperties.find({
'ancestors.id': this.creatureId,
type: 'note',
removed: {$ne: true},
}, {
sort: {order: 1},
});
},
creature(){
return Creatures.findOne(this.creatureId);
},
classLevels(){
return getActiveProperties({
ancestorId: this.creatureId,
filter: {type: 'classLevel'},
});
},
},
methods: {
showCharacterForm(){
this.$store.commit('pushDialogStack', {
component: 'creature-form-dialog',
elementId: 'creature-summary',
data: {
_id: this.creatureId,
},
});
},
addExperience(){
this.$store.commit('pushDialogStack', {
component: 'experience-insert-dialog',
elementId: 'experience-add-button',
data: {
creatureIds: [this.creatureId],
component: 'experience-insert-dialog',
elementId: 'experience-add-button',
data: {
creatureIds: [this.creatureId],
startAsMilestone: this.creature.variables.milestoneLevels &&
!!this.creature.variables.milestoneLevels.value,
},
});
},
});
},
showExperienceList(){
this.$store.commit('pushDialogStack', {
component: 'experience-list-dialog',
elementId: 'experience-info-button',
data: {
creatureId: this.creatureId,
component: 'experience-list-dialog',
elementId: 'experience-info-button',
data: {
creatureId: this.creatureId,
startAsMilestone: this.creature.variables.milestoneLevels &&
!!this.creature.variables.milestoneLevels.value,
},
});
},
});
},
showSlotDialog(){
this.$store.commit('pushDialogStack', {
component: 'slot-details-dialog',
elementId: 'slot-card',
data: {
creatureId: this.creatureId,
},
});
component: 'slot-details-dialog',
elementId: 'slot-card',
data: {
creatureId: this.creatureId,
},
});
},
},
},
};
</script>

View File

@@ -41,6 +41,7 @@
v-if="!slot.quantityExpected || slot.spaceLeft"
icon
:data-id="`slot-add-button-${slot._id}`"
class="slot-add-button"
style="background-color: inherit;"
@click="fillSlot(slot)"
>

View File

@@ -10,7 +10,6 @@
<Sidebar />
</v-navigation-drawer>
<router-view
v-model="tabs"
name="toolbar"
/>
<v-toolbar
@@ -50,7 +49,6 @@
style="width: 100%"
>
<router-view
v-model="tabs"
name="toolbarExtension"
/>
</div>
@@ -60,7 +58,7 @@
<v-fade-transition
mode="out-in"
>
<router-view :tabs.sync="tabs" />
<router-view />
</v-fade-transition>
</v-content>
<router-view

View File

@@ -141,7 +141,12 @@
if (error){
console.error(error);
} else {
this.$router.push({ path: `/character/${result}`})
this.$store.commit(
'setTabForCharacterSheet',
{id: result, tab: 4}
);
this.$store.commit('setShowBuildDialog', true);
this.$router.push({ path: `/character/${result}`});
}
});
} else {

View File

@@ -2,7 +2,6 @@
<character-sheet
show-menu-button
:creature-id="$route.params.id"
:tabs.sync="activeTab"
/>
</template>
@@ -12,21 +11,5 @@ export default {
components: {
CharacterSheet,
},
props: {
tabs: {
type: Number,
required: true,
},
},
computed: {
activeTab: {
get(){
return this.tabs;
},
set(newTab){
this.$emit('update:tabs', newTab);
},
},
},
}
</script>

View File

@@ -14,6 +14,8 @@ const store = new Vuex.Store({
drawer: undefined,
rightDrawer: undefined,
pageTitle: undefined,
characterSheetTabs: {},
showBuildDialog: false,
},
mutations: {
toggleDrawer (state) {
@@ -32,6 +34,12 @@ const store = new Vuex.Store({
state.pageTitle = value;
document.title = value;
},
setTabForCharacterSheet(state, {tab, id}){
Vue.set(state.characterSheetTabs, id, tab);
},
setShowBuildDialog(state, value){
state.showBuildDialog = value;
},
},
});