mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
rendering channels
This commit is contained in:
parent
213577e418
commit
8a1531bcee
@ -25,6 +25,7 @@ export const SessionWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
min-height: 0;
|
||||
}
|
||||
.center {
|
||||
flex-grow: 1;
|
||||
@ -57,6 +58,7 @@ export const SessionWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
min-height: 0;
|
||||
}
|
||||
.center {
|
||||
flex-grow: 1;
|
||||
|
@ -1,8 +1,15 @@
|
||||
import { Input } from 'antd';
|
||||
import { Input, List } from 'antd';
|
||||
import { ChannelsWrapper } from './Channels.styled';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { useChannels } from './useChannels.hook';
|
||||
import { ChannelItem } from './channelItem/ChannelItem';
|
||||
|
||||
export function Channels() {
|
||||
|
||||
const { state, actions } = useChannels();
|
||||
|
||||
console.log(state);
|
||||
|
||||
return (
|
||||
<ChannelsWrapper>
|
||||
<div class="search">
|
||||
@ -10,6 +17,13 @@ export function Channels() {
|
||||
<Input bordered={false} allowClear={true} placeholder="Channels" prefix={<SearchOutlined />} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="results">
|
||||
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.channels} gutter="0"
|
||||
renderItem={item => (
|
||||
<ChannelItem item={item} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</ChannelsWrapper>
|
||||
);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ export const ChannelsWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: ${Colors.formBackground};
|
||||
min-height: 0;
|
||||
|
||||
.search {
|
||||
padding: 8px;
|
||||
@ -17,4 +18,8 @@ export const ChannelsWrapper = styled.div`
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.results {
|
||||
min-height: 0;
|
||||
overflow: scroll;
|
||||
`;
|
||||
|
31
net/web/src/session/channels/channelItem/ChannelItem.jsx
Normal file
31
net/web/src/session/channels/channelItem/ChannelItem.jsx
Normal 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>
|
||||
)
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
`;
|
@ -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 };
|
||||
}
|
61
net/web/src/session/channels/useChannels.hook.js
Normal file
61
net/web/src/session/channels/useChannels.hook.js
Normal 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 };
|
||||
}
|
Loading…
Reference in New Issue
Block a user