diff --git a/package.json b/package.json index 934dd5f..d711f05 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "alpha-web", "version": "0.4.1", "private": false, + "engines": { + "node": "<=9 >=8" + }, "dependencies": { "autoprefixer": "7.1.6", "babel-core": "6.26.0", @@ -54,6 +57,7 @@ "redux": "^3.7.2", "redux-auth-wrapper": "^2.0.3", "redux-thunk": "^2.2.0", + "remarkable": "^1.7.1", "showdown": "^1.8.6", "sjcl": "^1.0.7", "steem": "^0.7.1", diff --git a/src/actions/createPostActions.js b/src/actions/createPostActions.js index 7098815..2b92aa6 100644 --- a/src/actions/createPostActions.js +++ b/src/actions/createPostActions.js @@ -1,6 +1,5 @@ import _ from 'lodash'; -import getStore from '../utils/storeUtils'; import haprampAPI from '../utils/haprampAPI'; import Steem from '../utils/steem'; @@ -35,28 +34,30 @@ export const clearError = () => dispatch => dispatch({ type: actionTypes.CLEAR_E export const setHashtags = hashtags => dispatch => dispatch({ type: actionTypes.SET_HASHTAGS, hashtags }); -export const createPost = oldData => (dispatch) => { +export const createPost = oldData => (dispatch, getState) => { // Deep copy const data = _.cloneDeep(oldData); const { tags, post, community } = data; dispatch({ type: actionTypes.POST_CREATE_INIT }); - const author = getStore().getState().authUser.username; + const author = getState().authUser.username; + // TODO: Generate a better permlink const permlink = `${new Date().toISOString().replace(/[^a-zA-Z0-9]+/g, '').toLowerCase()}-post`; const fullPermlink = `${author}/${permlink}`; return haprampAPI.v2.post.prepare(post, fullPermlink) - .then(body => Steem.sc2Operations.createPost(author, body, tags, post, permlink, community) + .then(body => Steem.sc2Operations + .createPost(author, body, tags, post, permlink, community) .then(() => dispatch({ type: actionTypes.POST_CREATED, fullPermlink })) .catch((e) => { console.log('Steem error', e); return dispatch({ type: actionTypes.CREATE_ERROR, message: e, element: 'top' }); - }) - .catch((e) => { - console.log('Hapramp API Error', e); - dispatch({ type: actionTypes.CREATE_ERROR, message: e, element: 'top' }); - })); + })) + .catch((e) => { + console.log('Hapramp API Error', e); + dispatch({ type: actionTypes.CREATE_ERROR, message: e, element: 'top' }); + }); }; export const resetPostCreate = () => dispatch => dispatch({ type: actionTypes.POST_CREATE_RESET }); diff --git a/src/components/browseCommunity/index.js b/src/components/browseCommunity/index.js index 6ed6e67..2a4ac65 100644 --- a/src/components/browseCommunity/index.js +++ b/src/components/browseCommunity/index.js @@ -5,7 +5,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import Sidebar from '../sidebar'; -import Post from '../post'; +import PostCard from '../../post/PostCard'; import { loadFeedsByCreated, loadFeedsByHot, loadFeedsByTrending } from '../../actions/userFeedActions'; import { loadUserAccounts } from '../../actions/allUserActions'; import feedStyles from '../feed/styles.scss'; @@ -59,7 +59,7 @@ class BrowseCommunity extends React.Component {
{this.props.userFeed[this.props.match.params.filter].posts && this.props.userFeed[this.props.match.params.filter].posts.map(post => ( - ))} diff --git a/src/components/contentSingle/index.js b/src/components/contentSingle/index.js index 33c5b0a..fd8d797 100644 --- a/src/components/contentSingle/index.js +++ b/src/components/contentSingle/index.js @@ -3,8 +3,7 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { loadPost } from '../../actions/allPostsActions'; -import PostSingle from '../postSingle'; -import ArticleSingle from '../articleSingle'; +import PostSingle from '../../post/PostSingle'; class ContentSingle extends React.Component { constructor(props) { @@ -19,10 +18,9 @@ class ContentSingle extends React.Component { return (
- {this.props.post.json_metadata.content.type === 'post' ? - : - } -
); + +
+ ); } } diff --git a/src/components/feed/index.js b/src/components/feed/index.js index fa852fe..af8db24 100644 --- a/src/components/feed/index.js +++ b/src/components/feed/index.js @@ -6,7 +6,7 @@ import PropTypes from 'prop-types'; import { loadFeedsForUser } from '../../actions/userFeedActions'; import { loadUserAccounts } from '../../actions/allUserActions'; -import Post from '../post'; +import PostCard from '../../post/PostCard'; import AddContentButton from '../addContentButton'; import Sidebar from '../sidebar'; import styles from './styles.scss'; @@ -35,7 +35,7 @@ class Feed extends React.Component {
{this.props.userFeed.posts && this.props.userFeed.posts.map(post => - )} + )}
diff --git a/src/components/postSingle/index.js b/src/components/postSingle/index.js deleted file mode 100644 index 6942f12..0000000 --- a/src/components/postSingle/index.js +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import PropTypes from 'prop-types'; - -import indexStyles from '../../index.scss'; -import PostUserMeta from '../postUserMeta'; -import { getCommunitiesForPost } from '../../utils/communityUtils'; -import { fixUser } from '../../utils/defaultFixUtils'; -import styles from './styles.scss'; -import PostData from '../postData'; -import ActionBar from '../actionBar'; -import CustomTags from '../customTags'; -import Replies from '../replies'; - -class PostSingle extends React.Component { - static isMedia(content) { - return content.data[0].type.toLowerCase() === 'image' || content.data[0].type.toLowerCase() === 'youtube'; - } - - componentDidMount() { - window.scrollTo(0, 0); - } - - getLeftSection() { - if (PostSingle.isMedia(this.props.post.json_metadata.content)) { - return ( -
- -
); - } - return
; - } - - getRightSection() { - const containsImage = PostSingle.isMedia(this.props.post.json_metadata.content); - const classes = containsImage ? - ['uk-width-1-1@s', 'uk-width-1-2@m', 'uk-width-1-2@l'] : - ['uk-width-1-1@s', 'uk-width-2-3@m', 'uk-width-1-2@l']; - const data = containsImage ? - this.props.post.json_metadata.content.data[1] : - this.props.post.json_metadata.content.data[0]; - return ( -
- -
- {data.content} -
- - - -
); - } - - render() { - return ( -
- {this.getLeftSection()} - {this.getRightSection()} -
); - } -} - -PostSingle.propTypes = { - post: PropTypes.shape().isRequired, - postingUser: PropTypes.shape({ - json_metadata: PropTypes.shape({ - profile: PropTypes.shape({ - name: PropTypes.string, - profile_image: PropTypes.string, - }), - }), - }), -}; - -PostSingle.defaultProps = { - postingUser: {}, -}; - -const mapStateToProps = (state, ownProps) => { - const post = state.allPosts.posts[ownProps.postPermlink]; - const postingUsername = post.author; - const postingUser = fixUser(state.allUsers.users[postingUsername], postingUsername); - return { - post: state.allPosts.posts[ownProps.postPermlink], - postingUser, - }; -}; - -export default connect(mapStateToProps)(PostSingle); diff --git a/src/components/postSingle/styles.scss b/src/components/postSingle/styles.scss deleted file mode 100644 index 7d330d3..0000000 --- a/src/components/postSingle/styles.scss +++ /dev/null @@ -1,7 +0,0 @@ -.sideImage { - width: 100%; -} - -.rightContent { - margin-top: 32px; -} diff --git a/src/components/userProfile/index.js b/src/components/userProfile/index.js index 27da0be..d52dd3a 100644 --- a/src/components/userProfile/index.js +++ b/src/components/userProfile/index.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import userPlaceholder from './user-placeholder.jpg'; import styles from './styles.scss'; import indexStyles from '../../index.scss'; -import Post from '../post'; +import PostCard from '../../post/PostCard'; import { getFollowCount, getUserFeeds, loadUserProfileInfo, resetUserProfileInfo, @@ -131,7 +131,7 @@ class UserProfile extends React.Component { {this.props.userProfile .blog .posts - .map(item => )} + .map(item => )}
); diff --git a/src/components/actionBar/index.js b/src/post/ActionBar/index.js similarity index 100% rename from src/components/actionBar/index.js rename to src/post/ActionBar/index.js diff --git a/src/components/actionBar/styles.scss b/src/post/ActionBar/styles.scss similarity index 100% rename from src/components/actionBar/styles.scss rename to src/post/ActionBar/styles.scss diff --git a/src/components/customTags/index.js b/src/post/CustomTags/index.js similarity index 100% rename from src/components/customTags/index.js rename to src/post/CustomTags/index.js diff --git a/src/components/customTags/styles.scss b/src/post/CustomTags/styles.scss similarity index 100% rename from src/components/customTags/styles.scss rename to src/post/CustomTags/styles.scss diff --git a/src/post/PostBody/index.js b/src/post/PostBody/index.js new file mode 100644 index 0000000..b192990 --- /dev/null +++ b/src/post/PostBody/index.js @@ -0,0 +1,53 @@ +import React from 'react'; +import Remarkable from 'remarkable'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; + +import styles from './styles.scss'; + +const remarkable = new Remarkable({ + html: true, + breaks: true, + linkify: true, + typographer: false, + quotes: '“”‘’', +}); + +const PostBody = ({ + className, body, author, permlink, minify, ...props +}) => ( +
+
+ { + minify + && ( +
+ + READ MORE + +
+ ) + } +
+); + +PostBody.propTypes = { + className: PropTypes.string, + body: PropTypes.string.isRequired, + author: PropTypes.string.isRequired, + permlink: PropTypes.string.isRequired, + minify: PropTypes.bool, +}; + +PostBody.defaultProps = { + className: '', + minify: false, +}; + +export default PostBody; diff --git a/src/post/PostBody/styles.scss b/src/post/PostBody/styles.scss new file mode 100644 index 0000000..c91ad20 --- /dev/null +++ b/src/post/PostBody/styles.scss @@ -0,0 +1,56 @@ +@import "../../index.scss"; + +.container { + padding: 0 24px; +} + +.bodyContainer { + font-size: 16px; + color: rgba(0,0,0,0.54); + line-height: 24px; +} + +.bodyContainer h1 { + font-family: Roboto-Medium; + font-size: 36px; + color: $primary-color; + line-height: 54px; +} + +.bodyContainer h2 { + font-family: Roboto; + font-size: 18px; + color: $primary-color; + line-height: 30px; +} + +.articleReadMore { + margin-top: -16px; + padding: 8px 0; + background-color: rgba(255, 255, 255, 0.9); + color: #3F72AF; + letter-spacing: 2px; + font-weight: 500; + position: relative; + cursor: pointer; +} + +.readMoreText { + padding: 4px 8px; + color: rgba(0, 0, 0, 0.54); + background: white; + border: 1px solid rgba(0, 0, 0, 0.24); + border-radius: 4px; + transition: all 0.3s; +} + +.readMoreText:hover { + background-color: $primary-color; + color: white; + transition: all 0.3s; +} + +.minify { + max-height: 380px; + overflow: hidden; +} diff --git a/src/components/post/index.js b/src/post/PostCard/index.js similarity index 64% rename from src/components/post/index.js rename to src/post/PostCard/index.js index 2da2f31..c854a96 100644 --- a/src/components/post/index.js +++ b/src/post/PostCard/index.js @@ -1,23 +1,23 @@ import React from 'react'; import { connect } from 'react-redux'; -import { Link, withRouter } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; import PropTypes from 'prop-types'; -import PostData from '../postData'; import styles from './styles.scss'; import indexStyles from '../../index.scss'; import { ratePost } from '../../actions/allPostsActions'; -import PostUserMeta from '../postUserMeta'; +import PostUserMeta from '../PostUserMeta'; import { getCommunitiesForPost } from '../../utils/communityUtils'; import { fixUser } from '../../utils/defaultFixUtils'; -import ActionBar from '../actionBar'; +import ActionBar from '../ActionBar'; +import PostBody from '../../post/PostBody'; const Post = (props) => { if (!props.post) { return
Loading...
; } - const { content } = props.post.json_metadata; + const { body, author, permlink } = props.post; /* Author details */ const user = props.postingUser; @@ -36,19 +36,12 @@ const Post = (props) => { communities={getCommunitiesForPost(props.post)} /> {/* Actual post */} -
- {content && content.data.map((data, idx) => - )} -
- {content.type === 'article' && -
- READ MORE - -
} - {/* Action bar */} +
); }; diff --git a/src/components/post/styles.scss b/src/post/PostCard/styles.scss similarity index 100% rename from src/components/post/styles.scss rename to src/post/PostCard/styles.scss diff --git a/src/components/articleSingle/index.js b/src/post/PostSingle/index.js similarity index 84% rename from src/components/articleSingle/index.js rename to src/post/PostSingle/index.js index 0e57887..3729a32 100644 --- a/src/components/articleSingle/index.js +++ b/src/post/PostSingle/index.js @@ -3,13 +3,13 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { fixUser } from '../../utils/defaultFixUtils'; -import PostData from '../postData'; import indexStyles from '../../index.scss'; -import CustomTags from '../customTags'; -import ActionBar from '../actionBar'; -import Replies from '../replies'; -import PostUserMeta from '../postUserMeta'; +import CustomTags from '../CustomTags'; +import ActionBar from '../ActionBar'; +import Replies from '../Replies'; +import PostUserMeta from '../PostUserMeta'; import { getCommunitiesForPost } from '../../utils/communityUtils'; +import PostBody from '../PostBody'; class ArticleSingle extends React.Component { componentDidMount() { @@ -17,6 +17,7 @@ class ArticleSingle extends React.Component { } render() { + const { body, author, permlink } = this.props.post; return (
@@ -32,11 +33,13 @@ class ArticleSingle extends React.Component { }} created={this.props.post.created} communities={getCommunitiesForPost(this.props.post)} - className={['uk-padding', 'uk-margin-large-bottom'].join(' ')} + className={['uk-padding'].join(' ')} + /> + -
- {this.props.post.json_metadata.content.data.map(content => )} -
(
diff --git a/src/components/pendingReply/styles.scss b/src/post/Replies/PendingReply/styles.scss similarity index 100% rename from src/components/pendingReply/styles.scss rename to src/post/Replies/PendingReply/styles.scss diff --git a/src/components/reply/index.js b/src/post/Replies/Reply/index.js similarity index 95% rename from src/components/reply/index.js rename to src/post/Replies/Reply/index.js index c6cf235..cdd2da0 100644 --- a/src/components/reply/index.js +++ b/src/post/Replies/Reply/index.js @@ -2,7 +2,7 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import { fixUser } from '../../utils/defaultFixUtils'; +import { fixUser } from '../../../utils/defaultFixUtils'; import styles from './styles.scss'; const Reply = props => ( diff --git a/src/components/reply/styles.scss b/src/post/Replies/Reply/styles.scss similarity index 100% rename from src/components/reply/styles.scss rename to src/post/Replies/Reply/styles.scss diff --git a/src/components/replies/index.js b/src/post/Replies/index.js similarity index 94% rename from src/components/replies/index.js rename to src/post/Replies/index.js index 57b5fd0..9608179 100644 --- a/src/components/replies/index.js +++ b/src/post/Replies/index.js @@ -3,10 +3,10 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { loadReplies } from '../../actions/repliesActions'; -import Reply from '../reply'; +import Reply from './Reply'; import styles from './styles.scss'; -import CreateReply from '../createReply'; -import PendingReply from '../pendingReply'; +import CreateReply from './CreateReply'; +import PendingReply from './PendingReply'; class Replies extends React.Component { constructor(props) { diff --git a/src/components/replies/styles.scss b/src/post/Replies/styles.scss similarity index 100% rename from src/components/replies/styles.scss rename to src/post/Replies/styles.scss diff --git a/src/utils/steem.js b/src/utils/steem.js index 8f8eb21..53d1557 100644 --- a/src/utils/steem.js +++ b/src/utils/steem.js @@ -170,7 +170,6 @@ class SteemAPI { json_metadata: JSON.stringify({ tags, app: 'hapramp/0.0.1', - content, }), }; const benef = getCommentBeneficiaries(permlink, author); @@ -289,7 +288,7 @@ SteemAPI.sc2Operations = { jsonMetadata: { tags, app: 'hapramp/0.0.1', - content, + // content, }, }; SteemAPI.sc2Api.comment( diff --git a/yarn.lock b/yarn.lock index 3e90d59..2a6790c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -263,6 +263,13 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@~0.1.15: + version "0.1.16" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" + dependencies: + underscore "~1.7.0" + underscore.string "~2.4.0" + aria-query@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.7.1.tgz#26cbb5aff64144b0a825be1846e0b16cfa00b11e" @@ -400,6 +407,10 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" +autolinker@~0.15.0: + version "0.15.3" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832" + autoprefixer@7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7" @@ -6007,6 +6018,13 @@ relateurl@0.2.x: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" +remarkable@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6" + dependencies: + argparse "~0.1.15" + autolinker "~0.15.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -6977,6 +6995,14 @@ ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" +underscore.string@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.4.0.tgz#8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b" + +underscore@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"