rendering channels

This commit is contained in:
Roland Osborne 2022-08-09 11:14:36 -07:00
parent 213577e418
commit 8a1531bcee
7 changed files with 179 additions and 1 deletions

View File

@ -25,6 +25,7 @@ export const SessionWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
min-height: 0;
} }
.center { .center {
flex-grow: 1; flex-grow: 1;
@ -57,6 +58,7 @@ export const SessionWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
min-height: 0;
} }
.center { .center {
flex-grow: 1; flex-grow: 1;

View File

@ -1,8 +1,15 @@
import { Input } from 'antd'; import { Input, List } from 'antd';
import { ChannelsWrapper } from './Channels.styled'; import { ChannelsWrapper } from './Channels.styled';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import { useChannels } from './useChannels.hook';
import { ChannelItem } from './channelItem/ChannelItem';
export function Channels() { export function Channels() {
const { state, actions } = useChannels();
console.log(state);
return ( return (
<ChannelsWrapper> <ChannelsWrapper>
<div class="search"> <div class="search">
@ -10,6 +17,13 @@ export function Channels() {
<Input bordered={false} allowClear={true} placeholder="Channels" prefix={<SearchOutlined />} /> <Input bordered={false} allowClear={true} placeholder="Channels" prefix={<SearchOutlined />} />
</div> </div>
</div> </div>
<div class="results">
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.channels} gutter="0"
renderItem={item => (
<ChannelItem item={item} />
)}
/>
</div>
</ChannelsWrapper> </ChannelsWrapper>
); );
} }

View File

@ -7,6 +7,7 @@ export const ChannelsWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: ${Colors.formBackground}; background-color: ${Colors.formBackground};
min-height: 0;
.search { .search {
padding: 8px; padding: 8px;
@ -17,4 +18,8 @@ export const ChannelsWrapper = styled.div`
border-radius: 8px; border-radius: 8px;
} }
} }
.results {
min-height: 0;
overflow: scroll;
`; `;

View File

@ -0,0 +1,31 @@
import { ChannelItemWrapper } from './ChannelItem.styled';
import { useChannelItem } from './useChannelItem.hook';
import { SolutionOutlined } from '@ant-design/icons';
export function ChannelItem({ item }) {
const { state, actions } = useChannelItem(item);
return (
<ChannelItemWrapper>
{ state.contacts.length === 0 && (
<div class="notes">
<div class="logo">
<SolutionOutlined />
</div>
<div class="subject">
</div>
<div class="markup">
</div>
</div>
)}
{ state.contacts.length === 1 && (
<div>PERSONAL</div>
)}
{ state.contacts.length > 1 && (
<div>GROUP</div>
)}
</ChannelItemWrapper>
)
}

View File

@ -0,0 +1,29 @@
import styled from 'styled-components';
import Colors from 'constants/Colors';
export const ChannelItemWrapper = styled.div`
height: 48px;
width: 100%;
display: flex;
flex-direction: row;
flex-align: center;
border-bottom: 1px solid ${Colors.divider};
.logo {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid ${Colors.grey};
width: 32px;
height: 32px;
border-radius: 8px;
font-size: 18px;
}
.subject {
flex-grow: 1;
}
.markup {
}
`;

View File

@ -0,0 +1,36 @@
import { useContext, useState, useEffect } from 'react';
import { ProfileContext } from 'context/ProfileContext';
import { CardContext } from 'context/CardContext';
export function useChannelItem(item) {
const [state, setState] = useState({
contacts: [],
});
const profile = useContext(ProfileContext);
const card = useContext(CardContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
const actions = {
};
useEffect(() => {
let contacts = [];
if (item.guid != null && profile.state.profile.guid != item.guid) {
contacts.push(card.actions.getCardByGuid(item.guid));
}
for (let guid of item.data.channelDetail?.members) {
if (guid != profile.state.profile.guid) {
contacts.push(card.actions.getCardByGuid(guid));
}
}
updateState({ contacts });
}, [profile, item]);
return { state, actions };
}

View File

@ -0,0 +1,61 @@
import { useContext, useState, useEffect } from 'react';
import { StoreContext } from 'context/StoreContext';
import { ChannelContext } from 'context/ChannelContext';
import { CardContext } from 'context/CardContext';
export function useChannels() {
const [state, setState] = useState({
channels: [],
busy: false }
);
const card = useContext(CardContext);
const channel = useContext(ChannelContext);
const store = useContext(StoreContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
const actions = {
};
const setUpdated = (chan) => {
const login = store.state['login:timestamp'];
const update = chan?.data?.channelSummary?.lastTopic?.created;
if (!update || (login && update < login)) {
chan.updated = false;
return;
}
let key = `${chan.id}::${chan.cardId}`
if (store.state[key] && store.state[key] == chan.revision) {
chan.updated = false;
}
else {
chan.updated = true;
}
}
useEffect(() => {
let merged = [];
card.state.cards.forEach((value, key, map) => {
merged.push(...Array.from(value.channels.values()));
});
merged.push(...Array.from(channel.state.channels.values()));
merged.sort((a, b) => {
if (a?.data?.channelSummary?.lastTopic?.created > b?.data?.channelSummary?.lastTopic?.created) {
return -1;
}
return 1;
});
merged.forEach(chan => { setUpdated(chan) });
updateState({ channels: merged });
}, [channel, card, store]);
return { state, actions };
}