From 7af3b8e06e78df648237be3dbb2966f1dabcacb8 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 30 Jan 2017 13:02:22 +0200 Subject: [PATCH] Upgraded spells page to Polymer 1 --- .../attacks/attackEdit/attackEdit.html | 10 +- .../features/featureDialog/featureDialog.js | 21 +- .../views/character/features/features.js | 2 +- .../spells/spellDialog/spellDialog.css | 8 +- .../spells/spellDialog/spellDialog.html | 159 +++++------ .../spells/spellDialog/spellDialog.js | 99 ++++--- .../spellListDialog/spellListDialog.html | 48 ++-- .../spells/spellListDialog/spellListDialog.js | 84 ++++-- .../client/views/character/spells/spells.css | 14 +- .../client/views/character/spells/spells.html | 250 +++++++++--------- .../client/views/character/spells/spells.js | 103 ++++---- .../inputSuffixes/inputSuffixes.html | 13 + 12 files changed, 435 insertions(+), 376 deletions(-) create mode 100644 rpg-docs/client/views/paperTemplates/inputSuffixes/inputSuffixes.html diff --git a/rpg-docs/client/views/character/attacks/attackEdit/attackEdit.html b/rpg-docs/client/views/character/attacks/attackEdit/attackEdit.html index aca4fde8..2a4230d0 100644 --- a/rpg-docs/client/views/character/attacks/attackEdit/attackEdit.html +++ b/rpg-docs/client/views/character/attacks/attackEdit/attackEdit.html @@ -5,10 +5,7 @@ -
- This is a formula field - -
+ {{> formulaSuffix}}
@@ -18,10 +15,7 @@ -
- This field accepts formulae in {curly brackets} - -
+ {{> bracketSuffix}}
diff --git a/rpg-docs/client/views/character/features/featureDialog/featureDialog.js b/rpg-docs/client/views/character/features/featureDialog/featureDialog.js index 247574c4..5e5ce31e 100644 --- a/rpg-docs/client/views/character/features/featureDialog/featureDialog.js +++ b/rpg-docs/client/views/character/features/featureDialog/featureDialog.js @@ -67,13 +67,20 @@ const debounce = (f) => _.debounce(f, 300); Template.featureEdit.events({ "input #featureNameInput": debounce(function(event){ - var name = event.currentTarget.value; - Features.update(this._id, { - $set: {name: name} - }, { - removeEmptyStrings: false, - trimStrings: false, - }); + const input = event.currentTarget; + var name = input.value; + if (!name){ + input.invalid = true; + input.errorMessage = "Name is required"; + } else { + input.invalid = false; + Features.update(this._id, { + $set: {name: name} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + } }), "input #featureDescriptionInput": debounce(function(event){ var description = event.currentTarget.value; diff --git a/rpg-docs/client/views/character/features/features.js b/rpg-docs/client/views/character/features/features.js index 605ceb72..b54f62a9 100644 --- a/rpg-docs/client/views/character/features/features.js +++ b/rpg-docs/client/views/character/features/features.js @@ -54,7 +54,7 @@ Template.features.events({ template: "featureDialog", data: {featureId: featureId, charId: this._id, startEditing: true}, element: event.currentTarget, - returnElement: instance.find(`.featureCard[data-id='${featureId}']`), + returnElement: () => instance.find(`.featureCard[data-id='${featureId}']`), }); }, "click .featureCard .top": function(event){ diff --git a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.css b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.css index 6639585f..322ecc5b 100644 --- a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.css +++ b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.css @@ -1,3 +1,7 @@ -.spellDialog paper-checkbox { - margin: 8px 16px 8px 8px; +.spell-dialog paper-checkbox { + margin: 8px; +} + +.spell-dialog paper-dropdown-menu, .spell-dialog paper-input { + margin: 0 4px; } diff --git a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html index cee3b459..07d9faa7 100644 --- a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html +++ b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html @@ -1,36 +1,38 @@ diff --git a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.js b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.js index 9b2c7ad9..601b67a2 100644 --- a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.js +++ b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.js @@ -24,7 +24,7 @@ Template.spellDialog.events({ "tap #deleteButton": function(event, instance){ Spells.softRemoveNode(instance.data.spellId); GlobalUI.deletedToast(instance.data.spellId, "Spells", "Spell"); - GlobalUI.closeDetail(); + popDialogStack(); }, }); @@ -47,10 +47,6 @@ Template.spellDetails.helpers({ }, }); -Template.spellEdit.onRendered(function(){ - updatePolymerInputs(this); -}); - Template.spellEdit.helpers({ spellLists: function(){ return SpellLists.find({charId: this.charId}, {fields: {name: 1}}); @@ -70,55 +66,92 @@ Template.spellEdit.helpers({ }, }); +const debounce = (f) => _.debounce(f, 300); + Template.spellEdit.events({ - "change #spellNameInput, input #spellNameInput": function(event){ + "change #spellNameInput, input #spellNameInput": debounce(function(event){ + const input = event.currentTarget; + var value = input.value; + if (!value){ + input.invalid = true; + input.errorMessage = "Name is required"; + } else { + input.invalid = false; + Spells.update(this._id, { + $set: {name: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + } + }), + "change #castingTimeInput, input #castingTimeInput": debounce(function(event){ var value = event.currentTarget.value; - Spells.update(this._id, {$set: {name: value}}); - }, - "change #castingTimeInput": function(event){ + Spells.update(this._id, { + $set: {castingTime: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "change #rangeInput, input #rangeInput": debounce(function(event){ var value = event.currentTarget.value; - Spells.update(this._id, {$set: {castingTime: value}}); - }, - "change #rangeInput": function(event){ + Spells.update(this._id, { + $set: {range: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "change #durationInput, input #durationInput": debounce(function(event){ var value = event.currentTarget.value; - Spells.update(this._id, {$set: {range: value}}); - }, - "change #durationInput": function(event){ + Spells.update(this._id, { + $set: {duration: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "change #materialInput, input #materialInput": debounce(function(event){ var value = event.currentTarget.value; - Spells.update(this._id, {$set: {duration: value}}); - }, - "change #materialInput": function(event){ + Spells.update(this._id, { + $set: {"components.material": value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "input #descriptionInput": debounce(function(event){ var value = event.currentTarget.value; - Spells.update(this._id, {$set: {"components.material": value}}); - }, - "change #descriptionInput": function(event){ - var value = event.currentTarget.value; - Spells.update(this._id, {$set: {"description": value}}); - }, - "core-select #listDropdown": function(event){ + Spells.update(this._id, { + $set: {"description": value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "iron-select #listDropdown": function(event){ var detail = event.originalEvent.detail; - if (!detail.isSelected) return; var value = detail.item.getAttribute("name"); if (value == this.parent.id) return; - Spells.update(this._id, {$set: {"parent.id": value}}); + Spells.update(this._id, { + $set: {"parent.id": value} + }); }, - "core-select #levelDropdown": function(event){ + "iron-select #levelDropdown": function(event){ var detail = event.originalEvent.detail; - if (!detail.isSelected) return; var value = detail.item.getAttribute("name"); if (value == this.level) return; Spells.update(this._id, {$set: {level: value}}); }, - "core-select #schoolDropdown": function(event){ + "iron-select #schoolDropdown": function(event){ var detail = event.originalEvent.detail; - if (!detail.isSelected) return; var value = detail.item.getAttribute("name"); if (value == this.school) return; Spells.update(this._id, {$set: {school: value}}); }, - "core-select #preparedDropdown": function(event){ + "iron-select #preparedDropdown": function(event){ var detail = event.originalEvent.detail; - if (!detail.isSelected) return; var value = detail.item.getAttribute("name"); if (value == this.school) return; Spells.update(this._id, {$set: {prepared: value}}); diff --git a/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.html b/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.html index 3bed65e6..8063d957 100644 --- a/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.html +++ b/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.html @@ -2,10 +2,10 @@ {{#with spellList}} {{#baseDialog title=name class=colorClass startEditing=../startEditing}}
-
+
{{#if attackBonus}}
- Attack Bonus: {{evaluate charId attackBonus}} + Attack Bonus: {{evaluateSigned charId attackBonus}}
{{/if}} {{#if saveDC}} @@ -15,7 +15,7 @@ {{/if}} {{#if maxPrepared}}
- Max Prepared: {{evaluateSigned charId maxPrepared}} + Max Prepared Spells: {{evaluate charId maxPrepared}}
{{/if}}
@@ -23,36 +23,26 @@
{{#markdown}}{{evaluateString charId description}}{{/markdown}}
{{else}} +
- + + -
+ + {{> formulaSuffix}} + -
+ + {{> formulaSuffix}} + -
+ + {{> formulaSuffix}} + - - - - - + + +
{{/baseDialog}} {{/with}} - \ No newline at end of file + diff --git a/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.js b/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.js index 60065831..c967d72c 100644 --- a/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.js +++ b/rpg-docs/client/views/character/spells/spellListDialog/spellListDialog.js @@ -1,48 +1,80 @@ -Template.spellListDialog.onRendered(function(){ - updatePolymerInputs(this); +Template.spellListDialog.helpers({ + spellList: function(){ + return SpellLists.findOne(this.spellListId); + } }); +const debounce = (f) => _.debounce(f, 300); + Template.spellListDialog.events({ "color-change": function(event, instance){ SpellLists.update(instance.data.spellListId, {$set: {color: event.color}}); }, - "tap #deleteButton": function(event, instance){ + "click #deleteButton": function(event, instance){ SpellLists.softRemoveNode(instance.data.spellListId); GlobalUI.deletedToast( instance.data.spellListId, "SpellLists", "Spell list and contents" ); - GlobalUI.closeDetail(); + popDialogStack(); }, //TODO clean up String -> num here so they don't need casting by Schema.clean //TODO validate input (integer, non-negative, etc) for these inputs and give validation errors - "change #spellListNameInput, input #spellListNameInput": function(event){ + "change #spellListNameInput, input #spellListNameInput": + debounce(function(event){ + const input = event.currentTarget; + var value = input.value; + if (!value){ + input.invalid = true; + input.errorMessage = "Name is required"; + } else { + input.invalid = false; + SpellLists.update(this._id, { + $set: {name: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + } + }), + "change #spellListSaveDCInput, input #spellListSaveDCInput": + debounce(function(event){ var value = event.currentTarget.value; - SpellLists.update(this._id, {$set: {name: value}}); - }, - "change #spellListSaveDCInput, input #spellListSaveDCInput": function(event){ - var value = event.currentTarget.value; - SpellLists.update(this._id, {$set: {saveDC: value}}); - }, + SpellLists.update(this._id, { + $set: {saveDC: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), "change #spellListAttackBonusInput, input #spellListAttackBonusInput": - function(event){ + debounce(function(event){ var value = event.currentTarget.value; - SpellLists.update(this._id, {$set: {attackBonus: value}}); - }, + SpellLists.update(this._id, { + $set: {attackBonus: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), "change #spellListMaxPreparedInput, input #spellListMaxPreparedInput": - function(event){ + debounce(function(event){ var value = event.currentTarget.value; - SpellLists.update(this._id, {$set: {maxPrepared: value}}); - }, - "change #spellListDescriptionInput": function(event){ + SpellLists.update(this._id, { + $set: {maxPrepared: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), + "input #spellListDescriptionInput": debounce(function(event){ var value = event.currentTarget.value; - SpellLists.update(this._id, {$set: {description: value}}); - }, -}); - -Template.spellListDialog.helpers({ - spellList: function(){ - return SpellLists.findOne(this.spellListId); - } + SpellLists.update(this._id, { + $set: {description: value} + }, { + removeEmptyStrings: false, + trimStrings: false, + }); + }), }); diff --git a/rpg-docs/client/views/character/spells/spells.css b/rpg-docs/client/views/character/spells/spells.css index 4fe22baa..148d2d0f 100644 --- a/rpg-docs/client/views/character/spells/spells.css +++ b/rpg-docs/client/views/character/spells/spells.css @@ -67,17 +67,15 @@ margin: 4px; } -.spellList .containerMain { - -ms-column-width: 300px; - -webkit-column-width: 300px; - -moz-column-width: 300px; +.spellList.card .bottom.list { column-width: 300px; - -ms-column-gap: 8px; - -webkit-column-gap: 8px; - -moz-column-gap: 8px; column-gap: 8px; - -moz-column-fill: balance; column-fill: balance; + padding: 16px 4px; +} + +.spellList .bottom .paper-font-subhead { + margin-left: 16px; } .spellLevel { diff --git a/rpg-docs/client/views/character/spells/spells.html b/rpg-docs/client/views/character/spells/spells.html index 7ea409f8..35c0736e 100644 --- a/rpg-docs/client/views/character/spells/spells.html +++ b/rpg-docs/client/views/character/spells/spells.html @@ -1,147 +1,145 @@ diff --git a/rpg-docs/client/views/character/spells/spells.js b/rpg-docs/client/views/character/spells/spells.js index 067160d1..e7cf0ad7 100644 --- a/rpg-docs/client/views/character/spells/spells.js +++ b/rpg-docs/client/views/character/spells/spells.js @@ -11,13 +11,17 @@ var spellLevels = [ {name: "Level 9", level: 9}, ]; +const showUnprepared = (listId) => { + return Session.get(`showUnprepared.${listId}`); +} + Template.spells.helpers({ spellLists: function(){ return SpellLists.find({charId: this._id}, {sort: {color: 1, name: 1}}); }, spellCount: function(list, charId){ - if (!list || !list.settings) return; - if (list.settings.showUnprepared){ + if (!list) return; + if (showUnprepared(list._id)){ return Spells.find( {charId: charId, "parent.id": list._id, level: this.level}, {fields: {_id: 1, level: 1}} @@ -43,6 +47,9 @@ Template.spells.helpers({ levels: function(){ return spellLevels; }, + showUnprepared: function(listId){ + return showUnprepared(listId); + }, numPrepared: function(){ return Spells.find({ charId: Template.parentData()._id, @@ -72,8 +79,8 @@ Template.spells.helpers({ isPrepared: function(){ return this.prepared === "prepared" || this.prepared === "always"; }, - showSpell: function(listShowPrepped){ - if (listShowPrepped) { + showSpell: function(listId){ + if (showUnprepared(listId)) { return true; } else { return this.prepared === "prepared" || this.prepared === "always"; @@ -84,7 +91,9 @@ Template.spells.helpers({ }, cantCast: function(level, char){ for (var i = level; i <= 9; i++){ - if (Characters.calculate.attributeValue(char._id, "level" + i + "SpellSlots") > 0){ + if (Characters.calculate.attributeValue( + char._id, "level" + i + "SpellSlots" + ) > 0){ return false; } } @@ -97,21 +106,27 @@ Template.spells.helpers({ }, hasSlots: function(){ for (var i = 1; i <= 9; i += 1){ - if (Characters.calculate.attributeBase(this._id, "level" + i + "SpellSlots")){ + if (Characters.calculate.attributeBase( + this._id, "level" + i + "SpellSlots" + )){ return true; } } return false; }, slotBubbles: function(char){ - var baseSlots = Characters.calculate.attributeBase(char._id, "level" + this.level + "SpellSlots"); - var currentSlots = Characters.calculate.attributeValue(char._id, "level" + this.level + "SpellSlots"); + var baseSlots = Characters.calculate.attributeBase( + char._id, "level" + this.level + "SpellSlots" + ); + var currentSlots = Characters.calculate.attributeValue( + char._id, "level" + this.level + "SpellSlots" + ); var slotsUsed = baseSlots - currentSlots; var bubbles = []; var i; for (i = 0; i < currentSlots; i++){ bubbles.push({ - icon: "radio-button-on", + icon: "radio-button-checked", disabled: i !== currentSlots - 1 || !canEditCharacter(char._id), //last full slot not disabled attribute: "level" + this.level + "SpellSlots", charId: char._id, @@ -119,7 +134,7 @@ Template.spells.helpers({ } for (i = 0; i < slotsUsed; i++){ bubbles.push({ - icon: "radio-button-off", + icon: "radio-button-unchecked", disabled: i !== 0 || !canEditCharacter(char._id), //first empty slot not disabled attribute: "level" + this.level + "SpellSlots", charId: char._id, @@ -133,11 +148,11 @@ Template.spells.helpers({ }); Template.spells.events({ - "tap .slotBubble": function(event){ + "click .slotBubble": function(event){ var modifier; if (!event.currentTarget.disabled){ var char = Characters.findOne(this.charId); - if (event.currentTarget.icon === "radio-button-off"){ + if (event.currentTarget.icon === "radio-button-unchecked"){ if ( Characters.calculate.attributeValue(char._id, this.attribute) < Characters.calculate.attributeBase(char._id, this.attribute) @@ -156,51 +171,49 @@ Template.spells.events({ } event.stopPropagation(); }, - "tap .spellSlot": function(event, instance) { + "click .spellSlot": function(event, instance) { var name = "Level " + this.level + " Spell Slots"; var stat = "level" + this.level + "SpellSlots"; var charId = instance.data._id; - GlobalUI.setDetail({ + pushDialogStack({ template: "attributeDialog", data: {name: name, statName: stat, charId: charId}, - heroId: charId + stat, + element: event.currentTarget, }); }, - "tap .spellList .top": function(event){ - GlobalUI.setDetail({ + "click .spellList .top": function(event){ + pushDialogStack({ template: "spellListDialog", data: {spellListId: this._id, charId: this.charId}, - heroId: this._id, + element: event.currentTarget.parentElement, }); }, - "tap .spell": function(event){ - GlobalUI.setDetail({ + "click .spell": function(event){ + pushDialogStack({ template: "spellDialog", data: {spellId: this._id, charId: this.charId}, - heroId: this._id, + element: event.currentTarget, }); }, - "tap .addSpellList": function(event){ + "click .addSpellList": function(event, instance){ var charId = this.charId; - SpellLists.insert({ + var id = SpellLists.insert({ name: "New SpellList", charId: this._id, saveDC: "8 + intelligenceMod + proficiencyBonus", attackBonus: "intelligenceMod + proficiencyBonus", - }, function(error, id){ - if (!error){ - GlobalUI.setDetail({ - template: "spellListDialog", - data: {spellListId: id, charId: charId, startEditing: true}, - heroId: id, - }); - } + }); + pushDialogStack({ + template: "spellListDialog", + data: {spellListId: id, charId: charId, startEditing: true}, + element: event.currentTarget, + returnElement: () => instance.find(`.spellList[data-id='${id}']`), }); }, - "tap .addSpell": function(event){ + "click .addSpell": function(event, instance){ var charId = this.charId; var listId = SpellLists.findOne({charId: this._id})._id; - Spells.insert({ + var id = Spells.insert({ name: "New Spell", charId: this._id, parent: { @@ -208,17 +221,15 @@ Template.spells.events({ collection: "SpellLists", }, prepared: "prepared", - }, function(error, id){ - if (!error){ - GlobalUI.setDetail({ - template: "spellDialog", - data: {spellId: id, charId: charId, startEditing: true}, - heroId: id, - }); - } + }); + pushDialogStack({ + template: "spellDialog", + data: {spellId: id, charId: charId, startEditing: true}, + element: event.currentTarget, + returnElement: () => instance.find(`.spell[data-id='${id}']`), }); }, - "tap .preparedCheckbox": function(event){ + "click .preparedCheckbox": function(event){ event.stopPropagation(); }, "change .preparedCheckbox": function(event){ @@ -228,12 +239,12 @@ Template.spells.events({ else if (this.prepared === "prepared" && !value) Spells.update(this._id, {$set: {prepared: "unprepared"}}); }, - "tap .prepSpells": function(event){ - SpellLists.update(this._id, {$set: {"settings.showUnprepared": true}}); + "click .prepSpells": function(event){ + Session.set(`showUnprepared.${this._id}`, true); event.stopPropagation(); }, - "tap .finishPrep": function(event){ - SpellLists.update(this._id, {$set: {"settings.showUnprepared": false}}); + "click .finishPrep": function(event){ + Session.set(`showUnprepared.${this._id}`, false); event.stopPropagation(); }, }); diff --git a/rpg-docs/client/views/paperTemplates/inputSuffixes/inputSuffixes.html b/rpg-docs/client/views/paperTemplates/inputSuffixes/inputSuffixes.html new file mode 100644 index 00000000..fc0964df --- /dev/null +++ b/rpg-docs/client/views/paperTemplates/inputSuffixes/inputSuffixes.html @@ -0,0 +1,13 @@ + + +