diff --git a/net/web/src/User/Conversation/TopicItem/TopicItem.jsx b/net/web/src/User/Conversation/TopicItem/TopicItem.jsx index c5cda964..90b56680 100644 --- a/net/web/src/User/Conversation/TopicItem/TopicItem.jsx +++ b/net/web/src/User/Conversation/TopicItem/TopicItem.jsx @@ -2,24 +2,26 @@ import React, { useEffect, useState } from 'react'; import { TopicItemWrapper } from './TopicItem.styled'; import ReactResizeDetector from 'react-resize-detector'; import { useTopicItem } from './useTopicItem.hook'; +import { Avatar } from 'avatar/Avatar'; export function TopicItem({ topic }) { - const { state, actions } = useTopicItem(); - const [ text, setText ] = useState(null); + const { state, actions } = useTopicItem(topic); - useEffect(() => { - try { - setText(JSON.parse(topic.data.topicDetail.data).text); - } - catch(err) { - console.log("invalid topic", topic); - } - }, [topic]); + let name = state.name ? state.name : state.handle; + let nameClass = state.name ? 'set' : 'unset'; return ( -
{ text }
+
+ +
+
+
+
{ name }
+
+
{ state.message }
+
) } diff --git a/net/web/src/User/Conversation/TopicItem/TopicItem.styled.js b/net/web/src/User/Conversation/TopicItem/TopicItem.styled.js index a5bbbb91..64875042 100644 --- a/net/web/src/User/Conversation/TopicItem/TopicItem.styled.js +++ b/net/web/src/User/Conversation/TopicItem/TopicItem.styled.js @@ -1,7 +1,39 @@ import styled from 'styled-components'; export const TopicItemWrapper = styled.div` + display: flex; + flex-direction: row; width: 100%; + padding-left: 8px; + padding-right: 8px; + + .avatar { + height: 32px; + width: 32px; + } + + .topic { + display: flex; + flex-direction: column; + padding-left: 8px; + + .info { + display: flex; + flex-direction: row; + .set { + font-weight: bold; + color: #444444; + } + .unset { + font-weight: bold; + font-style: italic; + color: #888888; + } + } + + .message { + } + } `; diff --git a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js index 3f5a20e2..694091e1 100644 --- a/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js +++ b/net/web/src/User/Conversation/TopicItem/useTopicItem.hook.js @@ -1,16 +1,49 @@ import { useContext, useState, useEffect, useRef } from 'react'; import { ConversationContext } from 'context/ConversationContext'; +import { ProfileContext } from 'context/ProfileContext'; +import { CardContext } from 'context/CardContext'; -export function useTopicItem() { +export function useTopicItem(topic) { - const [state, setState] = useState({}); + const [guid, setGuid] = useState(null); + const [state, setState] = useState({ + name: null, + handle: null, + imageUrl: null, + message: null, + }); + + const profile = useContext(ProfileContext); + const card = useContext(CardContext); const conversation = useContext(ConversationContext); const updateState = (value) => { setState((s) => ({ ...s, ...value })); } + useEffect(() => { + let message; + try { + message = JSON.parse(topic.data.topicDetail.data).text; + } + catch(err) { + console.log(err); + } + + if (profile.state.init && card.state.init && conversation.state.init) { + const topicGuid = topic.data.topicDetail.guid; + if (profile.state.profile.guid == topicGuid) { + const { name, handle, imageUrl } = profile.actions.getProfile(); + updateState({ name, handle, imageUrl, message }); + } + else { + const { name, handle, imageUrl } = card.actions.getCardProfileByGuid(topicGuid); + updateState({ name, handle, imageUrl, message }); + } + } + }, [profile, card, conversation, topic]); + const actions = { }; diff --git a/net/web/src/avatar/Avatar.jsx b/net/web/src/avatar/Avatar.jsx new file mode 100644 index 00000000..85dfc80c --- /dev/null +++ b/net/web/src/avatar/Avatar.jsx @@ -0,0 +1,20 @@ +import React, { useState } from 'react' +import { UserOutlined } from '@ant-design/icons'; +import { AvatarWrapper } from './Avatar.styled'; + +export function Avatar({ imageUrl }) { + if (imageUrl == null) { + return ( + + + + ) + } else { + return ( + + + + ); + } +} + diff --git a/net/web/src/avatar/Avatar.styled.jsx b/net/web/src/avatar/Avatar.styled.jsx new file mode 100644 index 00000000..72fdb081 --- /dev/null +++ b/net/web/src/avatar/Avatar.styled.jsx @@ -0,0 +1,17 @@ +import styled from 'styled-components'; + +export const AvatarWrapper = styled.div` + border-radius: 4px; + overflow: hidden; + height: 100%; + display: flex; + font-size: 24px; + align-items: center; + justify-content: center; + + .avatar { + object-fit: contain; + height: 100%; + } +`; + diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index 22241a31..251b1f3b 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -179,9 +179,20 @@ export function useCardContext() { setCards(rev); }, getCardByGuid: getCardByGuid, + getCardProfileByGuid: (guid) => { + let card = getCardByGuid(guid); + if (card) { + let { name, handle } = card.data.cardProfile; + if (card.data.cardProfile.imageSet) { + return { name, handle, imageUrl: getCardImageUrl(access.current, card.id, card.data.profileRevision) }; + } + return { name, handle } + } + return {}; + }, getImageUrl: (cardId) => { let card = cards.current.get(cardId); - if (!card) { + if (!card || !card.data.cardProfile.imageSet) { return null; } return getCardImageUrl(access.current, cardId, card.data.profileRevision) diff --git a/net/web/src/context/useProfileContext.hook.js b/net/web/src/context/useProfileContext.hook.js index b9c454ff..7f0773fe 100644 --- a/net/web/src/context/useProfileContext.hook.js +++ b/net/web/src/context/useProfileContext.hook.js @@ -48,6 +48,13 @@ export function useProfileContext() { setProfileImage: async (image) => { await setProfileImage(access.current, image); }, + getProfile: () => { + const { name, handle, image, revision } = state.profile; + if (image == null || image == '') { + return { name, handle }; + } + return { name, handle, imageUrl: getProfileImageUrl(access.current, revision) }; + }, profileImageUrl: () => getProfileImageUrl(access.current, revision.current), }