Compare commits

...

28 Commits
0.6.4 ... 0.6.8

Author SHA1 Message Date
Stefan Zermatten
d9368b06d0 Merge branch 'bugfix-0.6.8' 2015-08-27 12:07:42 +02:00
Stefan Zermatten
2703367681 Proficiencies now get disabled when their features are disabled 2015-08-27 12:05:56 +02:00
Stefan Zermatten
d419442549 Fixed share dialog not finding usernames or email addresses 2015-08-27 11:59:38 +02:00
Stefan Zermatten
99df01c950 Prevented negative temporary hitpoints being added 2015-08-27 11:43:34 +02:00
Stefan Zermatten
d76349b3bb Merge branch 'release-0.6.7a' 2015-07-29 09:57:06 +02:00
Stefan Zermatten
39c061f4e8 Fixed formatting of not found page, now has a toolbar and centered text 2015-07-29 09:55:22 +02:00
Stefan Zermatten
6d167ddb22 Fixed formatting of loading page, more padding 2015-07-29 09:55:01 +02:00
Stefan Zermatten
037acbd459 Added Starter Set Wizard to the front page 2015-07-29 09:54:43 +02:00
Stefan Zermatten
4d3fc3bb09 Fixed accidental back() requests when closing detail dialogs 2015-07-29 09:54:18 +02:00
Stefan Zermatten
4b984d4fac Made analytics show all characters as the same page 2015-07-29 09:53:46 +02:00
Stefan Zermatten
58843613ba Merge branch 'release-0.6.7' 2015-07-27 13:12:42 +02:00
Stefan Zermatten
39b549b24b Bumped version 2015-07-27 13:12:28 +02:00
Stefan Zermatten
c79177de72 Added Google Analytics 2015-07-27 13:10:33 +02:00
Stefan Zermatten
11d09b1487 Fixed effect values not being visible on mobile 2015-07-27 12:16:02 +02:00
Stefan Zermatten
0e4918d57d Merge branch 'hotfix-style' 2015-07-27 12:08:22 +02:00
Stefan Zermatten
949f313af2 removed 1st column of all tables being 100px 2015-07-27 12:08:15 +02:00
Stefan Zermatten
85b63f152f Merge branch 'release-0.6.6' into develop 2015-07-27 11:23:12 +02:00
Stefan Zermatten
2141d52a7a Merge branch 'release-0.6.6' 2015-07-27 11:22:41 +02:00
Stefan Zermatten
4c84235064 Bumped version 2015-07-27 11:22:26 +02:00
Stefan Zermatten
0e194a5408 Added markdown to text areas 2015-07-27 10:21:26 +02:00
Stefan Zermatten
4b60eac330 Fixed typo on change log 2015-07-24 11:52:46 +02:00
Stefan Zermatten
cb017c359d Merge branch 'release-0.6.5' into develop 2015-07-24 11:31:05 +02:00
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
42 changed files with 228 additions and 86 deletions

1
rpg-docs/.gitignore vendored
View File

@@ -1,5 +1,6 @@
.meteor/local .meteor/local
.meteor/meteorite .meteor/meteorite
settings.json
public/components public/components
nohup.out nohup.out
dump dump

View File

@@ -27,3 +27,5 @@ fourseven:scss@2.1.1
wolves:bourbon wolves:bourbon
meteorhacks:subs-manager meteorhacks:subs-manager
meteorhacks:kadira meteorhacks:kadira
chuangbo:marked
reywood:iron-router-ga

View File

@@ -14,6 +14,7 @@ blaze-tools@1.0.3
boilerplate-generator@1.0.3 boilerplate-generator@1.0.3
callback-hook@1.0.3 callback-hook@1.0.3
check@1.0.5 check@1.0.5
chuangbo:marked@0.3.5
coffeescript@1.0.6 coffeescript@1.0.6
dburles:collection-helpers@1.0.3 dburles:collection-helpers@1.0.3
dburles:mongo-collection-instances@0.3.3 dburles:mongo-collection-instances@0.3.3
@@ -70,6 +71,7 @@ reactive-dict@1.1.0
reactive-var@1.0.5 reactive-var@1.0.5
reload@1.1.3 reload@1.1.3
retry@1.0.3 retry@1.0.3
reywood:iron-router-ga@0.6.0
routepolicy@1.0.5 routepolicy@1.0.5
service-configuration@1.0.4 service-configuration@1.0.4
session@1.1.0 session@1.1.0

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

