mirror of
https://github.com/balzack/databag.git
synced 2025-04-24 02:25:26 +00:00
add sending text message
This commit is contained in:
parent
23728243df
commit
5417db7caf
@ -55,8 +55,8 @@
|
||||
|
||||
.add {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
height: 128px;
|
||||
border-top: 1px solid var(--mantine-color-text-7);
|
||||
width: calc(100% - 32px);
|
||||
margin-left: 16px;
|
||||
@ -112,4 +112,32 @@
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.message {
|
||||
width: calc(100% - 16px);
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.attach {
|
||||
padding: 4px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.send {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React, {useEffect, useRef, useCallback} from 'react'
|
||||
import React, {useState, useEffect, useRef, useCallback} from 'react'
|
||||
import { Focus } from 'databag-client-sdk'
|
||||
import classes from './Conversation.module.css'
|
||||
import { useConversation } from './useConversation.hook';
|
||||
import { IconX, IconSettings, IconHome, IconServer, IconShield, IconLock, IconExclamationCircle } from '@tabler/icons-react'
|
||||
import { Divider, Text, ActionIcon, Loader } from '@mantine/core'
|
||||
import { IconSend, IconTextSize, IconTextColor, IconVideo, IconFile, IconDisc, IconCamera, IconX, IconSettings, IconHome, IconServer, IconShield, IconLock, IconExclamationCircle } from '@tabler/icons-react'
|
||||
import { Divider, Text, Textarea, ActionIcon, Loader } from '@mantine/core'
|
||||
import { Message } from '../message/Message';
|
||||
import { modals } from '@mantine/modals'
|
||||
|
||||
const PAD_HEIGHT = (1024 - 64);
|
||||
const LOAD_DEBOUNCE = 1000;
|
||||
@ -21,6 +22,7 @@ export function Conversation() {
|
||||
const thread = useRef(null as HTMLDivElement | null);
|
||||
const scrollPos = useRef(0);
|
||||
const debounce = useRef(false);
|
||||
const [sending, setSending] = useState(false);
|
||||
const { state, actions } = useConversation();
|
||||
const attachImage = useRef({ click: ()=>{} } as HTMLInputElement);
|
||||
|
||||
@ -28,6 +30,33 @@ export function Conversation() {
|
||||
actions.add(e.target.files[0]);
|
||||
};
|
||||
|
||||
const sendMessage = async () => {
|
||||
if (!sending) {
|
||||
setSending(true);
|
||||
try {
|
||||
await actions.send();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
showError();
|
||||
}
|
||||
setSending(false);
|
||||
}
|
||||
}
|
||||
|
||||
const showError = () => {
|
||||
modals.openConfirmModal({
|
||||
title: state.strings.operationFailed,
|
||||
withCloseButton: true,
|
||||
overlayProps: {
|
||||
backgroundOpacity: 0.55,
|
||||
blur: 3,
|
||||
},
|
||||
children: <Text>{state.strings.tryAgain}</Text>,
|
||||
cancelProps: { display: 'none' },
|
||||
confirmProps: { display: 'none' },
|
||||
})
|
||||
}
|
||||
|
||||
const onScroll = () => {
|
||||
if (thread.current) {
|
||||
const { scrollHeight, clientHeight, scrollTop } = thread.current;
|
||||
@ -87,7 +116,7 @@ export function Conversation() {
|
||||
<IconExclamationCircle size={24} />
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.title} onClick={() => attachImage.current.click()}>
|
||||
<div className={classes.title}>
|
||||
{ state.detailSet && state.subject && (
|
||||
<Text className={classes.label}>{ state.subject }</Text>
|
||||
)}
|
||||
@ -125,6 +154,33 @@ export function Conversation() {
|
||||
</div>
|
||||
<div className={classes.add}>
|
||||
<input type='file' name="asset" accept="image/*" ref={attachImage} onChange={e => onSelectImage(e)} style={{display: 'none'}}/>
|
||||
<Textarea className={classes.message} placeholder={state.strings.newMessage} value={state.message} onChange={(event) => actions.setMessage(event.currentTarget.value)} disabled={!state.detail || state.detail.locked} />
|
||||
<div className={classes.controls}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconCamera />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconVideo />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconDisc />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconFile />
|
||||
</ActionIcon>
|
||||
<Divider size="sm" orientation="vertical" />
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconTextSize />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<IconTextColor />
|
||||
</ActionIcon>
|
||||
<div className={classes.send}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.message || !state.detail || state.detail.locked} onClick={sendMessage} loading={sending}>
|
||||
<IconSend />
|
||||
</ActionIcon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -29,6 +29,7 @@ export function useConversation() {
|
||||
subject: '',
|
||||
subjectNames: [],
|
||||
unknownContacts: 0,
|
||||
message: '',
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -108,6 +109,9 @@ export function useConversation() {
|
||||
close: () => {
|
||||
app.actions.clearFocus();
|
||||
},
|
||||
setMessage: (message: string) => {
|
||||
updateState({ message });
|
||||
},
|
||||
more: async () => {
|
||||
const focus = app.state.focus;
|
||||
if (focus) {
|
||||
@ -120,6 +124,16 @@ export function useConversation() {
|
||||
}
|
||||
}
|
||||
},
|
||||
send: async () => {
|
||||
const focus = app.state.focus;
|
||||
const sealed = state.detail?.sealed ? true : false;
|
||||
if (focus) {
|
||||
const subject = (assets: {assetId: string, appId: string}[]) => ({ text: state.message });
|
||||
const progress = (precent: number) => {};
|
||||
await focus.addTopic(sealed, sealed ? 'sealedtopic' : 'superbasictopic', subject, [], progress);
|
||||
updateState({ message: '' });
|
||||
}
|
||||
},
|
||||
add: async (file: File) => {
|
||||
const focus = app.state.focus;
|
||||
if (focus) {
|
||||
|
@ -201,7 +201,7 @@ export class FocusModule implements Focus {
|
||||
await this.removeLocalChannelTopic(id);
|
||||
}
|
||||
}
|
||||
this.storeView = { revision: nextRev, marker: delta.marker };
|
||||
this.storeView = { revision: nextRev, marker: this.storeView.marker };
|
||||
await this.setChannelTopicRevision(this.storeView);
|
||||
|
||||
if (this.nextRevision === nextRev) {
|
||||
@ -1117,9 +1117,9 @@ export class FocusModule implements Focus {
|
||||
}
|
||||
const { node, secure, token } = connection
|
||||
if (cardId) {
|
||||
return await getContactChannelTopics(node, secure, token, channelId, revision, (begin || !revision) ? BATCH_COUNT : null, begin, end);
|
||||
return await getContactChannelTopics(node, secure, token, channelId, revision, (end || !revision) ? BATCH_COUNT : null, begin, end);
|
||||
} else {
|
||||
return await getChannelTopics(node, secure, token, channelId, revision, (begin || !revision) ? BATCH_COUNT : null, begin, end);
|
||||
return await getChannelTopics(node, secure, token, channelId, revision, (end || !revision) ? BATCH_COUNT : null, begin, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user