mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
rendering card updated status
This commit is contained in:
parent
35a4a51094
commit
cedd337ab0
@ -35,7 +35,7 @@ export function Session() {
|
|||||||
{ (viewport.state.display === 'xlarge') && (
|
{ (viewport.state.display === 'xlarge') && (
|
||||||
<div class="desktop-layout noselect">
|
<div class="desktop-layout noselect">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Identity openCards={actions.openCards} />
|
<Identity openCards={actions.openCards} cardUpdated={state.cardUpdated} />
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<Channels />
|
<Channels />
|
||||||
</div>
|
</div>
|
||||||
@ -75,7 +75,7 @@ export function Session() {
|
|||||||
{ (viewport.state.display === 'large' || viewport.state.display === 'medium') && (
|
{ (viewport.state.display === 'large' || viewport.state.display === 'medium') && (
|
||||||
<div class="tablet-layout noselect">
|
<div class="tablet-layout noselect">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Identity openCards={actions.openCards} />
|
<Identity openCards={actions.openCards} cardUpdated={state.cardUpdated} />
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<Channels />
|
<Channels />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Input, List } from 'antd';
|
import { Input, List } from 'antd';
|
||||||
import { CardsWrapper } from './Cards.styled';
|
import { CardsWrapper } from './Cards.styled';
|
||||||
import { RightOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons';
|
import { SortAscendingOutlined, RightOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { useCards } from './useCards.hook';
|
import { useCards } from './useCards.hook';
|
||||||
import { CardItem } from './cardItem/CardItem';
|
import { CardItem } from './cardItem/CardItem';
|
||||||
|
|
||||||
@ -12,6 +12,16 @@ export function Cards({ close }) {
|
|||||||
<CardsWrapper>
|
<CardsWrapper>
|
||||||
<div class="view">
|
<div class="view">
|
||||||
<div class="search">
|
<div class="search">
|
||||||
|
{ !state.sorted && (
|
||||||
|
<div class="unsorted" onClick={() => actions.setSort(true)}>
|
||||||
|
<SortAscendingOutlined />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{ state.sorted && (
|
||||||
|
<div class="sorted" onClick={() => actions.setSort(false)}>
|
||||||
|
<SortAscendingOutlined />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div class="filter">
|
<div class="filter">
|
||||||
<Input bordered={false} allowClear={true} placeholder="Contacts" prefix={<SearchOutlined />}
|
<Input bordered={false} allowClear={true} placeholder="Contacts" prefix={<SearchOutlined />}
|
||||||
size="large" spellCheck="false" onChange={(e) => actions.onFilter(e.target.value)} />
|
size="large" spellCheck="false" onChange={(e) => actions.onFilter(e.target.value)} />
|
||||||
|
@ -19,6 +19,25 @@ export const CardsWrapper = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
|
.sorted {
|
||||||
|
color: ${Colors.enabled};
|
||||||
|
font-size: 18px;
|
||||||
|
padding-right: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsorted {
|
||||||
|
color: ${Colors.disabled};
|
||||||
|
font-size: 18px;
|
||||||
|
padding-right: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
border: 1px solid ${Colors.divider};
|
border: 1px solid ${Colors.divider};
|
||||||
background-color: ${Colors.white};
|
background-color: ${Colors.white};
|
||||||
@ -70,7 +89,7 @@ export const CardsWrapper = styled.div`
|
|||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export function CardItem() {
|
export function CardItem({ item }) {
|
||||||
return <div>CARD ITEM</div>
|
return <div>{ item?.data?.cardProfile?.name }</div>
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ export function useCards() {
|
|||||||
const [filter, setFilter] = useState(null);
|
const [filter, setFilter] = useState(null);
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
|
sorted: false,
|
||||||
display: null,
|
display: null,
|
||||||
cards: [],
|
cards: [],
|
||||||
busy: false }
|
busy: false }
|
||||||
@ -23,10 +24,44 @@ export function useCards() {
|
|||||||
onFilter: (value) => {
|
onFilter: (value) => {
|
||||||
setFilter(value.toUpperCase());
|
setFilter(value.toUpperCase());
|
||||||
},
|
},
|
||||||
|
setSort: (value) => {
|
||||||
|
updateState({ sorted: value });
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
}, [card]);
|
const contacts = Array.from(card.state.cards.values());
|
||||||
|
|
||||||
|
let filtered = contacts.filter((contact) => {
|
||||||
|
if (!filter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!contact?.data?.cardProfile?.name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return contact.data.cardProfile.name.toUpperCase().includes(filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.sorted) {
|
||||||
|
filtered.sort((a, b) => {
|
||||||
|
if (a?.data?.cardProfile?.name > b?.data?.cardProfile?.name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
filtered.sort((a, b) => {
|
||||||
|
if (a?.data?.cardDetails?.statusUpdated > b?.data?.cardDetails?.statusUpdated) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState({ cards: filtered });
|
||||||
|
|
||||||
|
}, [card, filter, state.sorted]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateState({ display: viewport.state.display });
|
updateState({ display: viewport.state.display });
|
||||||
|
@ -64,7 +64,7 @@ export const ChannelsWrapper = styled.div`
|
|||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Dropdown, Menu, Tooltip } from 'antd';
|
import { Dropdown, Menu, Tooltip } from 'antd';
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
import { IdentityWrapper } from './Identity.styled';
|
import { IdentityWrapper, ErrorNotice, InfoNotice } from './Identity.styled';
|
||||||
import { useIdentity } from './useIdentity.hook';
|
import { useIdentity } from './useIdentity.hook';
|
||||||
import { ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons';
|
import { InfoCircleOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
export function Identity({ openCards }) {
|
export function Identity({ openCards, cardUpdated }) {
|
||||||
|
|
||||||
const { state, actions } = useIdentity();
|
const { state, actions } = useIdentity();
|
||||||
|
|
||||||
@ -31,15 +31,25 @@ export function Identity({ openCards }) {
|
|||||||
<div class="label">
|
<div class="label">
|
||||||
<div class="name">{state.name}</div>
|
<div class="name">{state.name}</div>
|
||||||
<div class="handle">
|
<div class="handle">
|
||||||
<div class="alert">
|
<div class="notice">
|
||||||
{ state.disconnected && (
|
{ state.disconnected && (
|
||||||
<Tooltip placement="right" title="disconnected from server">
|
<Tooltip placement="right" title="disconnected from server">
|
||||||
<ExclamationCircleOutlined />
|
<ErrorNotice>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</ErrorNotice>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>{state.handle}</div>
|
<div>{state.handle}</div>
|
||||||
<div class="alert"></div>
|
<div class="notice">
|
||||||
|
{ cardUpdated && (
|
||||||
|
<Tooltip placement="right" title="contacts have updated">
|
||||||
|
<InfoNotice>
|
||||||
|
<InfoCircleOutlined />
|
||||||
|
</InfoNotice>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="drop">
|
<div class="drop">
|
||||||
|
@ -47,11 +47,21 @@ export const IdentityWrapper = styled.div`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
.alert {
|
.notice {
|
||||||
width: 24px;
|
width: 32px;
|
||||||
color: ${Colors.alert};
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const ErrorNotice = styled.div`
|
||||||
|
color: ${Colors.alert};
|
||||||
|
`
|
||||||
|
|
||||||
|
export const InfoNotice = styled.div`
|
||||||
|
color: ${Colors.primary};
|
||||||
|
`
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useContext, useState, useEffect, useRef } from 'react';
|
||||||
|
import { CardContext } from 'context/CardContext';
|
||||||
|
import { StoreContext } from 'context/StoreContext';
|
||||||
|
|
||||||
export function useSession() {
|
export function useSession() {
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
|
cardUpdated: false,
|
||||||
conversation: false,
|
conversation: false,
|
||||||
details: false,
|
details: false,
|
||||||
cards: false,
|
cards: false,
|
||||||
@ -10,18 +13,39 @@ export function useSession() {
|
|||||||
profile: false,
|
profile: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const card = useContext(CardContext);
|
||||||
|
const store = useContext(StoreContext);
|
||||||
|
|
||||||
|
const storeStatus = useRef(null);
|
||||||
|
const cardStatus = useRef(null);
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }));
|
setState((s) => ({ ...s, ...value }));
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
const contacts = Array.from(card.state.cards.values());
|
||||||
updateState({ cards: true });
|
|
||||||
}, 1000);
|
let updated;
|
||||||
setTimeout(() => {
|
contacts.forEach(contact => {
|
||||||
updateState({ contact: true });
|
if (!updated || updated < contact?.data?.cardDetail?.statusUpdated) {
|
||||||
}, 2000);
|
updated = contact?.data?.cardDetail?.statusUpdated;
|
||||||
}, []);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.cards) {
|
||||||
|
cardStatus.current = updated;
|
||||||
|
storeStatus.current = updated;
|
||||||
|
store.actions.setValue('cards:updated', updated);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState({ cardUpdated: cardStatus.current > storeStatus.current });
|
||||||
|
}, [card]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
storeStatus.current = store.actions.getValue('cards:updated');
|
||||||
|
updateState({ cardUpdated: cardStatus.current > storeStatus.current });
|
||||||
|
}, [store]);
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
closeDetails: () => {
|
closeDetails: () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user