1
0
mirror of https://github.com/stolksdorf/homebrewery.git synced 2025-12-24 03:01:31 +00:00

Polishing the sidebar so more

This commit is contained in:
Scott Tolksdorf
2015-11-16 14:22:00 -05:00
parent e6e87457da
commit 5918267c86
10 changed files with 152 additions and 154 deletions

View File

@@ -68,15 +68,16 @@ var Encounter = React.createClass({
getPlayerObjects : function(){
return _.map(this.props.players.split('\n'), function(line){
return _.reduce(this.props.players.split('\n'), function(r, line){
var parts = line.split(' ');
if(parts.length != 2) return null;
return {
if(parts.length != 2) return r;
r.push({
name : parts[0],
initiative : parts[1] * 1,
isPC : true
}
})
return r;
},[])
},
@@ -84,7 +85,7 @@ var Encounter = React.createClass({
var self = this;
var sortedEnemies = _.sortBy(_.union(_.values(this.state.enemies), this.getPlayerObjects()), function(e){
if(e.initiative) return -e.initiative;
if(e && e.initiative) return -e.initiative;
return 0;
});

View File

@@ -131,13 +131,10 @@ var MonsterCard = React.createClass({
var self = this;
var usedItems = this.state.usedItems.slice(0);
return _.map(this.props.items, function(item, index){
var used = _.contains(usedItems, item);
if(used){
usedItems.splice(usedItems.indexOf(item), 1);
}
return <span
key={index}
className={cx({'used' : used})}
@@ -174,11 +171,13 @@ var MonsterCard = React.createClass({
{this.renderSpells()}
</div>
<div className='abilitiesContainer'>
{this.props.abilities}
</div>
<div className='itemContainer'>
<i className='fa fa-flask' />
{this.renderItems()}
</div>
</div>
);
}

View File

@@ -1,4 +1,5 @@
@marginSize : 10px;
.noselect(){
-webkit-touch-callout : none;
-webkit-user-select : none;
@@ -7,9 +8,6 @@
-ms-user-select : none;
user-select : none;
}
@marginSize : 10px;
.playerCard{
display : inline-block;
box-sizing : border-box;
@@ -17,25 +15,21 @@
padding : 10px;
background-color : white;
border : 1px solid #bbb;
.name{
margin-right: 20px;
margin-right : 20px;
}
.initiative{
font-size: 0.8em;
font-size : 0.8em;
i{
font-size: 0.8em;
font-size : 0.8em;
}
}
&:nth-child(5n + 1){ background-color: fade(@blue, 25%); }
&:nth-child(5n + 2){ background-color: fade(@purple, 25%); }
&:nth-child(5n + 3){ background-color: fade(@steel, 25%); }
&:nth-child(5n + 4){ background-color: fade(@green, 25%); }
&:nth-child(5n + 5){ background-color: fade(@orange, 25%); }
}
.monsterCard{
position : relative;
display : inline-block;
@@ -50,19 +44,19 @@
position : absolute;
top : 0px;
left : 0px;
z-index : 50;
height : 3px;
max-width : 100%;
background-color : @green;
z-index : 50;
}
.overhealbar{
position : absolute;
top : 0px;
left : 0px;
z-index : 100;
height : 3px;
max-width : 100%;
background-color : @blueLight;
z-index : 100;
}
&.hurt{
.healthbar{
@@ -70,26 +64,25 @@
}
}
&.last_legs{
background-color: lighten(@red, 49%);
background-color : lighten(@red, 49%);
.healthbar{
background-color : red;
}
}
&.dead{
opacity: 0.3;
opacity : 0.3;
}
&>.info{
margin-bottom: 10px;
margin-bottom : 10px;
.name{
font-size: 1.5em;
margin-right: 10px;
margin-right : 10px;
font-size : 1.5em;
}
.stat{
font-size: 0.7em;
margin-right: 5px;
margin-right : 5px;
font-size : 0.7em;
i{
font-size: 0.7em;
font-size : 0.7em;
}
}
}
@@ -118,17 +111,21 @@
font-weight : 800;
}
}
.abilitiesContainer{
margin-top : 5px;
}
.itemContainer{
margin-top : 5px;
i{
font-size : 0.7em;
}
span{
cursor: pointer;
font-size: 0.7em;
margin-right: 5px;
margin-right : 5px;
cursor : pointer;
font-size : 0.7em;
&.used{
text-decoration: line-through;
text-decoration : line-through;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -47,7 +47,7 @@ var encounters = [
];
var MonsterManual = {
var monsterManual = {
'goblin' : {
"hp" : 40,
"mov": 30,
@@ -97,69 +97,48 @@ var NaturalCrit = React.createClass({
getInitialState: function() {
var self = this;
return {
selectedEncounterIndex : 0,
encounters : JSON.parse(localStorage.getItem('encounters')) || encounters,
monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || monsterManual,
encounters : encounters,
monsterManual : MonsterManual,
players : 'jasper 13'
players : localStorage.getItem('players') || 'jasper 13\nzatch 19'
};
},
createEnemy : function(type, index){
var stats = MonsterManual[type]
return _.extend({
id : type + index,
name : type,
currentHP : stats.hp,
initiative : _.random(1,20) + attrMod(stats.attr.dex)
}, stats);
},
addPC : function(name, initiative){
this.state.enemies[name] = {
name : name,
id : name,
initiative : initiative,
isPC : true
};
this.setState({
enemies : this.state.enemies
})
},
addRandomPC : function(){
this.addPC(
_.sample(['zatch', 'jasper', 'el toro', 'tulik']) + _.random(1,1000),
_.random(1,25)
)
},
handleJSONChange : function(encounterIndex, json){
handleEncounterJSONChange : function(encounterIndex, json){
this.state.encounters[encounterIndex] = json;
this.setState({
encounters : this.state.encounters
})
localStorage.setItem("encounters", JSON.stringify(this.state.encounters));
},
handleEncounterChange : function(encounterIndex){
handleMonsterManualJSONChange : function(json){
this.setState({
selectedEncounterIndex : encounterIndex
monsterManual : json
});
localStorage.setItem("monsterManual", JSON.stringify(this.state.monsterManual));
},
handlePlayerChange : function(e){
this.setState({
players : e.target.value
});
localStorage.setItem("players", e.target.value);
},
handleSelectedEncounterChange : function(encounterIndex){
this.setState({
selectedEncounterIndex : encounterIndex
});
},
handleRemoveEncounter : function(encounterIndex){
this.state.encounters.splice(encounterIndex, 1);
this.setState({
encounters : this.state.encounters
});
localStorage.setItem("encounters", JSON.stringify(this.state.encounters));
},
renderSelectedEncounter : function(){
var self = this;
@@ -183,9 +162,6 @@ var NaturalCrit = React.createClass({
render : function(){
var self = this;
console.log(this.state.encounters);
return(
<div className='naturalCrit'>
<Sidebar
@@ -194,8 +170,10 @@ var NaturalCrit = React.createClass({
monsterManual={this.state.monsterManual}
players={this.state.players}
onSelectEncounter={this.handleEncounterChange}
onJSONChange={this.handleJSONChange}
onSelectEncounter={this.handleSelectedEncounterChange}
onRemoveEncounter={this.handleRemoveEncounter}
onJSONChange={this.handleEncounterJSONChange}
onMonsterManualChange={this.handleMonsterManualJSONChange}
onPlayerChange={this.handlePlayerChange}
/>

View File

@@ -15,8 +15,9 @@ var Sidebar = React.createClass({
onSelectEncounter : function(){},
onJSONChange : function(encounterIndex, json){},
onMonsterManualChange : function(json){},
onPlayerChange : function(){},
onRemoveEncounter : function(encounterIndex){}
};
},
@@ -33,17 +34,14 @@ var Sidebar = React.createClass({
},
handleJSONChange : function(encounterIndex, json){
this.props.onJSONChange(encounterIndex, json);
},
handleSelectEncounter : function(encounterIndex){
console.log(encounterIndex);
this.props.onSelectEncounter(encounterIndex);
},
handleRemoveEncounter : function(encounterIndex){
this.props.onRemoveEncounter(encounterIndex);
},
renderEncounters : function(){
var self = this;
@@ -53,7 +51,7 @@ var Sidebar = React.createClass({
var isSelected = self.props.selectedEncounter == index;
return <div className={cx('encounter' , {'selected' : isSelected})} key={index}>
<i onClick={self.handleSelectEncounter.bind(self, index)} className={cx('fa', {
<i onClick={self.handleSelectEncounter.bind(self, index)} className={cx('select', 'fa', {
'fa-square-o' : !isSelected,
'fa-check-square-o' : isSelected,
})} />
@@ -64,6 +62,8 @@ var Sidebar = React.createClass({
json={encounter}
onJSONChange={self.handleJSONChange.bind(self, index)}
/>
<i onClick={self.handleRemoveEncounter.bind(self, index)} className='remove fa fa-times' />
</div>
})
},
@@ -81,11 +81,20 @@ var Sidebar = React.createClass({
<div className='contents'>
<div className='monsterManualContainer'>
<i className='fa fa-book' />
<JSONFileEditor name="Monster Manual" />
<JSONFileEditor
name="Monster Manual"
json={this.props.monsterManual}
onJSONChange={this.onMonsterManualChange}
/>
</div>
<div className='encounterContainer'>
<h3> <i className='fa fa-flag' /> Encounters </h3>
<h3>
<i className='fa fa-flag' /> Encounters
<button onClick={} className='addEncounter'>
<i className='fa fa-plus' />
</button>
</h3>
{this.renderEncounters()}
<div className='controls'>

View File

@@ -41,6 +41,7 @@
cursor : pointer;
fill : white;
}
span.name{
.animateAll();
position : absolute;
@@ -68,17 +69,51 @@
.encounterContainer{
margin-bottom : 20px;
h3{
background-color : fade(@red, 25%);
background-color : @red;
color : white;
button{
outline: none;
border : none;
cursor: pointer;
background-color: transparent;
.animate(color);
float : right;
&:hover{
color : white;
}
}
}
.encounter{
padding-left: 20px;
position: relative;
i.remove{
position: absolute;
top : 3px;
right : 3px;
font-size: 0.6em;
cursor: pointer;
color : #333;
&:hover{
color: @red;
}
}
i.select{
cursor: pointer;
}
.jsonFileEditor{
display: inline-block;
}
&.selected{
background-color : @green;
background-color : fade(@green, 30%);
}
}
}
.addPlayers{
h3{
background-color : fade(@purple, 25%);
//background-color : fade(@purple, 25%);
color : white;
background-color: @purple;
}
textarea{
height : 80px;

View File

@@ -7,7 +7,7 @@
<link rel="icon" href="/assets/NaturalCrit/favicon.ico" type="image/x-icon" />
{{=vitreum.css}}
{{=vitreum.globals}}
<title>NaturalCrit</title>
<title>Natural Crit - D&D Combat Manager</title>
</head>
<body>
<div id="reactContainer">{{=vitreum.component}}</div>

View File

@@ -2,29 +2,16 @@ var React = require('react');
var _ = require('lodash');
var cx = require('classnames');
var JSONEditor = require('jsoneditor');
//var editor = new JSONEditor(container);
var json = {
test : 6,
arr : [true, 1,2,3,4],
yo : {
yeah : true
}
}
var downloadFile = function(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
@@ -32,10 +19,8 @@ var downloadFile = function(filename, text) {
var JsonFileEditor = React.createClass({
getDefaultProps: function() {
return {
name : "yo",
json : json,
name : "test",
json : {},
onJSONChange : function(){}
};
},
@@ -45,11 +30,11 @@ var JsonFileEditor = React.createClass({
showEditor: false
};
},
componentWillReceiveProps: function(nextProps) {
//this.editor.set(nextProps.json);
if(JSON.stringify(nextProps.json) != JSON.stringify(this.editor.get())){
this.editor.set(nextProps.json);
}
},
componentDidMount: function() {
this.editor = new JSONEditor(this.refs.editor, {
change : this.handleJSONChange,
@@ -57,23 +42,14 @@ var JsonFileEditor = React.createClass({
}, this.props.json)
},
handleJSONChange : function(){
this.props.onJSONChange(this.editor.get());
//try to store in local storage?
},
handleShowEditorClick : function(){
this.setState({
showEditor : !this.state.showEditor
})
},
handleDownload : function(){
downloadFile(this.props.name + '.json', JSON.stringify(this.props.json, null, '\t'));
},
@@ -88,12 +64,6 @@ var JsonFileEditor = React.createClass({
handleUploadClick : function(){
this.refs.uploader.click()
},
handleRemove : function(){
},
renderEditor : function(){
return <div className='jsonEditor' ref='editor' />
@@ -104,23 +74,14 @@ var JsonFileEditor = React.createClass({
var self = this;
return(
<div className={cx('jsonFileEditor', {'showEditor' : this.state.showEditor})}>
<span className='name'>{this.props.name}</span>
<div className='controls'>
<button className='showEditor' onClick={this.handleShowEditorClick}><i className='fa fa-edit' /></button>
<button className='downloadJSON' onClick={this.handleDownload}><i className='fa fa-download' /></button>
<button className='uploadJSON' onClick={this.handleUploadClick}><i className='fa fa-cloud-upload' /></button>
</div>
{this.renderEditor()}
<input type="file" id="input" onChange={this.handleUpload} ref='uploader' />
</div>

View File

@@ -2,34 +2,52 @@
@import (less) "./jsoneditor.css";
.jsonFileEditor{
position : relative;
width : 100%;
padding : 10px;
&.showEditor{
.jsonEditor{
display : initial;
}
}
.jsonEditor{
position : absolute;
display : none;
top : 100%;
left : 0px;
z-index : 1000;
min-width : 400px;
background-color : white;
}
.name{
display : inline-block;
font-size : 0.8em;
font-weight : 800;
min-width: 100px;
}
.controls{
position : absolute;
top : 0px;
right : 0px;
display: inline-block;
float: right;
//position : absolute;
//top : 0px;
//right : 0px;
button{
outline: none;
border : none;
cursor: pointer;
background-color: transparent;
.animate(color);
&:hover{
&.showEditor{ color : @green; }
&.downloadJSON{ color : @blue; }
&.uploadJSON{ color : @orange; }
}
}
}
input[type="file"]{
display: none;
display : none;
}
}