mirror of
https://github.com/stolksdorf/homebrewery.git
synced 2025-12-16 08:15:55 +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 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({
|
var Editor = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
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){
|
handleTextChange : function(text){
|
||||||
this.props.onChange(text);
|
this.props.onChange(text);
|
||||||
},
|
},
|
||||||
|
handleCursorActivty : function(curpos){
|
||||||
iconClick : function(snippetFn){
|
this.cursorPosition = curpos;
|
||||||
var curPos = this.refs.textarea.selectionStart;
|
|
||||||
this.props.onChange(this.props.text.slice(0, curPos) +
|
|
||||||
snippetFn() +
|
|
||||||
this.props.text.slice(curPos + 1));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTemplateIcons : function(){
|
handleSnippetClick : function(injectText){
|
||||||
return _.map(Snippets, (t) => {
|
if(!this.cursorPosition) return;
|
||||||
return <div className='icon' key={t.icon}
|
var lines = this.props.value.split('\n');
|
||||||
onClick={this.iconClick.bind(this, t.snippet)}
|
lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText);
|
||||||
data-tooltip={t.tooltip}>
|
|
||||||
<i className={'fa ' + t.icon} />
|
this.handleTextChange(lines.join('\n'));
|
||||||
</div>;
|
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(){
|
renderSnippetGroups : function(){
|
||||||
return _.map(Snippets, (snippetGroup)=>{
|
return _.map(Snippets, (snippetGroup)=>{
|
||||||
@@ -43,19 +60,25 @@ var Editor = React.createClass({
|
|||||||
groupName={snippetGroup.groupName}
|
groupName={snippetGroup.groupName}
|
||||||
icon={snippetGroup.icon}
|
icon={snippetGroup.icon}
|
||||||
snippets={snippetGroup.snippets}
|
snippets={snippetGroup.snippets}
|
||||||
|
key={snippetGroup.groupName}
|
||||||
|
onSnippetClick={this.handleSnippetClick}
|
||||||
/>
|
/>
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return(
|
return(
|
||||||
<div className='editor'>
|
<div className='editor' ref='main'>
|
||||||
{this.renderTemplateIcons()}
|
<div className='snippetBar' ref='snippetBar'>
|
||||||
<div className='snippetBar'>
|
|
||||||
{this.renderSnippetGroups()}
|
{this.renderSnippetGroups()}
|
||||||
</div>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -65,6 +88,12 @@ module.exports = Editor;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var SnippetGroup = React.createClass({
|
var SnippetGroup = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
@@ -74,19 +103,27 @@ var SnippetGroup = React.createClass({
|
|||||||
onSnippetClick : function(){},
|
onSnippetClick : function(){},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
handleSnippetClick : function(snippet){
|
||||||
return {
|
this.props.onSnippetClick(execute(snippet.gen));
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
renderSnippets : function(){
|
||||||
|
return _.map(this.props.snippets, (snippet)=>{
|
||||||
handleSnippetClick : function(){
|
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(){
|
render : function(){
|
||||||
return <div className='snippetGroup'>
|
return <div className='snippetGroup'>
|
||||||
|
<div className='text'>
|
||||||
<i className={'fa fa-fw ' + this.props.icon} />
|
<i className={'fa fa-fw ' + this.props.icon} />
|
||||||
|
<span className='groupName'>{this.props.groupName}</span>
|
||||||
|
</div>
|
||||||
|
<div className='dropdown'>
|
||||||
|
{this.renderSnippets()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,10 @@
|
|||||||
|
|
||||||
.editor{
|
.editor{
|
||||||
position : relative;
|
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{
|
.snippetBar{
|
||||||
padding : 5px;
|
padding : 5px;
|
||||||
@@ -48,7 +13,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
//justify-content: center;
|
|
||||||
|
|
||||||
|
|
||||||
.snippetGroup{
|
.snippetGroup{
|
||||||
@@ -59,11 +23,56 @@
|
|||||||
background-color: #999;
|
background-color: #999;
|
||||||
}
|
}
|
||||||
padding : 5px;
|
padding : 5px;
|
||||||
font-size: 20px;
|
font-size: 15px;
|
||||||
margin: 0px 10px;
|
margin: 0px 10px;
|
||||||
|
|
||||||
|
.text{
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
.groupName{
|
||||||
|
margin-left: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//cursor : pointer;
|
//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',
|
name : 'Spell',
|
||||||
icon : 'fa-magic',
|
icon : 'fa-magic',
|
||||||
snippet : SpellGen
|
gen : SpellGen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Test',
|
||||||
|
icon : 'fa-rocket',
|
||||||
|
gen : function(){ return "TEST"}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -174,7 +179,7 @@ module.exports = [
|
|||||||
{
|
{
|
||||||
name : 'Spell',
|
name : 'Spell',
|
||||||
icon : 'fa-magic',
|
icon : 'fa-magic',
|
||||||
snippet : SpellGen
|
gen : SpellGen
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -185,7 +190,7 @@ module.exports = [
|
|||||||
{
|
{
|
||||||
name : 'Spell',
|
name : 'Spell',
|
||||||
icon : 'fa-magic',
|
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 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){
|
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 [
|
return [
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ var HomePage = React.createClass({
|
|||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSplitMove : function(){
|
||||||
|
this.refs.editor.update();
|
||||||
|
},
|
||||||
|
|
||||||
handleTextChange : function(text){
|
handleTextChange : function(text){
|
||||||
this.setState({
|
this.setState({
|
||||||
text : text
|
text : text
|
||||||
@@ -59,16 +63,12 @@ var HomePage = React.createClass({
|
|||||||
//localStorage.setItem(KEY, text);
|
//localStorage.setItem(KEY, text);
|
||||||
},
|
},
|
||||||
|
|
||||||
render : function(){
|
renderNavbar : function(){
|
||||||
return(
|
return <Navbar>
|
||||||
<div className='homePage page'>
|
|
||||||
<Navbar>
|
|
||||||
|
|
||||||
<Nav.section>
|
<Nav.section>
|
||||||
<Nav.item>Bad Ass Brew</Nav.item>
|
<Nav.item>Bad Ass Brew</Nav.item>
|
||||||
</Nav.section>
|
</Nav.section>
|
||||||
|
|
||||||
|
|
||||||
<Nav.section>
|
<Nav.section>
|
||||||
<RedditShare brew={{text : this.state.text}}/>
|
<RedditShare brew={{text : this.state.text}}/>
|
||||||
<Nav.item
|
<Nav.item
|
||||||
@@ -92,10 +92,16 @@ var HomePage = React.createClass({
|
|||||||
</Nav.item>
|
</Nav.item>
|
||||||
</Nav.section>
|
</Nav.section>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function(){
|
||||||
|
return(
|
||||||
|
<div className='homePage page'>
|
||||||
|
{this.renderNavbar()}
|
||||||
|
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
<SplitPane>
|
<SplitPane onDragFinish={this.handleSplitMove} ref='pane'>
|
||||||
<Editor value={this.state.text} onChange={this.handleTextChange} />
|
<Editor value={this.state.text} onChange={this.handleTextChange} ref='editor'/>
|
||||||
<div>{this.state.text}</div>
|
<div>{this.state.text}</div>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ var _ = require('lodash');
|
|||||||
var cx = require('classnames');
|
var cx = require('classnames');
|
||||||
|
|
||||||
var SplitPane = React.createClass({
|
var SplitPane = React.createClass({
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
onDragFinish : function(){} //fires when dragging
|
||||||
|
};
|
||||||
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
storageKey : 'naturalcrit-pane-split',
|
storageKey : 'naturalcrit-pane-split',
|
||||||
@@ -20,20 +25,23 @@ var SplitPane = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleUp : function(){
|
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 });
|
this.setState({ isDragging : false });
|
||||||
},
|
},
|
||||||
handleDown : function(){
|
handleDown : function(){
|
||||||
this.setState({ isDragging : true });
|
this.setState({ isDragging : true });
|
||||||
this.unFocus()
|
//this.unFocus()
|
||||||
},
|
},
|
||||||
handleMove : function(e){
|
handleMove : function(e){
|
||||||
if(!this.state.isDragging) return;
|
if(!this.state.isDragging) return;
|
||||||
this.setState({
|
this.setState({
|
||||||
size : e.pageX
|
size : e.pageX
|
||||||
});
|
});
|
||||||
window.localStorage.setItem(this.props.storageKey, e.pageX);
|
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
unFocus : function() {
|
unFocus : function() {
|
||||||
if(document.selection){
|
if(document.selection){
|
||||||
document.selection.empty();
|
document.selection.empty();
|
||||||
@@ -41,12 +49,9 @@ var SplitPane = React.createClass({
|
|||||||
window.getSelection().removeAllRanges();
|
window.getSelection().removeAllRanges();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
renderDivider : function(){
|
renderDivider : function(){
|
||||||
return <div
|
return <div className='divider' onMouseDown={this.handleDown} />
|
||||||
className='divider'
|
|
||||||
onMouseDown={this.handleDown}
|
|
||||||
/>
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
|
|||||||
@@ -34,20 +34,35 @@ var CodeEditor = React.createClass({
|
|||||||
|
|
||||||
this.codeMirror.on('change', this.handleChange);
|
this.codeMirror.on('change', this.handleChange);
|
||||||
this.codeMirror.on('cursorActivity', this.handleCursorActivity);
|
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) {
|
if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) {
|
||||||
this.codeMirror.setValue(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){
|
handleChange : function(editor){
|
||||||
this.props.onChange(editor.getValue());
|
this.props.onChange(editor.getValue());
|
||||||
},
|
},
|
||||||
handleCursorActivity : function(){
|
handleCursorActivity : function(){
|
||||||
this.props.onCursorActivity(this.codeMirror.getCursor());
|
this.props.onCursorActivity(this.codeMirror.doc.getCursor());
|
||||||
},
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
|
|||||||
Reference in New Issue
Block a user