Implemented Feature editing UI

This commit is contained in:
Thaum
2015-01-21 11:16:00 +00:00
parent 078f873219
commit 84512beb72
32 changed files with 1072 additions and 161 deletions

View File

@@ -0,0 +1,55 @@
this.GlobalUI = (function() {
function GlobalUI() {}
GlobalUI.dialog = {};
GlobalUI.toast = function(text, className) {
var toast;
toast = $("[global-toast]")[0];
toast.text = text;
return toast.show();
};
GlobalUI.showDialog = function(opts) {
this.dialog = $("[global-dialog]")[0];
Session.set("global.ui.dialogHeader", opts.heading);
Session.set("global.ui.dialogData", opts.data);
Session.set("global.ui.dialogTemplate", opts.template);
Session.set("global.ui.dialogFullOnMobile", opts.fullOnMobile != null);
return Tracker.afterFlush((function(_this) {
return function() {
return _this.dialog.open();
};
})(this));
};
GlobalUI.closeDialog = function() {
return this.dialog.close();
};
return GlobalUI;
})();
Template.layout.helpers({
globalDialogTemplate: function() {
return Session.get("global.ui.dialogTemplate");
},
globalDialogData: function() {
return Session.get("global.ui.dialogData");
},
globalDialogFullOnMobile: function() {
return Session.get("global.ui.dialogFullOnMobile");
},
globalDialogHeader: function(){
return Session.get("global.ui.dialogHeader");
}
});
Template.layout.events({
"core-overlay-close-completed [global-dialog]": function(e) {
Session.set("global.ui.dialogTemplate", null);
Session.set("global.ui.dialogData", null);
return Session.set("global.ui.dialogFullOnMobile", null);
},
});

View File

@@ -0,0 +1 @@
AutoForm.setDefaultTemplate('paper');

View File

@@ -1,5 +1,5 @@
<template name="stats">
<core-animated-pages selected={{selectedSection}} transitions="hero-transition cross-fade">
<core-animated-pages selected={{selectedSection}} transitions="hero-transition cross-fade" fit style="overflow-y: scroll">
<section id="stats">
{{> abilityCards}}
</section>

View File

@@ -17,14 +17,14 @@
</paper-tabs>
</div>
</core-toolbar>
<div>
<core-animated-pages id="tabPages" selected={{selectedTab}} transitions="slide-from-right">
<swipe-detect touch-action="pan-y">{{> stats}}</swipe-detect>
<swipe-detect touch-action="pan-y">{{> features}}</swipe-detect>
<swipe-detect touch-action="pan-y">inventory</swipe-detect>
<swipe-detect touch-action="pan-y">spellBook</swipe-detect>
<swipe-detect touch-action="pan-y">persona</swipe-detect>
<swipe-detect touch-action="pan-y">journal</swipe-detect>
<div fit>
<core-animated-pages id="tabPages" selected={{selectedTab}} transitions="slide-from-right" fit>
<swipe-detect touch-action="pan-y" flex>{{> stats}}</swipe-detect>
<swipe-detect touch-action="pan-y" flex>{{> features}}</swipe-detect>
<swipe-detect touch-action="pan-y" flex>{{> inventory}}</swipe-detect>
<swipe-detect touch-action="pan-y" flex>spellBook</swipe-detect>
<swipe-detect touch-action="pan-y" flex>persona</swipe-detect>
<swipe-detect touch-action="pan-y" flex>journal</swipe-detect>
</core-animated-pages>
</div>
</template>

View File

