mirror of
https://github.com/stolksdorf/homebrewery.git
synced 2025-12-15 22:35:59 +00:00
Editor pane looks finished, injecting snippet text is workign and snippet group structure done
This commit is contained in:
@@ -6,6 +6,16 @@ var CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
|
||||
|
||||
var Snippets = require('./snippets/snippets.js');
|
||||
|
||||
|
||||
var splice = function(str, index, inject){
|
||||
return str.slice(0, index) + inject + str.slice(index);
|
||||
};
|
||||
var execute = function(val){
|
||||
if(_.isFunction(val)) return val();
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
var Editor = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
@@ -14,28 +24,35 @@ var Editor = React.createClass({
|
||||
};
|
||||
},
|
||||
|
||||
cursorPosition : null,
|
||||
|
||||
|
||||
componentDidMount: function() {
|
||||
var paneHeight = this.refs.main.parentNode.clientHeight;
|
||||
paneHeight -= this.refs.snippetBar.clientHeight + 1;
|
||||
this.refs.codeEditor.codeMirror.setSize(null, paneHeight);
|
||||
},
|
||||
|
||||
handleTextChange : function(text){
|
||||
this.props.onChange(text);
|
||||
},
|
||||
|
||||
iconClick : function(snippetFn){
|
||||
var curPos = this.refs.textarea.selectionStart;
|
||||
this.props.onChange(this.props.text.slice(0, curPos) +
|
||||
snippetFn() +
|
||||
this.props.text.slice(curPos + 1));
|
||||
handleCursorActivty : function(curpos){
|
||||
this.cursorPosition = curpos;
|
||||
},
|
||||
|
||||
renderTemplateIcons : function(){
|
||||
return _.map(Snippets, (t) => {
|
||||
return <div className='icon' key={t.icon}
|
||||
onClick={this.iconClick.bind(this, t.snippet)}
|
||||
data-tooltip={t.tooltip}>
|
||||
<i className={'fa ' + t.icon} />
|
||||
</div>;
|
||||
})
|
||||
handleSnippetClick : function(injectText){
|
||||
if(!this.cursorPosition) return;
|
||||
var lines = this.props.value.split('\n');
|
||||
lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText);
|
||||
|
||||
this.handleTextChange(lines.join('\n'));
|
||||
this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length);
|
||||
},
|
||||
|
||||
//Called when there are changes to the editor's dimensions
|
||||
update : function(){
|
||||
this.refs.codeEditor.updateSize();
|
||||
},
|
||||
|
||||
renderSnippetGroups : function(){
|
||||
return _.map(Snippets, (snippetGroup)=>{
|
||||
@@ -43,19 +60,25 @@ var Editor = React.createClass({
|
||||
groupName={snippetGroup.groupName}
|
||||
icon={snippetGroup.icon}
|
||||
snippets={snippetGroup.snippets}
|
||||
key={snippetGroup.groupName}
|
||||
onSnippetClick={this.handleSnippetClick}
|
||||
/>
|
||||
})
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return(
|
||||
<div className='editor'>
|
||||
{this.renderTemplateIcons()}
|
||||
<div className='snippetBar'>
|
||||
<div className='editor' ref='main'>
|
||||
<div className='snippetBar' ref='snippetBar'>
|
||||
{this.renderSnippetGroups()}
|
||||
</div>
|
||||
<CodeEditor wrap={true} language='gfm' value={this.props.value} onChange={this.handleTextChange} />
|
||||
|
||||
<CodeEditor
|
||||
ref='codeEditor'
|
||||
wrap={true}
|
||||
language='gfm'
|
||||
value={this.props.value}
|
||||
onChange={this.handleTextChange}
|
||||
onCursorActivity={this.handleCursorActivty} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -65,6 +88,12 @@ module.exports = Editor;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var SnippetGroup = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
@@ -74,19 +103,27 @@ var SnippetGroup = React.createClass({
|
||||
onSnippetClick : function(){},
|
||||
};
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
};
|
||||
handleSnippetClick : function(snippet){
|
||||
this.props.onSnippetClick(execute(snippet.gen));
|
||||
},
|
||||
|
||||
|
||||
handleSnippetClick : function(){
|
||||
|
||||
renderSnippets : function(){
|
||||
return _.map(this.props.snippets, (snippet)=>{
|
||||
return <div className='snippet' key={snippet.name} onClick={this.handleSnippetClick.bind(this, snippet)}>
|
||||
<i className={'fa fa-fw ' + snippet.icon} />
|
||||
{snippet.name}
|
||||
</div>
|
||||
})
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='snippetGroup'>
|
||||
<div className='text'>
|
||||
<i className={'fa fa-fw ' + this.props.icon} />
|
||||
<span className='groupName'>{this.props.groupName}</span>
|
||||
</div>
|
||||
<div className='dropdown'>
|
||||
{this.renderSnippets()}
|
||||
</div>
|
||||
</div>
|
||||
},
|
||||
|
||||
|
||||
@@ -1,45 +1,10 @@
|
||||
|
||||
.editor{
|
||||
position : relative;
|
||||
height : 100%;
|
||||
min-height : 100%;
|
||||
width : 100%;
|
||||
//display: flex;
|
||||
//flex-direction: column;
|
||||
/*
|
||||
.textIcons{
|
||||
display : inline-block;
|
||||
vertical-align : top;
|
||||
.icon{
|
||||
display : inline-block;
|
||||
height : 30px;
|
||||
width : 30px;
|
||||
cursor : pointer;
|
||||
font-size : 1.5em;
|
||||
line-height : 30px;
|
||||
text-align : center;
|
||||
&:nth-child(8n + 1){ background-color: @blue; }
|
||||
&:nth-child(8n + 2){ background-color: @orange; }
|
||||
&:nth-child(8n + 3){ background-color: @teal; }
|
||||
&:nth-child(8n + 4){ background-color: @red; }
|
||||
&:nth-child(8n + 5){ background-color: @purple; }
|
||||
&:nth-child(8n + 6){ background-color: @silver; }
|
||||
&:nth-child(8n + 7){ background-color: @yellow; }
|
||||
&:nth-child(8n + 8){ background-color: @green; }
|
||||
}
|
||||
}
|
||||
textarea{
|
||||
box-sizing : border-box;
|
||||
resize : none;
|
||||
overflow-y : scroll;
|
||||
height : 100%;
|
||||
width : 100%;
|
||||
padding : 10px;
|
||||
border : none;
|
||||
outline: none;
|
||||
}
|
||||
*/
|
||||
|
||||
width : 100%;
|
||||
|
||||
height : 500px;
|
||||
|
||||
.snippetBar{
|
||||
padding : 5px;
|
||||
@@ -48,7 +13,6 @@
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
//justify-content: center;
|
||||
|
||||
|
||||
.snippetGroup{
|
||||
@@ -59,11 +23,56 @@
|
||||
background-color: #999;
|
||||
}
|
||||
padding : 5px;
|
||||
font-size: 20px;
|
||||
font-size: 15px;
|
||||
margin: 0px 10px;
|
||||
|
||||
.text{
|
||||
line-height: 20px;
|
||||
|
||||
.groupName{
|
||||
margin-left: 6px;
|
||||
font-size: 12px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//cursor : pointer;
|
||||
|
||||
&:hover{
|
||||
.dropdown{
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.dropdown{
|
||||
position: absolute;
|
||||
z-index : 1000;
|
||||
background-color: #ddd;
|
||||
padding : 5px;
|
||||
visibility: hidden;
|
||||
|
||||
.snippet{
|
||||
font-size: 13px;
|
||||
padding : 10px;
|
||||
.animate(background-color);
|
||||
cursor : pointer;
|
||||
&:hover{
|
||||
background-color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.codeEditor{
|
||||
height : 100%;
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,12 @@ module.exports = [
|
||||
{
|
||||
name : 'Spell',
|
||||
icon : 'fa-magic',
|
||||
snippet : SpellGen
|
||||
gen : SpellGen
|
||||
},
|
||||
{
|
||||
name : 'Test',
|
||||
icon : 'fa-rocket',
|
||||
gen : function(){ return "TEST"}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -174,7 +179,7 @@ module.exports = [
|
||||
{
|
||||
name : 'Spell',
|
||||
icon : 'fa-magic',
|
||||
snippet : SpellGen
|
||||
gen : SpellGen
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -185,7 +190,7 @@ module.exports = [
|
||||
{
|
||||
name : 'Spell',
|
||||
icon : 'fa-magic',
|
||||
snippet : SpellGen
|
||||
gen : SpellGen
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -56,9 +56,9 @@ module.exports = function(){
|
||||
var spellSchools = ["abjuration", "conjuration", "divination", "enchantment", "evocation", "illusion", "necromancy", "transmutation"];
|
||||
|
||||
|
||||
var components = _.sample(["V", "S", "M"], _.random(1,3)).join(', ');
|
||||
var components = _.sampleSize(["V", "S", "M"], _.random(1,3)).join(', ');
|
||||
if(components.indexOf("M") !== -1){
|
||||
components += " (" + _.sample(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")"
|
||||
components += " (" + _.sampleSize(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")"
|
||||
}
|
||||
|
||||
return [
|
||||
|
||||
@@ -51,6 +51,10 @@ var HomePage = React.createClass({
|
||||
*/
|
||||
},
|
||||
|
||||
handleSplitMove : function(){
|
||||
this.refs.editor.update();
|
||||
},
|
||||
|
||||
handleTextChange : function(text){
|
||||
this.setState({
|
||||
text : text
|
||||
@@ -59,16 +63,12 @@ var HomePage = React.createClass({
|
||||
//localStorage.setItem(KEY, text);
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return(
|
||||
<div className='homePage page'>
|
||||
<Navbar>
|
||||
|
||||
renderNavbar : function(){
|
||||
return <Navbar>
|
||||
<Nav.section>
|
||||
<Nav.item>Bad Ass Brew</Nav.item>
|
||||
</Nav.section>
|
||||
|
||||
|
||||
<Nav.section>
|
||||
<RedditShare brew={{text : this.state.text}}/>
|
||||
<Nav.item
|
||||
@@ -92,10 +92,16 @@ var HomePage = React.createClass({
|
||||
</Nav.item>
|
||||
</Nav.section>
|
||||
</Navbar>
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return(
|
||||
<div className='homePage page'>
|
||||
{this.renderNavbar()}
|
||||
|
||||
<div className='content'>
|
||||
<SplitPane>
|
||||
<Editor value={this.state.text} onChange={this.handleTextChange} />
|
||||
<SplitPane onDragFinish={this.handleSplitMove} ref='pane'>
|
||||
<Editor value={this.state.text} onChange={this.handleTextChange} ref='editor'/>
|
||||
<div>{this.state.text}</div>
|
||||
</SplitPane>
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@ var _ = require('lodash');
|
||||
var cx = require('classnames');
|
||||
|
||||
var SplitPane = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
onDragFinish : function(){} //fires when dragging
|
||||
};
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
storageKey : 'naturalcrit-pane-split',
|
||||
@@ -20,20 +25,23 @@ var SplitPane = React.createClass({
|
||||
},
|
||||
|
||||
handleUp : function(){
|
||||
if(this.state.isDragging){
|
||||
this.props.onDragFinish(this.state.size);
|
||||
window.localStorage.setItem(this.props.storageKey, this.state.size);
|
||||
}
|
||||
this.setState({ isDragging : false });
|
||||
},
|
||||
handleDown : function(){
|
||||
this.setState({ isDragging : true });
|
||||
this.unFocus()
|
||||
//this.unFocus()
|
||||
},
|
||||
handleMove : function(e){
|
||||
if(!this.state.isDragging) return;
|
||||
this.setState({
|
||||
size : e.pageX
|
||||
});
|
||||
window.localStorage.setItem(this.props.storageKey, e.pageX);
|
||||
},
|
||||
|
||||
/*
|
||||
unFocus : function() {
|
||||
if(document.selection){
|
||||
document.selection.empty();
|
||||
@@ -41,12 +49,9 @@ var SplitPane = React.createClass({
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
},
|
||||
|
||||
*/
|
||||
renderDivider : function(){
|
||||
return <div
|
||||
className='divider'
|
||||
onMouseDown={this.handleDown}
|
||||
/>
|
||||
return <div className='divider' onMouseDown={this.handleDown} />
|
||||
},
|
||||
|
||||
render : function(){
|
||||
|
||||
@@ -34,20 +34,35 @@ var CodeEditor = React.createClass({
|
||||
|
||||
this.codeMirror.on('change', this.handleChange);
|
||||
this.codeMirror.on('cursorActivity', this.handleCursorActivity);
|
||||
this.updateSize();
|
||||
},
|
||||
|
||||
componentWillReceiveProps: _.debounce(function(nextProps){
|
||||
componentWillReceiveProps: function(nextProps){
|
||||
if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) {
|
||||
this.codeMirror.setValue(nextProps.value);
|
||||
}
|
||||
}, 0),
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
return false;
|
||||
},
|
||||
|
||||
setCursorPosition : function(line, char){
|
||||
setTimeout(()=>{
|
||||
this.codeMirror.focus();
|
||||
this.codeMirror.doc.setCursor(line, char);
|
||||
}, 10);
|
||||
},
|
||||
|
||||
updateSize : function(){
|
||||
this.codeMirror.refresh();
|
||||
},
|
||||
|
||||
handleChange : function(editor){
|
||||
this.props.onChange(editor.getValue());
|
||||
},
|
||||
handleCursorActivity : function(){
|
||||
this.props.onCursorActivity(this.codeMirror.getCursor());
|
||||
this.props.onCursorActivity(this.codeMirror.doc.getCursor());
|
||||
},
|
||||
|
||||
render : function(){
|
||||
|
||||
Reference in New Issue
Block a user