mirror of
https://github.com/balzack/databag.git
synced 2025-04-22 17:45:18 +00:00
adding contact controls
This commit is contained in:
parent
37978e65b7
commit
6d9b9fbc15
@ -335,8 +335,9 @@ export function useCardContext() {
|
||||
setCardConnecting: async (cardId) => {
|
||||
return await setCardConnecting(access.current, cardId);
|
||||
},
|
||||
setCardConnected: async (cardId, token, view, article, channel, profile) => {
|
||||
return await setCardConnected(access.current, cardId, token, view, article, channel, profile);
|
||||
setCardConnected: async (cardId, token, rev) => {
|
||||
return await setCardConnected(access.current, cardId, token,
|
||||
rev.viewRevision, rev.articleRevision, rev.channelRevision, rev.profileRevision);
|
||||
},
|
||||
setCardConfirmed: async (cardId) => {
|
||||
return await setCardConfirmed(access.current, cardId);
|
||||
|
@ -72,7 +72,7 @@ export function Session() {
|
||||
)}
|
||||
{ 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 && (
|
||||
|
@ -15,11 +15,13 @@ export function Account({ closeAccount, openProfile }) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="link" onClick={openProfile}>
|
||||
<SettingOutlined />
|
||||
<div class="label">Update Profile</div>
|
||||
</div>
|
||||
<AccountAccess />
|
||||
<div class="bottom">
|
||||
<div class="link" onClick={openProfile}>
|
||||
<SettingOutlined />
|
||||
<div class="label">Update Profile</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AccountWrapper>
|
||||
);
|
||||
|
@ -41,18 +41,26 @@ export const AccountWrapper = styled.div`
|
||||
justify-content: center;
|
||||
padding-top: 32px;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
|
||||
.link {
|
||||
color: ${Colors.primary};
|
||||
padding-top: 16px;
|
||||
padding-bottom: 8px;
|
||||
.bottom {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 16px;
|
||||
|
||||
.label {
|
||||
padding-left: 8px;
|
||||
.link {
|
||||
color: ${Colors.primary};
|
||||
padding-top: 16px;
|
||||
padding-bottom: 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.label {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export const AccountAccessWrapper = styled.div`
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
|
@ -16,7 +16,7 @@ export function useCardItem(item) {
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ logo: card.actions.getImageUrl(item.id) });
|
||||
}, [card]);
|
||||
}, [card, item]);
|
||||
|
||||
const actions = {
|
||||
resync: async () => {
|
||||
|
@ -63,9 +63,9 @@ export function useCards() {
|
||||
return 0;
|
||||
}
|
||||
if (!aUpdated || (aUpdated < bUpdated)) {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { Modal } from 'antd';
|
||||
import { ContactWrapper } from './Contact.styled';
|
||||
import { useContact } from './useContact.hook';
|
||||
import { Logo } from 'logo/Logo';
|
||||
import { DatabaseOutlined, CloseOutlined, RightOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons';
|
||||
import { DatabaseOutlined, LoadingOutlined, CloseOutlined, RightOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons';
|
||||
|
||||
export function Contact({ close, guid, listing }) {
|
||||
|
||||
const { state, actions } = useContact(guid, listing);
|
||||
const { state, actions } = useContact(guid, listing, close);
|
||||
|
||||
const Image = (
|
||||
<div class="logo">
|
||||
@ -13,6 +14,19 @@ export function Contact({ close, guid, listing }) {
|
||||
</div>
|
||||
);
|
||||
|
||||
const updateContact = async (action) => {
|
||||
try {
|
||||
await action();
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
Modal.error({
|
||||
title: 'Failed to Update Contact',
|
||||
content: 'Please try again.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const Details = (
|
||||
<div class="details">
|
||||
<div class="name">
|
||||
@ -32,6 +46,49 @@ export function Contact({ close, guid, listing }) {
|
||||
<BookOutlined />
|
||||
<div class="data">{ state.description }</div>
|
||||
</div>
|
||||
|
||||
{ state.status === 'connected' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.disconnect)}>Disconnect</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.disconnectRemove)}>Delete Contact</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ state.status === 'pending' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.saveContact)}>Save Contact</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.saveConnect)}>Save and Accept</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.remove)}>Ignore Request</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ state.status === 'requested' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.saveConnect)}>Accept Connection</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.disconnect)}>Ignore Request</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ state.status === 'connecting' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.disconnect)}>Cancel Request</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.disconnectRemove)}>Delete Contact</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ state.status === 'confirmed' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.connect)}>Request Connection</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.remove)}>Delete Contact</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ state.status === 'disconnected' && (
|
||||
<div class="controls">
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.saveContact)}>Save Contact</div>
|
||||
<div class={ state.buttonStatus } onClick={() => updateContact(actions.saveConnect)}>Save and Request</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -85,7 +85,7 @@ export const ContactWrapper = styled.div`
|
||||
.data {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,5 +168,40 @@ export const ContactWrapper = styled.div`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
|
||||
.button {
|
||||
width: 192px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
color: ${Colors.white};
|
||||
background-color: ${Colors.primary};
|
||||
}
|
||||
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.idle {
|
||||
cursor: pointer;
|
||||
opactiy: 0;
|
||||
}
|
||||
|
||||
.busy {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
|
@ -3,18 +3,23 @@ import { CardContext } from 'context/CardContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { ViewportContext } from 'context/ViewportContext';
|
||||
import { getListingImageUrl } from 'api/getListingImageUrl';
|
||||
import { getListingMessage } from 'api/getListingMessage';
|
||||
|
||||
export function useContact(guid, listing) {
|
||||
export function useContact(guid, listing, close) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
logo: null,
|
||||
name: null,
|
||||
cardId: null,
|
||||
location: null,
|
||||
description: null,
|
||||
handle: null,
|
||||
node: null,
|
||||
removed: false,
|
||||
init: false,
|
||||
status: null,
|
||||
busy: false,
|
||||
buttonStatus: 'button idle',
|
||||
});
|
||||
|
||||
const card = useContext(CardContext);
|
||||
@ -26,36 +31,125 @@ export function useContact(guid, listing) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let logo, name, location, description, handle, node;
|
||||
let logo, name, location, description, handle, node, status, cardId;
|
||||
let contact = card.actions.getCardByGuid(guid);
|
||||
if (contact) {
|
||||
let cardProfile = contact?.data?.cardProfile;
|
||||
let cardDetail = contact?.data?.cardDetail;
|
||||
cardId = contact.id;
|
||||
handle = cardProfile.handle;
|
||||
node = cardProfile.node;
|
||||
logo = card.actions.getImageUrl(contact.id);
|
||||
name = cardProfile.name;
|
||||
location = cardProfile.location;
|
||||
description = cardProfile.description;
|
||||
status = cardDetail.status;
|
||||
}
|
||||
else if (listing) {
|
||||
handle = listing.handle;
|
||||
cardId = null;
|
||||
node = listing.node;
|
||||
logo = listing.imageSet ? getListingImageUrl(listing.node, listing.guid) : null;
|
||||
name = listing.name;
|
||||
location = listing.location;
|
||||
description = listing.description;
|
||||
status = 'disconnected';
|
||||
}
|
||||
else {
|
||||
updateState({ removed: true });
|
||||
}
|
||||
updateState({ init: true, logo, name, location, description, handle, node });
|
||||
updateState({ init: true, logo, name, location, description, handle, node, status, cardId });
|
||||
}, [card, guid, listing]);
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ display: viewport.state.display });
|
||||
}, [viewport]);
|
||||
|
||||
const applyAction = async (action) => {
|
||||
if (!state.busy) {
|
||||
try {
|
||||
updateState({ busy: true, buttonStatus: 'button busy', action });
|
||||
await action();
|
||||
updateState({ busy: false, buttonStatus: 'button idle' });
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false, buttonStatus: 'button idle' });
|
||||
throw new Error("failed to update contact");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("operation in progress");
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
saveContact: async () => {
|
||||
await applyAction(async () => {
|
||||
let message = await getListingMessage(state.node, guid);
|
||||
await card.actions.addCard(message);
|
||||
});
|
||||
},
|
||||
saveConnect: async () => {
|
||||
await applyAction(async () => {
|
||||
let profile = await getListingMessage(state.node, guid);
|
||||
let added = await card.actions.addCard(profile);
|
||||
await card.actions.setCardConnecting(added.id);
|
||||
let open = await card.actions.getCardOpenMessage(added.id);
|
||||
let contact = await card.actions.setCardOpenMessage(state.node, open);
|
||||
if (contact.status === 'connected') {
|
||||
await card.actions.setCardConnected(added.id, contact.token, contact);
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteContact: async () => {
|
||||
await applyAction(async () => {
|
||||
await card.actions.removeCard(state.cardId);
|
||||
close();
|
||||
});
|
||||
},
|
||||
connect: async () => {
|
||||
await applyAction(async () => {
|
||||
await card.actions.setCardConnecting(state.cardId);
|
||||
let message = await card.actions.getCardOpenMessage(state.cardId);
|
||||
let contact = await card.actions.setCardOpenMessage(state.node, message);
|
||||
if (contact.status === 'connected') {
|
||||
await card.actions.setCardConnected(state.cardId, contact.token, contact);
|
||||
}
|
||||
});
|
||||
},
|
||||
disconnect: async () => {
|
||||
await applyAction(async () => {
|
||||
await card.actions.setCardConfirmed(state.cardId);
|
||||
try {
|
||||
let message = await card.actions.getCardCloseMessage(state.cardId);
|
||||
await card.actions.setCardCloseMessage(state.node, message);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
disconnectRemove: async () => {
|
||||
await applyAction(async () => {
|
||||
await card.actions.setCardConfirmed(state.cardId);
|
||||
try {
|
||||
let message = await card.actions.getCardCloseMessage(state.cardId);
|
||||
await card.actions.setCardCloseMessage(state.node, message);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
await card.actions.removeCard(state.cardId);
|
||||
close();
|
||||
});
|
||||
},
|
||||
remove: async () => {
|
||||
await applyAction(async () => {
|
||||
await card.actions.removeCard(state.cardId);
|
||||
close();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
|
Loading…
x
Reference in New Issue
Block a user