From 12730ad0e700a91f117d2b01cc83632f71fec763 Mon Sep 17 00:00:00 2001 From: Isaac Visintainer Date: Wed, 29 Jan 2020 11:44:11 -0800 Subject: [PATCH] adds publish new post page --- pkg/interface/publish/package-lock.json | 51 +++++++--- pkg/interface/publish/package.json | 2 + pkg/interface/publish/src/css/custom.css | 87 ++++++++++++++++- pkg/interface/publish/src/index.css | 2 + .../publish/src/js/components/lib/new-post.js | 97 ++++++++++++++++++- .../publish/src/js/components/root.js | 49 +++++++--- 6 files changed, 258 insertions(+), 30 deletions(-) diff --git a/pkg/interface/publish/package-lock.json b/pkg/interface/publish/package-lock.json index 61e5c9ba28..21222af209 100644 --- a/pkg/interface/publish/package-lock.json +++ b/pkg/interface/publish/package-lock.json @@ -750,6 +750,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "codemirror": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.51.0.tgz", + "integrity": "sha512-vyuYYRv3eXL0SCuZA4spRFlKNzQAewHcipRQCOKgRy7VNAvZxTKzbItdbCl4S5AgPZ5g3WkHp+ibWQwv9TLG7Q==" + }, "collect-stream": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/collect-stream/-/collect-stream-1.2.1.tgz", @@ -1791,7 +1796,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1812,12 +1818,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1832,17 +1840,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1959,7 +1970,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1971,6 +1983,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1985,6 +1998,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1992,12 +2006,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2016,6 +2032,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2096,7 +2113,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2108,6 +2126,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2193,7 +2212,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2229,6 +2249,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2248,6 +2269,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2291,12 +2313,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -4535,6 +4559,11 @@ "scheduler": "^0.13.6" } }, + "react-codemirror2": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-6.0.0.tgz", + "integrity": "sha512-D7y9qZ05FbUh9blqECaJMdDwKluQiO3A9xB+fssd5jKM7YAXucRuEOlX32mJQumUvHUkHRHqXIPBjm6g0FW0Ag==" + }, "react-dom": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", diff --git a/pkg/interface/publish/package.json b/pkg/interface/publish/package.json index 0f5a1d350f..bb0236de2f 100644 --- a/pkg/interface/publish/package.json +++ b/pkg/interface/publish/package.json @@ -26,10 +26,12 @@ }, "dependencies": { "classnames": "^2.2.6", + "codemirror": "^5.51.0", "del": "^5.1.0", "lodash": "^4.17.11", "moment": "^2.20.1", "react": "^16.5.2", + "react-codemirror2": "^6.0.0", "react-dom": "^16.8.6", "react-router-dom": "^5.0.0", "urbit-ob": "^4.1.2", diff --git a/pkg/interface/publish/src/css/custom.css b/pkg/interface/publish/src/css/custom.css index 3e1b2b2d77..4a07935d98 100644 --- a/pkg/interface/publish/src/css/custom.css +++ b/pkg/interface/publish/src/css/custom.css @@ -1,3 +1,10 @@ +:root { + --dark-gray: #555555; + --gray: #7F7F7F; + --medium-gray: #CCCCCC; + --light-gray: rgba(0,0,0,0.08); +} + html, body { height: 100%; width: 100%; @@ -67,4 +74,82 @@ a { .mw-300-ns { max-width: 300px; } -} \ No newline at end of file +} + +.NewPost { + width: 100%; + height: calc(100% - 103px); + display: flex; + padding-top: 8px; +} + +.react-codemirror2 { + width: 100%; +} + + +.CodeMirror { + padding: 12px; + height: 100% !important; + max-width: 700px; + width: 100% !important; + cursor: text; + font-size: 12px; + line-height: 20px; + * { + font-family: 'Source Code Pro'; + } +} + +.CodeMirror-selected { background:#BAE3FE !important; } + +.cm-s-tlon span { font-family: "Source Code Pro"} +.cm-s-tlon span.cm-meta { color: var(--gray); } +.cm-s-tlon span.cm-number { color: var(--gray); } +.cm-s-tlon span.cm-keyword { line-height: 1em; font-weight: bold; color: var(--gray); } +.cm-s-tlon span.cm-atom { font-weight: bold; color: var(--gray); } +.cm-s-tlon span.cm-def { color: black; } +.cm-s-tlon span.cm-variable { color: black; } +.cm-s-tlon span.cm-variable-2 { color: black; } +.cm-s-tlon span.cm-variable-3, .cm-s-tlon span.cm-type { color: black; } +.cm-s-tlon span.cm-property { color: black; } +.cm-s-tlon span.cm-operator { color: black; } +.cm-s-tlon span.cm-comment { color: black; background-color: var(--light-gray); padding:2px; border-radius: 2px;} +.cm-s-tlon span.cm-string { color: var(--dark-gray); } +.cm-s-tlon span.cm-string-2 { color: var(--gray); } +.cm-s-tlon span.cm-qualifier { color: #555; } +.cm-s-tlon span.cm-error { color: #FF0000; } +.cm-s-tlon span.cm-attribute { color: var(--gray); } +.cm-s-tlon span.cm-tag { color: var(--gray); } +.cm-s-tlon span.cm-link { color: var(--dark-gray); text-decoration: none;} +.cm-s-tlon .CodeMirror-activeline-background { background: var(--gray); } +.cm-s-tlon .CodeMirror-cursor { + border-left: 2px solid #3687FF; +} + +.cm-s-tlon span.cm-builtin { color: var(--gray); } +.cm-s-tlon span.cm-bracket { color: var(--gray); } +/* .cm-s-tlon { font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;} */ + + +.cm-s-tlon .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } + +.CodeMirror-hints.tlon { + /* font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; */ + color: #616569; + background-color: #ebf3fd !important; +} + +.CodeMirror-hints.tlon .CodeMirror-hint-active { + background-color: #a2b8c9 !important; + color: #5c6065 !important; +} + +.title-input[placeholder]:empty:before { + content: attr(placeholder); + color: #7F7F7F; +} + +[contenteditable]:focus { + outline: 0px solid transparent; +} diff --git a/pkg/interface/publish/src/index.css b/pkg/interface/publish/src/index.css index 06e538967f..e111ffd5a5 100644 --- a/pkg/interface/publish/src/index.css +++ b/pkg/interface/publish/src/index.css @@ -3,3 +3,5 @@ @import 'css/custom.css'; @import 'css/spinner.css'; +@import '../node_modules/codemirror/lib/codemirror.css'; +@import '../node_modules/codemirror/theme/material.css'; diff --git a/pkg/interface/publish/src/js/components/lib/new-post.js b/pkg/interface/publish/src/js/components/lib/new-post.js index 16f49165f4..17f9abd0e0 100644 --- a/pkg/interface/publish/src/js/components/lib/new-post.js +++ b/pkg/interface/publish/src/js/components/lib/new-post.js @@ -1,12 +1,103 @@ import React, { Component } from 'react' +import { Controlled as CodeMirror } from 'react-codemirror2' +import { dateToDa, stringToSymbol } from '/lib/util'; -//TODO integrate codemirror work from GA +import 'codemirror/mode/markdown/markdown'; export class NewPost extends Component { + constructor(props) { + super(props); + this.state = { + body: "# Hello", + title: '', + submit: false, + awaiting: null, + } + + this.postSubmit = this.postSubmit.bind(this); + this.titleChange = this.titleChange.bind(this); + this.bodyChange = this.bodyChange.bind(this); + } + + postSubmit() { + let newNote = { + "new-note": { + who: this.props.host.slice(1), + book: this.props.notebookName, + note: stringToSymbol(this.state.title), + title: this.state.title, + body: this.state.body, + } + } + + this.setState({ + awaiting: newNote["new-note"].note + }, () => { + window.api.action("publish", "publish-action", newNote); + }); + } + + componentDidUpdate(prevProps, prevState) { + if (this.props.notebook.notes[this.state.awaiting]) { + let redirect = + `/~publish/note/${this.props.host}/${this.props.notebookName}/${this.state.awaiting}`; + this.props.history.push(redirect); + } + } + + titleChange(evt) { + let submit = !(evt.target.value === '' || this.state.body === ''); + this.setState({title: evt.target.value, submit: submit}); + } + + bodyChange(editor, data, value) { + let submit = !(value === '' || this.state.title === ''); + this.setState({body: value, submit: submit}); + } + render() { + const options = { + mode: 'markdown', + theme: 'tlon', + lineNumbers: false, + lineWrapping: true, + scrollbarStyle: null, + cursorHeight: 0.85 + }; + + let date = dateToDa(new Date()).slice(1, -10); + + let submitStyle = (this.state.submit) + ? { color: '#2AA779', cursor: "pointer" } + : { color: '#B1B2B3', cursor: "auto" }; + return ( -
- +
+
+
+ +
+ + + +
{date}
+
+ +
+ this.bodyChange(e, d, v)} + onChange={(editor, data, value) => {}} + /> +
) } diff --git a/pkg/interface/publish/src/js/components/root.js b/pkg/interface/publish/src/js/components/root.js index 160eae90df..0d588356f3 100644 --- a/pkg/interface/publish/src/js/components/root.js +++ b/pkg/interface/publish/src/js/components/root.js @@ -6,8 +6,8 @@ import { NewScreen } from '/components/lib/new'; import { JoinScreen } from '/components/lib/join'; import { Notebook } from '/components/lib/notebook'; import { Note } from '/components/lib/note'; +import { NewPost } from '/components/lib/new-post'; -//TODO add new note route export class Root extends Component { constructor(props) { super(props); @@ -78,20 +78,39 @@ export class Root extends Component { let ship = props.match.params.ship || ""; let notebook = props.match.params.notebook || ""; - return ( - - - - ) + if (view === "new") { + return ( + + + + ) + } + else { + return ( + + + + ) + } }}/> {