mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
rendering contact profile
This commit is contained in:
parent
8401a2295a
commit
bdf4df5844
@ -27,6 +27,7 @@ export function useViewportContext() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(handleResize, 1000); //cludge for my mobile browser
|
||||
handleResize();
|
||||
window.addEventListener('resize', handleResize);
|
||||
window.addEventListener('orientationchange', handleResize);
|
||||
|
@ -3,7 +3,6 @@ import { Drawer } from 'antd';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { SessionWrapper } from './Session.styled';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { ViewportContext } from 'context/ViewportContext';
|
||||
import { useSession } from './useSession.hook';
|
||||
import { Conversation } from './conversation/Conversation';
|
||||
import { Details } from './details/Details';
|
||||
@ -21,7 +20,6 @@ export function Session() {
|
||||
|
||||
const { state, actions } = useSession();
|
||||
const app = useContext(AppContext);
|
||||
const viewport = useContext(ViewportContext);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
@ -60,7 +58,7 @@ console.log(state);
|
||||
|
||||
return (
|
||||
<SessionWrapper>
|
||||
{ (viewport.state.display === 'xlarge') && (
|
||||
{ (state.display === 'xlarge') && (
|
||||
<div class="desktop-layout noselect">
|
||||
<div class="left">
|
||||
<Identity openAccount={openAccount} openCards={openCards} cardUpdated={state.cardUpdated} />
|
||||
@ -95,8 +93,9 @@ console.log(state);
|
||||
{ state.cards && (
|
||||
<div class="reframe">
|
||||
<Cards closeCards={closeCards} openContact={actions.openContact} openListing={actions.openListing} />
|
||||
<Drawer title="Basic Drawer" placement="bottom" closable={false} visible={state.listing}
|
||||
onClose={actions.closeListing} getContainer={false} height={'80%'} style={{ position: 'absolute', overflow: 'hidden' }}>
|
||||
<Drawer bodyStyle={{ padding: 0 }} placement="bottom" closable={false} visible={state.listing}
|
||||
onClose={actions.closeListing} getContainer={false} height={'80%'}
|
||||
style={{ position: 'absolute', overflow: 'hidden' }}>
|
||||
<Listing openContact={actions.openContact} />
|
||||
</Drawer>
|
||||
</div>
|
||||
@ -109,7 +108,7 @@ console.log(state);
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ (viewport.state.display === 'large' || viewport.state.display === 'medium') && (
|
||||
{ (state.display === 'large' || state.display === 'medium') && (
|
||||
<div class="tablet-layout noselect">
|
||||
<div class="left">
|
||||
<Identity openAccount={actions.openProfile} openCards={actions.openCards} cardUpdated={state.cardUpdated} />
|
||||
@ -129,17 +128,18 @@ console.log(state);
|
||||
<Details cardId={state.cardId} conversationId={state.conversationId} />
|
||||
)}
|
||||
</Drawer>
|
||||
<Drawer bodyStyle={{ padding: 0 }} width={'33%'} closable={false} onClose={actions.closeCards} visible={state.cards} zIndex={20} push={state.contact}>
|
||||
<Drawer bodyStyle={{ padding: 0 }} width={'33%'} closable={false} onClose={closeCards} visible={state.cards} zIndex={20} push={state.contact}>
|
||||
{ state.cards && (
|
||||
<Cards closeCards={closeCards} openContact={actions.openContact} openListing={actions.openListing} />
|
||||
)}
|
||||
<Drawer title="Basic Drawer" placement="bottom" closable={false} visible={state.listing}
|
||||
onClose={actions.closeListing} getContainer={false} height={'80%'} style={{ overflow: 'hidden', position: 'absolute' }}>
|
||||
<Drawer bodyStyle={{ padding: 0 }} placement="bottom" closable={false} visible={state.listing}
|
||||
onClose={actions.closeListing} getContainer={false} height={'80%'}
|
||||
style={{ overflow: 'hidden', position: 'absolute' }}>
|
||||
<Listing openContact={actions.openContact} />
|
||||
</Drawer>
|
||||
<Drawer bodyStyle={{ padding: 0 }} width={'33%'} closable={false} onClose={actions.closeContact} visible={state.contact} zIndex={30}>
|
||||
{ state.contact && (
|
||||
<Contact close={actions.closeContact} guid={state.contactGuid} node={state.contactNode} />
|
||||
<Contact close={actions.closeContact} guid={state.contactGuid} listing={state.contactListing} />
|
||||
)}
|
||||
</Drawer>
|
||||
</Drawer>
|
||||
@ -151,7 +151,7 @@ console.log(state);
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ (viewport.state.display === 'small') && (
|
||||
{ (state.display === 'small') && (
|
||||
<div class="mobile-layout noselect">
|
||||
<div class="top">
|
||||
<div class="reframe">
|
||||
@ -179,7 +179,7 @@ console.log(state);
|
||||
)}
|
||||
{ state.contact && (
|
||||
<div class="reframe">
|
||||
<Contact close={actions.closeContact} guid={state.contactGuid} node={state.contactNode} />
|
||||
<Contact close={actions.closeContact} guid={state.contactGuid} listing={state.contactListing} />
|
||||
</div>
|
||||
)}
|
||||
{ (state.profile || state.account) && (
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Drawer, Input, List } from 'antd';
|
||||
import { CardsWrapper } from './Cards.styled';
|
||||
import { SortAscendingOutlined, DoubleRightOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { SortAscendingOutlined, UpOutlined, DoubleRightOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { useCards } from './useCards.hook';
|
||||
import { CardItem } from './cardItem/CardItem';
|
||||
|
||||
@ -50,8 +50,8 @@ export function Cards({ closeCards, openContact, openListing }) {
|
||||
{ state.display !== 'small' && (
|
||||
<div class="bar">
|
||||
<div class="add" onClick={openListing}>
|
||||
<UserOutlined />
|
||||
<div class="label">New Contact</div>
|
||||
<UpOutlined />
|
||||
<div class="label">Find New Contact</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
@ -86,8 +86,7 @@ export const CardsWrapper = styled.div`
|
||||
.add {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: ${Colors.primary};
|
||||
color: ${Colors.white};
|
||||
color: ${Colors.primary};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 16px;
|
||||
|
@ -21,7 +21,7 @@ export function CardItem({ item, open }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<CardItemWrapper onClick={() => open(profile.guid, profile.node)}>
|
||||
<CardItemWrapper onClick={() => open(profile.guid)}>
|
||||
<Logo url={state.logo} width={32} height={32} radius={8} />
|
||||
<div class="details">
|
||||
<div class="name">{ profile?.name }</div>
|
||||
|
@ -1,6 +1,63 @@
|
||||
import { ContactWrapper } from './Contact.styled';
|
||||
import { useContact } from './useContact.hook';
|
||||
import { Logo } from 'logo/Logo';
|
||||
import { RightOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons';
|
||||
|
||||
export function Contact({ close, guid, node }) {
|
||||
return <ContactWrapper />;
|
||||
export function Contact({ close, guid, listing }) {
|
||||
|
||||
const { state, actions } = useContact(guid, listing);
|
||||
|
||||
const Image = (
|
||||
<div class="logo">
|
||||
<Logo url={state.logo} width={'100%'} radius={8} />
|
||||
</div>
|
||||
);
|
||||
|
||||
const Details = (
|
||||
<div class="details">
|
||||
<div class="name">
|
||||
<div class="data">{ state.name }</div>
|
||||
</div>
|
||||
<div class="location">
|
||||
<EnvironmentOutlined />
|
||||
<div class="data">{ state.location }</div>
|
||||
</div>
|
||||
<div class="description">
|
||||
<BookOutlined />
|
||||
<div class="data">{ state.description }</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<ContactWrapper>
|
||||
{ state.init && state.display === 'xlarge' && (
|
||||
<>
|
||||
<div class="header">
|
||||
<div class="handle">{ state.handle }</div>
|
||||
<div class="close" onClick={close}>
|
||||
<RightOutlined />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
{ Image }
|
||||
{ Details }
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{ state.init && state.display !== 'xlarge' && (
|
||||
<div class="view">
|
||||
<div class="title">{ state.handle }</div>
|
||||
<div class="section">Contact Profile</div>
|
||||
<div class="controls">
|
||||
{ Image }
|
||||
{ Details }
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</ContactWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7,5 +7,115 @@ export const ContactWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: ${Colors.profileForm};
|
||||
|
||||
|
||||
.header {
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
height: 48px;
|
||||
border-bottom: 1px solid ${Colors.profileDivider};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
.handle {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
flex-grow: 1;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-size: 16px;
|
||||
color: ${Colors.primary};
|
||||
cursor: pointer;
|
||||
padding-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding-top: 32px;
|
||||
|
||||
.logo {
|
||||
position: relative;
|
||||
width: 20vw;
|
||||
margin-right: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.section {
|
||||
width: 100%;
|
||||
color: ${Colors.grey};
|
||||
padding-top: 16px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.name {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.data {
|
||||
padding-right: 8px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.location {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.data {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.data {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
|
70
net/web/src/session/contact/useContact.hook.js
Normal file
70
net/web/src/session/contact/useContact.hook.js
Normal file
@ -0,0 +1,70 @@
|
||||
import { useContext, useState, useEffect } from 'react';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { ViewportContext } from 'context/ViewportContext';
|
||||
import { getListingImageUrl } from 'api/getListingImageUrl';
|
||||
|
||||
export function useContact(guid, listing) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
logo: null,
|
||||
name: null,
|
||||
location: null,
|
||||
description: null,
|
||||
handle: null,
|
||||
removed: false,
|
||||
init: false,
|
||||
});
|
||||
|
||||
const card = useContext(CardContext);
|
||||
const profile = useContext(ProfileContext);
|
||||
const viewport = useContext(ViewportContext);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let logo, name, location, description, handle;
|
||||
let contact = card.actions.getCardByGuid(guid);
|
||||
if (contact) {
|
||||
let cardProfile = contact?.data?.cardProfile;
|
||||
if (cardProfile.node != profile.state.profile.node) {
|
||||
handle = cardProfile.handle + '@' + cardProfile.node;
|
||||
}
|
||||
else {
|
||||
handle = cardProfile.handle;
|
||||
}
|
||||
logo = card.actions.getImageUrl(contact.id);
|
||||
name = cardProfile.name;
|
||||
location = cardProfile.location;
|
||||
description = cardProfile.description;
|
||||
}
|
||||
else if (listing) {
|
||||
if (listing.node != profile.state.profile.node) {
|
||||
handle = listing.handle + '@' + listing.node;
|
||||
}
|
||||
else {
|
||||
handle = listing.handle;
|
||||
}
|
||||
logo = listing.imageSet ? getListingImageUrl(listing.node, listing.guid) : null;
|
||||
name = listing.name;
|
||||
location = listing.location;
|
||||
description = listing.description;
|
||||
}
|
||||
else {
|
||||
updateState({ removed: true });
|
||||
}
|
||||
updateState({ init: true, logo, name, location, description, handle });
|
||||
}, [card, guid, listing]);
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ display: viewport.state.display });
|
||||
}, [viewport]);
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ export const IdentityWrapper = styled.div`
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 16px;
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
|
@ -1,4 +1,45 @@
|
||||
import { Modal, Button, Drawer, Input, List } from 'antd';
|
||||
import { ListingWrapper } from './Listing.styled';
|
||||
import { DatabaseOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { useListing } from './useListing.hook';
|
||||
import { ListingItem } from './listingItem/ListingItem';
|
||||
|
||||
export function Listing({ openContact }) {
|
||||
return <div onClick={() => openContact('asdf', 'qwer')}>LISTING</div>
|
||||
|
||||
const { state, actions } = useListing();
|
||||
|
||||
const getListing = async () => {
|
||||
try {
|
||||
await actions.getListing();
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
Modal.error({
|
||||
title: 'Communication Error',
|
||||
content: 'Please confirm your server name.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ListingWrapper>
|
||||
<div class="search">
|
||||
<div class="node">
|
||||
<Input bordered={false} allowClear={true} placeholder="Server"
|
||||
prefix={<DatabaseOutlined />} value={state.node} spellCheck="false"
|
||||
disabled={state.disabled} onChange={(e) => actions.onNode(e.target.value)} />
|
||||
</div>
|
||||
<div class="inline">
|
||||
<Button type="text" icon={<SearchOutlined />} loading={state.busy} onClick={getListing}></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view">
|
||||
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.contacts} gutter="0"
|
||||
renderItem={item => (
|
||||
<ListingItem item={item} node={state.node} open={openContact} />
|
||||
)} />
|
||||
</div>
|
||||
</ListingWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
45
net/web/src/session/listing/Listing.styled.js
Normal file
45
net/web/src/session/listing/Listing.styled.js
Normal file
@ -0,0 +1,45 @@
|
||||
import styled from 'styled-components';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export const ListingWrapper = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: ${Colors.card};
|
||||
|
||||
.view {
|
||||
min-height: 0;
|
||||
overflow: scroll;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search {
|
||||
border-bottom: 1px solid ${Colors.divider};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 48px;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.node {
|
||||
border: 1px solid ${Colors.divider};
|
||||
background-color: ${Colors.white};
|
||||
border-radius: 8px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.inline {
|
||||
padding-left: 8px;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
`;
|
18
net/web/src/session/listing/listingItem/ListingItem.jsx
Normal file
18
net/web/src/session/listing/listingItem/ListingItem.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { ListingItemWrapper } from './ListingItem.styled';
|
||||
import { useListingItem } from './useListingItem.hook';
|
||||
import { Logo } from 'logo/Logo';
|
||||
|
||||
export function ListingItem({ item, node, open }) {
|
||||
|
||||
const { state, actions } = useListingItem(node, item);
|
||||
|
||||
return (
|
||||
<ListingItemWrapper onClick={() => open(item.guid, item)}>
|
||||
<Logo url={state.logo} width={32} height={32} radius={8} />
|
||||
<div class="details">
|
||||
<div class="name">{ state.name }</div>
|
||||
<div class="handle">{ state.handle }</div>
|
||||
</div>
|
||||
</ListingItemWrapper>
|
||||
);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import styled from 'styled-components';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export const ListingItemWrapper = styled.div`
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid ${Colors.divider};
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
|
||||
&:hover {
|
||||
background-color: ${Colors.formHover};
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.details {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 16px;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.handle {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
@ -0,0 +1,21 @@
|
||||
import { useContext, useState, useEffect } from 'react';
|
||||
import { getListingImageUrl } from 'api/getListingImageUrl';
|
||||
|
||||
export function useListingItem(server, item) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
logo: item.imageSet ? getListingImageUrl(server, item.guid) : null,
|
||||
name: item.name,
|
||||
handle: item.handle,
|
||||
});
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
54
net/web/src/session/listing/useListing.hook.js
Normal file
54
net/web/src/session/listing/useListing.hook.js
Normal file
@ -0,0 +1,54 @@
|
||||
import { useContext, useState, useEffect } from 'react';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { getListing } from 'api/getListing';
|
||||
|
||||
export function useListing() {
|
||||
|
||||
const [state, setState] = useState({
|
||||
contacts: [],
|
||||
node: null,
|
||||
busy: false,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
const profile = useContext(ProfileContext);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const actions = {
|
||||
onNode: (value) => {
|
||||
updateState({ node: value });
|
||||
},
|
||||
getListing: async () => {
|
||||
updateState({ busy: true });
|
||||
try {
|
||||
let contacts = await getListing(state.node);
|
||||
console.log(contacts);
|
||||
let filtered = contacts.filter(contact => (contact.guid !== profile.state.profile.guid));
|
||||
console.log(filtered);
|
||||
let sorted = filtered.sort((a, b) => {
|
||||
if (a?.name < b?.name) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
console.log(sorted);
|
||||
updateState({ busy: false, contacts: sorted });
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false });
|
||||
throw new Error("failed to list contacts");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let node = profile?.state?.profile?.node;
|
||||
updateState({ disabled: node == null || node == '', node });
|
||||
}, [profile]);
|
||||
|
||||
return { state, actions };
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { useContext, useState, useEffect, useRef } from 'react';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
import { StoreContext } from 'context/StoreContext';
|
||||
import { ViewportContext } from 'context/ViewportContext';
|
||||
|
||||
export function useSession() {
|
||||
|
||||
const [state, setState] = useState({
|
||||
cardUpdated: false,
|
||||
contactGuid: null,
|
||||
contactNode: null,
|
||||
listingNode: null,
|
||||
contactListing: null,
|
||||
conversation: false,
|
||||
details: false,
|
||||
cards: false,
|
||||
@ -20,6 +20,7 @@ export function useSession() {
|
||||
|
||||
const card = useContext(CardContext);
|
||||
const store = useContext(StoreContext);
|
||||
const viewport = useContext(ViewportContext);
|
||||
|
||||
const storeStatus = useRef(null);
|
||||
const cardStatus = useRef(null);
|
||||
@ -28,6 +29,10 @@ export function useSession() {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ display: viewport.state.display });
|
||||
}, [viewport]);
|
||||
|
||||
useEffect(() => {
|
||||
const contacts = Array.from(card.state.cards.values());
|
||||
|
||||
@ -62,14 +67,14 @@ export function useSession() {
|
||||
closeCards: () => {
|
||||
updateState({ cards: false });
|
||||
},
|
||||
openListing: (listingNode) => {
|
||||
updateState({ listing: true, listingNode });
|
||||
openListing: () => {
|
||||
updateState({ listing: true });
|
||||
},
|
||||
closeListing: () => {
|
||||
updateState({ listing: false });
|
||||
},
|
||||
openContact: (contactGuid, contactNode) => {
|
||||
updateState({ contact: true, contactGuid, contactNode });
|
||||
openContact: (contactGuid, contactListing) => {
|
||||
updateState({ contact: true, contactGuid, contactListing });
|
||||
},
|
||||
closeContact: () => {
|
||||
updateState({ contact: false });
|
||||
|
Loading…
Reference in New Issue
Block a user