diff --git a/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx b/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx index f20a06a..1973c77 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, List, Placeholder, + Dimmer, Grid, Image, List, Placeholder, } from 'semantic-ui-react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; @@ -12,7 +12,9 @@ import { useDispatch, useSelector } from 'react-redux'; import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions'; import { breeze } from '../../../redux/store'; import './styles.css'; -import { TOPICS_DATABASE } from '../../../constants/OrbitDatabases'; +import { TOPICS_DATABASE, USER_DATABASE } from '../../../constants/OrbitDatabases'; +import determineKVAddress from '../../../utils/orbitUtils'; +import { PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys'; const { orbit } = breeze; @@ -24,8 +26,10 @@ const TopicListRow = (props) => { const [topicAuthor, setTopicAuthor] = useState(null); const [timeAgo, setTimeAgo] = useState(null); const [topicSubject, setTopicSubject] = useState(null); + const [topicAuthorMeta, setTopicAuthorMeta] = useState(null); const userAddress = useSelector((state) => state.user.address); const topics = useSelector((state) => state.orbitData.topics); + const users = useSelector((state) => state.orbitData.users); const dispatch = useDispatch(); const history = useHistory(); const { t } = useTranslation(); @@ -47,6 +51,13 @@ const TopicListRow = (props) => { dbName: TOPICS_DATABASE, userAddress: topicAuthorAddress, }); + + dispatch({ + type: FETCH_USER_DATABASE, + orbit, + dbName: USER_DATABASE, + userAddress: topicAuthorAddress, + }); } }, [dispatch, topicAuthorAddress, userAddress]); @@ -59,6 +70,23 @@ const TopicListRow = (props) => { } }, [topicId, topics]); + useEffect(() => { + if (topicAuthorAddress !== null) { + determineKVAddress({ orbit, dbName: USER_DATABASE, userAddress: topicAuthorAddress }) + .then((userOrbitAddress) => { + const userFound = users + .find((user) => user.id === userOrbitAddress); + + if (userFound) { + setTopicAuthorMeta(userFound); + } + }) + .catch((error) => { + console.error('Error during service worker registration:', error); + }); + } + }, [topicAuthorAddress, users]); + return useMemo(() => { const handleTopicClick = () => { history.push(`/topics/${topicId}`); @@ -66,8 +94,24 @@ const TopicListRow = (props) => { return ( - - + {topicAuthorMeta !== null && topicAuthorMeta[PROFILE_PICTURE] + ? ( + + ) + : ( + + )} + @@ -103,7 +147,7 @@ const TopicListRow = (props) => { ); - }, [history, loading, numberOfReplies, t, timeAgo, topicAuthor, topicId, topicSubject]); + }, [history, loading, numberOfReplies, t, timeAgo, topicAuthor, 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 8e808b6..6f92675 100644 --- a/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css +++ b/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css @@ -4,5 +4,18 @@ } .list-item { + display: flex !important; text-align: start; } + +.profile-picture { + cursor: pointer; + max-width: 36px; + max-height: 36px; + margin: 0; + vertical-align: middle; +} + +.list-content { + flex-grow: 1; +} diff --git a/packages/concordia-app/src/constants/UserDatabaseKeys.js b/packages/concordia-app/src/constants/UserDatabaseKeys.js index 91b7bd7..db2b2d6 100644 --- a/packages/concordia-app/src/constants/UserDatabaseKeys.js +++ b/packages/concordia-app/src/constants/UserDatabaseKeys.js @@ -1,2 +1,9 @@ export const PROFILE_PICTURE = 'profile_picture'; export const LOCATION = 'location'; + +const userDatabaseKeys = [ + PROFILE_PICTURE, + LOCATION, +]; + +export default userDatabaseKeys; diff --git a/packages/concordia-app/src/redux/reducers/peerDbReplicationReducer.js b/packages/concordia-app/src/redux/reducers/peerDbReplicationReducer.js index 5d29a3e..117d442 100644 --- a/packages/concordia-app/src/redux/reducers/peerDbReplicationReducer.js +++ b/packages/concordia-app/src/redux/reducers/peerDbReplicationReducer.js @@ -1,7 +1,7 @@ import { UPDATE_ORBIT_DATA } from '../actions/peerDbReplicationActions'; const initialState = { - fetchedPeerDatabases: [], + users: [], topics: [], posts: [], }; @@ -10,10 +10,13 @@ const peerDbReplicationReducer = (state = initialState, action) => { const { type } = action; if (type === UPDATE_ORBIT_DATA) { - const { topics, posts } = action; + const { users, topics, posts } = action; return { ...state, + users: [ + ...users, + ], topics: [ ...topics, ], diff --git a/packages/concordia-app/src/redux/sagas/peerDbReplicationSaga.js b/packages/concordia-app/src/redux/sagas/peerDbReplicationSaga.js index 3b94829..61f702c 100644 --- a/packages/concordia-app/src/redux/sagas/peerDbReplicationSaga.js +++ b/packages/concordia-app/src/redux/sagas/peerDbReplicationSaga.js @@ -9,7 +9,8 @@ import { } from '@ezerous/breeze/src/orbit/orbitActions'; import determineKVAddress from '../../utils/orbitUtils'; import { FETCH_USER_DATABASE, UPDATE_ORBIT_DATA } from '../actions/peerDbReplicationActions'; -import { POSTS_DATABASE, TOPICS_DATABASE } from '../../constants/OrbitDatabases'; +import { POSTS_DATABASE, TOPICS_DATABASE, USER_DATABASE } from '../../constants/OrbitDatabases'; +import userDatabaseKeys from '../../constants/UserDatabaseKeys'; function* fetchUserDb({ orbit, userAddress, dbName }) { const peerDbAddress = yield call(determineKVAddress, { @@ -20,11 +21,39 @@ function* fetchUserDb({ orbit, userAddress, dbName }) { } function* updateReduxState({ database }) { - const { topics, posts } = yield select((state) => ({ + const { users, topics, posts } = yield select((state) => ({ + users: state.orbitData.users, topics: state.orbitData.topics, posts: state.orbitData.posts, })); + if (database.dbname === USER_DATABASE) { + const oldUsersUnchanged = users + .filter((user) => !database.id !== user.id); + + yield put({ + type: UPDATE_ORBIT_DATA, + users: [ + ...oldUsersUnchanged, + { + id: database.id, + // Don't ask how.. it just works + ...Object + .entries(database.all) + .filter(([key]) => userDatabaseKeys.includes(key)) + .reduce(((acc, keyValue) => { + const [key, value] = keyValue; + acc[key] = value; + + return acc; + }), {}), + }, + ], + topics: [...topics], + posts: [...posts], + }); + } + if (database.dbname === TOPICS_DATABASE) { const oldTopicsUnchanged = topics .filter((topic) => !Object @@ -34,6 +63,7 @@ function* updateReduxState({ database }) { yield put({ type: UPDATE_ORBIT_DATA, + users: [...users], topics: [ ...oldTopicsUnchanged, ...Object @@ -56,6 +86,7 @@ function* updateReduxState({ database }) { yield put({ type: UPDATE_ORBIT_DATA, + users: [...users], topics: [...topics], posts: [ ...oldPostsUnchanged,