Compare commits

...

6 Commits
0.6.4 ... 0.6.5

Author SHA1 Message Date
Stefan Zermatten
15aaaa5c14 Merge branch 'release-0.6.5' 2015-07-24 11:29:50 +02:00
Stefan Zermatten
290bee83b4 Bumped version 2015-07-24 11:29:03 +02:00
Stefan Zermatten
fcd2461205 Merge branch 'master' into release-0.6.5 2015-07-24 11:26:46 +02:00
Stefan Zermatten
52198d0249 Disabled edit buttons for read-only viewers 2015-07-23 15:07:39 +02:00
Stefan Zermatten
ba7ccfdfa0 Added support for character profile pictures 2015-07-23 15:04:43 +02:00
Stefan Zermatten
92d3b086fa net worth calculations now take into account your containers' values 2015-07-23 09:14:55 +02:00
19 changed files with 135 additions and 50 deletions

View File

@@ -7,6 +7,7 @@ Schemas.Character = new SimpleSchema({
alignment: {type: String, defaultValue: "", trim: false, optional: true}, alignment: {type: String, defaultValue: "", trim: false, optional: true},
gender: {type: String, defaultValue: "", trim: false, optional: true}, gender: {type: String, defaultValue: "", trim: false, optional: true},
race: {type: String, defaultValue: "", trim: false, optional: true}, race: {type: String, defaultValue: "", trim: false, optional: true},
picture: {type: String, defaultValue: "", trim: true, optional: true},
description: {type: String, defaultValue: "", trim: false, optional: true}, description: {type: String, defaultValue: "", trim: false, optional: true},
personality: {type: String, defaultValue: "", trim: false, optional: true}, personality: {type: String, defaultValue: "", trim: false, optional: true},
ideals: {type: String, defaultValue: "", trim: false, optional: true}, ideals: {type: String, defaultValue: "", trim: false, optional: true},

View File

@@ -5,7 +5,7 @@ Schemas.TemporaryHitPoints = new SimpleSchema({
name: {type: String, optional: true}, name: {type: String, optional: true},
maximum: {type: Number, defaultValue: 0}, maximum: {type: Number, defaultValue: 0},
used: {type: Number, defaultValue: 0}, used: {type: Number, defaultValue: 0},
deleteOnZero:{type: Boolean, defaultValue: true}, deleteOnZero:{type: Boolean, defaultValue: false},
dateAdded: { dateAdded: {
type: Date, type: Date,
autoValue: function() { autoValue: function() {

View File

@@ -1,6 +1,10 @@
Template.registerHelper("canEditCharacter", function(charId) { Template.registerHelper("canEditCharacter", function(charId) {
return canEditCharacter(charId);
});
canEditCharacter = function(charId) {
var char = Characters.findOne(charId) var char = Characters.findOne(charId)
var userId = Meteor.userId(); var userId = Meteor.userId();
return char.owner === userId || return char.owner === userId ||
_.contains(char.writers, userId); _.contains(char.writers, userId);
}); };

View File

@@ -95,14 +95,15 @@
<core-tooltip label="Feature enabled" <core-tooltip label="Feature enabled"
position="left"> position="left">
<paper-checkbox class="enabledCheckbox" <paper-checkbox class="enabledCheckbox"
checked={{enabled}}> checked={{enabled}}
disabled={{#unless canEditCharacter charId}}true{{/unless}}>
</paper-checkbox> </paper-checkbox>
</core-tooltip> </core-tooltip>
{{/if}} {{/if}}
</div> </div>
{{#if description}} {{#if description}}
<div flex class="bottom text" <div flex class="bottom text"
>{{evaluateString charId description}}</div> >{{evaluateString charId shortDescription}}</div>
{{/if}} {{/if}}
{{#if hasUses}} {{#if hasUses}}
<div layout horizontal center end-justified> <div layout horizontal center end-justified>

View File

@@ -3,14 +3,19 @@ Template.features.helpers({
var features = Features.find({charId: this._id}, {sort: {color: 1, name: 1}}); var features = Features.find({charId: this._id}, {sort: {color: 1, name: 1}});
return features; return features;
}, },
shortDescription: function() {
if (_.isString(this.description)){
return this.description.split(/[\n\r]{3,}/)[0];
}
},
hasUses: function(){ hasUses: function(){
return this.usesValue() > 0; return this.usesValue() > 0;
}, },
noUsesLeft: function(){ noUsesLeft: function(){
return this.usesLeft() <= 0; return this.usesLeft() <= 0 || !canEditCharacter(this.charId);
}, },
usesFull: function(){ usesFull: function(){
return this.usesLeft() >= this.usesValue(); return this.usesLeft() >= this.usesValue() || !canEditCharacter(this.charId);
}, },
colorClass: function(){ colorClass: function(){
return getColorClass(this.color); return getColorClass(this.color);
@@ -99,12 +104,12 @@ Template.resource.helpers({
var value = Characters.calculate.attributeValue(this.char._id, this.name); var value = Characters.calculate.attributeValue(this.char._id, this.name);
var base = Characters.calculate.attributeBase(this.char._id, this.name); var base = Characters.calculate.attributeBase(this.char._id, this.name);
var baseBigger = value < base; var baseBigger = value < base;
return !baseBigger; return !baseBigger || !canEditCharacter(this.char._id);
}, },
cantDecrement: function(){ cantDecrement: function(){
var value = Characters.calculate.attributeValue(this.char._id, this.name); var value = Characters.calculate.attributeValue(this.char._id, this.name);
var valuePositive = value > 0; var valuePositive = value > 0;
return !valuePositive; return !valuePositive || !canEditCharacter(this.char._id);
}, },
getColor: function(){ getColor: function(){
var value = Characters.calculate.attributeValue(this.char._id, this.name); var value = Characters.calculate.attributeValue(this.char._id, this.name);

View File

@@ -35,8 +35,7 @@
<div class="item-slot"> <div class="item-slot">
<div class="item buff" <div class="item buff"
hero-id="main" {{detailHero}} hero-id="main" {{detailHero}}
layout horizontal center layout horizontal center>
draggable="true">
<div flex> <div flex>
<core-icon icon="work" <core-icon icon="work"
style="margin-right: 16px"> style="margin-right: 16px">
@@ -114,6 +113,7 @@
</div> </div>
<core-tooltip label="Container carried" position="left"> <core-tooltip label="Container carried" position="left">
<paper-checkbox class="carriedCheckbox" <paper-checkbox class="carriedCheckbox"
disabled={{#unless canEditCharacter charId}}true{{/unless}}
checked={{isCarried}}> checked={{isCarried}}>
</paper-checkbox> </paper-checkbox>
</core-tooltip> </core-tooltip>
@@ -152,11 +152,11 @@
<div class="item {{hidden}} inventoryItem" <div class="item {{hidden}} inventoryItem"
hero-id="main" {{detailHero}} hero-id="main" {{detailHero}}
layout horizontal center layout horizontal center
draggable="true"> draggable={{canEditCharacter charId}}>
<div flex class="itemName"> <div flex class="itemName">
{{#if ne1 quantity}}{{quantity}}&nbsp;{{/if}}{{pluralName}} {{#if ne1 quantity}}{{quantity}}&nbsp;{{/if}}{{pluralName}}
</div> </div>
{{#if settings.showIncrement}} {{#if settings.showIncrement}}{{#if canEditCharacter charId}}
<div class="incrementButtons"> <div class="incrementButtons">
<paper-icon-button class="addItemQuantity" <paper-icon-button class="addItemQuantity"
icon="add" icon="add"
@@ -166,7 +166,7 @@
icon="remove" icon="remove"
style="margin-right: -8px"></paper-icon-button> style="margin-right: -8px"></paper-icon-button>
</div> </div>
{{/if}} {{/if}}{{/if}}
</div> </div>
</div> </div>
</template> </template>

View File

@@ -44,6 +44,12 @@ Template.inventory.helpers({
).forEach(function(item){ ).forEach(function(item){
worth += item.totalValue(); worth += item.totalValue();
}); });
Containers.find(
{charId: this._id},
{fields: {value : 1}}
).forEach(function(container) {
if (container.value) worth += container.value;
});
return worth; return worth;
}, },
weightCarried: function(){ weightCarried: function(){

View File

@@ -10,7 +10,8 @@
layout horizontal center> layout horizontal center>
<div flex>Experience</div> <div flex>Experience</div>
<div >{{characterCalculate "experience" _id}} XP</div> <div >{{characterCalculate "experience" _id}} XP</div>
<paper-icon-button class="black54" id="addXP" icon="add"></paper-icon-button> <paper-icon-button class="black54" id="addXP" icon="add"
disabled={{#unless canEditCharacter _id}}true{{/unless}}></paper-icon-button>
</div> </div>
<div class="bottom list"> <div class="bottom list">
{{#each experiences}} {{#each experiences}}
@@ -55,7 +56,8 @@
</div> </div>
<paper-icon-button class="black54" <paper-icon-button class="black54"
id="addClassButton" id="addClassButton"
icon="add"> icon="add"
disabled={{#unless canEditCharacter _id}}true{{/unless}}>
</paper-icon-button> </paper-icon-button>
</div> </div>
<div class="bottom list"> <div class="bottom list">

View File

@@ -1,5 +1,5 @@
<template name="backgroundDialog"> <template name="backgroundDialog">
{{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true" startEditing=startEditing}} {{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true"}}
<div class="pre-wrap">{{evaluateString charId value}}</div> <div class="pre-wrap">{{evaluateString charId value}}</div>
{{> proficiencyViewList charId=charId parentId=charId parentGroup="background"}} {{> proficiencyViewList charId=charId parentId=charId parentGroup="background"}}
{{else}} {{else}}

View File

@@ -1,18 +1,36 @@
<template name="personaDetailsDialog"> <template name="personaDetailsDialog">
{{#baseDialog title=name class="deep-purple white-text" hideColor="true" hideDelete="true" startEditing=startEditing}} {{#baseDialog title=name class="deep-purple white-text" hideColor="true" hideDelete="true" startEditing=startEditing}}
{{alignment}} {{gender}} {{race}} {{#with char}}
<div>{{alignment}} {{gender}} {{race}}</div>
<core-image style="width: 350px; height: 350px; margin-top: 8px;"
sizing="cover"
hero-id="image" hero
src={{picture}}></core-image>
{{/with}}
{{else}} {{else}}
{{> personaDetailsEdit}} {{#with char}}
{{> personaDetailsEdit}}
{{/with}}
{{/baseDialog}} {{/baseDialog}}
</template> </template>
<template name="personaDetailsEdit"> <template name="personaDetailsEdit">
<!--Name--> <div layout horizontal center-justified>
<paper-input id="nameInput" label="Name" floatinglabel value={{name}}></paper-input><br> <div flex style="max-width: 350px;" layout vertical>
<!--Alignment--> <!--Name-->
<paper-input id="alignmentInput" label="Alignment" floatinglabel value={{alignment}}></paper-input><br> <paper-input id="nameInput" label="Name" floatinglabel value={{name}}></paper-input>
<!--Gender--> <!--Alignment-->
<paper-input id="genderInput" label="Gender" floatinglabel value={{gender}}></paper-input><br> <paper-input id="alignmentInput" label="Alignment" floatinglabel value={{alignment}}></paper-input>
<!--Race--> <!--Gender-->
<paper-input id="raceInput" label="Race" floatinglabel value={{race}}></paper-input><br> <paper-input id="genderInput" label="Gender" floatinglabel value={{gender}}></paper-input>
<!--Race-->
<paper-input id="raceInput" label="Race" floatinglabel value={{race}}></paper-input>
<!--Picture-->
<paper-input id="pictureInput" label="Picture URL" floatinglabel value={{picture}}></paper-input>
<core-image style="height:350px; width: 100%; margin-top: 8px;"
sizing="cover"
hero-id="image" hero
src={{picture}}></core-image>
</div>
</div>
</template> </template>

View File

@@ -2,21 +2,34 @@ Template.personaDetailsEdit.onRendered(function(){
updatePolymerInputs(this); updatePolymerInputs(this);
}); });
Template.personaDetailsDialog.helpers({
char: function() {
return Characters.findOne(
this._id,
{fields: {name: 1, alignment: 1, gender: 1, race: 1, picture: 1}}
);
}
});
Template.personaDetailsEdit.events({ Template.personaDetailsEdit.events({
"change #nameInput": function(event){ "change #nameInput": function(event){
var input = event.currentTarget.value; var input = event.currentTarget.value;
Characters.update(this.charId, {$set: {name: input}}); Characters.update(this._id, {$set: {name: input}});
}, },
"change #alignmentInput": function(event){ "change #alignmentInput": function(event){
var input = event.currentTarget.value; var input = event.currentTarget.value;
Characters.update(this.charId, {$set: {alignment: input}}); Characters.update(this._id, {$set: {alignment: input}});
}, },
"change #genderInput": function(event){ "change #genderInput": function(event){
var input = event.currentTarget.value; var input = event.currentTarget.value;
Characters.update(this.charId, {$set: {gender: input}}); Characters.update(this._id, {$set: {gender: input}});
}, },
"change #raceInput": function(event){ "change #raceInput": function(event){
var input = event.currentTarget.value; var input = event.currentTarget.value;
Characters.update(this.charId, {$set: {race: input}}); Characters.update(this._id, {$set: {race: input}});
},
"change #pictureInput": function(event){
var input = event.currentTarget.value;
Characters.update(this._id, {$set: {picture: input}});
}, },
}); });

View File

@@ -3,7 +3,35 @@
<div id="persona" class="scroll-y" fit> <div id="persona" class="scroll-y" fit>
<div class="column-container"> <div class="column-container">
{{#with characterDetails}} {{#with characterDetails}}
{{#containerCardHelper this}}{{alignment}} {{gender}} {{race}}{{/containerCardHelper}} <paper-shadow class="card"
hero-id="main" {{detailHero "details" _id}}>
{{#unless picture}}
<div class="top subhead characterField {{colorClass}}"
hero-id="toolbar" {{detailHero "details" _id}}>
<div class="subhead" flex
hero-id="title" {{detailHero "details" _id}}>
{{name}}
</div>
</div>
{{else}}
<core-image class="characterField clickable"
style="height:350px; width: 100%;
background-color: #e8e8e8;"
sizing="cover"
hero-id="image" {{detailHero "details" _id}}
src={{picture}}></core-image>
{{/unless}}
<div class="bottom">
{{#if picture}}
<div class="title" hero-id="title" {{detailHero "details" _id}}>
{{name}}
</div>
{{/if}}
<div class="subhead">
{{alignment}} {{gender}} {{race}}
</div>
</div>
</paper-shadow>
{{/with}} {{/with}}
{{> containerCard characterField "description" "Description"}} {{> containerCard characterField "description" "Description"}}
{{> containerCard characterField "personality" "Personality Traits"}} {{> containerCard characterField "personality" "Personality Traits"}}

View File

@@ -11,12 +11,12 @@ Template.persona.helpers({
characterDetails: function(){ characterDetails: function(){
var char = Characters.findOne( var char = Characters.findOne(
this._id, this._id,
{fields: {name: 1, gender: 1, alignment: 1, race:1}} {fields: {name: 1, gender: 1, alignment: 1, race:1, picture: 1}}
); );
char.field = "details"; char.field = "details";
char.title = char.name; char.title = char.name;
char.color = "d"; char.color = "d";
char.topClass = "characterField"; char.startEditing = true;
return char; return char;
}, },
characterField: function(field, title){ characterField: function(field, title){
@@ -40,7 +40,7 @@ Template.persona.helpers({
Template.persona.events({ Template.persona.events({
"tap .characterField": function(event){ "tap .characterField": function(event){
if (this.field === "details"){ if (this.field == "details"){
this.charId = Template.parentData()._id; this.charId = Template.parentData()._id;
GlobalUI.setDetail({ GlobalUI.setDetail({
template: "personaDetailsDialog", template: "personaDetailsDialog",
@@ -58,6 +58,7 @@ Template.persona.events({
field: this.field, field: this.field,
title: this.title, title: this.title,
color: this.color, color: this.color,
startEditing: true,
}, },
heroId: this._id + this.field, heroId: this._id + this.field,
}); });

View File

@@ -72,6 +72,7 @@
<core-tooltip label="Change prepared spells" <core-tooltip label="Change prepared spells"
position="left"> position="left">
<paper-icon-button class="prepSpells" <paper-icon-button class="prepSpells"
disabled={{#unless canEditCharacter charId}}true{{/unless}}
icon="book"> icon="book">
</paper-icon-button> </paper-icon-button>
</core-tooltip> </core-tooltip>

View File

@@ -112,7 +112,7 @@ Template.spells.helpers({
for (i = 0; i < currentSlots; i++){ for (i = 0; i < currentSlots; i++){
bubbles.push({ bubbles.push({
icon: "radio-button-on", icon: "radio-button-on",
disabled: i !== currentSlots - 1, //last full slot not disabled disabled: i !== currentSlots - 1 || !canEditCharacter(char._id), //last full slot not disabled
attribute: "level" + this.level + "SpellSlots", attribute: "level" + this.level + "SpellSlots",
charId: char._id, charId: char._id,
}); });
@@ -120,7 +120,7 @@ Template.spells.helpers({
for (i = 0; i < slotsUsed; i++){ for (i = 0; i < slotsUsed; i++){
bubbles.push({ bubbles.push({
icon: "radio-button-off", icon: "radio-button-off",
disabled: i !== 0, //first empty slot not disabled disabled: i !== 0 || !canEditCharacter(char._id), //first empty slot not disabled
attribute: "level" + this.level + "SpellSlots", attribute: "level" + this.level + "SpellSlots",
charId: char._id, charId: char._id,
}); });

View File

@@ -6,7 +6,11 @@
hero-id="toolbar" {{detailHero "hitPoints" _id}} hero-id="toolbar" {{detailHero "hitPoints" _id}}
layout vertical center center-justified> layout vertical center center-justified>
<div class="hitPointTitle clickable">Hit Points</div> <div class="hitPointTitle clickable">Hit Points</div>
<paper-icon-button class="white54" id="addTempHP" icon="add"></paper-icon-button> <paper-icon-button class="white54"
id="addTempHP"
icon="add"
disabled={{#unless canEditCharacter _id}}true{{/unless}}>
</paper-icon-button>
</div> </div>
<div class="right" flex layout vertical center-justified style="min-width: 180px;"> <div class="right" flex layout vertical center-justified style="min-width: 180px;">
<div layout horizontal> <div layout horizontal>
@@ -14,6 +18,7 @@
value={{characterCalculate "attributeValue" _id "hitPoints"}} value={{characterCalculate "attributeValue" _id "hitPoints"}}
max={{characterCalculate "attributeBase" _id "hitPoints"}} max={{characterCalculate "attributeBase" _id "hitPoints"}}
editable pin editable pin
disabled={{#unless canEditCharacter _id}}true{{/unless}}
role="slider"> role="slider">
</paper-diff-slider> </paper-diff-slider>
</div> </div>

View File

@@ -2,11 +2,11 @@ Template.hitDice.helpers({
cantIncrement: function(){ cantIncrement: function(){
var value = Characters.calculate.attributeValue(this.char._id, this.name); var value = Characters.calculate.attributeValue(this.char._id, this.name);
var base = Characters.calculate.attributeBase(this.char._id, this.name); var base = Characters.calculate.attributeBase(this.char._id, this.name);
return value >= base; return value >= base || !canEditCharacter(this.char._id);
}, },
cantDecrement: function(){ cantDecrement: function(){
var value = Characters.calculate.attributeValue(this.char._id, this.name); var value = Characters.calculate.attributeValue(this.char._id, this.name);
return value <= 0; return value <= 0 || !canEditCharacter(this.char._id);
}, },
conMod: function(){ conMod: function(){
return signedString( return signedString(

View File

@@ -9,20 +9,11 @@ Template.baseDialog.onRendered(function(){
Template.baseDialog.helpers({ Template.baseDialog.helpers({
editing: function(){ editing: function(){
return Template.instance().editing.get(); return Template.instance().editing.get() && canEditCharacter(Template.parentData().charId);
}, },
showEdit: function() { showEdit: function() {
if (this.hideEdit) return false; if (this.hideEdit) return false;
var charId = Template.parentData().charId; return canEditCharacter(Template.parentData().charId);
var userId = Meteor.userId();
if (!userId) return false;
if (charId){
var char = Characters.findOne(charId);
if (char)
return char.owner === userId ||
_.contains(char.writers, userId);
}
return true;
}, },
}); });

View File

@@ -219,3 +219,12 @@ ChangeLogs.insert({
"Skills should have correct min and max effects applied again", "Skills should have correct min and max effects applied again",
], ],
}); });
ChangeLogs.insert({
version: "0.6.5",
changes: [
"Net worth now takes container values into account",
"Added support for character pictures",
"Disabled edit buttons for reada-only viewers",
],
});