rendering topic item components

This commit is contained in:
Roland Osborne 2022-04-28 15:24:49 -07:00
parent 119b62327b
commit 2ba6853db5
7 changed files with 136 additions and 14 deletions

View File

@ -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 (
<TopicItemWrapper>
<div>{ text }</div>
<div class="avatar">
<Avatar imageUrl={state.imageUrl} />
</div>
<div class="topic">
<div class="info">
<div class={nameClass}>{ name }</div>
</div>
<div class="message">{ state.message }</div>
</div>
</TopicItemWrapper>
)
}

View File

@ -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 {
}
}
`;

View File

@ -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 = {
};

View File

@ -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 (
<AvatarWrapper>
<UserOutlined />
</AvatarWrapper>
)
} else {
return (
<AvatarWrapper>
<img class='avatar' src={ imageUrl } alt='' />
</AvatarWrapper>
);
}
}

View File

@ -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%;
}
`;

View File

@ -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)

View File

@ -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),
}