diff --git a/.gitignore b/.gitignore index 022473023..cc4d5aab7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ dist build/daemon.zip .vimrc + +ui/yarn.lock \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f98234a7c..22c52c75c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,10 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added + * Support markdown makeup in claim description * State is persisted through app close and re-open, resulting in faster opens + * + ### Changed * Upgraded to lbry daemon 0.13, including updating API signatures diff --git a/ui/js/component/common.js b/ui/js/component/common.js index 38dbf83fd..57314bdd3 100644 --- a/ui/js/component/common.js +++ b/ui/js/component/common.js @@ -1,5 +1,7 @@ import React from "react"; +import ReactDOMServer from "react-dom/server"; import lbry from "../lbry.js"; +import ReactMarkdown from "react-markdown"; //component/icon.js export class Icon extends React.PureComponent { @@ -42,6 +44,40 @@ export class TruncatedText extends React.PureComponent { } } +export class TruncatedMarkdown extends React.PureComponent { + static propTypes = { + lines: React.PropTypes.number, + }; + + static defaultProps = { + lines: null, + }; + + transformMarkdown(text) { + // render markdown to html string then trim html tag + let htmlString = ReactDOMServer.renderToStaticMarkup( + + ); + var txt = document.createElement("textarea"); + txt.innerHTML = htmlString; + return txt.value.replace(/<(?:.|\n)*?>/gm, ""); + } + + render() { + let content = this.props.children && typeof this.props.children === "string" + ? this.transformMarkdown(this.props.children) + : this.props.children; + return ( + + {content} + + ); + } +} + export class BusyMessage extends React.PureComponent { static propTypes = { message: React.PropTypes.string, diff --git a/ui/js/component/fileCard/view.jsx b/ui/js/component/fileCard/view.jsx index bf0901035..094973d7e 100644 --- a/ui/js/component/fileCard/view.jsx +++ b/ui/js/component/fileCard/view.jsx @@ -2,7 +2,12 @@ import React from "react"; import lbry from "lbry.js"; import lbryuri from "lbryuri.js"; import Link from "component/link"; -import { Thumbnail, TruncatedText, Icon } from "component/common"; +import { + Thumbnail, + TruncatedText, + Icon, + TruncatedMarkdown, +} from "component/common"; import FilePrice from "component/filePrice"; import UriIndicator from "component/uriIndicator"; @@ -86,7 +91,7 @@ class FileCard extends React.PureComponent { style={{ backgroundImage: "url('" + metadata.thumbnail + "')" }} />}
- {description} + {description}
{obscureNsfw && this.state.hovered diff --git a/ui/js/component/fileTile/view.jsx b/ui/js/component/fileTile/view.jsx index d19ce0137..c0b650670 100644 --- a/ui/js/component/fileTile/view.jsx +++ b/ui/js/component/fileTile/view.jsx @@ -3,7 +3,11 @@ import lbry from "lbry.js"; import lbryuri from "lbryuri.js"; import Link from "component/link"; import FileActions from "component/fileActions"; -import { Thumbnail, TruncatedText } from "component/common.js"; +import { + Thumbnail, + TruncatedText, + TruncatedMarkdown, +} from "component/common.js"; import FilePrice from "component/filePrice"; import UriIndicator from "component/uriIndicator"; @@ -117,9 +121,9 @@ class FileTile extends React.PureComponent {

{title}

- + {description} - +
diff --git a/ui/js/component/form.js b/ui/js/component/form.js index 7ab78325c..a05843f23 100644 --- a/ui/js/component/form.js +++ b/ui/js/component/form.js @@ -1,6 +1,8 @@ import React from "react"; import FileSelector from "./file-selector.js"; import { Icon } from "./common.js"; +import SimpleMDE from "react-simplemde-editor"; +import style from "react-simplemde-editor/dist/simplemde.min.css"; var formFieldCounter = 0, formFieldFileSelectorTypes = ["file", "directory"], @@ -38,6 +40,9 @@ export class FormField extends React.PureComponent { } else if (this.props.type == "text-number") { this._element = "input"; this._type = "text"; + } else if (this.props.type == "SimpleMDE") { + this._element = SimpleMDE; + this._type = "textarea"; } else if (formFieldFileSelectorTypes.includes(this.props.type)) { this._element = "input"; this._type = "hidden"; @@ -81,6 +86,8 @@ export class FormField extends React.PureComponent { getValue() { if (this.props.type == "checkbox") { return this.refs.field.checked; + } else if (this.props.type == "SimpleMDE") { + return this.refs.field.simplemde.value(); } else { return this.refs.field.value; } @@ -106,7 +113,6 @@ export class FormField extends React.PureComponent { delete otherProps.className; delete otherProps.postfix; delete otherProps.prefix; - const element = (
- {metadata && metadata.description} +
{metadata diff --git a/ui/js/page/publish/view.jsx b/ui/js/page/publish/view.jsx index 2628e01e8..e54be1eaf 100644 --- a/ui/js/page/publish/view.jsx +++ b/ui/js/page/publish/view.jsx @@ -520,7 +520,7 @@ class PublishPage extends React.PureComponent {