@@ -0,0 +1,24 @@
<template name="autoFeatureDialog">
{{> quickForm schema="Schemas.Feature" id="insertFeatureForm" type="insert"}}
<paper-button affirmative>Cancel</paper-button>
<paper-button affirmative>Save Item</paper-button>
</template>
<template name="featureDialog">
{{#with feature}}
<div class="featureDialogWidth"></div>
<paper-input id="featureNameInput" label="Name" floatinglabel value={{name}}></paper-input>
<paper-input-decorator label="Description" floatinglabel layout vertical>
<paper-autogrow-textarea>
<textarea id="featureDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
</paper-autogrow-textarea>
</paper-input-decorator>
<h3>Effects</h3>
{{#each effects}}
{{>featureEffect}}
{{/each}}
<br>
<paper-icon-button id="addEffectButton" role="button" tabindex="0" icon="add" aria-label="addEffect"></paper-icon-button>
{{/with}}
<paper-button affirmative>Done</paper-button>
</template>

View File

@@ -0,0 +1,36 @@
Template.featureDialog.rendered = function(){
var self = this;
this.autorun(function(){
var feature = Features.findOne(Template.currentData().featureId, {fields: {name: 1}});
if(feature && feature.name) Session.set("global.ui.dialogHeader", feature.name);
})
}
Template.featureDialog.events({
"tap #addEffectButton": function(){
var numUpdated = Features.update(this._id, {
$push: {
"effects": {
name: "fe",
operation: "add",
type: "feature"
}
}
});
console.log("pushed add button ", numUpdated, " updated");
},
"change #featureNameInput": function(event){
var name = Template.instance().find("#featureNameInput").value;
Features.update(this._id, {$set: {name: name}});
},
"change #featureDescriptionInput": function(event){
var description = Template.instance().find("#featureDescriptionInput").value;
Features.update(this._id, {$set: {description: description}});
}
});
Template.featureDialog.helpers({
feature: function(){
return Features.findOne(this.featureId);
}
});

View File

@@ -0,0 +1,69 @@
<template name="featureEffect">
<paper-dropdown-menu id="statGroupDropDown" label="Stat Group">
<paper-dropdown class="dropdown">
<core-menu id="statGroupMenu" class="menu" selected={{selectedStatGroup}}>
{{#each statGroups}}
<paper-item>{{this}}</paper-item>
{{/each}}
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
{{#if stats}}
<paper-dropdown-menu id="statDropDown" label="Stat">
<paper-dropdown class="dropdown">
<core-menu id="statMenu" class="menu" selected={{selectedStat}}>
{{#each stats}}
<paper-item>{{name}}</paper-item>
{{/each}}
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
{{/if}}
{{#if operations}}
<paper-dropdown-menu id="operationDropDown" label="Operation">
<paper-dropdown class="dropdown">
<core-menu id="operationMenu" class="menu" selected={{selectedOperation}}>
{{#each operations}}
<paper-item>{{name}}</paper-item>
{{/each}}
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
{{/if}}
{{> Template.dynamic template=effectValueTemplate data=valueTemplateData}}
{{#if needsCommit}}
<paper-icon-button id="commitChanges" role="button" tabindex="0" icon="check" aria-label="Commit Changes"></paper-icon-button>
<paper-icon-button id="clearChanges" role="button" tabindex="0" icon="clear" aria-label="Clear Changes"></paper-icon-button>
{{else}}
<paper-icon-button id="deleteEffect" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
{{/if}}
<br>
</template>
<template name="regularEffectValue">
<paper-input id="effectValueInput" label="Value" floatinglabel value={{effectValue}}></paper-input>
</template>
<template name="multiplierEffectValue">
<paper-dropdown-menu id="damageMultiplierDropDown" label="Damage Multiplier">
<paper-dropdown class="dropdown">
<core-menu id="multiplierMenu" class="menu" selected={{selectedDamageMultiplier}}>
<paper-item>Resistance</paper-item>
<paper-item>Vulnerability</paper-item>
<paper-item>Immunity</paper-item>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
<template name="proficiencyEffectValue">
<paper-dropdown-menu id="proficiencyDropDown" label="Proficiency">
<paper-dropdown class="dropdown">
<core-menu id="proficiencyMenu" class="menu" selected={{selectedProfiencyMultiplier}}>
<paper-item>Proficient</paper-item>
<paper-item>Half Prof. Bonus</paper-item>
<paper-item>Double Prof. Bonus</paper-item>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>

View File

@@ -0,0 +1,329 @@
var stats = [
{stat: "strength", name: "Strength", group: "Ability Scores"},
{stat: "dexterity", name: "Dexterity", group: "Ability Scores"},
{stat: "constitution", name: "Constitution", group: "Ability Scores"},
{stat: "intelligence", name: "Intelligence", group: "Ability Scores"},
{stat: "wisdom", name: "Wisdom", group: "Ability Scores"},
{stat: "charisma", name: "Charisma", group: "Ability Scores"},
{name: "Strength Save", stat: "strengthSave", group: "Saving Throws"},
{name: "Dexterity Save", stat: "dexteritySave", group: "Saving Throws"},
{name: "Constitution Save", stat: "constitutionSave", group: "Saving Throws"},
{name: "Intelligence Save", stat: "intelligenceSave", group: "Saving Throws"},
{name: "Wisdom Save", stat: "wisdomSave", group: "Saving Throws"},
{name: "Charisma Save", stat: "charismaSave", group: "Saving Throws"},
{name: "Acrobatics", stat: "acrobatics", group: "Skills"},
{name: "Animal Handling", stat: "animalHandling", group: "Skills"},
{name: "Arcana", stat: "arcana", group: "Skills"},
{name: "Athletics", stat: "athletics", group: "Skills"},
{name: "Deception", stat: "deception", group: "Skills"},
{name: "History", stat: "history", group: "Skills"},
{name: "Insight", stat: "insight", group: "Skills"},
{name: "Intimidation", stat: "intimidation", group: "Skills"},
{name: "Investigation", stat: "investigation", group: "Skills"},
{name: "Medicine", stat: "medicine", group: "Skills"},
{name: "Nature", stat: "nature", group: "Skills"},
{name: "Perception", stat: "perception", group: "Skills"},
{name: "Performance", stat: "performance", group: "Skills"},
{name: "Persuasion", stat: "persuasion", group: "Skills"},
{name: "Religion", stat: "religion", group: "Skills"},
{name: "Sleight of Hand", stat: "sleightOfHand", group: "Skills"},
{name: "Stealth", stat: "stealth", group: "Skills"},
{name: "Survival", stat: "survival", group: "Skills"},
{stat: "hitPoints", name: "Hit Points", group: "Stats"},
{stat: "armor", name: "Armor", group: "Stats"},
{stat: "speed", name: "Speed", group: "Stats"},
{stat: "ki", name: "Ki Points", group: "Stats"},
{stat: "sorceryPoints", name: "Sorcery Points", group: "Stats"},
{stat: "rages", name: "Rages", group: "Stats"},
{stat: "rageDamage", name: "Rage Damage", group: "Stats"},
{stat: "expertiseDice", name: "Expertise Dice", group: "Stats"},
{stat: "superiorityDice", name: "Superiority Dice", group: "Stats"},
{stat: "level1SpellSlots", name: "level 1", group: "Spell Slots"},
{stat: "level2SpellSlots", name: "level 2", group: "Spell Slots"},
{stat: "level3SpellSlots", name: "level 3", group: "Spell Slots"},
{stat: "level4SpellSlots", name: "level 4", group: "Spell Slots"},
{stat: "level5SpellSlots", name: "level 5", group: "Spell Slots"},
{stat: "level6SpellSlots", name: "level 6", group: "Spell Slots"},
{stat: "level7SpellSlots", name: "level 7", group: "Spell Slots"},
{stat: "level8SpellSlots", name: "level 8", group: "Spell Slots"},
{stat: "level9SpellSlots", name: "level 9", group: "Spell Slots"},
{stat: "d6HitDice", name: "d6", group: "Hit Dice"},
{stat: "d8HitDice", name: "d8", group: "Hit Dice"},
{stat: "d10HitDice", name: "d10", group: "Hit Dice"},
{stat: "d12HitDice", name: "d12", group: "Hit Dice"},
{stat: "acidMultiplier", name: "Acid", group: "Weakness/Resistance"},
{stat: "bludgeoningMultiplier", name: "Bludgeoning", group: "Weakness/Resistance"},
{stat: "coldMultiplier", name: "Cold", group: "Weakness/Resistance"},
{stat: "fireMultiplier", name: "Fire", group: "Weakness/Resistance"},
{stat: "forceMultiplier", name: "Force", group: "Weakness/Resistance"},
{stat: "lightningMultiplier", name: "Lightning", group: "Weakness/Resistance"},
{stat: "necroticMultiplier", name: "Necrotic", group: "Weakness/Resistance"},
{stat: "piercingMultiplier", name: "Piercing", group: "Weakness/Resistance"},
{stat: "poisonMultiplier", name: "Poison", group: "Weakness/Resistance"},
{stat: "psychicMultiplier", name: "Psychic", group: "Weakness/Resistance"},
{stat: "radiantMultiplier", name: "Radiant", group: "Weakness/Resistance"},
{stat: "slashingMultiplier", name: "Slashing", group: "Weakness/Resistance"},
{stat: "thunderMultiplier", name: "Thunder", group: "Weakness/Resistance"}
];
var statsDict = _.indexBy(stats, "stat")
var statGroups = _.groupBy(stats, "group");
var statGroupNames = _.keys(statGroups);
var statGroupIndex = function(statName){
if(!_.isString(statName)) return;
var stat = statsDict[statName];
if(stat){
return _.indexOf(statGroupNames, stat.group)
}
}
var statIndex = function(statName){
if(!_.isString(statName)) return;
var stat = statsDict[statName];
if(!stat) return;
var group = statGroups[stat.group];
if(!group) return;
return _.indexOf(_.pluck(group, "stat"), statName);
}
var attributeOperations = [
{name: "Base Value", operation: "base"},
{name: "Add", operation: "add"},
{name: "Multiply", operation: "mul"},
{name: "Min", operation: "min"},
{name: "Max", operation: "max"}
];
var skillOperations = [
{name: "Proficiency", operation: "proficiency"},
{name: "Add", operation: "add"},
{name: "Multiply", operation: "mul"},
{name: "Min", operation: "min"},
{name: "Max", operation: "max"},
{name: "Advantage", operation: "advantage"},
{name: "Disadvantage", operation: "disadvantage"},
{name: "Passive Bonus", operation: "passiveAdd"},
{name: "Automatically Fail", operation: "fail"},
{name: "Conditional Benefit", operation: "conditional"}
];
var operationIndex = function(statName, operation){
if(!_.isString(statName)) return;
if(!_.isString(operation)) return;
var group = statsDict[statName].group;
var opGroup;
if(group === "Saving Throws" || group === "Skills"){
opGroup = skillOperations;
} else {
opGroup = attributeOperations;
}
return _.indexOf(_.pluck(opGroup, "operation"), operation);
}
Template.featureEffect.created = function(){
this.selectedStatGroup = new ReactiveVar();
this.selectedStat = new ReactiveVar();
this.selectedOperation = new ReactiveVar();
this.value = new ReactiveVar();
};
Template.featureEffect.rendered = function(){
var self = this;
self.autorun(function(){
var data = Template.currentData();
if(!data) return;
if(data.stat){
if(statsDict[data.stat]){
self.selectedStatGroup.set(statsDict[data.stat].group);
}
self.selectedStat.set(data.stat);
}
if(data.operation){
self.selectedOperation.set(data.operation);
}
var value = undefined;
if(_.isNumber(data.value)){
value = data.value;
} else if (_.isString(data.calculation)){
value = data.calculation;
}
if(value){
self.value.set(value);
}
})
};
Template.featureEffect.helpers({
selectedStatGroup: function(){
var groupName = Template.instance().selectedStatGroup.get();
return _.indexOf(statGroupNames, groupName);
},
selectedStat: function(){
var statName = Template.instance().selectedStat.get();
return statIndex(statName);
},
selectedOperation: function(){
var opName = Template.instance().selectedOperation.get();
var statName = Template.instance().selectedStat.get();
return operationIndex(statName, opName);
},
statGroups: function(){
return statGroupNames;
},
stats: function(){
var group = Template.instance().selectedStatGroup.get();
return statGroups[group];
},
operations: function(){
var group = Template.instance().selectedStatGroup.get();
if(group === "Weakness/Resistance") return null;
if(group === "Saving Throws" || group === "Skills"){
return skillOperations;
} else {
return attributeOperations;
}
},
effectValueTemplate: function(){
//resistance/vulnerability template
var group = Template.instance().selectedStatGroup.get();
if(group === "Weakness/Resistance") return "multiplierEffectValue";
var op = Template.instance().selectedOperation.get();
if(!op) return null;
//operations that don't need templates
if(op === "advantage" || op === "disadvantage" || op === "fail") return null;
//proficiency template
if(op === "proficiency") return "proficiencyEffectValue";
//default template
return "regularEffectValue";
},
needsCommit: function(){
var inst = Template.instance();
if(
inst.selectedStat.get() !== this.stat ||
inst.selectedOperation.get() !== this.operation ||
(inst.value.get() !== this.value && inst.value.get() !== this.calculation)
){
return true;
} else {
return false;
}
},
valueTemplateData: function(){
var value = Template.instance().value.get()
var effectValue = value;
var selectedDamageMultiplier = null;
if(value === 0.5) selectedDamageMultiplier = 0;
if(value === 2) selectedDamageMultiplier = 1;
if(value === 0) selectedDamageMultiplier = 2;
var selectedProfiencyMultiplier = null;
if(value === 1) selectedProfiencyMultiplier = 0;
if(value === 0.5) selectedProfiencyMultiplier = 1;
if(value === 2) selectedProfiencyMultiplier = 2;
var data = {
effectValue: effectValue,
selectedDamageMultiplier: selectedDamageMultiplier,
selectedProfiencyMultiplier: selectedProfiencyMultiplier
};
return data;
}
});
Template.featureEffect.events({
"tap #commitChanges": function(event){
var newEffect = this;
var inst = Template.instance();
newEffect.operation = inst.selectedOperation.get();
newEffect.stat = inst.selectedStat.get();
var val = inst.value.get();
if(_.isNumber(val)){
newEffect.value = val;
newEffect.calculation = null;
} else if(_.isString(val)) {
newEffect.calculation = val;
newEffect.value = null;
}
Meteor.call("updateFeatureEffect", Template.parentData()._id, newEffect);
},
"tap #clearChanges": function(event){
//essentially re-render
var inst = Template.instance();
if(this.operation) inst.selectedOperation.set(this.operation);
if(this.stat) inst.selectedStat.set(this.stat);
if(this.stat) inst.selectedStatGroup.set(statsDict[this.stat].group)
var value = undefined;
if(_.isNumber(this.value)){
value = this.value;
} else if (_.isString(this.calculation)){
value = this.calculation;
}
inst.value.set(value);
},
"tap #deleteEffect": function(event){
Features.update(Template.parentData()._id, { $pull: { "effects": {_id: this._id} } });
},
"core-select #statGroupMenu": function(event){
var groupIndex = Template.instance().find("#statGroupMenu").selected;
var groupName = statGroupNames[groupIndex]
var oldName = Template.instance().selectedStatGroup.get();
if(oldName != groupName){
Template.instance().selectedStatGroup.set(groupName);
var oldIndex = statGroupIndex(Template.instance().selectedStat.get())
if(oldIndex != groupIndex){
Template.instance().selectedStat.set(null);
}
}
},
"core-select #statMenu": function(event){
var statIndex = Template.instance().find("#statMenu").selected;
var groupIndex = Template.instance().find("#statGroupMenu").selected;
var groupName = statGroupNames[groupIndex]
var group = statGroups[groupName];
var statObj = group[statIndex];
if(!statObj) return;
var statName = statObj.stat;
Template.instance().selectedStat.set(statName);
},
"core-select #operationMenu": function(event){
var groupName = Template.instance().selectedStatGroup.get();
var opGroup = (groupName === "Saving Throws" || groupName === "Skills")? skillOperations : attributeOperations;
var opIndex = Template.instance().find("#operationMenu").selected;
var op = opGroup[opIndex];
if(!op) return;
var opName = op.operation;
Template.instance().selectedOperation.set(opName);
},
"core-select #multiplierMenu": function(event){
var inst = Template.instance();
var selected = Template.instance().find("#multiplierMenu").selected;
if(selected === 0){
inst.value.set(0.5);
inst.selectedOperation.set("mul");
} else if (selected === 1){
inst.value.set(2);
inst.selectedOperation.set("mul");
} else if (selected === 2){
inst.value.set(0);
inst.selectedOperation.set("max");
}
},
"core-select #proficiencyMenu": function(event){
var inst = Template.instance();
var selected = inst.find("#proficiencyMenu").selected;
var value;
if(selected === 0){
inst.value.set(1);
} else if (selected === 1){
inst.value.set(0.5);
} else if (selected === 2){
inst.value.set(2);
}
},
"change #effectValueInput": function(event){
var inst = Template.instance();
var value = inst.find("#effectValueInput").value;
inst.value.set(value);
}
});

View File

@@ -0,0 +1,5 @@
paper-shadow.featureCard {
padding: 16px;
margin: 8px;
background: white;
}

View File

@@ -1,32 +1,22 @@
<template name="features">
<div class="statsFlex"><!--resources-->
{{#if attributeBase "rages"}}
{{#statCard id="rages" type="attribute" title="Rages"}}
{{attributeValue "rages"}}
{{/statCard}}
{{/if}}
{{#if canCast}}
{{#statCard id="spellSlots" type="attribute" title="Spell Slots"}}
<h1>{{> spellSlots}}</h1>
{{/statCard}}
{{/if}}
{{#if attributeBase "sorceryPoints"}}
{{#statCard id="sorceryPoints" type="attribute" title="Sorcery Points"}}
{{attributeValue "sorceryPoints"}}
{{/statCard}}
{{/if}}
{{#if attributeBase "expertiseDice"}}
{{#statCard id="expertiseDice" type="attribute" title="Expertise Dice"}}
{{attributeValue "expertiseDice"}}
{{/statCard}}
{{/if}}
{{#if attributeBase "superiorityDice"}}
{{#statCard id="superiorityDice" type="attribute" title="Superiority Dice"}}
{{attributeValue "superiorityDice"}}
{{/statCard}}
{{/if}}
</div>
<div class="actionsFlex">
<div class="resources"><!--resources-->
</div>
<div class="actions">
</div>
<div class="features">
{{#each features}}
<paper-shadow class="featureCard">
<div class="featureCardTop">
<h1>{{name}}</h1>
</div>
<div class="featureCardBottom">
<p>{{description}}</p>
</div>
<paper-ripple fit></paper-ripple>
</paper-shadow>
{{/each}}
</div>
<paper-fab id="addFeature" icon="add" title="Add" role="button" tabindex="0" aria-label="Add"></paper-fab>
</template>

View File

@@ -1,19 +1,27 @@
Template.features.helpers({
features: function(){
var features = Features.find({character: this._id});
var features = Features.find({charId: this._id});
return features;
}
});
Template.features.events({
// Fires when any element is clicked
'change .enabled': function (event) {
var enable = event.target.checked
Features.update(this._id, {$set: {enabled: enable}});
if(enable){
Template.parentData(1).pushEffects(this.name, this.effects);
} else {
Template.parentData(1).pullEffects(this.effects);
}
"tap #addFeature": function(event){
var featureId = Features.insert({name: "New Feature", charId: this._id});
GlobalUI.showDialog({
heading: "New Feature",
template: "featureDialog",
data: {featureId: featureId},
fullOnMobile: true
})
},
"tap .featureCard": function(event){
var featureId = this._id;
GlobalUI.showDialog({
heading: this.name,
template: "featureDialog",
data: {featureId: featureId},
fullOnMobile: true
})
}
});

View File

@@ -0,0 +1,23 @@
body /deep/ .featureDialogWidth {
width: 600px;
}
body /deep/ #statGroupDropDown {
width: 120px;
}
body /deep/ #statDropDown {
width: 120px;
}
body /deep/ #operationDropDown {
width: 100px;
}
body /deep/ #damageMultiplierDropDown {
width: 120px;
}
body /deep/ #proficiencyDropDown {
width: 120px;
}

View File

@@ -1,20 +1,27 @@
<template name="inventory">
<paper-shadow class="equipment">
Armor: {{#if equippedArmor}}{{equippedArmor}}{{else}}None{{/if}}
<paper-shadow class="equipment card double">
Armor:<br>
<paper-item>{{#if armor}}{{armor.name}}{{else}}none{{/if}}</paper-item>
Equipment:<br>
{{#each equipment}}
<paper-item>
{{name}}
</paper-item>
{{/each}}
</paper-shadow>
<div class="containers">
{{#each containers}}
<paper-shadow>
<h3>{{name}}</h3>
<table>
{{#each items}}
<tr class={{#if isSelected}}selected{{/if}}>
<td>{{#if stackable}}{{quantity}}{{/if}}</td>
<td>{{pluralName}}</td>
</tr>
{{/each}}
</table>
</paper-shadow>
<paper-shadow class="card">
<h3>{{name}}</h3>
{{#each items ../_id _id}}
<paper-item>
{{#if stackable}}{{quantity}}{{/if}} {{pluralName}}
</paper-item>
{{/each}}
</paper-shadow>
{{/each}}
</div>
<paper-fab id="add" icon="add" title="Add" role="button" tabindex="0" aria-label="Add"></paper-fab>
<paper-fab id="addItem" icon="note-add" title="Add Item" role="button" tabindex="0" aria-label="Add Item"></paper-fab>
<paper-fab id="addContainer" icon="work" title="Add Container" role="button" tabindex="0" aria-label="Add Container"></paper-fab>
</template>

View File

@@ -0,0 +1,27 @@
Template.inventory.helpers({
containers: function(){
return Containers.find({charId: this._id})
},
items: function(charId, containerId){
return Items.find({charId: charId, equipped: false, container: containerId })
},
armor: function(){
return Items.findOne({ charId: this._id, equipped: true, equipmentSlot: "armor" })
},
equipment: function(){
return Items.find({ charId: this._id, equipped: true, equipmentSlot: {$ne: "armor"} })
}
});
Template.inventory.events({
"tap #addItem": function(){
GlobalUI.showDialog({
template: "itemDialog",
data: null,
fullOnMobile: true
})
},
"tap #addContainer": function(){
Containers.insert({name: "New Container", isCarried: true, charId: this._id});
}
})

View File

@@ -0,0 +1,5 @@
<template name="itemDialog">
{{> quickForm collection="Items" id="insertItemForm" type="insert"}}
<paper-button affirmative>Cancel</paper-button>
<paper-button affirmative>Save Item</paper-button>
</template>

View File

@@ -1,6 +1,6 @@
<head>
<title>RPG Docs</title>
<meta name="viewport" content="width=device-width initial-scale=1.0, user-scalable=no">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic,900,900italic,100italic,100&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic,900,900italic,100italic,100&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<script src="/components/webcomponentsjs/webcomponents.js"></script>
</head>

View File

@@ -8,11 +8,15 @@
<link rel="import" href="/components/core-scaffold/core-scaffold.html">
<!--paper components-->
<link rel="import" href="/components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="/components/paper-dialog/paper-dialog.html">
<link rel="import" href="/components/paper-dropdown/paper-dropdown.html">
<link rel="import" href="/components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="/components/paper-fab/paper-fab.html">
<link rel="import" href="/components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="/components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="/components/paper-input/paper-input.html">
<link rel="import" href="/components/paper-input/paper-input-decorator.html">
<link rel="import" href="/components/paper-item/paper-item.html">
<link rel="import" href="/components/paper-shadow/paper-shadow.html">
<link rel="import" href="/components/paper-spinner/paper-spinner.html">

View File

@@ -13,11 +13,14 @@
</core-header-panel>
</core-drawer-panel>
<paper-action-dialog global-dialog layered backdrop
<paper-action-dialog global-dialog backdrop
transition="paper-dialog-transition-bottom"
full-on-mobile>
class={{#if globalDialogFullOnMobile}}full-on-mobile{{/if}}
autoclosedisabled
heading={{globalDialogHeader}}
layered>
{{#if globalDialogTemplate}}
{{> UI.dynamic template=globalDialogTemplate data=globalDialogData}}
{{> UI.dynamic template=globalDialogTemplate data=globalDialogData}}
{{/if}}
</paper-action-dialog>