mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 05:22:27 +03:00
adds publish new post page
This commit is contained in:
parent
d2ad5b143d
commit
12730ad0e7
51
pkg/interface/publish/package-lock.json
generated
51
pkg/interface/publish/package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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 (
|
||||
<div>
|
||||
|
||||
<div className="center mw7 f9 h-100">
|
||||
<div style={{padding: 16}} className="flex-col">
|
||||
<div className="w-100 tl">
|
||||
<button disabled={!this.state.submit} style={submitStyle}
|
||||
onClick={this.postSubmit}>
|
||||
Publish To {this.props.notebook.title}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<input type="text"
|
||||
style={{paddingBottom: 8, paddingTop: 24}}
|
||||
className="w-100"
|
||||
onChange={this.titleChange}
|
||||
placeholder="New Post" />
|
||||
|
||||
<div style={{color:'#7F7F7F'}}>{date}</div>
|
||||
</div>
|
||||
|
||||
<div className="NewPost">
|
||||
<CodeMirror
|
||||
value={this.state.body}
|
||||
options={options}
|
||||
onBeforeChange={(e, d, v) => this.bodyChange(e, d, v)}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -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 (
|
||||
<Skeleton
|
||||
popout={false}
|
||||
active={"rightPanel"}
|
||||
rightPanelHide={false}
|
||||
sidebarShown={true}
|
||||
notebooks={state.notebooks}>
|
||||
<Notebook
|
||||
notebooks={state.notebooks}
|
||||
view={view}
|
||||
ship={ship}
|
||||
book={notebook}/>
|
||||
</Skeleton>
|
||||
)
|
||||
if (view === "new") {
|
||||
return (
|
||||
<Skeleton
|
||||
popout={false}
|
||||
active={"rightPanel"}
|
||||
rightPanelHide={false}
|
||||
sidebarShown={true}
|
||||
notebooks={state.notebooks}>
|
||||
<NewPost
|
||||
notebook={state.notebooks[ship][notebook]}
|
||||
host={ship}
|
||||
notebookName={notebook}
|
||||
{...props}
|
||||
/>
|
||||
</Skeleton>
|
||||
)
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<Skeleton
|
||||
popout={false}
|
||||
active={"rightPanel"}
|
||||
rightPanelHide={false}
|
||||
sidebarShown={true}
|
||||
notebooks={state.notebooks}>
|
||||
<Notebook
|
||||
notebooks={state.notebooks}
|
||||
view={view}
|
||||
ship={ship}
|
||||
book={notebook}/>
|
||||
</Skeleton>
|
||||
)
|
||||
}
|
||||
}}/>
|
||||
<Route exact path="/~publish/(popout)?/note/:ship/:notebook/:note"
|
||||
render={ (props) => {
|
||||
|
Loading…
Reference in New Issue
Block a user