diff --git a/app/client/web/src/details/Details.module.css b/app/client/web/src/details/Details.module.css index 5cb2d5a0..de301b6c 100644 --- a/app/client/web/src/details/Details.module.css +++ b/app/client/web/src/details/Details.module.css @@ -175,7 +175,7 @@ .cards { min-width: 0; width: 100%; - flex-shink: 1; + flex-shrink: 1; overflow: auto; } } diff --git a/app/client/web/src/details/Details.tsx b/app/client/web/src/details/Details.tsx index 97f8ed04..c08e50f4 100644 --- a/app/client/web/src/details/Details.tsx +++ b/app/client/web/src/details/Details.tsx @@ -4,21 +4,46 @@ import classes from './Details.module.css' import { IconUserCog, IconEyeOff, IconAlertHexagon, IconMessageX, IconLogout2, IconHome, IconServer, IconShield, IconShieldOff, IconCalendarClock, IconExclamationCircle, IconX, IconEdit, IconDeviceFloppy, IconArrowBack, IconLabel } from '@tabler/icons-react' import { Divider, Text, Textarea, Image, TextInput, ActionIcon } from '@mantine/core' import { Card } from '../card/Card'; +import { modals } from '@mantine/modals' export function Details({ close }: { close?: () => void }) { const { state, actions } = useDetails() + const [saving, setSaving] = useState(false); const undo = () => { actions.undoSubject(); } - const save = () => { - console.log('save subject'); + const save = async () => { + if (!saving) { + setSaving(true); + try { + await actions.saveSubject(); + } catch (err) { + console.log(err); + showError(); + } + setSaving(false); + } + } + + const showError = () => { + modals.openConfirmModal({ + title: state.strings.operationFailed, + withCloseButton: true, + overlayProps: { + backgroundOpacity: 0.55, + blur: 3, + }, + children: {state.strings.tryAgain}, + cancelProps: { display: 'none' }, + confirmProps: { display: 'none' }, + }) } const cards = state.channelCards.map((card, index) => ( - + )) return ( @@ -42,7 +67,7 @@ export function Details({ close }: { close?: () => void }) { )} { state.editSubject != state.subject && ( - + )} } /> @@ -135,9 +160,13 @@ export function Details({ close }: { close?: () => void }) {
{ state.hostCard && ( - ]} /> )} + { state.profile && ( + ] : []} /> + )} { cards } { state.unknownContacts > 0 && ( { state.strings.unknown }: {state.unknownContacts} diff --git a/app/client/web/src/details/useDetails.hook.ts b/app/client/web/src/details/useDetails.hook.ts index 9c11feb9..467d25e3 100644 --- a/app/client/web/src/details/useDetails.hook.ts +++ b/app/client/web/src/details/useDetails.hook.ts @@ -8,6 +8,9 @@ export function useDetails() { const display = useContext(DisplayContext) as ContextType const app = useContext(AppContext) as ContextType const [state, setState] = useState({ + cardId: null as null | string, + channelId: '', + detail: undefined as undefined | FocusDetail, access: false, host: false, sealed: false, @@ -18,10 +21,11 @@ export function useDetails() { subject: '', editSubject: '', created: '', - profile: null as null | Porfile, - cards: [] as Card[], + profile: null as null | Profile, + cards: new Map(), hostCard: null as null | Card, channelCards: [] as Card[], + unknownContacts: 0, }) // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -89,16 +93,16 @@ export function useDetails() { updateState({ profile }); } const setDetail = (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => { - const detail = focused ? focused.detail : null; const cardId = focused.cardId; + const channelId = focused.channelId; const access = Boolean(detail); const sealed = detail?.sealed; const locked = detail?.locked; const host = cardId == null; const subject = detail?.data?.subject ? detail.data.subject : ''; const created = detail?.created ? getTimestamp(detail.created) : ''; - updateState({ detail, editSubject: subject, subject, cardId, access, sealed, locked, host, created }); + updateState({ detail, editSubject: subject, subject, channelId, cardId, access, sealed, locked, host, created }); } focus.addDetailListener(setDetail); contact.addCardListener(setCards); @@ -118,8 +122,9 @@ export function useDetails() { undoSubject: () => { updateState({ editSubject: state.subject }); }, - saveSubject: () => { - console.log('saving subject'); + saveSubject: async () => { + const content = app.state.session.getContent() + await content.setChannelSubject(state.channelId, state.sealed ? 'sealed' : 'superbasic', { subject: state.editSubject }); }, } diff --git a/app/sdk/src/net/setChannelSubject.ts b/app/sdk/src/net/setChannelSubject.ts index 2ccae24e..24e46e00 100644 --- a/app/sdk/src/net/setChannelSubject.ts +++ b/app/sdk/src/net/setChannelSubject.ts @@ -5,7 +5,7 @@ export async function setChannelSubject(node: string, secure: boolean, token: st const endpoint = `http${secure ? 's' : ''}://${node}/content/channels/${channelId}/subject?agent=${token}`; const { status } = await fetchWithTimeout(endpoint, { method: 'PUT', - body: JSON.stringify(data), + body: JSON.stringify(params), }); checkResponse(status); }