diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx
deleted file mode 100644
index 82dab8f..0000000
--- a/client/homebrew/brewRenderer/brewRenderer.jsx
+++ /dev/null
@@ -1,145 +0,0 @@
-const React = require('react');
-const _ = require('lodash');
-const cx = require('classnames');
-
-const Markdown = require('homebrewery/markdown.js');
-const ErrorBar = require('./errorBar/errorBar.jsx');
-
-const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx')
-const Store = require('homebrewery/brew.store.js');
-
-
-const PAGE_HEIGHT = 1056;
-const PPR_THRESHOLD = 50;
-
-const BrewRenderer = React.createClass({
- getDefaultProps: function() {
- return {
- brewText : '',
- errors : []
- };
- },
- getInitialState: function() {
- const pages = this.props.brewText.split('\\page');
-
- return {
- viewablePageNumber: 0,
- height : 0,
- isMounted : false,
- pages : pages,
- usePPR : pages.length >= PPR_THRESHOLD
- };
- },
- height : 0,
- pageHeight : PAGE_HEIGHT,
- lastRender :
,
-
- componentDidMount: function() {
- this.updateSize();
- window.addEventListener("resize", this.updateSize);
- },
- componentWillUnmount: function() {
- window.removeEventListener("resize", this.updateSize);
- },
-
- componentWillReceiveProps: function(nextProps) {
- if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
-
- const pages = nextProps.brewText.split('\\page');
- this.setState({
- pages : pages,
- usePPR : pages.length >= PPR_THRESHOLD
- })
- },
-
- updateSize : function() {
- setTimeout(()=>{
- if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
- }, 1);
-
- this.setState({
- height : this.refs.main.parentNode.clientHeight,
- isMounted : true
- });
- },
-
- handleScroll : function(e){
- this.setState({
- viewablePageNumber : Math.floor(e.target.scrollTop / this.pageHeight)
- });
- },
-
- shouldRender : function(pageText, index){
- if(!this.state.isMounted) return false;
-
- var viewIndex = this.state.viewablePageNumber;
- if(index == viewIndex - 1) return true;
- if(index == viewIndex) return true;
- if(index == viewIndex + 1) return true;
-
- //Check for style tages
- if(pageText.indexOf('
-
-
-
-# ${_.sample(titles)}
-
-
-
-##### ${_.sample(subtitles)}
-
-
-\\page`
-}
\ No newline at end of file
diff --git a/client/homebrew/editor/snippetbar/snippets/fullclass.gen.js b/client/homebrew/editor/snippetbar/snippets/fullclass.gen.js
deleted file mode 100644
index 9a2da20..0000000
--- a/client/homebrew/editor/snippetbar/snippets/fullclass.gen.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var _ = require('lodash');
-
-var ClassFeatureGen = require('./classfeature.gen.js');
-
-var ClassTableGen = require('./classtable.gen.js');
-
-module.exports = function(){
-
- var classname = _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
- 'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge'])
-
-
- var image = _.sample(_.map([
- "http://orig01.deviantart.net/4682/f/2007/099/f/c/bard_stick_figure_by_wrpigeek.png",
- "http://img07.deviantart.net/a3c9/i/2007/099/3/a/archer_stick_figure_by_wrpigeek.png",
- "http://pre04.deviantart.net/d596/th/pre/f/2007/099/5/2/adventurer_stick_figure_by_wrpigeek.png",
- "http://img13.deviantart.net/d501/i/2007/099/d/4/black_mage_stick_figure_by_wrpigeek.png",
- "http://img09.deviantart.net/5cf3/i/2007/099/d/d/dark_knight_stick_figure_by_wrpigeek.png",
- "http://pre01.deviantart.net/7a34/th/pre/f/2007/099/6/3/monk_stick_figure_by_wrpigeek.png",
- "http://img11.deviantart.net/5dcc/i/2007/099/d/1/mystic_knight_stick_figure_by_wrpigeek.png",
- "http://pre08.deviantart.net/ad45/th/pre/f/2007/099/a/0/thief_stick_figure_by_wrpigeek.png",
- ], function(url){
- return "
"
- }))
-
-
- return [
- image,
- "",
- "```",
- "```",
- "\n\n",
- "## " + classname,
- "Cool intro stuff will go here",
-
- "\\page",
- ClassTableGen(classname),
- ClassFeatureGen(classname),
-
-
-
- ].join('\n') + '\n\n\n';
-};
\ No newline at end of file
diff --git a/client/homebrew/editor/snippetbar/snippets/magic.gen.js b/client/homebrew/editor/snippetbar/snippets/magic.gen.js
deleted file mode 100644
index 82469cd..0000000
--- a/client/homebrew/editor/snippetbar/snippets/magic.gen.js
+++ /dev/null
@@ -1,91 +0,0 @@
-var _ = require('lodash');
-
-var spellNames = [
- "Astral Rite of Acne",
- "Create Acne",
- "Cursed Ramen Erruption",
- "Dark Chant of the Dentists",
- "Erruption of Immaturity",
- "Flaming Disc of Inconvenience",
- "Heal Bad Hygene",
- "Heavenly Transfiguration of the Cream Devil",
- "Hellish Cage of Mucus",
- "Irritate Peanut Butter Fairy",
- "Luminous Erruption of Tea",
- "Mystic Spell of the Poser",
- "Sorcerous Enchantment of the Chimneysweep",
- "Steak Sauce Ray",
- "Talk to Groupie",
- "Astonishing Chant of Chocolate",
- "Astounding Pasta Puddle",
- "Ball of Annoyance",
- "Cage of Yarn",
- "Control Noodles Elemental",
- "Create Nervousness",
- "Cure Baldness",
- "Cursed Ritual of Bad Hair",
- "Dispell Piles in Dentist",
- "Eliminate Florists",
- "Illusionary Transfiguration of the Babysitter",
- "Necromantic Armor of Salad Dressing",
- "Occult Transfiguration of Foot Fetish",
- "Protection from Mucus Giant",
- "Tinsel Blast",
- "Alchemical Evocation of the Goths",
- "Call Fangirl",
- "Divine Spell of Crossdressing",
- "Dominate Ramen Giant",
- "Eliminate Vindictiveness in Gym Teacher",
- "Extra-Planar Spell of Irritation",
- "Induce Whining in Babysitter",
- "Invoke Complaining",
- "Magical Enchantment of Arrogance",
- "Occult Globe of Salad Dressing",
- "Overwhelming Enchantment of the Chocolate Fairy",
- "Sorcerous Dandruff Globe",
- "Spiritual Invocation of the Costumers",
- "Ultimate Rite of the Confetti Angel",
- "Ultimate Ritual of Mouthwash",
-];
-
-module.exports = {
-
- spellList : function(){
- var levels = ['Cantrips (0 Level)', '2nd Level', '3rd Level', '4th Level', '5th Level', '6th Level', '7th Level', '8th Level', '9th Level'];
-
- var content = _.map(levels, (level)=>{
- var spells = _.map(_.sampleSize(spellNames, _.random(5, 15)), (spell)=>{
- return `- ${spell}`;
- }).join('\n');
- return `##### ${level} \n${spells} \n`;
- }).join('\n');
-
- return `\n${content}\n
`;
- },
-
- spell : function(){
- var level = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th"];
- var spellSchools = ["abjuration", "conjuration", "divination", "enchantment", "evocation", "illusion", "necromancy", "transmutation"];
-
-
- var components = _.sampleSize(["V", "S", "M"], _.random(1,3)).join(', ');
- if(components.indexOf("M") !== -1){
- components += " (" + _.sampleSize(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")"
- }
-
- return [
- "#### " + _.sample(spellNames),
- "*" + _.sample(level) + "-level " + _.sample(spellSchools) + "*",
- "___",
- "- **Casting Time:** 1 action",
- "- **Range:** " + _.sample(["Self", "Touch", "30 feet", "60 feet"]),
- "- **Components:** " + components,
- "- **Duration:** " + _.sample(["Until dispelled", "1 round", "Instantaneous", "Concentration, up to 10 minutes", "1 hour"]),
- "",
- "A flame, equivalent in brightness to a torch, springs from from an object that you touch. ",
- "The effect look like a regular flame, but it creates no heat and doesn't use oxygen. ",
- "A *continual flame* can be covered or hidden but not smothered or quenched.",
- "\n\n\n"
- ].join('\n');
- }
-}
\ No newline at end of file
diff --git a/client/homebrew/editor/snippetbar/snippets/monsterblock.gen.js b/client/homebrew/editor/snippetbar/snippets/monsterblock.gen.js
deleted file mode 100644
index abbcd6c..0000000
--- a/client/homebrew/editor/snippetbar/snippets/monsterblock.gen.js
+++ /dev/null
@@ -1,196 +0,0 @@
-var _ = require('lodash');
-
-var genList = function(list, max){
- return _.sampleSize(list, _.random(0,max)).join(', ') || "None";
-}
-
-var getMonsterName = function(){
- return _.sample([
- "All-devouring Baseball Imp",
- "All-devouring Gumdrop Wraith",
- "Chocolate Hydra",
- "Devouring Peacock",
- "Economy-sized Colossus of the Lemonade Stand",
- "Ghost Pigeon",
- "Gibbering Duck",
- "Sparklemuffin Peacock Spider",
- "Gum Elemental",
- "Illiterate Construct of the Candy Store",
- "Ineffable Chihuahua",
- "Irritating Death Hamster",
- "Irritating Gold Mouse",
- "Juggernaut Snail",
- "Juggernaut of the Sock Drawer",
- "Koala of the Cosmos",
- "Mad Koala of the West",
- "Milk Djinni of the Lemonade Stand",
- "Mind Ferret",
- "Mystic Salt Spider",
- "Necrotic Halitosis Angel",
- "Pinstriped Famine Sheep",
- "Ritalin Leech",
- "Shocker Kangaroo",
- "Stellar Tennis Juggernaut",
- "Wailing Quail of the Sun",
- "Angel Pigeon",
- "Anime Sphinx",
- "Bored Avalanche Sheep of the Wasteland",
- "Devouring Nougat Sphinx of the Sock Drawer",
- "Djinni of the Footlocker",
- "Ectoplasmic Jazz Devil",
- "Flatuent Angel",
- "Gelatinous Duck of the Dream-Lands",
- "Gelatinous Mouse",
- "Golem of the Footlocker",
- "Lich Wombat",
- "Mechanical Sloth of the Past",
- "Milkshake Succubus",
- "Puffy Bone Peacock of the East",
- "Rainbow Manatee",
- "Rune Parrot",
- "Sand Cow",
- "Sinister Vanilla Dragon",
- "Snail of the North",
- "Spider of the Sewer",
- "Stellar Sawdust Leech",
- "Storm Anteater of Hell",
- "Stupid Spirit of the Brewery",
- "Time Kangaroo",
- "Tomb Poodle",
- ]);
-}
-
-var getType = function(){
- return _.sample(['Tiny', 'Small', 'Medium', 'Large', 'Gargantuan', 'Stupidly vast']) + " " + _.sample(['beast', 'fiend', 'annoyance', 'guy', 'cutie'])
-}
-
-var getAlignment = function(){
- return _.sample([
- "annoying evil",
- "chaotic gossipy",
- "chaotic sloppy",
- "depressed neutral",
- "lawful bogus",
- "lawful coy",
- "manic-depressive evil",
- "narrow-minded neutral",
- "neutral annoying",
- "neutral ignorant",
- "oedpipal neutral",
- "silly neutral",
- "unoriginal neutral",
- "weird neutral",
- "wordy evil",
- "unaligned"
- ]);
-};
-
-var getStats = function(){
- return '>|' + _.times(6, function(){
- var num = _.random(1,20);
- var mod = Math.ceil(num/2 - 5)
- return num + " (" + (mod >= 0 ? '+'+mod : mod ) + ")"
- }).join('|') + '|';
-}
-
-var genAbilities = function(){
- return _.sample([
- "> ***Pack Tactics.*** These guys work together. Like super well, you don't even know.",
- "> ***False Appearance. *** While the armor reamin motionless, it is indistinguishable from a normal suit of armor.",
- ]);
-}
-
-var genAction = function(){
- var name = _.sample([
- "Abdominal Drop",
- "Airplane Hammer",
- "Atomic Death Throw",
- "Bulldog Rake",
- "Corkscrew Strike",
- "Crossed Splash",
- "Crossface Suplex",
- "DDT Powerbomb",
- "Dual Cobra Wristlock",
- "Dual Throw",
- "Elbow Hold",
- "Gory Body Sweep",
- "Heel Jawbreaker",
- "Jumping Driver",
- "Open Chin Choke",
- "Scorpion Flurry",
- "Somersault Stump Fists",
- "Suffering Wringer",
- "Super Hip Submission",
- "Super Spin",
- "Team Elbow",
- "Team Foot",
- "Tilt-a-whirl Chin Sleeper",
- "Tilt-a-whirl Eye Takedown",
- "Turnbuckle Roll"
- ])
-
- return "> ***" + name + ".*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) ";
-}
-
-
-module.exports = {
-
- full : function(){
- return [
- "___",
- "___",
- "> ## " + getMonsterName(),
- ">*" + getType() + ", " + getAlignment() + "*",
- "> ___",
- "> - **Armor Class** " + _.random(10,20),
- "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)",
- "> - **Speed** " + _.random(0,50) + "ft.",
- ">___",
- ">|STR|DEX|CON|INT|WIS|CHA|",
- ">|:---:|:---:|:---:|:---:|:---:|:---:|",
- getStats(),
- ">___",
- "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3),
- "> - **Senses** passive Perception " + _.random(3, 20),
- "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2),
- "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)",
- "> ___",
- _.times(_.random(3,6), function(){
- return genAbilities()
- }).join('\n>\n'),
- "> ### Actions",
- _.times(_.random(4,6), function(){
- return genAction()
- }).join('\n>\n'),
- ].join('\n') + '\n\n\n';
- },
-
- half : function(){
- return [
- "___",
- "> ## " + getMonsterName(),
- ">*" + getType() + ", " + getAlignment() + "*",
- "> ___",
- "> - **Armor Class** " + _.random(10,20),
- "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)",
- "> - **Speed** " + _.random(0,50) + "ft.",
- ">___",
- ">|STR|DEX|CON|INT|WIS|CHA|",
- ">|:---:|:---:|:---:|:---:|:---:|:---:|",
- getStats(),
- ">___",
- "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3),
- "> - **Senses** passive Perception " + _.random(3, 20),
- "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2),
- "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)",
- "> ___",
- _.times(_.random(0,2), function(){
- return genAbilities()
- }).join('\n>\n'),
- "> ### Actions",
- _.times(_.random(1,2), function(){
- return genAction()
- }).join('\n>\n'),
- ].join('\n') + '\n\n\n';
- }
-}
diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js
deleted file mode 100644
index bcb1df9..0000000
--- a/client/homebrew/editor/snippetbar/snippets/snippets.js
+++ /dev/null
@@ -1,267 +0,0 @@
-var MagicGen = require('./magic.gen.js');
-var ClassTableGen = require('./classtable.gen.js');
-var MonsterBlockGen = require('./monsterblock.gen.js');
-var ClassFeatureGen = require('./classfeature.gen.js');
-var FullClassGen = require('./fullclass.gen.js');
-var CoverPageGen = require('./coverpage.gen.js');
-var TableOfContentsGen = require('./tableOfContents.gen.js');
-
-
-module.exports = [
-
- {
- groupName : 'Editor',
- icon : 'fa-pencil',
- snippets : [
- {
- name : "Column Break",
- icon : 'fa-columns',
- gen : "```\n```\n\n"
- },
- {
- name : "New Page",
- icon : 'fa-file-text',
- gen : "\\page\n\n"
- },
- {
- name : "Vertical Spacing",
- icon : 'fa-arrows-v',
- gen : "\n\n"
- },
- {
- name : "Wide Block",
- icon : 'fa-arrows-h',
- gen : "\nEverything in here will be extra wide. Tables, text, everything! Beware though, CSS columns can behave a bit weird sometimes.\n
\n"
- },
- {
- name : "Image",
- icon : 'fa-image',
- gen : [
- "
",
- "Credit: Kyounghwan Kim"
- ].join('\n')
- },
- {
- name : "Background Image",
- icon : 'fa-tree',
- gen : [
- "
"
- ].join('\n')
- },
-
- {
- name : "Page Number",
- icon : 'fa-bookmark',
- gen : "1
\n\n\n"
- },
-
- {
- name : "Auto-incrementing Page Number",
- icon : 'fa-sort-numeric-asc',
- gen : "\n"
- },
-
- {
- name : "Link to page",
- icon : 'fa-link',
- gen : "[Click here](#p3) to go to page 3\n"
- },
-
- {
- name : "Table of Contents",
- icon : 'fa-book',
- gen : TableOfContentsGen
- },
-
-
- ]
- },
-
-
- /************************* PHB ********************/
-
- {
- groupName : 'PHB',
- icon : 'fa-book',
- snippets : [
- {
- name : 'Spell',
- icon : 'fa-magic',
- gen : MagicGen.spell,
- },
- {
- name : 'Spell List',
- icon : 'fa-list',
- gen : MagicGen.spellList,
- },
- {
- name : 'Class Feature',
- icon : 'fa-trophy',
- gen : ClassFeatureGen,
- },
- {
- name : 'Note',
- icon : 'fa-sticky-note',
- gen : function(){
- return [
- "> ##### Time to Drop Knowledge",
- "> Use notes to point out some interesting information. ",
- "> ",
- "> **Tables and lists** both work within a note."
- ].join('\n');
- },
- },
- {
- name : 'Descriptive Text Box',
- icon : 'fa-sticky-note-o',
- gen : function(){
- return [
- "",
- "##### Time to Drop Knowledge",
- "Use notes to point out some interesting information. ",
- "",
- "**Tables and lists** both work within a note.",
- "
"
- ].join('\n');
- },
- },
- {
- name : 'Monster Stat Block',
- icon : 'fa-bug',
- gen : MonsterBlockGen.half,
- },
- {
- name : 'Wide Monster Stat Block',
- icon : 'fa-paw',
- gen : MonsterBlockGen.full,
- },
- {
- name : 'Cover Page',
- icon : 'fa-file-word-o',
- gen : CoverPageGen,
- },
- ]
- },
-
-
-
- /********************* TABLES *********************/
-
- {
- groupName : 'Tables',
- icon : 'fa-table',
- snippets : [
- {
- name : "Class Table",
- icon : 'fa-table',
- gen : ClassTableGen.full,
- },
- {
- name : "Half Class Table",
- icon : 'fa-list-alt',
- gen : ClassTableGen.half,
- },
- {
- name : 'Table',
- icon : 'fa-th-list',
- gen : function(){
- return [
- "##### Cookie Tastiness",
- "| Tastiness | Cookie Type |",
- "|:----:|:-------------|",
- "| -5 | Raisin |",
- "| 8th | Chocolate Chip |",
- "| 11th | 2 or lower |",
- "| 14th | 3 or lower |",
- "| 17th | 4 or lower |\n\n",
- ].join('\n');
- },
- },
- {
- name : 'Wide Table',
- icon : 'fa-list',
- gen : function(){
- return [
- "",
- "##### Cookie Tastiness",
- "| Tastiness | Cookie Type |",
- "|:----:|:-------------|",
- "| -5 | Raisin |",
- "| 8th | Chocolate Chip |",
- "| 11th | 2 or lower |",
- "| 14th | 3 or lower |",
- "| 17th | 4 or lower |",
- "
\n\n"
- ].join('\n');
- },
- },
- {
- name : 'Split Table',
- icon : 'fa-th-large',
- gen : function(){
- return [
- "",
- "| d10 | Damage Type |",
- "|:---:|:------------|",
- "| 1 | Acid |",
- "| 2 | Cold |",
- "| 3 | Fire |",
- "| 4 | Force |",
- "| 5 | Lightning |",
- "",
- "```",
- "```",
- "",
- "| d10 | Damage Type |",
- "|:---:|:------------|",
- "| 6 | Necrotic |",
- "| 7 | Poison |",
- "| 8 | Psychic |",
- "| 9 | Radiant |",
- "| 10 | Thunder |",
- "
\n\n",
- ].join('\n');
- },
- }
- ]
- },
-
-
-
-
- /**************** PRINT *************/
-
- {
- groupName : 'Print',
- icon : 'fa-print',
- snippets : [
- {
- name : "A4 PageSize",
- icon : 'fa-file-o',
- gen : [''
- ].join('\n')
- },
- {
- name : "Ink Friendly",
- icon : 'fa-tint',
- gen : ['',
- ''
- ].join('\n')
- },
- ]
- },
-
-]
diff --git a/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js b/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js
deleted file mode 100644
index 448b2f4..0000000
--- a/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const _ = require('lodash');
-
-const getTOC = (pages) => {
- const add1 = (title, page)=>{
- res.push({
- title : title,
- page : page + 1,
- children : []
- });
- }
- const add2 = (title, page)=>{
- if(!_.last(res)) add1('', page);
- _.last(res).children.push({
- title : title,
- page : page + 1,
- children : []
- });
- }
- const add3 = (title, page)=>{
- if(!_.last(res)) add1('', page);
- if(!_.last(_.last(res).children)) add2('', page);
- _.last(_.last(res).children).children.push({
- title : title,
- page : page + 1,
- children : []
- });
- }
-
- let res = [];
- _.each(pages, (page, pageNum)=>{
- const lines = page.split('\n');
- _.each(lines, (line) => {
- if(_.startsWith(line, '# ')){
- const title = line.replace('# ', '');
- add1(title, pageNum)
- }
- if(_.startsWith(line, '## ')){
- const title = line.replace('## ', '');
- add2(title, pageNum);
- }
- if(_.startsWith(line, '### ')){
- const title = line.replace('### ', '');
- add3(title, pageNum);
- }
- })
- });
- return res;
-}
-
-module.exports = function(brew){
- const pages = brew.split('\\page');
- const TOC = getTOC(pages);
- const markdown = _.reduce(TOC, (r, g1, idx1)=>{
- r.push(`- **[${idx1 + 1} ${g1.title}](#p${g1.page})**`)
- if(g1.children.length){
- _.each(g1.children, (g2, idx2) => {
- r.push(` - [${idx1 + 1}.${idx2 + 1} ${g2.title}](#p${g2.page})`);
- if(g2.children.length){
- _.each(g2.children, (g3, idx3) => {
- r.push(` - [${idx1 + 1}.${idx2 + 1}.${idx3 + 1} ${g3.title}](#p${g3.page})`);
- });
- }
- });
- }
- return r;
- }, []).join('\n');
-
- return `
-##### Table Of Contents
-${markdown}
-
\n`;
-}
\ No newline at end of file
diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx
index eb90542..0e73a56 100644
--- a/client/homebrew/homebrew.jsx
+++ b/client/homebrew/homebrew.jsx
@@ -7,10 +7,10 @@ const Actions = require('homebrewery/brew.actions.js');
const HomePage = require('./pages/homePage/homePage.jsx');
const EditPage = require('./pages/editPage/editPage.jsx');
-const UserPage = require('./pages/userPage/userPage.jsx');
-const SharePage = require('./pages/sharePage/sharePage.jsx');
+//const UserPage = require('./pages/userPage/userPage.jsx');
+//const SharePage = require('./pages/sharePage/sharePage.jsx');
const NewPage = require('./pages/newPage/newPage.jsx');
-const ErrorPage = require('./pages/errorPage/errorPage.jsx');
+//const ErrorPage = require('./pages/errorPage/errorPage.jsx');
const PrintPage = require('./pages/printPage/printPage.jsx');
let Router;
@@ -47,6 +47,7 @@ const Homebrew = React.createClass({
id={args.id}
brew={this.props.brew} />
},
+ /*
'/share/:id' : (args) => {
if(!this.props.brew.shareId){
@@ -62,7 +63,7 @@ const Homebrew = React.createClass({
username={args.username}
brews={this.props.brews}
/>
- },
+ },*/
'/print/:id' : (args, query) => {
return ;
},
diff --git a/client/homebrew/navbar/continousSave.navitem (DESKTOP-HB50B8V's conflicted copy 2017-01-22).jsx b/client/homebrew/navbar/continousSave.navitem (DESKTOP-HB50B8V's conflicted copy 2017-01-22).jsx
new file mode 100644
index 0000000..5ea9d36
--- /dev/null
+++ b/client/homebrew/navbar/continousSave.navitem (DESKTOP-HB50B8V's conflicted copy 2017-01-22).jsx
@@ -0,0 +1,76 @@
+const flux = require('pico-flux')
+const React = require('react');
+const _ = require('lodash');
+const cx = require('classnames');
+
+const Nav = require('naturalcrit/nav/nav.jsx');
+
+const Store = require('homebrewery/brew.store.js');
+const Actions = require('homebrewery/brew.actions.js');
+
+const onStoreChange = () => {
+ return {
+ status : Store.getStatus(),
+ errors : Store.getErrors()
+ }
+};
+
+const ContinousSave = React.createClass({
+ getDefaultProps: function() {
+ return {
+ status : 'ready',
+ errors : undefined
+ };
+ },
+ componentDidMount: function() {
+ flux.actionEmitter.on('dispatch', this.actionHandler);
+ window.onbeforeunload = ()=>{
+ if(this.props.status !== 'ready') return 'You have unsaved changes!';
+ };
+ },
+ componentWillUnmount: function() {
+ flux.actionEmitter.removeListener('dispatch', this.actionHandler);
+ window.onbeforeunload = function(){};
+ },
+ actionHandler : function(actionType){
+ if(actionType == 'UPDATE_BREW_TEXT' || actionType == 'UPDATE_META'){
+ Actions.pendingSave();
+ }
+ },
+ handleClick : function(){
+ Actions.save();
+ },
+ renderError : function(){
+ let errMsg = '';
+ try{
+ errMsg += this.state.errors.toString() + '\n\n';
+ errMsg += '```\n' + JSON.stringify(this.state.errors.response.error, null, ' ') + '\n```';
+ }catch(e){}
+
+ return
+ Oops!
+
+ Looks like there was a problem saving.
+ Report the issue
+ here
+ .
+
+
+ },
+ render : function(){
+ if(this.props.status == 'error') return this.renderError();
+
+ if(this.props.status == 'saving'){
+ return saving...
+ }
+ if(this.props.status == 'pending'){
+ return Save Now
+ }
+ if(this.props.status == 'ready'){
+ return saved.
+ }
+ },
+
+});
+
+module.exports = Store.createSmartComponent(ContinousSave, onStoreChange);
\ No newline at end of file
diff --git a/client/homebrew/navbar/reddit.navitem.jsx b/client/homebrew/navbar/continousSave.navitem.jsx
similarity index 100%
rename from client/homebrew/navbar/reddit.navitem.jsx
rename to client/homebrew/navbar/continousSave.navitem.jsx
diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less
index bb2a843..2370537 100644
--- a/client/homebrew/navbar/navbar.less
+++ b/client/homebrew/navbar/navbar.less
@@ -125,4 +125,11 @@
text-align : center;
}
}
+
+ .staticSave.navItem{
+ background-color: @orange;
+ &:hover{
+ background-color: @green;
+ }
+ }
}
\ No newline at end of file
diff --git a/client/homebrew/navbar/staticSave.navitem.jsx b/client/homebrew/navbar/staticSave.navitem.jsx
new file mode 100644
index 0000000..17c2e1d
--- /dev/null
+++ b/client/homebrew/navbar/staticSave.navitem.jsx
@@ -0,0 +1,37 @@
+const React = require('react');
+const _ = require('lodash');
+const cx = require('classnames');
+
+const Nav = require('naturalcrit/nav/nav.jsx');
+const Store = require('homebrewery/brew.store.js');
+const Actions = require('homebrewery/brew.actions.js');
+
+const StaticSave = React.createClass({
+ getDefaultProps: function() {
+ return {
+ status : 'ready'
+ };
+ },
+ handleClick : function(){
+ Actions.saveNew();
+ },
+ render : function(){
+ if(this.props.status === 'saving'){
+ return
+ save...
+
+ }
+ if(this.props.status === 'ready'){
+ return
+ save
+
+ }
+ }
+});
+
+
+module.exports = Store.createSmartComponent(StaticSave, ()=>{
+ return {
+ status : Store.getStatus()
+ }
+});
\ No newline at end of file
diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx
index a63c6d5..9e94407 100644
--- a/client/homebrew/pages/editPage/editPage.jsx
+++ b/client/homebrew/pages/editPage/editPage.jsx
@@ -10,35 +10,31 @@ const Navbar = require('../../navbar/navbar.jsx');
const ReportIssue = require('../../navbar/issue.navitem.jsx');
const PrintLink = require('../../navbar/print.navitem.jsx');
const Account = require('../../navbar/account.navitem.jsx');
+const Save = require('../../navbar/continousSave.navitem.jsx');
//const RecentlyEdited = require('../../navbar/recent.navitem.jsx').edited;
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
-const Editor = require('../../editor/editor.jsx');
-const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+
const Markdown = require('homebrewery/markdown.js');
-
const SAVE_TIMEOUT = 3000;
+const BrewInterface = require('homebrewery/brewInterface/brewInterface.jsx');
+const Utils = require('homebrewery/utils.js');
+
+
+const Store = require('homebrewery/brew.store.js');
+const Actions = require('homebrewery/brew.actions.js');
+
+
+
+
+
const EditPage = React.createClass({
getDefaultProps: function() {
return {
- brew : {
- text : '',
- shareId : null,
- editId : null,
- createdAt : null,
- updatedAt : null,
-
- title : '',
- description : '',
- tags : '',
- published : false,
- authors : [],
- systems : []
- }
+ brew : {}
};
},
@@ -56,17 +52,11 @@ const EditPage = React.createClass({
savedBrew : null,
componentDidMount: function(){
- this.trySave();
+ //this.trySave();
window.onbeforeunload = ()=>{
- if(this.state.isSaving || this.state.isPending){
- return 'You have unsaved changes!';
- }
+ if(Store.getStatus() !== 'ready') return 'You have unsaved changes!';
};
- this.setState({
- htmlErrors : Markdown.validate(this.state.brew.text)
- })
-
document.addEventListener('keydown', this.handleControlKeys);
},
componentWillUnmount: function() {
@@ -75,12 +65,20 @@ const EditPage = React.createClass({
},
+ handleControlKeys : Utils.controlKeys({
+ s : Actions.pendingSave,
+ p : ()=>{
+ window.open(`/print/${this.props.brew.shareId}?dialog=true`, '_blank').focus();
+ }
+ }),
+
+/*
handleControlKeys : function(e){
if(!(e.ctrlKey || e.metaKey)) return;
const S_KEY = 83;
const P_KEY = 80;
if(e.keyCode == S_KEY) this.save();
- if(e.keyCode == P_KEY) window.open(`/print/${this.props.brew.shareId}?dialog=true`, '_blank').focus();
+ if(e.keyCode == P_KEY)
if(e.keyCode == P_KEY || e.keyCode == S_KEY){
e.stopPropagation();
e.preventDefault();
@@ -115,7 +113,7 @@ const EditPage = React.createClass({
this.trySave();
},
-
+*/
hasChanges : function(){
if(this.savedBrew){
return !_.isEqual(this.state.brew, this.savedBrew)
@@ -214,16 +212,7 @@ const EditPage = React.createClass({
{this.renderNavbar()}
-
-
-
-
+
}
diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx
index b5a34b1..3597fe3 100644
--- a/client/homebrew/pages/homePage/homePage.jsx
+++ b/client/homebrew/pages/homePage/homePage.jsx
@@ -10,10 +10,6 @@ const RecentNavItem = require('../../navbar/recent.navitem.jsx');
const AccountNavItem = require('../../navbar/account.navitem.jsx');
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
-const Editor = require('../../editor/editor.smart.jsx');
-const BrewRenderer = require('../../brewRenderer/brewRenderer.smart.jsx');
-
const BrewInterface = require('homebrewery/brewInterface/brewInterface.jsx');
@@ -40,7 +36,7 @@ const HomePage = React.createClass({
},
renderNavbar : function(){
- return
+ return
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx
index 46d0fe2..dfeaf5d 100644
--- a/client/homebrew/pages/newPage/newPage.jsx
+++ b/client/homebrew/pages/newPage/newPage.jsx
@@ -1,23 +1,26 @@
const React = require('react');
const _ = require('lodash');
-const cx = require('classnames');
-const request = require("superagent");
-const Markdown = require('homebrewery/markdown.js');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
-const AccountNavItem = require('../../navbar/account.navitem.jsx');
-const IssueNavItem = require('../../navbar/issue.navitem.jsx');
+const Account = require('../../navbar/account.navitem.jsx');
+const Issue = require('../../navbar/issue.navitem.jsx');
+const Save = require('../../navbar/staticSave.navitem.jsx');
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
-const Editor = require('../../editor/editor.jsx');
-const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+
+const Store = require('homebrewery/brew.store.js');
+const Actions = require('homebrewery/brew.actions.js');
+
+const BrewInterface = require('homebrewery/brewInterface/brewInterface.jsx');
+
+const Utils = require('homebrewery/utils.js');
const KEY = 'homebrewery-new';
const NewPage = React.createClass({
+ /*
getInitialState: function() {
return {
metadata : {
@@ -34,8 +37,13 @@ const NewPage = React.createClass({
errors : []
};
},
+ */
componentDidMount: function() {
const storage = localStorage.getItem(KEY);
+
+ //TODO: Add aciton to load from local?
+
+
if(storage){
this.setState({
text : storage
@@ -46,8 +54,15 @@ const NewPage = React.createClass({
componentWillUnmount: function() {
document.removeEventListener('keydown', this.handleControlKeys);
},
+ handleControlKeys : Utils.controlKeys({
+ s : Actions.saveNew,
+ p : Actions.localPrint
+ }),
+
+/*
handleControlKeys : function(e){
+ console.log(e);
if(!(e.ctrlKey || e.metaKey)) return;
const S_KEY = 83;
const P_KEY = 80;
@@ -59,24 +74,7 @@ const NewPage = React.createClass({
}
},
- handleSplitMove : function(){
- this.refs.editor.update();
- },
-
- handleMetadataChange : function(metadata){
- this.setState({
- metadata : _.merge({}, this.state.metadata, metadata)
- });
- },
-
- handleTextChange : function(text){
- this.setState({
- text : text,
- errors : Markdown.validate(text)
- });
- localStorage.setItem(KEY, text);
- },
-
+/*
save : function(){
this.setState({
isSaving : true
@@ -99,7 +97,8 @@ const NewPage = React.createClass({
window.location = '/edit/' + brew.editId;
})
},
-
+*/
+ /*
renderSaveButton : function(){
if(this.state.isSaving){
return
@@ -111,48 +110,45 @@ const NewPage = React.createClass({
}
},
-
+ */
+/*
print : function(){
localStorage.setItem('print', this.state.text);
window.open('/print?dialog=true&local=print','_blank');
},
+*/
+/*
renderLocalPrintButton : function(){
- return
+ return
get PDF
},
renderNavbar : function(){
- return
-
-
- {this.state.metadata.title}
-
-
-
- {this.renderSaveButton()}
- {this.renderLocalPrintButton()}
-
-
-
-
+ return
},
+*/
render : function(){
return
- {this.renderNavbar()}
+
+
+ {Store.getMetaData().title}
+
+
+
+
+
+ get PDF
+
+
+
+
+
+
-
-
-
-
+
}
diff --git a/client/homebrew/pages/newPage/newPage.less b/client/homebrew/pages/newPage/newPage.less
index 8cd21b2..48296ad 100644
--- a/client/homebrew/pages/newPage/newPage.less
+++ b/client/homebrew/pages/newPage/newPage.less
@@ -1,10 +1,4 @@
.newPage{
- .saveButton{
- background-color: @orange;
- &:hover{
- background-color: @green;
- }
- }
}
\ No newline at end of file
diff --git a/client/homebrew/pages/printPage/printPage.jsx b/client/homebrew/pages/printPage/printPage.jsx
index 91f1785..70ab71a 100644
--- a/client/homebrew/pages/printPage/printPage.jsx
+++ b/client/homebrew/pages/printPage/printPage.jsx
@@ -12,21 +12,17 @@ const PrintPage = React.createClass({
}
};
},
-
getInitialState: function() {
return {
brewText: this.props.brew.text
};
},
-
componentDidMount: function() {
if(this.props.query.local){
this.setState({ brewText : localStorage.getItem(this.props.query.local)});
}
-
if(this.props.query.dialog) window.print();
},
-
renderPages : function(){
return _.map(this.state.brewText.split('\\page'), (page, index) => {
return {
+ const brew = Store.getBrew();
+ dispatch('SET_STATUS', 'saving');
+ request
+ .put('/api/update/' + brew.editId)
+ .send(brew)
+ .end((err, res) => {
+ if(err) return dispatch('SET_STATUS', 'error', err);
+ dispatch('SET_STATUS', 'ready');
+ dispatch('SET_BREW', res.body);
+ });
+ },
+
saveNew : () => {
- //TODO: Maybe set the status?
+ dispatch('SET_STATUS', 'saving');
request.post('/api')
.send(Store.getBrew())
.end((err, res)=>{
- if(err) return;
+ if(err) return dispatch('SET_STATUS', 'error', err);
const brew = res.body;
window.location = '/edit/' + brew.editId;
});
+ },
+ localPrint : ()=>{
+ localStorage.setItem('print', Store.getBrewText());
+ window.open('/print?dialog=true&local=print','_blank');
}
};
diff --git a/shared/homebrewery/brew.store.js b/shared/homebrewery/brew.store.js
index e521d98..5879701 100644
--- a/shared/homebrewery/brew.store.js
+++ b/shared/homebrewery/brew.store.js
@@ -21,7 +21,8 @@ let State = {
systems : []
},
- errors : []
+ errors : [],
+ status : 'ready', //ready, pending, saving, error
};
const Store = flux.createStore({
@@ -34,6 +35,10 @@ const Store = flux.createStore({
},
UPDATE_META : (meta) => {
State.brew = _.merge({}, State.brew, meta);
+ },
+ SET_STATUS : (status, error) => {
+ State.status = status;
+ if(error) State.errors = error;
}
});
@@ -53,9 +58,12 @@ Store.getMetaData = ()=>{
Store.getErrors = ()=>{
return State.errors;
};
-
Store.getVersion = ()=>{
return State.version;
};
+Store.getStatus = ()=>{
+ return State.status;
+};
+
module.exports = Store;
\ No newline at end of file
diff --git a/shared/homebrewery/brewEditor/brewEditor.jsx b/shared/homebrewery/brewEditor/brewEditor.jsx
index a8fa891..0c1fec7 100644
--- a/shared/homebrewery/brewEditor/brewEditor.jsx
+++ b/shared/homebrewery/brewEditor/brewEditor.jsx
@@ -66,6 +66,11 @@ const BrewEditor = React.createClass({
})
},
+ brewJump : function(){
+ const currentPage = this.getCurrentPage();
+ window.location.hash = 'p' + currentPage;
+ },
+
//Called when there are changes to the editor's dimensions
update : function(){
this.refs.codeEditor.updateSize();
@@ -113,6 +118,12 @@ const BrewEditor = React.createClass({
onChange={this.handleTextChange}
onCursorActivity={this.handleCursorActivty} />
+
+ {/*
+
+
+
+ */}
);
}
});
diff --git a/shared/homebrewery/brewEditor/brewEditor.less b/shared/homebrewery/brewEditor/brewEditor.less
index d82c96d..6fde51b 100644
--- a/shared/homebrewery/brewEditor/brewEditor.less
+++ b/shared/homebrewery/brewEditor/brewEditor.less
@@ -5,8 +5,23 @@
.codeEditor{
height : 100%;
.pageLine{
- background-color : fade(#333, 30%);
+ background-color : fade(#333, 15%);
border-bottom : #333 solid 1px;
}
}
+
+ .brewJump{
+ position: absolute;
+ background-color: @teal;
+ cursor: pointer;
+ width : 30px;
+ height : 30px;
+ display : flex;
+ align-items : center;
+ bottom : 20px;
+ right : 20px;
+ z-index: 1000000;
+ justify-content:center;
+ .tooltipLeft("Jump to brew page");
+ }
}
\ No newline at end of file
diff --git a/shared/homebrewery/brewRenderer/brewRenderer.jsx b/shared/homebrewery/brewRenderer/brewRenderer.jsx
index ff59cff..82dab8f 100644
--- a/shared/homebrewery/brewRenderer/brewRenderer.jsx
+++ b/shared/homebrewery/brewRenderer/brewRenderer.jsx
@@ -5,6 +5,7 @@ const cx = require('classnames');
const Markdown = require('homebrewery/markdown.js');
const ErrorBar = require('./errorBar/errorBar.jsx');
+const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx')
const Store = require('homebrewery/brew.store.js');
@@ -130,6 +131,7 @@ const BrewRenderer = React.createClass({
style={{height : this.state.height}}>
+
{this.renderPages()}
diff --git a/shared/homebrewery/utils.js b/shared/homebrewery/utils.js
new file mode 100644
index 0000000..9237178
--- /dev/null
+++ b/shared/homebrewery/utils.js
@@ -0,0 +1,20 @@
+const _ = require('lodash');
+
+
+const Utils = {
+ controlKeys : (mapping) => {
+ return (e) => {
+ if(!(e.ctrlKey || e.metaKey)) return;
+ if(typeof mapping[e.key] === 'function'){
+ mapping[e.key]();
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }
+ },
+
+
+
+};
+
+module.exports = Utils;
\ No newline at end of file