Skip to content

Commit

Permalink
remove draft from chatstore
Browse files Browse the repository at this point in the history
and use it directly in the composer component
  • Loading branch information
Simon-Laux authored and Jikstra committed Nov 20, 2020
1 parent 88db921 commit 4bbdbe3
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 28 deletions.
7 changes: 0 additions & 7 deletions src/main/deltachat/chatlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,6 @@ export default class DCChatList extends SplitOut {
return rawChat.toJson()
}

async _getDraft(chatId: number):Promise<JsonMessage|null> {
const draft = this._dc.getDraft(chatId)
return draft ? draft.toJson() : null
}

async _getChatContactIds(chatId: number) {
return this._dc.getChatContacts(chatId)
}
Expand Down Expand Up @@ -176,7 +171,6 @@ export default class DCChatList extends SplitOut {
const contactIds = await this._getChatContactIds(chatId)

const contacts = await this._getChatContacts(contactIds)
const draft = await this._getDraft(chatId)
const muted = await this.isChatMuted(chatId)
const ephemeralTimer = this._dc.getChatEphemeralTimer(chatId)

Expand All @@ -200,7 +194,6 @@ export default class DCChatList extends SplitOut {
isGroup: isGroup,
isDeaddrop: chatId === C.DC_CHAT_ID_DEADDROP,
isDeviceChat: chat.isDeviceTalk,
draft,
selfInGroup: isGroup && contactIds.indexOf(C.DC_CONTACT_ID_SELF) !== -1,
muted,
ephemeralTimer,
Expand Down
6 changes: 6 additions & 0 deletions src/main/deltachat/messagelist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
MessageSearchResult,
MessageTypeAttachment,
msgStatus,
JsonMessage,
} from '../../shared/shared-types'
export default class DCMessageList extends SplitOut {
sendMessage(
Expand Down Expand Up @@ -74,6 +75,11 @@ export default class DCMessageList extends SplitOut {
return this._dc.getMessageInfo(msgId)
}

async getDraft(chatId: number): Promise<JsonMessage | null> {
const draft = this._dc.getDraft(chatId)
return draft ? draft.toJson() : null
}

setDraft(
chatId: number,
{
Expand Down
102 changes: 94 additions & 8 deletions src/renderer/components/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { useChatStore } from '../../stores/chat'
import { EmojiData, BaseEmoji } from 'emoji-mart'
import { replaceColonsSafe } from '../conversations/emoji'
import { JsonMessage } from '../../../shared/shared-types'
import { Qoute } from '../message/Message'
import { DeltaBackend } from '../../delta-remote'
const { remote } = window.electron_functions

const log = getLogger('renderer/composer')
Expand All @@ -33,18 +35,19 @@ const Composer = forwardRef<
isDisabled: boolean
disabledReason: string
chatId: number
draft: JsonMessage | null
setComposerSize: (size: number) => void
}
>((props, ref) => {
const { isDisabled, disabledReason, chatId, draft } = props
const { isDisabled, disabledReason, chatId } = props
const chatStoreDispatch = useChatStore()[1]
const [showEmojiPicker, setShowEmojiPicker] = useState(false)

const messageInputRef = useRef<ComposerMessageInput>()
const emojiAndStickerRef = useRef<HTMLDivElement>()
const pickerButtonRef = useRef()

const { draftState, updateDraftText } = useDraft(chatId, messageInputRef)

const sendMessage = () => {
const message = messageInputRef.current.getText()
if (message.match(/^\s*$/)) {
Expand Down Expand Up @@ -75,14 +78,12 @@ const Composer = forwardRef<
}

const onEmojiIconClick = () => setShowEmojiPicker(!showEmojiPicker)

const onEmojiSelect = (emoji: EmojiData) => {
log.debug(`EmojiPicker: Selected ${emoji.id}`)
messageInputRef.current.insertStringAtCursorPosition(
(emoji as BaseEmoji).native
)
}

useEffect(() => {
if (!showEmojiPicker) return
const onClick = ({
Expand Down Expand Up @@ -126,10 +127,10 @@ const Composer = forwardRef<
<div className='composer' ref={ref}>
<div className='upper-bar'>
<div className='quote-section'>
{hasQoute && (
{draftState.quotedText !== null && (
<Qoute
quotedText={message.msg.quotedText}
quotedMessageId={message.msg.quotedMessageId}
quotedText={draftState.quotedText}
quotedMessageId={draftState.quotedMessageId}
/>
)}
<button>X</button>
Expand All @@ -153,7 +154,7 @@ const Composer = forwardRef<
sendMessage={sendMessage}
setComposerSize={props.setComposerSize}
chatId={chatId}
draft={draft?.text || ''}
updateDraftText={updateDraftText}
/>
)}
</SettingsContext.Consumer>
Expand Down Expand Up @@ -183,3 +184,88 @@ const Composer = forwardRef<
})

export default Composer

type draftObject = { chatId: number } & Pick<
JsonMessage,
'text' | 'file' | 'quotedMessageId' | 'quotedText'
>

function useDraft(
chatId: number,
inputRef: React.MutableRefObject<ComposerMessageInput>
) {
const [startingText, setStartingText] = useState('')
const [draftState, setDraft] = useState<draftObject>({
chatId,
text: '',
file: null,
quotedMessageId: 0,
quotedText: null,
})
const draftRef = useRef<draftObject>()
draftRef.current = draftState

useEffect(() => {
log.debug('reloading chat because id changed', chatId)
//load
DeltaBackend.call('messageList.getDraft', chatId).then(newDraft => {
if (!newDraft) {
log.debug('no draft')
setDraft(_ => ({
chatId,
text: '',
file: null,
quotedMessageId: 0,
quotedText: null,
}))
inputRef.current?.setText('')
} else {
setDraft(old => ({
...old,
text: newDraft.text,
file: newDraft.file,
quotedMessageId: newDraft.quotedMessageId,
quotedText: newDraft.quotedText,
}))
inputRef.current?.setText(newDraft.text)
}
})
}, [chatId])

const saveDraft = async () => {
const draft = draftRef.current
const oldChatId = chatId
await DeltaBackend.call('messageList.setDraft', chatId, {
text: draft.text,
filename: draft.file,
qouteMessageId: draft.quotedMessageId,
})

if (oldChatId !== chatId) {
log.debug('switched chat no reloading of draft required')
return
}
const newDraft = await DeltaBackend.call('messageList.getDraft', chatId)
if (newDraft) {
setDraft(old => ({
...old,
file: newDraft.file,
quotedMessageId: newDraft.quotedMessageId,
quotedText: newDraft.quotedText,
}))
// don't load text to prevent bugging back
}
}

const updateDraftText = (text: string, InputChatId: number) => {
if (chatId !== InputChatId) {
log.warn("chat Id and InputChatId don't match, do nothing")
} else {
draftRef.current.text = text
// setDraft(state => ({ ...state, text }))
saveDraft()
}
}

return { draftState, startingText, updateDraftText }
}
24 changes: 18 additions & 6 deletions src/renderer/components/composer/ComposerMessageInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import debounce from 'debounce'
import { ActionEmitter, KeybindAction } from '../../keybindings'

type ComposerMessageInputProps = {
draft: string
chatId: number
setComposerSize: (size: number) => void
sendMessage: () => void
enterKeySends: boolean
updateDraftText: (text: string, InputChatId: number) => void
}

type ComposerMessageInputState = {
text: string
chatId: number
// error?:boolean|Error
loadingDraft: boolean
}

export default class ComposerMessageInput extends React.Component<
Expand All @@ -28,8 +29,9 @@ export default class ComposerMessageInput extends React.Component<
constructor(props: ComposerMessageInputProps) {
super(props)
this.state = {
text: props.draft ? props.draft : '',
text: '',
chatId: props.chatId,
loadingDraft: true,
}

this.composerSize = 48
Expand All @@ -43,7 +45,7 @@ export default class ComposerMessageInput extends React.Component<

this.saveDraft = debounce(() => {
const { text, chatId } = this.state
DeltaBackend.call('messageList.setDraft', chatId, {text})
this.props.updateDraftText(text, chatId)
}, 500)

this.textareaRef = React.createRef()
Expand All @@ -63,11 +65,16 @@ export default class ComposerMessageInput extends React.Component<
currentState: ComposerMessageInputState
) {
if (currentState.chatId !== props.chatId) {
return { chatId: props.chatId, text: props.draft ? props.draft : '' }
return { chatId: props.chatId, text: '', loadingDraft: true }
}
return null
}

setText(text: string) {
this.setState({ text })
this.setState({ loadingDraft: false })
}

setComposerSize(size: number) {
this.composerSize = size
this.props.setComposerSize(size)
Expand Down Expand Up @@ -102,14 +109,18 @@ export default class ComposerMessageInput extends React.Component<
if (prevState.chatId === this.state.chatId) {
this.resizeTextareaAndComposer()
if (prevState.text !== this.state.text) {
this.saveDraft()
if (!this.state.loadingDraft) {
this.saveDraft()
}
}
}
}

onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
this.setState({ text: e.target.value /*error: false*/ })
this.saveDraft()
if (!this.state.loadingDraft) {
this.saveDraft()
}
}

keyEventToAction(e: React.KeyboardEvent<HTMLTextAreaElement>) {
Expand Down Expand Up @@ -200,6 +211,7 @@ export default class ComposerMessageInput extends React.Component<
onKeyDown={this.onKeyDown}
onChange={this.onChange}
placeholder={window.static_translate('write_message_desktop')}
disabled={this.state.loadingDraft}
/>
)
}
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/components/message/MessageListAndComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export default function MessageListAndComposer({
cb: (yes: boolean) =>
yes &&
sanitizedFileList.forEach(({ path }) =>
DeltaBackend.call('messageList.sendMessage', chat.id, {filename: path})
DeltaBackend.call('messageList.sendMessage', chat.id, {
filename: path,
})
),
})
}
Expand Down Expand Up @@ -132,7 +134,6 @@ export default function MessageListAndComposer({
<Composer
ref={refComposer}
chatId={chat.id}
draft={chat.draft}
setComposerSize={setComposerSize.bind(this)}
isDisabled={disabled}
disabledReason={disabledReason}
Expand Down
5 changes: 5 additions & 0 deletions src/renderer/delta-remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
DeltaChatAccount,
DesktopSettings,
QrCodeResponse,
JsonMessage,
} from '../shared/shared-types'
import { MuteDuration } from '../shared/constants'
import { LocaleData } from '../shared/localize'
Expand Down Expand Up @@ -241,6 +242,10 @@ class DeltaRemote {
messageIds: number[]
): Promise<{ [key: number]: MessageType | { msg: null } }>
call(fnName: 'messageList.getMessageInfo', msgId: number): Promise<string>
call(
fnName: 'messageList.getDraft',
chatId: number
): Promise<JsonMessage | null>
call(
fnName: 'messageList.setDraft',
chatId: number,
Expand Down
12 changes: 8 additions & 4 deletions src/renderer/stores/chat.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ipcBackend, saveLastChatId } from '../ipc'
import { Store, useStore, Action } from './store'
import { JsonContact, FullChat, MessageType, JsonMessage } from '../../shared/shared-types'
import {
JsonContact,
FullChat,
MessageType,
JsonMessage,
} from '../../shared/shared-types'
import { DeltaBackend } from '../delta-remote'
import { runtime } from '../runtime'

Expand All @@ -27,7 +32,6 @@ class state implements FullChat {
freshMessageCounter = 0
isGroup = false
isDeaddrop = false
draft: JsonMessage | null = null

messageIds: number[] = []
messages: { [key: number]: MessageType | { msg: null } } = {}
Expand Down Expand Up @@ -236,8 +240,8 @@ chatStore.attachEffect(async ({ type, payload }, state) => {
payload[0],
{
text: payload[1],
filename:payload[2],
location: payload[3]
filename: payload[2],
location: payload[3],
}
)
chatStore.dispatch({
Expand Down
1 change: 0 additions & 1 deletion src/shared/shared-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ export interface FullChat {
isGroup: boolean
isDeaddrop: boolean
isDeviceChat: boolean
draft: JsonMessage | null
selfInGroup: boolean
muted: boolean
ephemeralTimer: number
Expand Down

0 comments on commit 4bbdbe3

Please sign in to comment.