Browse Source

Add react-avatar

develop
Ezerous 4 years ago
parent
commit
2d0cb5ed0a
  1. 1
      packages/concordia-app/package.json
  2. 40
      packages/concordia-app/src/components/PostList/PostListRow/index.jsx
  3. 11
      packages/concordia-app/src/components/PostList/PostListRow/styles.css
  4. 52
      packages/concordia-app/src/components/ProfileImage.jsx
  5. 50
      packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx
  6. 15
      packages/concordia-app/src/components/TopicList/TopicListRow/styles.css
  7. 39
      packages/concordia-app/src/views/Profile/GeneralTab/index.jsx
  8. 17
      packages/concordia-app/src/views/Profile/GeneralTab/styles.css
  9. 37
      yarn.lock

1
packages/concordia-app/package.json

@ -36,6 +36,7 @@
"lodash": "^4.17.20",
"prop-types": "~15.7.2",
"react": "~16.13.1",
"react-avatar": "~3.9.7",
"react-dom": "~16.13.1",
"react-i18next": "^11.7.3",
"react-markdown": "^5.0.3",

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

@ -17,6 +17,7 @@ import determineKVAddress from '../../../utils/orbitUtils';
import { USER_PROFILE_PICTURE } from '../../../constants/orbit/UserDatabaseKeys';
import { POST_CONTENT } from '../../../constants/orbit/PostsDatabaseKeys';
import { FORUM_CONTRACT } from '../../../constants/contracts/ContractNames';
import ProfileImage from '../../ProfileImage';
const { orbit } = breeze;
@ -90,34 +91,6 @@ const PostListRow = (props) => {
}
}, [postAuthorAddress, users]);
const authorAvatar = useMemo(() => (postAuthorMeta !== null && postAuthorMeta[USER_PROFILE_PICTURE]
? (
<Image
avatar
src={postAuthorMeta[USER_PROFILE_PICTURE]}
/>
)
: (
<Icon
name="user circle"
size="big"
inverted
color="black"
/>
)), [postAuthorMeta]);
const authorAvatarLink = useMemo(() => {
if (postAuthorAddress) {
return (
<Link to={`/users/${postAuthorAddress}`}>
{authorAvatar}
</Link>
);
}
return authorAvatar;
}, [authorAvatar, postAuthorAddress]);
const focusRef = useCallback((node) => {
if (focus && node !== null) {
node.scrollIntoView({ behavior: 'smooth' });
@ -134,7 +107,13 @@ const PostListRow = (props) => {
>
<Ref innerRef={focusRef}>
<Feed.Label className="post-profile-picture">
{authorAvatarLink}
<ProfileImage
topicAuthorAddress={postAuthorAddress}
topicAuthor={postAuthor}
topicAuthorMeta={postAuthorMeta}
size="42"
link
/>
</Feed.Label>
</Ref>
<Feed.Content className="post-content">
@ -162,8 +141,7 @@ const PostListRow = (props) => {
</Feed.Extra>
</Feed.Content>
</Dimmer.Dimmable>
), [
authorAvatarLink, focusRef, loading, postAuthor, postAuthorAddress, postContent, postId, postIndex, t, timeAgo,
), [focusRef, loading, postAuthor, postAuthorAddress, postAuthorMeta, postContent, postId, postIndex, t, timeAgo,
topicId,
]);
};

11
packages/concordia-app/src/components/PostList/PostListRow/styles.css

@ -3,15 +3,7 @@
}
.post-profile-picture {
margin-top: 1rem;
}
.post-profile-picture img {
border-radius: 50%;
width: 3rem !important;
height: 3rem !important;
max-width: none !important;
margin: 0 !important;
margin-top: 0.9rem;
}
.post-content {
@ -21,6 +13,7 @@
.post-content > div.summary {
font-size: 1rem !important;
}
.post-content .placeholder {
margin: 0.5rem 0 0;
font-size: 2rem !important;

52
packages/concordia-app/src/components/ProfileImage.jsx

@ -0,0 +1,52 @@
import React, { useMemo } from 'react';
import Avatar from 'react-avatar';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { USER_PROFILE_PICTURE } from '../constants/orbit/UserDatabaseKeys';
const ProfileImage = (props) => {
const {
topicAuthorAddress, topicAuthor, topicAuthorMeta, avatarUrl, size, link,
} = props;
const stopClickPropagation = (event) => {
event.stopPropagation();
};
const authorAvatar = useMemo(() => {
let profileImageUrl = '';
if (avatarUrl) profileImageUrl = avatarUrl;
else if (topicAuthorMeta && topicAuthorMeta[USER_PROFILE_PICTURE]) profileImageUrl = topicAuthorMeta[USER_PROFILE_PICTURE];
return (
<Avatar
name={topicAuthor}
size={size}
round
src={profileImageUrl}
/>
);
}, [avatarUrl, size, topicAuthor, topicAuthorMeta]);
return useMemo(() => {
if (link && topicAuthorAddress) {
return (
<Link to={`/users/${topicAuthorAddress}`} onClick={stopClickPropagation}>
{authorAvatar}
</Link>
);
}
return authorAvatar;
}, [authorAvatar, link, topicAuthorAddress]);
};
ProfileImage.propTypes = {
topicAuthorAddress: PropTypes.string,
topicAuthor: PropTypes.string,
topicAuthorMeta: PropTypes.shape({ id: PropTypes.string, profile_picture: PropTypes.string }),
avatarUrl: PropTypes.string,
size: PropTypes.string,
link: PropTypes.bool,
};
export default ProfileImage;

50
packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx

@ -2,7 +2,7 @@ import React, {
memo, useEffect, useMemo, useState,
} from 'react';
import {
Dimmer, Grid, Icon, Image, Item, List, Placeholder, Segment,
Dimmer, Grid, Icon, Item, List, Placeholder, Segment,
} from 'semantic-ui-react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
@ -10,12 +10,12 @@ import TimeAgo from 'react-timeago';
import { useHistory } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import ProfileImage from '../../ProfileImage';
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions';
import { breeze } from '../../../redux/store';
import './styles.css';
import { TOPICS_DATABASE, USER_DATABASE } from '../../../constants/orbit/OrbitDatabases';
import determineKVAddress from '../../../utils/orbitUtils';
import { USER_PROFILE_PICTURE } from '../../../constants/orbit/UserDatabaseKeys';
import { TOPIC_SUBJECT } from '../../../constants/orbit/TopicsDatabaseKeys';
import { FORUM_CONTRACT } from '../../../constants/contracts/ContractNames';
@ -94,35 +94,6 @@ const TopicListRow = (props) => {
event.stopPropagation();
};
const authorAvatar = useMemo(() => (topicAuthorMeta !== null && topicAuthorMeta[USER_PROFILE_PICTURE]
? (
<Image
className="profile-picture"
src={topicAuthorMeta[USER_PROFILE_PICTURE]}
/>
)
: (
<List.Icon
name="user circle"
size="big"
inverted
color="black"
verticalAlign="middle"
/>
)), [topicAuthorMeta]);
const authorAvatarLink = useMemo(() => {
if (topicAuthorAddress) {
return (
<Link to={`/users/${topicAuthorAddress}`} onClick={stopClickPropagation}>
{authorAvatar}
</Link>
);
}
return authorAvatar;
}, [authorAvatar, topicAuthorAddress]);
return useMemo(() => {
const handleTopicClick = () => {
history.push(`/topics/${topicId}`);
@ -133,7 +104,13 @@ const TopicListRow = (props) => {
<Grid columns={2}>
<Grid.Column width={1} className="topic-row-avatar">
<Item>
{authorAvatarLink}
<ProfileImage
topicAuthorAddress={topicAuthorAddress}
topicAuthor={topicAuthor}
topicAuthorMeta={topicAuthorMeta}
size="65"
link
/>
</Item>
</Grid.Column>
<Grid.Column width={15} className="topic-row-content">
@ -173,7 +150,11 @@ const TopicListRow = (props) => {
{ numberOfReplies }
</span>
)
: <Placeholder fluid className="replies-placeholder"><Placeholder.Line /></Placeholder>}
: (
<Placeholder fluid className="replies-placeholder">
<Placeholder.Line />
</Placeholder>
)}
</Grid.Column>
</Grid.Row>
</Grid>
@ -183,9 +164,8 @@ const TopicListRow = (props) => {
</Segment>
</Dimmer.Dimmable>
);
}, [authorAvatarLink, history, loading, numberOfReplies, t, timeAgo, topicAuthor, topicAuthorAddress, topicId, topicSubject]);
}, [history, loading, numberOfReplies, t, timeAgo, topicAuthor, topicAuthorAddress, topicAuthorMeta, topicId, topicSubject]);
};
TopicListRow.defaultProps = {

15
packages/concordia-app/src/components/TopicList/TopicListRow/styles.css

@ -26,14 +26,14 @@
.topic-row-avatar {
margin: auto;
padding-left: 0.75em !important;
padding-left: 1rem !important;
padding-right: 0 !important;
font-size: 2rem;
color: red;
}
.topic-row-avatar i {
text-align: left !important;
margin:0;
.topic-row-avatar span{
color: white;
}
.topic-row-content {
@ -49,13 +49,6 @@
font-size: 0.9em !important;
}
.profile-picture {
border-radius: 50%;
max-width: none !important;
width: 2em;
height: 2em;
}
.replies-placeholder{
float:right;
width: 6rem;

39
packages/concordia-app/src/views/Profile/GeneralTab/index.jsx

@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react';
import {
Button, Icon, Image, Placeholder, Table,
Button, Icon, Placeholder, Table,
} from 'semantic-ui-react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
@ -10,8 +10,9 @@ import databases, { USER_DATABASE } from '../../../constants/orbit/OrbitDatabase
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions';
import { breeze } from '../../../redux/store';
import { USER_LOCATION, USER_PROFILE_PICTURE } from '../../../constants/orbit/UserDatabaseKeys';
import './styles.css';
import EditInformationModal from './EditInformationModal';
import ProfileImage from '../../../components/ProfileImage';
import './styles.css';
const { orbit } = breeze;
@ -66,24 +67,6 @@ const GeneralTab = (props) => {
}
}, [dispatch, profileAddress, users]);
const authorAvatar = useMemo(() => (profileMetadataFetched && userAvatarUrl
? (
<Image
className="general-tab-profile-picture"
centered
size="tiny"
src={userAvatarUrl}
/>
)
: (
<Icon
name="user circle"
size="massive"
inverted
color="black"
/>
)), [profileMetadataFetched, userAvatarUrl]);
const userLocationCell = useMemo(() => {
if (!profileMetadataFetched) {
return (
@ -123,7 +106,14 @@ const GeneralTab = (props) => {
<Table basic="very" singleLine>
<Table.Body>
<Table.Row textAlign="center">
<Table.Cell colSpan="3">{authorAvatar}</Table.Cell>
<Table.Cell colSpan="3" className="profile-image">
<ProfileImage
topicAuthorAddress={profileAddress}
topicAuthor={username}
avatarUrl={userAvatarUrl}
size="160"
/>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell><strong>{t('profile.general.tab.username.row.title')}</strong></Table.Cell>
@ -182,6 +172,7 @@ const GeneralTab = (props) => {
<Table.Row>
<Table.HeaderCell colSpan="2">
<Button
id="edit-info-button"
floated="right"
icon
labelPosition="left"
@ -200,11 +191,7 @@ const GeneralTab = (props) => {
</Table>
{isSelf && editInformationModal}
</>
), [
authorAvatar, editInformationModal, isSelf, numberOfPosts, numberOfTopics, profileAddress, profileMetadataFetched,
t, userInfoOrbitAddress, userLocationCell, userPostsOrbitAddress, userRegistrationTimestamp, userTopicsOrbitAddress,
username,
]);
), [editInformationModal, isSelf, numberOfPosts, numberOfTopics, profileAddress, profileMetadataFetched, t, userAvatarUrl, userInfoOrbitAddress, userLocationCell, userPostsOrbitAddress, userRegistrationTimestamp, userTopicsOrbitAddress, username]);
};
GeneralTab.defaultProps = {

17
packages/concordia-app/src/views/Profile/GeneralTab/styles.css

@ -1,7 +1,12 @@
.general-tab-profile-picture {
border-radius: 50%;
width: 12rem !important;
height: 12rem !important;
margin: 2rem;
vertical-align: middle;
.profile-image{
padding: 3rem !important;
}
#edit-info-button {
margin: 1rem;
background-color: var(--secondary-color);
}
#edit-info-button:hover {
background-color: var(--secondary-color-highlighted);
}

37
yarn.lock

@ -4157,6 +4157,11 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@ -4681,7 +4686,7 @@ core-js@^2.4.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.5.0:
core-js@^3.5.0, core-js@^3.6.1:
version "3.8.3"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0"
integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==
@ -4792,6 +4797,11 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@ -8861,7 +8871,7 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-buffer@^1.0.2, is-buffer@^1.1.5:
is-buffer@^1.0.2, is-buffer@^1.1.5, is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@ -9195,6 +9205,11 @@ is-resolvable@^1.0.0:
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
is-retina@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-retina/-/is-retina-1.0.3.tgz#d7401b286bea2ae37f62477588de504d0b8647e3"
integrity sha1-10AbKGvqKuN/Ykd1iN5QTQuGR+M=
is-retry-allowed@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
@ -11379,6 +11394,15 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
md5@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
mdast-add-list-metadata@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf"
@ -14492,6 +14516,15 @@ react-app-polyfill@^1.0.6:
regenerator-runtime "^0.13.3"
whatwg-fetch "^3.0.0"
react-avatar@^3.9.7:
version "3.9.7"
resolved "https://registry.yarnpkg.com/react-avatar/-/react-avatar-3.9.7.tgz#c7eb50d7f827350475ec6041f38fc2dbd249b740"
integrity sha512-UX1prYgo4gS1g2u16tZbx/Vy45M/BxyHHexIoRj6m9hI3ZR0FdHTDt66X5GpTtf6PRYE8KlvwHte1x5n8B0/XQ==
dependencies:
core-js "^3.6.1"
is-retina "^1.0.3"
md5 "^2.0.0"
react-dev-utils@^10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"

Loading…
Cancel
Save