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 {