Browse Source

Merge branch 'feature/105-add-post-hyperlinks' into 'develop'

Feature/105 add post hyperlinks

See merge request ecentrics/concordia!8
develop
Apostolos Fanakis 4 years ago
parent
commit
01975f2d19
  1. 36
      packages/concordia-app/src/components/PostList/PostListRow/index.jsx
  2. 8
      packages/concordia-app/src/components/PostList/index.jsx
  3. 5
      packages/concordia-app/src/views/Topic/TopicView/index.jsx
  4. 8
      packages/concordia-app/src/views/Topic/index.jsx
  5. 700
      yarn.lock

36
packages/concordia-app/src/components/PostList/PostListRow/index.jsx

@ -1,8 +1,8 @@
import React, { import React, {
memo, useEffect, useMemo, useState, memo, useEffect, useMemo, useState, useCallback,
} from 'react'; } from 'react';
import { import {
Dimmer, Icon, Image, Feed, Placeholder, Dimmer, Icon, Image, Feed, Placeholder, Ref,
} from 'semantic-ui-react'; } from 'semantic-ui-react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -22,12 +22,13 @@ const { orbit } = breeze;
const PostListRow = (props) => { const PostListRow = (props) => {
const { const {
id: postId, postIndexInTopic, postCallHash, loading, id: postId, postIndex, postCallHash, loading, focus,
} = props; } = props;
const getPostResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getPost); const getPostResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getPost);
const [postAuthorAddress, setPostAuthorAddress] = useState(null); const [postAuthorAddress, setPostAuthorAddress] = useState(null);
const [postAuthor, setPostAuthor] = useState(null); const [postAuthor, setPostAuthor] = useState(null);
const [timeAgo, setTimeAgo] = useState(null); const [timeAgo, setTimeAgo] = useState(null);
const [topicId, setTopicId] = useState(null);
const [postContent, setPostContent] = useState(null); const [postContent, setPostContent] = useState(null);
const [postAuthorMeta, setPostAuthorMeta] = useState(null); const [postAuthorMeta, setPostAuthorMeta] = useState(null);
const userAddress = useSelector((state) => state.user.address); const userAddress = useSelector((state) => state.user.address);
@ -41,6 +42,7 @@ const PostListRow = (props) => {
setPostAuthorAddress(getPostResults[postCallHash].value[0]); setPostAuthorAddress(getPostResults[postCallHash].value[0]);
setPostAuthor(getPostResults[postCallHash].value[1]); setPostAuthor(getPostResults[postCallHash].value[1]);
setTimeAgo(getPostResults[postCallHash].value[2] * 1000); setTimeAgo(getPostResults[postCallHash].value[2] * 1000);
setTopicId(getPostResults[postCallHash].value[3]);
} }
}, [getPostResults, loading, postCallHash]); }, [getPostResults, loading, postCallHash]);
@ -116,18 +118,31 @@ const PostListRow = (props) => {
return authorAvatar; return authorAvatar;
}, [authorAvatar, postAuthorAddress]); }, [authorAvatar, postAuthorAddress]);
const focusRef = useCallback((node) => {
if (focus && node !== null) {
node.scrollIntoView({ behavior: 'smooth' });
}
}, [focus]);
return useMemo(() => ( return useMemo(() => (
<Dimmer.Dimmable as={Feed.Event} blurring dimmed={loading}> <Dimmer.Dimmable
as={Feed.Event}
blurring
dimmed={loading}
id={`post-${postId}`}
>
<Ref innerRef={focusRef}>
<Feed.Label className="post-profile-picture"> <Feed.Label className="post-profile-picture">
{authorAvatarLink} {authorAvatarLink}
</Feed.Label> </Feed.Label>
</Ref>
<Feed.Content> <Feed.Content>
<Feed.Summary> <Feed.Summary>
<div> <Link to={`/topics/${topicId}/#post-${postId}`}>
<span className="post-summary-meta-index"> <span className="post-summary-meta-index">
{t('post.list.row.post.id', { id: postIndexInTopic })} {t('post.list.row.post.id', { id: postIndex })}
</span> </span>
</div> </Link>
{postAuthor !== null && setPostAuthorAddress !== null && timeAgo !== null {postAuthor !== null && setPostAuthorAddress !== null && timeAgo !== null
? ( ? (
<> <>
@ -147,19 +162,22 @@ const PostListRow = (props) => {
</Feed.Content> </Feed.Content>
</Dimmer.Dimmable> </Dimmer.Dimmable>
), [ ), [
authorAvatarLink, loading, postAuthor, postAuthorAddress, postContent, postIndexInTopic, t, timeAgo, authorAvatarLink, focusRef, loading, postAuthor, postAuthorAddress, postContent, postId, postIndex, t, timeAgo,
topicId,
]); ]);
}; };
PostListRow.defaultProps = { PostListRow.defaultProps = {
loading: false, loading: false,
focus: false,
}; };
PostListRow.propTypes = { PostListRow.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
postIndexInTopic: PropTypes.number.isRequired, postIndex: PropTypes.number.isRequired,
postCallHash: PropTypes.string, postCallHash: PropTypes.string,
loading: PropTypes.bool, loading: PropTypes.bool,
focus: PropTypes.bool,
}; };
export default memo(PostListRow); export default memo(PostListRow);

8
packages/concordia-app/src/components/PostList/index.jsx

@ -11,7 +11,7 @@ import { FORUM_CONTRACT } from '../../constants/contracts/ContractNames';
const { contracts: { [FORUM_CONTRACT]: { methods: { getPost: { cacheCall: getPostChainData } } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { getPost: { cacheCall: getPostChainData } } } } } = drizzle;
const PostList = (props) => { const PostList = (props) => {
const { postIds, loading } = props; const { postIds, loading, focusOnPost } = props;
const [getPostCallHashes, setGetPostCallHashes] = useState([]); const [getPostCallHashes, setGetPostCallHashes] = useState([]);
const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized); const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized);
const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed); const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed);
@ -47,14 +47,15 @@ const PostList = (props) => {
return ( return (
<PostListRow <PostListRow
id={postId} id={postId}
postIndexInTopic={index + 1} postIndex={index + 1}
key={postId} key={postId}
postCallHash={postHash && postHash.hash} postCallHash={postHash && postHash.hash}
loading={postHash === undefined} loading={postHash === undefined}
focus={postId === focusOnPost}
/> />
); );
}); });
}, [getPostCallHashes, loading, postIds]); }, [focusOnPost, getPostCallHashes, loading, postIds]);
return ( return (
<Dimmer.Dimmable as={Feed} blurring dimmed={loading} id="post-list" size="large"> <Dimmer.Dimmable as={Feed} blurring dimmed={loading} id="post-list" size="large">
@ -67,6 +68,7 @@ const PostList = (props) => {
PostList.propTypes = { PostList.propTypes = {
postIds: PropTypes.arrayOf(PropTypes.number).isRequired, postIds: PropTypes.arrayOf(PropTypes.number).isRequired,
loading: PropTypes.bool, loading: PropTypes.bool,
focusOnPost: PropTypes.number,
}; };
export default PostList; export default PostList;

5
packages/concordia-app/src/views/Topic/TopicView/index.jsx

@ -24,7 +24,7 @@ const { orbit } = breeze;
const TopicView = (props) => { const TopicView = (props) => {
const { const {
topicId, topicAuthorAddress: initialTopicAuthorAddress, topicAuthor: initialTopicAuthor, topicId, topicAuthorAddress: initialTopicAuthorAddress, topicAuthor: initialTopicAuthor,
timestamp: initialTimestamp, postIds: initialPostIds, timestamp: initialTimestamp, postIds: initialPostIds, focusOnPost,
} = props; } = props;
const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized); const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized);
const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed); const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed);
@ -174,7 +174,7 @@ const TopicView = (props) => {
</Step> </Step>
</Step.Group> </Step.Group>
</Dimmer.Dimmable> </Dimmer.Dimmable>
<PostList postIds={postIds || []} loading={postIds === null} /> <PostList postIds={postIds || []} loading={postIds === null} focusOnPost={focusOnPost} />
{topicSubject !== null && postIds !== null && hasSignedUp && ( {topicSubject !== null && postIds !== null && hasSignedUp && (
<PostCreate <PostCreate
topicId={topicId} topicId={topicId}
@ -192,6 +192,7 @@ TopicView.propTypes = {
topicAuthor: PropTypes.string, topicAuthor: PropTypes.string,
timestamp: PropTypes.number, timestamp: PropTypes.number,
postIds: PropTypes.arrayOf(PropTypes.number), postIds: PropTypes.arrayOf(PropTypes.number),
focusOnPost: PropTypes.number,
}; };
export default TopicView; export default TopicView;

8
packages/concordia-app/src/views/Topic/index.jsx

@ -1,18 +1,22 @@
import React from 'react'; import React from 'react';
import { useRouteMatch } from 'react-router'; import { useLocation, useRouteMatch } from 'react-router';
import TopicCreate from './TopicCreate'; import TopicCreate from './TopicCreate';
import TopicView from './TopicView'; import TopicView from './TopicView';
const Topic = () => { const Topic = () => {
const match = useRouteMatch(); const match = useRouteMatch();
const { id: topicId } = match.params; const { id: topicId } = match.params;
const location = useLocation();
const postHash = location.hash;
const postId = postHash ? postHash.substring('#post-'.length) : null;
const focusPostId = postId ? parseInt(postId, 10) : null;
return topicId === 'new' return topicId === 'new'
? ( ? (
<TopicCreate /> <TopicCreate />
) )
: ( : (
<TopicView topicId={parseInt(topicId, 10)} /> <TopicView topicId={parseInt(topicId, 10)} focusOnPost={focusPostId} />
); );
}; };

700
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save