diff --git a/packages/concordia-app/package.json b/packages/concordia-app/package.json index 0cc2aeb..7642f95 100644 --- a/packages/concordia-app/package.json +++ b/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", diff --git a/packages/concordia-app/src/components/PostList/PostListRow/index.jsx b/packages/concordia-app/src/components/PostList/PostListRow/index.jsx index bbf8a04..371a218 100644 --- a/packages/concordia-app/src/components/PostList/PostListRow/index.jsx +++ b/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] - ? ( - - ) - : ( - - )), [postAuthorMeta]); - - const authorAvatarLink = useMemo(() => { - if (postAuthorAddress) { - return ( - - {authorAvatar} - - ); - } - - return authorAvatar; - }, [authorAvatar, postAuthorAddress]); - const focusRef = useCallback((node) => { if (focus && node !== null) { node.scrollIntoView({ behavior: 'smooth' }); @@ -134,7 +107,13 @@ const PostListRow = (props) => { > - {authorAvatarLink} + @@ -162,8 +141,7 @@ const PostListRow = (props) => { - ), [ - authorAvatarLink, focusRef, loading, postAuthor, postAuthorAddress, postContent, postId, postIndex, t, timeAgo, + ), [focusRef, loading, postAuthor, postAuthorAddress, postAuthorMeta, postContent, postId, postIndex, t, timeAgo, topicId, ]); }; diff --git a/packages/concordia-app/src/components/PostList/PostListRow/styles.css b/packages/concordia-app/src/components/PostList/PostListRow/styles.css index 9fc10c1..f8facec 100644 --- a/packages/concordia-app/src/components/PostList/PostListRow/styles.css +++ b/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; diff --git a/packages/concordia-app/src/components/ProfileImage.jsx b/packages/concordia-app/src/components/ProfileImage.jsx new file mode 100644 index 0000000..5c78f66 --- /dev/null +++ b/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 ( + + ); + }, [avatarUrl, size, topicAuthor, topicAuthorMeta]); + + return useMemo(() => { + if (link && topicAuthorAddress) { + return ( + + {authorAvatar} + + ); + } + 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; diff --git a/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx b/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx index c5e329b..6ff30cc 100644 --- a/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx +++ b/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] - ? ( - - ) - : ( - - )), [topicAuthorMeta]); - - const authorAvatarLink = useMemo(() => { - if (topicAuthorAddress) { - return ( - - {authorAvatar} - - ); - } - - return authorAvatar; - }, [authorAvatar, topicAuthorAddress]); - return useMemo(() => { const handleTopicClick = () => { history.push(`/topics/${topicId}`); @@ -133,7 +104,13 @@ const TopicListRow = (props) => { - {authorAvatarLink} + @@ -173,7 +150,11 @@ const TopicListRow = (props) => { { numberOfReplies } ) - : } + : ( + + + + )} @@ -183,9 +164,8 @@ const TopicListRow = (props) => { - ); - }, [authorAvatarLink, history, loading, numberOfReplies, t, timeAgo, topicAuthor, topicAuthorAddress, topicId, topicSubject]); + }, [history, loading, numberOfReplies, t, timeAgo, topicAuthor, topicAuthorAddress, topicAuthorMeta, topicId, topicSubject]); }; TopicListRow.defaultProps = { diff --git a/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css b/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css index b7a1e9c..2a7dda0 100644 --- a/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css +++ b/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; diff --git a/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx b/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx index a607ec2..8a5e211 100644 --- a/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx +++ b/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 - ? ( - - ) - : ( - - )), [profileMetadataFetched, userAvatarUrl]); - const userLocationCell = useMemo(() => { if (!profileMetadataFetched) { return ( @@ -123,7 +106,14 @@ const GeneralTab = (props) => { - {authorAvatar} + + + {t('profile.general.tab.username.row.title')} @@ -182,6 +172,7 @@ const GeneralTab = (props) => {
{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 = { diff --git a/packages/concordia-app/src/views/Profile/GeneralTab/styles.css b/packages/concordia-app/src/views/Profile/GeneralTab/styles.css index 365f5b6..bdf5ba1 100644 --- a/packages/concordia-app/src/views/Profile/GeneralTab/styles.css +++ b/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); } diff --git a/yarn.lock b/yarn.lock index eb2fb80..6d0e740 100644 --- a/yarn.lock +++ b/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"