Skip to content

Commit 91522de

Browse files
committed
Refactor useMessageList usage
1 parent 516a42c commit 91522de

File tree

4 files changed

+53
-67
lines changed

4 files changed

+53
-67
lines changed

packages/frontend/src/components/message/MessageList.tsx

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,33 +128,35 @@ type Props = {
128128
chat: T.FullChat
129129
refComposer: any
130130
messageListStore: MessageListStore
131+
messageListState: ReturnType<MessageListStore['getState']>
132+
fetchMoreBottom: () => void
133+
fetchMoreTop: () => void
131134
}
132135

133136
export default function MessageList({
134137
accountId,
135138
chat,
136139
refComposer,
137140
messageListStore,
141+
messageListState,
142+
fetchMoreBottom,
143+
fetchMoreTop,
138144
}: Props) {
139145
const {
140-
store: {
141-
scheduler,
142-
effect: { jumpToMessage, loadMissingMessages },
143-
reducer: { unlockScroll, clearJumpStack },
144-
activeView,
145-
},
146-
state: {
147-
oldestFetchedMessageListItemIndex,
148-
newestFetchedMessageListItemIndex,
149-
messageCache,
150-
messageListItems,
151-
viewState,
152-
jumpToMessageStack,
153-
loaded,
154-
},
155-
fetchMoreBottom,
156-
fetchMoreTop,
157-
} = useMessageList(messageListStore, accountId, chat.id)
146+
scheduler,
147+
effect: { jumpToMessage, loadMissingMessages },
148+
reducer: { unlockScroll, clearJumpStack },
149+
activeView,
150+
} = messageListStore
151+
const {
152+
oldestFetchedMessageListItemIndex,
153+
newestFetchedMessageListItemIndex,
154+
messageCache,
155+
messageListItems,
156+
viewState,
157+
jumpToMessageStack,
158+
loaded,
159+
} = messageListState
158160
const { hideReactionsBar, isReactionsBarShown } = useReactionsBar()
159161

160162
const messageListRef = useRef<HTMLDivElement | null>(null)

packages/frontend/src/components/message/MessageListAndComposer.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useEffect, useCallback, useMemo } from 'react'
1+
import React, { useRef, useEffect, useCallback } from 'react'
22
import { join, parse, ParsedPath } from 'path'
33
import { T } from '@deltachat/jsonrpc-client'
44

@@ -16,7 +16,7 @@ import { ReactionsBarProvider } from '../ReactionsBar'
1616
import useDialog from '../../hooks/dialog/useDialog'
1717
import useMessage from '../../hooks/chat/useMessage'
1818
import { Viewtype } from '@deltachat/jsonrpc-client/dist/generated/types'
19-
import { MessageListStore } from '../../stores/messagelist'
19+
import { useMessageList } from '../../stores/messagelist'
2020

2121
const log = getLogger('renderer/MessageListAndComposer')
2222

