mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
refactor add modal for webapp
This commit is contained in:
parent
064ec721af
commit
e405f46330
@ -1,5 +1,5 @@
|
|||||||
import { Modal, Input, List, Button, Switch } from 'antd';
|
import { Modal, Input, List, Button } from 'antd';
|
||||||
import { ChannelsWrapper, AddFooter } from './Channels.styled';
|
import { ChannelsWrapper } from './Channels.styled';
|
||||||
import { CommentOutlined, SearchOutlined } from '@ant-design/icons';
|
import { CommentOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { useChannels } from './useChannels.hook';
|
import { useChannels } from './useChannels.hook';
|
||||||
import { ChannelItem } from './channelItem/ChannelItem';
|
import { ChannelItem } from './channelItem/ChannelItem';
|
||||||
@ -9,34 +9,14 @@ export function Channels({ open, active }) {
|
|||||||
|
|
||||||
const { state, actions } = useChannels();
|
const { state, actions } = useChannels();
|
||||||
|
|
||||||
const addChannel = async () => {
|
const added = (id) => {
|
||||||
try {
|
actions.clearShowAdd();
|
||||||
const id = await actions.addChannel();
|
open(id);
|
||||||
actions.clearShowAdd();
|
|
||||||
open(id);
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
Modal.error({
|
|
||||||
title: 'Failed to Create Topic',
|
|
||||||
content: 'Please try again.',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFooter = (
|
const cancelled = () => {
|
||||||
<AddFooter>
|
actions.clearShowAdd();
|
||||||
<div class="seal">
|
}
|
||||||
{ state.sealable && (
|
|
||||||
<>
|
|
||||||
<Switch checked={state.seal} onChange={actions.setSeal} size="small" />
|
|
||||||
<span class="sealText">Sealed Channel</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<Button key="back" onClick={actions.clearShowAdd}>Cancel</Button>
|
|
||||||
<Button key="save" type="primary" loading={state.busy} onClick={addChannel}>Save</Button>
|
|
||||||
</AddFooter>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChannelsWrapper>
|
<ChannelsWrapper>
|
||||||
@ -69,9 +49,8 @@ export function Channels({ open, active }) {
|
|||||||
<Button type="primary" icon={<CommentOutlined />} onClick={actions.setShowAdd}>New Topic</Button>
|
<Button type="primary" icon={<CommentOutlined />} onClick={actions.setShowAdd}>New Topic</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Modal title="New Topic" centered visible={state.showAdd} footer={addFooter}
|
<Modal title="New Topic" centered visible={state.showAdd} footer={null}>
|
||||||
onCancel={actions.clearShowAdd}>
|
<AddChannel added={added} cancelled={cancelled} />
|
||||||
<AddChannel state={state} actions={actions} />
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</ChannelsWrapper>
|
</ChannelsWrapper>
|
||||||
);
|
);
|
||||||
|
@ -87,22 +87,3 @@ export const ChannelsWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AddFooter = styled.div`
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.seal {
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.sealText {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
|
@ -1,11 +1,30 @@
|
|||||||
import { Input } from 'antd';
|
import { Input, Space, Modal, Switch, Button } from 'antd';
|
||||||
import { AddChannelWrapper } from './AddChannel.styled';
|
import { AddChannelWrapper, AddFooter } from './AddChannel.styled';
|
||||||
import { CardSelect } from '../../cardSelect/CardSelect';
|
import { CardSelect } from '../../cardSelect/CardSelect';
|
||||||
|
import { useAddChannel } from './useAddChannel.hook';
|
||||||
|
|
||||||
export function AddChannel({ state, actions }) {
|
export function AddChannel({ added, cancelled }) {
|
||||||
|
|
||||||
|
const [ modal, modalContext ] = Modal.useModal();
|
||||||
|
const { state, actions } = useAddChannel();
|
||||||
|
|
||||||
|
const addChannel = async () => {
|
||||||
|
try {
|
||||||
|
const id = await actions.addChannel();
|
||||||
|
added(id);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
modal.error({
|
||||||
|
title: 'Failed to Create Topic',
|
||||||
|
content: 'Please try again.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AddChannelWrapper>
|
<AddChannelWrapper>
|
||||||
|
{ modalContext }
|
||||||
<Input placeholder="Subject (optional)" spellCheck="false" autocapitalize="word"
|
<Input placeholder="Subject (optional)" spellCheck="false" autocapitalize="word"
|
||||||
value={state.subject} onChange={(e) => actions.setSubject(e.target.value)} />
|
value={state.subject} onChange={(e) => actions.setSubject(e.target.value)} />
|
||||||
<div class="members">
|
<div class="members">
|
||||||
@ -23,6 +42,20 @@ export function AddChannel({ state, actions }) {
|
|||||||
unknown={0}
|
unknown={0}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<AddFooter>
|
||||||
|
<div class="seal">
|
||||||
|
{ state.sealable && (
|
||||||
|
<>
|
||||||
|
<Switch checked={state.seal} onChange={actions.setSeal} size="small" />
|
||||||
|
<span class="sealText">Sealed Channel</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Space>
|
||||||
|
<Button key="back" onClick={cancelled}>Cancel</Button>
|
||||||
|
<Button key="save" type="primary" loading={state.busy} onClick={addChannel}>Save</Button>
|
||||||
|
</Space>
|
||||||
|
</AddFooter>
|
||||||
</AddChannelWrapper>
|
</AddChannelWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,4 +23,23 @@ export const AddChannelWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const AddFooter = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 8px;
|
||||||
|
|
||||||
|
.seal {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.sealText {
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
105
net/web/src/session/channels/addChannel/useAddChannel.hook.js
Normal file
105
net/web/src/session/channels/addChannel/useAddChannel.hook.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { useContext, useState, useEffect } from 'react';
|
||||||
|
import { ChannelContext } from 'context/ChannelContext';
|
||||||
|
import { CardContext } from 'context/CardContext';
|
||||||
|
import { AccountContext } from 'context/AccountContext';
|
||||||
|
|
||||||
|
export function useAddChannel() {
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
sealable: false,
|
||||||
|
busy: false,
|
||||||
|
|
||||||
|
showAdd: false,
|
||||||
|
subject: null,
|
||||||
|
members: new Set(),
|
||||||
|
seal: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const card = useContext(CardContext);
|
||||||
|
const channel = useContext(ChannelContext);
|
||||||
|
const account = useContext(AccountContext);
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const { seal, sealKey } = account.state;
|
||||||
|
if (seal?.publicKey && sealKey?.public && sealKey?.private && seal.publicKey === sealKey.public) {
|
||||||
|
updateState({ seal: false, sealable: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateState({ seal: false, sealable: false });
|
||||||
|
}
|
||||||
|
}, [account.state]);
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
addChannel: async () => {
|
||||||
|
let conversation;
|
||||||
|
if (!state.busy) {
|
||||||
|
try {
|
||||||
|
updateState({ busy: true });
|
||||||
|
const cards = Array.from(state.members.values());
|
||||||
|
if (state.seal) {
|
||||||
|
const keys = [ account.state.sealKey.public ];
|
||||||
|
cards.forEach(id => {
|
||||||
|
keys.push(card.state.cards.get(id).data.cardProfile.seal);
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new Error("TODO");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conversation = await channel.actions.addChannel('superbasic', state.subject, cards);
|
||||||
|
}
|
||||||
|
updateState({ busy: false });
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
updateState({ busy: false });
|
||||||
|
throw new Error("failed to create new channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error("operation in progress");
|
||||||
|
}
|
||||||
|
return conversation.id;
|
||||||
|
},
|
||||||
|
setSeal: (seal) => {
|
||||||
|
if (seal) {
|
||||||
|
const cards = Array.from(state.members.values());
|
||||||
|
const members = new Set(state.members);
|
||||||
|
cards.forEach(id => {
|
||||||
|
if (!(card.state.cards.get(id)?.data?.cardProfile?.seal)) {
|
||||||
|
members.delete(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateState({ seal: true, members });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateState({ seal: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMember: (string) => {
|
||||||
|
const members = new Set(state.members);
|
||||||
|
if (members.has(string)) {
|
||||||
|
members.delete(string);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
members.add(string);
|
||||||
|
}
|
||||||
|
updateState({ members });
|
||||||
|
},
|
||||||
|
setSubject: (subject) => {
|
||||||
|
updateState({ subject });
|
||||||
|
},
|
||||||
|
cardFilter: (card) => {
|
||||||
|
if (state.seal) {
|
||||||
|
return card?.data?.cardDetail?.status === 'connected' && card?.data?.cardProfile?.seal;
|
||||||
|
}
|
||||||
|
return card?.data?.cardDetail?.status === 'connected';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return { state, actions };
|
||||||
|
}
|
||||||
|
|
@ -15,13 +15,7 @@ export function useChannels() {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
display: null,
|
display: null,
|
||||||
channels: [],
|
channels: [],
|
||||||
sealable: false,
|
|
||||||
busy: false,
|
|
||||||
|
|
||||||
showAdd: false,
|
showAdd: false,
|
||||||
subject: null,
|
|
||||||
members: new Set(),
|
|
||||||
seal: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const profile = useContext(ProfileContext);
|
const profile = useContext(ProfileContext);
|
||||||
@ -172,16 +166,6 @@ export function useChannels() {
|
|||||||
item.topicRevision = channelValue.data.topicRevision;
|
item.topicRevision = channelValue.data.topicRevision;
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const { seal, sealKey } = account.state;
|
|
||||||
if (seal?.publicKey && sealKey?.public && sealKey?.private && seal.publicKey === sealKey.public) {
|
|
||||||
updateState({ seal: false, sealable: true });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateState({ seal: false, sealable: false });
|
|
||||||
}
|
|
||||||
}, [account.state]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const login = store.state['login:timestamp'];
|
const login = store.state['login:timestamp'];
|
||||||
const conversations = new Map();
|
const conversations = new Map();
|
||||||
@ -278,78 +262,15 @@ export function useChannels() {
|
|||||||
}, [viewport]);
|
}, [viewport]);
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
addChannel: async () => {
|
|
||||||
let added;
|
|
||||||
if (!state.busy) {
|
|
||||||
try {
|
|
||||||
updateState({ busy: true });
|
|
||||||
const cards = Array.from(state.members.values());
|
|
||||||
if (state.seal) {
|
|
||||||
const keys = [ account.state.sealKey.public ];
|
|
||||||
cards.forEach(id => {
|
|
||||||
keys.push(card.state.cards.get(id).data.cardProfile.seal);
|
|
||||||
});
|
|
||||||
added = await channel.actions.addSealedChannel(cards, state.subject, keys);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
added = await channel.actions.addBasicChannel(cards, state.subject);
|
|
||||||
}
|
|
||||||
updateState({ busy: false });
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
updateState({ busy: false });
|
|
||||||
throw new Error("failed to create new channel");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error("operation in progress");
|
|
||||||
}
|
|
||||||
return added.id;
|
|
||||||
},
|
|
||||||
setSeal: (seal) => {
|
|
||||||
if (seal) {
|
|
||||||
const cards = Array.from(state.members.values());
|
|
||||||
const members = new Set(state.members);
|
|
||||||
cards.forEach(id => {
|
|
||||||
if (!(card.state.cards.get(id)?.data?.cardProfile?.seal)) {
|
|
||||||
members.delete(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateState({ seal: true, members });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateState({ seal: false });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFilter: (value) => {
|
onFilter: (value) => {
|
||||||
setFilter(value?.toUpperCase());
|
setFilter(value?.toUpperCase());
|
||||||
},
|
},
|
||||||
setShowAdd: () => {
|
setShowAdd: () => {
|
||||||
updateState({ showAdd: true, seal: false, members: new Set(), subject: null });
|
updateState({ showAdd: true });
|
||||||
},
|
},
|
||||||
clearShowAdd: () => {
|
clearShowAdd: () => {
|
||||||
updateState({ showAdd: false });
|
updateState({ showAdd: false });
|
||||||
},
|
},
|
||||||
onMember: (string) => {
|
|
||||||
const members = new Set(state.members);
|
|
||||||
if (members.has(string)) {
|
|
||||||
members.delete(string);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
members.add(string);
|
|
||||||
}
|
|
||||||
updateState({ members });
|
|
||||||
},
|
|
||||||
setSubject: (subject) => {
|
|
||||||
updateState({ subject });
|
|
||||||
},
|
|
||||||
cardFilter: (card) => {
|
|
||||||
if (state.seal) {
|
|
||||||
return card?.data?.cardDetail?.status === 'connected' && card?.data?.cardProfile?.seal;
|
|
||||||
}
|
|
||||||
return card?.data?.cardDetail?.status === 'connected';
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return { state, actions };
|
return { state, actions };
|
||||||
|
Loading…
Reference in New Issue
Block a user