@@ -30,7 +30,7 @@ Schemas.Proficiency = new SimpleSchema({
Proficiencies.attachSchema(Schemas.Proficiency); Proficiencies.attachSchema(Schemas.Proficiency);
Proficiencies.attachBehaviour("softRemovable"); Proficiencies.attachBehaviour("softRemovable");
makeChild(Proficiencies); makeChild(Proficiencies, ["enabled"]);
Proficiencies.allow(CHARACTER_SUBSCHEMA_ALLOW); Proficiencies.allow(CHARACTER_SUBSCHEMA_ALLOW);
Proficiencies.deny(CHARACTER_SUBSCHEMA_DENY); Proficiencies.deny(CHARACTER_SUBSCHEMA_DENY);

View File

@@ -3,9 +3,9 @@ TemporaryHitPoints = new Mongo.Collection("temporaryHitPoints");
Schemas.TemporaryHitPoints = new SimpleSchema({ Schemas.TemporaryHitPoints = new SimpleSchema({
charId: {type: String, regEx: SimpleSchema.RegEx.Id}, charId: {type: String, regEx: SimpleSchema.RegEx.Id},
name: {type: String, optional: true}, name: {type: String, optional: true},
maximum: {type: Number, defaultValue: 0}, maximum: {type: Number, defaultValue: 0, min: 0, max: 500},
used: {type: Number, defaultValue: 0}, used: {type: Number, defaultValue: 0, min: 0, max: 500},
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,7 @@
Router.configure({ Router.configure({
loadingTemplate: "loading", loadingTemplate: "loading",
layoutTemplate: "layout", layoutTemplate: "layout",
trackPageView: true,
}); });
Router.plugin("ensureSignedIn", { Router.plugin("ensureSignedIn", {
@@ -56,6 +57,12 @@ Router.map(function() {
document.title = name; document.title = name;
} }
}, },
//analytics
trackPageView: false,
onRun: function() {
window.ga && window.ga("send", "pageview", "/character");
this.next();
},
}); });
this.route("loading", { this.route("loading", {

View File

@@ -77,10 +77,10 @@ this.GlobalUI = (function() {
var throttleBack = _.throttle(function() { var throttleBack = _.throttle(function() {
history.back(); history.back();
}, 800, {trailing: false}); }, 100, {trailing: false});
GlobalUI.closeDetail = function() { GlobalUI.closeDetail = function() {
if (!!(window.history && window.history.pushState)) { if (window.history && history.pushState && history.state.detail === "opened") {
throttleBack(); throttleBack();
} else { } else {
Session.set("global.ui.detailShow", false); Session.set("global.ui.detailShow", false);

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

@@ -29,6 +29,11 @@ core-header-panel[drawer] {
box-shadow: 2px 0px 5px 0px rgba(0,0,0,0.2); box-shadow: 2px 0px 5px 0px rgba(0,0,0,0.2);
} }
//Paragraphs
p {
margin-bottom: 8px;
}
//Horizontal rule //Horizontal rule
hr { hr {
background-color: #444; background-color: #444;
@@ -37,7 +42,7 @@ hr {
color: #444; color: #444;
height: 1px; height: 1px;
line-height: 0; line-height: 0;
margin: 16px -16px; margin: 16px 0;
text-align: center; text-align: center;
} }

View File

@@ -1,8 +1,5 @@
td { td {
padding: 8px; padding: 8px;
&:nth-child(1) {
min-width: 100px;
}
} }
.strengthTable{ .strengthTable{

View File

@@ -44,7 +44,8 @@
label="Value" label="Value"
floatinglabel floatinglabel
value={{effectValue}} value={{effectValue}}
flex> flex
style="flex-basis: 100px;">
</paper-input> </paper-input>
</template> </template>

View File

@@ -32,7 +32,7 @@
{{/if}} {{/if}}
{{#if description}} {{#if description}}
<div class="pre-wrap">{{evaluateString charId description}}</div> <div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
{{/if}} {{/if}}
{{> effectsViewList charId=charId parentId=_id}} {{> effectsViewList charId=charId parentId=_id}}

View File

@@ -95,14 +95,16 @@
<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">
>{{evaluateString charId description}}</div> {{#markdown}}{{evaluateString charId shortDescription}}{{/markdown}}
</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(/^( *[-*_]){3,} *(?:\n+|$)/m)[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

@@ -41,6 +41,6 @@
</div> </div>
{{#if description}} {{#if description}}
<hr class="vertMargin"> <hr class="vertMargin">
<div class="pre-wrap">{{evaluateString charId description}}</div> <div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
{{/if}} {{/if}}
</template> </template>

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

@@ -18,8 +18,8 @@
{{#if requiresAttunement}}<div class="vertMargin">Requires Attunement</div>{{/if}} {{#if requiresAttunement}}<div class="vertMargin">Requires Attunement</div>{{/if}}
</div> </div>
{{#if description}} {{#if description}}
<hr class="vertMargin"> <hr style="margin: 16px 0 16px 0;">
<div class="pre-wrap">{{evaluateString charId description}}</div> <div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
{{/if}} {{/if}}
{{> effectsViewList charId=charId parentId=_id}} {{> effectsViewList charId=charId parentId=_id}}
{{> attacksViewList charId=charId parentId=_id}} {{> attacksViewList charId=charId parentId=_id}}

View File

@@ -6,7 +6,7 @@
</div> </div>
{{#if description}} {{#if description}}
<hr class="vertMargin"> <hr class="vertMargin">
<div class="pre-wrap">{{description}}</div> <div>{{#markdown}}{{description}}{{/markdown}}</div>
{{/if}} {{/if}}
{{else}} {{else}}
{{> experienceEdit}} {{> experienceEdit}}

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">
@@ -85,7 +87,7 @@
layout horizontal center> layout horizontal center>
{{name}} {{name}}
</div> </div>
<div class="bottom text">{{description}}</div> <div class="bottom">{{#markdown}}{{description}}{{/markdown}}</div>
</paper-shadow> </paper-shadow>
{{/each}} {{/each}}
</div> </div>

View File

@@ -1,7 +1,7 @@
<template name="noteDialog"> <template name="noteDialog">
{{#with note}} {{#with note}}
{{#baseDialog title=name class=colorClass startEditing=../startEditing}} {{#baseDialog title=name class=colorClass startEditing=../startEditing}}
<div class="pre-wrap">{{description}}</div> <div>{{#markdown}}{{description}}{{/markdown}}</div>
{{else}} {{else}}
{{> noteDialogEdit}} {{> noteDialogEdit}}
{{/baseDialog}} {{/baseDialog}}

View File

@@ -1,6 +1,6 @@
<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>{{#markdown}}{{evaluateString charId value}}{{/markdown}}</div>
{{> proficiencyViewList charId=charId parentId=charId parentGroup="background"}} {{> proficiencyViewList charId=charId parentId=charId parentGroup="background"}}
{{else}} {{else}}
{{> textDialogEdit}} {{> textDialogEdit}}

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"}}
@@ -40,6 +68,6 @@
{{title}} {{title}}
</div> </div>
</div> </div>
<div class="bottom text">{{> UI.contentBlock}}</div> <div class="bottom">{{#markdown}}{{> UI.contentBlock}}{{/markdown}}</div>
</paper-shadow> </paper-shadow>
</template> </template>

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

@@ -1,6 +1,6 @@
<template name="textDialog"> <template name="textDialog">
{{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true" startEditing=startEditing}} {{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true" startEditing=startEditing}}
<div class="pre-wrap">{{evaluateString charId value}}</div> <div>{{#markdown}}{{evaluateString charId value}}{{/markdown}}</div>
{{else}} {{else}}
{{> textDialogEdit}} {{> textDialogEdit}}
{{/baseDialog}} {{/baseDialog}}

View File

@@ -34,7 +34,7 @@
</div> </div>
{{/if}} {{/if}}
</div> </div>
<div class="pre-wrap">{{evaluateString charId description}}</div> <div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
{{> attacksViewList charId=charId parentId=_id}} {{> attacksViewList charId=charId parentId=_id}}
</template> </template>

View File

@@ -20,7 +20,7 @@
{{/if}} {{/if}}
</div> </div>
<hr class="vertMargin"> <hr class="vertMargin">
<div class="pre-wrap">{{evaluateString charId description}}</div> <div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
</div> </div>
{{else}} {{else}}
<!--Name--> <!--Name-->

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

@@ -1,9 +1,11 @@
Template.addTHPDialog.events({ Template.addTHPDialog.events({
"tap #addButton": function(event, instance){ "tap #addButton": function(event, instance){
var max = +instance.find("#quantityInput").value;
if (!max || max < 0) max = 0;
TemporaryHitPoints.insert({ TemporaryHitPoints.insert({
charId: this.charId, charId: this.charId,
name: instance.find("#nameInput").value, name: instance.find("#nameInput").value,
maximum: +instance.find("#quantityInput").value, maximum: max,
deleteOnZero: !!instance.find("#deleteWhenZeroCheckbox").checked, deleteOnZero: !!instance.find("#deleteWhenZeroCheckbox").checked,
}); });
} }

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>
@@ -28,9 +33,9 @@
role="slider" role="slider"
flex flex
></paper-diff-slider> ></paper-diff-slider>
{{#unless left}}{{#unless deleteOnZero}} {{#unless left}}
<paper-icon-button class="deleteTHP" icon="delete"></paper-icon-button> <paper-icon-button class="deleteTHP" icon="delete"></paper-icon-button>
{{/unless}}{{/unless}} {{/unless}}
</div> </div>
</div> </div>
{{/each}} {{/each}}

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

@@ -45,6 +45,15 @@
</div> </div>
<div class="bottom text">Lawful Good Human</div> <div class="bottom text">Lawful Good Human</div>
</paper-shadow> </paper-shadow>
<paper-shadow class="card characterCard ssWizard clickable"
z="2">
<div class="top subhead deep-purple white-text">
<div class="subhead" flex>
Starter Set Wizard
</div>
</div>
<div class="bottom text">Chaotic Good High Elf</div>
</paper-shadow>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -8,6 +8,9 @@ Template.intro.events({
"tap .ssArcher": function() { "tap .ssArcher": function() {
Router.go("/character/yBWwt5XQTTHZiRQxq"); Router.go("/character/yBWwt5XQTTHZiRQxq");
}, },
"tap .ssWizard": function() {
Router.go("/character/KxHKskm22fS2Xogah");
},
"tap .guideButton": function() { "tap .guideButton": function() {
Router.go("/guide"); Router.go("/guide");
}, },

View File

@@ -4,6 +4,9 @@
</core-toolbar> </core-toolbar>
<div fit layout vertical center center-justified> <div fit layout vertical center center-justified>
<paper-spinner class="bigSpinner" active></paper-spinner> <paper-spinner class="bigSpinner" active></paper-spinner>
<div class="subhead">{{randomHint}}</div> <div class="subhead"
style="margin-left: 16px;
margin-right: 16px;
text-align: center;">{{randomHint}}</div>
</div> </div>
</template> </template>

View File

@@ -1,10 +1,14 @@
<template name="notFound"> <template name="notFound">
<div layout vertical center center-justified fit> <core-toolbar class="app-grey white-text">
<h2>The data for the page you requested could not be found.</h2> <core-icon-button icon="menu" core-drawer-toggle></core-icon-button>
</core-toolbar>
<div layout vertical center center-justified fit
style="padding: 16px; text-align: center;">
<h2 style="margin-bottom: 12px;">The data for the page you requested could not be found.</h2>
{{#if currentUser}} {{#if currentUser}}
<h2>It might not exist, or you might not have permission to view it.</h2> <h3>It might not exist, or you might not have permission to view it.</h3>
{{else}} {{else}}
<h2>Perhaps you need to sign in first:</h2> <h3>Perhaps you need to sign in first:</h3>
{{atForm}} {{atForm}}
{{/if}} {{/if}}
</div> </div>

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

@@ -1,8 +1,13 @@
Meteor.methods({ Meteor.methods({
"getUserId": function(username){ "getUserId": function(username){
if (!username) return; if (!username) return;
regex = new RegExp("^" + username + "$", "i")
var user = Meteor.users.findOne( var user = Meteor.users.findOne(
{$or: [{username: username}, {"emails.address": username}]} {$or: [
{username: username},
{"emails.address": regex},
{"services.google.email": regex},
]}
); );
return user && user._id; return user && user._id;
} }

View File

@@ -219,3 +219,27 @@ 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 read-only viewers",
],
});
ChangeLogs.insert({
version: "0.6.6",
changes: [
"Text fields now accept github-flavor markdown formatting",
],
});
ChangeLogs.insert({
version: "0.6.7",
changes: [
"Fixed effect values not being visible on small screens",
"Added basic analytics",
],
});