@@ -100,17 +100,16 @@ export default function MessageListAndComposer({ accountId, chat }: Props) {
100100
const { openDialog, hasOpenDialogs } = useDialog()
101101
const { sendMessage } = useMessage()
102102

103-
// Create a store instance and share it between
104-
// useMessageList and useDraft to avoid redundant data loading
105-
const messageListStore = useMemo(() => {
106-
const store = new MessageListStore(accountId, chat.id)
107-
// Initialize the store
108-
store.effect.loadChat()
109-
return store
110-
}, [accountId, chat.id])
111-
112103
const regularMessageInputRef = useRef<ComposerMessageInput>(null)
113104
const editMessageInputRef = useRef<ComposerMessageInput>(null)
105+
106+
const {
107+
store: messageListStore,
108+
state: messageListState,
109+
fetchMoreBottom,
110+
fetchMoreTop,
111+
} = useMessageList(accountId, chat.id)
112+
114113
const {
115114
draftState,
116115
updateDraftText,
@@ -122,7 +121,7 @@ export default function MessageListAndComposer({ accountId, chat }: Props) {
122121
clearDraftStateAndUpdateTextareaValue,
123122
setDraftStateAndUpdateTextareaValue,
124123
} = useDraft(
125-
messageListStore,
124+
messageListState,
126125
accountId,
127126
chat.id,
128127
chat.isContactRequest,
@@ -307,6 +306,9 @@ export default function MessageListAndComposer({ accountId, chat }: Props) {
307306
chat={chat}
308307
refComposer={refComposer}
309308
messageListStore={messageListStore}
309+
messageListState={messageListState}
310+
fetchMoreBottom={fetchMoreBottom}
311+
fetchMoreTop={fetchMoreTop}
310312
/>
311313
</ReactionsBarProvider>
312314
</RecoverableCrashScreen>

packages/frontend/src/hooks/chat/useDraft.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { MessageTypeAttachmentSubset } from '../../components/attachment/Attachm
99
import { KeybindAction } from '../../keybindings'
1010
import useMessage from './useMessage'
1111
import ComposerMessageInput from '../../components/composer/ComposerMessageInput'
12-
import { MessageListStore, useMessageListStore } from '../../stores/messagelist'
12+
import { MessageListStore } from '../../stores/messagelist'
1313

1414
const log = getLogger('renderer/composer')
1515

@@ -35,7 +35,7 @@ function emptyDraft(chatId: number | null): DraftObject {
3535
}
3636

3737
export function useDraft(
38-
messageListStore: MessageListStore,
38+
messageListState: MessageListStore['state'],
3939
accountId: number,
4040
chatId: number | null,
4141
isContactRequest: boolean,
@@ -71,10 +71,6 @@ export function useDraft(
7171
_setDraftStateButKeepTextareaValue,
7272
] = useState<DraftObject>(emptyDraft(chatId))
7373

74-
// Use the shared store to access the message cache and list of messages
75-
const { messageCache, messageListItems } =
76-
useMessageListStore(messageListStore)
77-
7874
/**
7975
* `draftRef.current` gets set to `draftState` on every render.
8076
* That is, when you mutate the value of this ref,
@@ -266,14 +262,12 @@ export function useDraft(
266262
if (chatId == undefined || !canSend) {
267263
return
268264
}
269-
const quoteMessage = (messageId: number, jumpToOnly = false) => {
270-
if (!jumpToOnly) {
271-
draftRef.current.quote = {
272-
kind: 'WithMessage',
273-
messageId,
274-
} as Type.MessageQuote
275-
saveDraft()
276-
}
265+
const quoteMessage = (messageId: number) => {
266+
draftRef.current.quote = {
267+
kind: 'WithMessage',
268+
messageId,
269+
} as Type.MessageQuote
270+
saveDraft()
277271

278272
// TODO perf: jumpToMessage is not instant, but it should be
279273
// since the message is (almost?) always already rendered.
@@ -294,12 +288,12 @@ export function useDraft(
294288
*
295289
* see https://github.com/deltachat/deltachat-desktop/blob/77a1f88a351df49e5df38a14c3a1704a76ecdcb3/packages/frontend/src/components/message/Message.tsx#L274-L278
296290
*/
297-
const messageIds = Object.keys(messageCache)
291+
const messageIds = Object.keys(messageListState.messageCache)
298292
.map(Number)
299293
.filter(
300294
id =>
301-
messageCache[id]?.kind === 'message' &&
302-
messageCache[id]?.isInfo === false
295+
messageListState.messageCache[id]?.kind === 'message' &&
296+
messageListState.messageCache[id]?.isInfo === false
303297
)
304298
const currQuote = draftRef.current.quote
305299
if (!currQuote) {
@@ -317,7 +311,7 @@ export function useDraft(
317311
// maybe the message is just not in the cache (yet)
318312
// but still in the full list of messages
319313
// -> check if it's there
320-
const isQuoteInMessagelist = messageListItems.some(
314+
const isQuoteInMessagelist = messageListState.messageListItems.some(
321315
m => m.kind === 'message' && m.msg_id === currQuote.messageId
322316
)
323317
if (isQuoteInMessagelist) {

packages/frontend/src/stores/messagelist.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
defaultChatViewState,
1111
} from './chat/chat_view_reducer'
1212
import { ChatStoreScheduler } from './chat/chat_scheduler'
13-
import { useEffect, useReducer, useRef, useState } from 'react'
13+
import { useEffect, useRef, useState, useMemo } from 'react'
1414
import { useDebouncedCallback } from 'use-debounce'
1515
import { debounce } from 'debounce'
1616
import { getLogger } from '@deltachat-desktop/shared/logger'
@@ -58,7 +58,6 @@ const defaultState = () =>
5858
* of messages as per PAGE_SIZE constant. The store is also used in useDraft to avoid redundant data loading.
5959
*/
6060
export function useMessageList(
61-
store: MessageListStore,
6261
accountId: number,
6362
chatId: number
6463
): {
@@ -67,6 +66,12 @@ export function useMessageList(
6766
fetchMoreBottom: () => void
6867
fetchMoreTop: () => void
6968
} {
69+
const store = useMemo(() => {
70+
const store = new MessageListStore(accountId, chatId)
71+
store.effect.loadChat()
72+
return store
73+
}, [accountId, chatId])
74+
7075
// PERF: It's a shame that we have to re-render on settings changes
7176
// even though we only depend on `volume`,
7277
// but let's hope the React compiler will take care of this
@@ -1190,20 +1195,3 @@ async function loadMessages(
11901195

11911196
return await BackendRemote.rpc.getMessages(accountId, view)
11921197
}
1193-
1194-
// Custom hook to reactively access message list store state
1195-
export const useMessageListStore = (messageListStore: MessageListStore) => {
1196-
const [, forceUpdate] = useReducer(x => x + 1, 0)
1197-
1198-
useEffect(() => {
1199-
const unsubscribe = messageListStore.subscribe(() => {
1200-
forceUpdate()
1201-
})
1202-
return unsubscribe
1203-
}, [messageListStore])
1204-
1205-
return {
1206-
messageCache: messageListStore.state.messageCache,
1207-
messageListItems: messageListStore.state.messageListItems,
1208-
}
1209-
}

0 commit comments

Comments
 (0)