Browse Source

CHANGE | instant send text message (#40)

Допрацювання відправки текстових повідомлень.

Reviewed-on: #40
Co-authored-by: Yevhen Romanenko <yevhen.romanenko.jetup@gmail.com>
Co-committed-by: Yevhen Romanenko <yevhen.romanenko.jetup@gmail.com>
pull/41/head
Yevhen Romanenko 7 months ago committed by Vitalik Yatsenko
parent
commit
ed9ac6f170
  1. BIN
      android/app/src/main/assets/fonts/fontello.ttf
  2. 1
      src/api/chat-messages/requests.interfaces.ts
  3. BIN
      src/assets/fonts/fontello.ttf
  4. 18
      src/config/fontello.json
  5. 144
      src/managers/chat-message.manager.ts
  6. 123
      src/managers/fake-message.manager.ts
  7. 1
      src/managers/index.ts
  8. 10
      src/modules/chats/configs/chat-message-menu-options.config.ts
  9. 65
      src/modules/chats/core/fake-text-message-creator.ts
  10. 1
      src/modules/chats/core/index.ts
  11. 85
      src/modules/chats/hooks/use-chat-messages.hook.ts
  12. 8
      src/modules/chats/hooks/use-create-text-message.hook.ts
  13. 2
      src/modules/chats/screens/chat.tsx
  14. 2
      src/modules/chats/transforms/chat-messages.transforms.ts
  15. 6
      src/services/app.service.ts
  16. 1
      src/shared/components/plugins/chat/chat-bar.component.tsx
  17. 16
      src/shared/components/plugins/chat/chat-item.component.tsx
  18. 5
      src/shared/components/plugins/chat/chat-send-button.component.tsx
  19. 4
      src/shared/components/plugins/chat/edit-bar-section.component.tsx
  20. 2
      src/shared/components/plugins/chat/interfaces.ts
  21. 3
      src/shared/components/plugins/chat/reply-bar-section.component.tsx
  22. 2
      src/shared/enums/storage-keys.enum.ts
  23. 3
      src/shared/events/index.ts
  24. 8
      src/shared/interfaces/chats.interfaces.ts

BIN
android/app/src/main/assets/fonts/fontello.ttf

Binary file not shown.

1
src/api/chat-messages/requests.interfaces.ts

@ -27,6 +27,7 @@ export interface ISendTextMessage { @@ -27,6 +27,7 @@ export interface ISendTextMessage {
mentionsMessage?: string
replyToId?: number
offlineKey?: string
uniqueKey?: string
}
export interface IEditTextMessage {

BIN
src/assets/fonts/fontello.ttf

Binary file not shown.

18
src/config/fontello.json

@ -1069,6 +1069,24 @@ @@ -1069,6 +1069,24 @@
"search": [
"group-conversation"
]
},
{
"uid": "72109d2fb3088d0e66ea6a9204297651",
"css": "spin1",
"code": 59467,
"src": "fontelico"
},
{
"uid": "5d2d07f112b8de19f2c0dbfec3e42c05",
"css": "spin5",
"code": 59468,
"src": "fontelico"
},
{
"uid": "9bd60140934a1eb9236fd7a8ab1ff6ba",
"css": "spin4",
"code": 59469,
"src": "fontelico"
}
]
}

144
src/managers/chat-message.manager.ts

@ -31,6 +31,8 @@ import { DbActionsQueueItem } from '@/shared/interfaces/entities' @@ -31,6 +31,8 @@ import { DbActionsQueueItem } from '@/shared/interfaces/entities'
import _ from 'lodash'
import moment from 'moment'
import { accountManagerInstance } from './account.manager'
import { FakeMessageManager } from './fake-message.manager'
import { FakeTextMessageCreator } from '@/modules/chats/core'
export class ChatMessageManager extends Manager {
private CMRepository = ApiChatMessageRepository.getInstance()
@ -40,6 +42,8 @@ export class ChatMessageManager extends Manager { @@ -40,6 +42,8 @@ export class ChatMessageManager extends Manager {
private dbAQRepository = dbActionsQueueRepository
private accountManager = accountManagerInstance
private fakeMessageManager = FakeMessageManager.getInstance()
private dbAQTypeByMessageType = {
[MessageType.Text]: ActionsQueueType.SendTextMessage,
[MessageType.Image]: ActionsQueueType.SendImageMessage,
@ -228,61 +232,105 @@ export class ChatMessageManager extends Manager { @@ -228,61 +232,105 @@ export class ChatMessageManager extends Manager {
}
}
public async sendTextMessage(data: ISendTextMessage) {
if (this.isConnected === 'online') {
await this.CMRepository.sendTextMessageReq(data)
} else {
const account = await this.accountManager.getDbAccount()
const newMessage: DbChatMessageDto = {
id: generateId(),
type: MessageType.Text,
private async sendTextMessageOnline(
data: ISendTextMessage,
userId: number,
) {
const fakeMessage = await FakeTextMessageCreator.getInstance(
{
userId: userId,
chatId: data.chatId,
userId: account.id,
isPined: false,
createdAt: moment().toISOString(),
content: {
message: data.message,
},
events: null,
}
text: data.message,
mentionsMessage: data.mentionsMessage,
replyToId: data.replyToId,
},
this.dbCMRepository,
)
if (data.mentionsMessage)
newMessage.content.mentionsMessage = data.mentionsMessage
if (data.replyToId) {
const message = await this.dbCMRepository.getMessage(
data.replyToId.toString(),
)
if (message)
newMessage.content.replyToMessage = _.pick(message, [
'id',
'userId',
'type',
'content',
])
}
try {
await this.fakeMessageManager.storeFakeMessage(fakeMessage)
await this.dbAQRepository.addToQueue({
type: ActionsQueueType.SendTextMessage,
data: {
...data,
offlineKey: newMessage.id,
},
await this.CMRepository.sendTextMessageReq({
...data,
uniqueKey: fakeMessage.uniqueKey,
})
await this.dbCMRepository.saveMessage(newMessage)
await this.dbChatRepository.updateField(
data.chatId.toString(),
'lastMessageDate',
newMessage.createdAt,
} catch (e) {
console.log('error on send text message', e)
await this.fakeMessageManager.deleteFakeMessage(
fakeMessage.uniqueKey,
)
await this.dbChatRepository.updateField(
data.chatId.toString(),
'lastMessage',
newMessage,
appEvents.emit('openInfoModal', {
title: 'Помилка!',
message: 'Повідомлення не було доставлено.',
onPressOk: () => {},
})
}
}
private async sendTextMessageOffline(
data: ISendTextMessage,
userId: number,
) {
const newMessage: DbChatMessageDto = {
id: generateId(),
type: MessageType.Text,
chatId: data.chatId,
userId: userId,
isPined: false,
createdAt: moment().toISOString(),
content: {
message: data.message,
},
events: null,
}
if (data.mentionsMessage)
newMessage.content.mentionsMessage = data.mentionsMessage
if (data.replyToId) {
const message = await this.dbCMRepository.getMessage(
data.replyToId.toString(),
)
if (message)
newMessage.content.replyToMessage = _.pick(message, [
'id',
'userId',
'type',
'content',
])
}
appEvents.emit('onNewMessage', { message: newMessage })
await this.dbAQRepository.addToQueue({
type: ActionsQueueType.SendTextMessage,
data: {
...data,
offlineKey: newMessage.id,
},
})
await this.dbCMRepository.saveMessage(newMessage)
await this.dbChatRepository.updateField(
data.chatId.toString(),
'lastMessageDate',
newMessage.createdAt,
)
await this.dbChatRepository.updateField(
data.chatId.toString(),
'lastMessage',
newMessage,
)
appEvents.emit('onNewMessage', { message: newMessage })
}
public async sendTextMessage(data: ISendTextMessage) {
const account = await this.accountManager.getDbAccount()
if (this.isConnected === 'online') {
await this.sendTextMessageOnline(data, account.id)
} else {
await this.sendTextMessageOffline(data, account.id)
}
}

123
src/managers/fake-message.manager.ts

@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
import { storageService } from '@/services/system'
import { IChatMessage, StorageKey, appEvents } from '@/shared'
import _ from 'lodash'
export class FakeMessageManager {
private FilterMessagesToExcludeDuplicateKeys(
messages: (Omit<IChatMessage, 'id'> & { id: number })[],
encodedMessages: IChatMessage[],
chatId: number,
) {
return messages.filter(
it =>
!_.some(
it.chatId === chatId && encodedMessages,
msg => msg.uniqueKey === it.uniqueKey,
),
)
}
public async addProcessingMsgs(
messages: (Omit<IChatMessage, 'id'> & { id: number })[],
chatId: number,
) {
const processingMsgs = await storageService.get(StorageKey.Messages)
const encodeProcessingMessages = JSON.parse(
processingMsgs || '[]',
) as IChatMessage[]
if (!encodeProcessingMessages || _.isEmpty(encodeProcessingMessages)) {
return messages
}
await this.deleteDeliveredMsgs(messages, encodeProcessingMessages)
const updatedMessages = this.FilterMessagesToExcludeDuplicateKeys(
messages,
encodeProcessingMessages,
chatId,
)
return updatedMessages
}
public async remainingUndeliveredMsgs(
messages: IChatMessage[],
processingMsgs: IChatMessage[],
chatId: number,
) {
const filterMsg = processingMsgs.filter(it => it.chatId === chatId)
const deliveredMsgs = processingMsgs.filter(it =>
_.some(messages, msg => msg.uniqueKey === it.uniqueKey),
)
await this.deleteDeliveredMsgs(messages, deliveredMsgs)
const remainingMessages = filterMsg.filter(
it => !deliveredMsgs.some(msg => msg.uniqueKey === it.uniqueKey),
)
return remainingMessages
}
protected async deleteDeliveredMsgs(
messages: IChatMessage[],
processingMsgs: IChatMessage[],
) {
const deliveredMsgs = processingMsgs.filter(it =>
_.some(messages, msg => msg.uniqueKey === it.uniqueKey),
)
if (_.isEmpty(deliveredMsgs)) {
return
}
const restProcessingMsgs = processingMsgs.filter(
it => !_.some(messages, msg => msg.uniqueKey === it.uniqueKey),
)
const value = JSON.stringify(restProcessingMsgs)
await storageService.set(StorageKey.Messages, value)
}
public async storeFakeMessage(message: IChatMessage) {
const fakedMsgs = await storageService.get(StorageKey.Messages)
const encodeFakeMessage = JSON.parse(
fakedMsgs || '[]',
) as IChatMessage[]
const mergedMsgs = [..._.defaultTo(encodeFakeMessage, []), message]
const value = JSON.stringify(mergedMsgs)
await storageService.set(StorageKey.Messages, value)
appEvents.emit('onNewMessage', { message })
}
public async deleteFakeMessage(uniqueKey: string) {
const fakeMsgs = await storageService.get(StorageKey.Messages)
const processingMsgs: IChatMessage[] = JSON.parse(fakeMsgs || '[]')
if (!processingMsgs || _.isEmpty(processingMsgs)) {
return
}
const restMsgs = processingMsgs.filter(it => it.uniqueKey !== uniqueKey)
const value = JSON.stringify(restMsgs)
await storageService.set(StorageKey.Messages, value)
appEvents.emit('deleteFakeMessage', { uniqueKey })
}
static instance: FakeMessageManager
static getInstance() {
if (!FakeMessageManager.instance)
FakeMessageManager.instance = new FakeMessageManager()
return FakeMessageManager.instance
}
}
export const fakeMessageManager = FakeMessageManager.getInstance()

1
src/managers/index.ts

@ -11,3 +11,4 @@ export * from './chat.manager' @@ -11,3 +11,4 @@ export * from './chat.manager'
export * from './chat-member.manager'
export * from './chat-message.manager'
export * from './task-document.manager'
export * from './fake-message.manager'

10
src/modules/chats/configs/chat-message-menu-options.config.ts

@ -3,6 +3,7 @@ import { ChatMessageActionEnum } from '../enums' @@ -3,6 +3,7 @@ import { ChatMessageActionEnum } from '../enums'
interface IProps {
isOfflineMessage: boolean
isOfflineMode: boolean
isFakeMessage: boolean
onPress: (actionType: ChatMessageActionEnum) => void
canDeleteForAll?: boolean
canCopy?: boolean
@ -15,6 +16,7 @@ interface IProps { @@ -15,6 +16,7 @@ interface IProps {
export const getChatMessageMenuOptions = ({
isOfflineMessage,
isOfflineMode,
isFakeMessage,
canDeleteForAll,
canPin,
canCopy,
@ -74,6 +76,14 @@ export const getChatMessageMenuOptions = ({ @@ -74,6 +76,14 @@ export const getChatMessageMenuOptions = ({
},
}
if (isFakeMessage) {
const fakeOptions = []
if (canCopy) fakeOptions.push(menuOptions.copy)
fakeOptions.push(menuOptions.cancel)
return fakeOptions
}
if (isOfflineMessage) {
const offlineOptions = []
if (canCopy) offlineOptions.push(menuOptions.copy)

65
src/modules/chats/core/fake-text-message-creator.ts

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
import { DbChatMessageRepository } from '@/repositories/db/chat-message.repository'
import { MessageType, generateId } from '@/shared'
import _ from 'lodash'
export interface IFakeTextMessage {
userId: number
chatId: string | number
text: string
mentionsMessage?: string
replyToId?: number
}
export class FakeTextMessageCreator {
constructor(
public userId: number,
public chatId: string | number,
public text: string,
public mentionsMessage?: string,
public replyToId?: number,
) {}
static async getInstance(
params: IFakeTextMessage,
dbCMRepository: DbChatMessageRepository,
) {
const { userId, chatId, text, mentionsMessage, replyToId } = params
const uniqueKey = generateId()
const message = {
id: generateId(),
chatId,
userId,
type: MessageType.Text,
isPined: false,
content: {
message: text,
mentionsMessage,
replyToMessage: undefined,
},
createdAt: new Date().toISOString(),
events: null,
uniqueKey,
isFake: true,
}
if (mentionsMessage) message.content.mentionsMessage = mentionsMessage
if (replyToId) {
const replyMessage = await dbCMRepository.getMessage(
replyToId.toString(),
)
if (replyMessage)
message.content.replyToMessage = _.pick(replyMessage, [
'id',
'userId',
'type',
'content',
])
}
return message
}
}

1
src/modules/chats/core/index.ts

@ -0,0 +1 @@ @@ -0,0 +1 @@
export * from './fake-text-message-creator'

85
src/modules/chats/hooks/use-chat-messages.hook.ts

@ -20,7 +20,6 @@ import { selectAccount, selectId } from '@/store/account' @@ -20,7 +20,6 @@ import { selectAccount, selectId } from '@/store/account'
import { UnselectChat } from '@/store/chats'
import { simpleDispatch } from '@/store/store-helpers'
import _ from 'lodash'
import { Platform } from 'react-native'
import { useCallback, useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { getChatMessageMenuOptions } from '../configs'
@ -30,6 +29,7 @@ import store from '@/store' @@ -30,6 +29,7 @@ import store from '@/store'
import { chatMessageManager } from '@/managers'
import { isMessageEqualURL } from '@/shared/helpers'
import { COPY_ENABLED_MESSAGES_TYPES } from '../consts'
import { fakeMessageManager } from '@/managers/fake-message.manager'
export const useChatMessages = (
chatId: number | string,
@ -167,35 +167,6 @@ export const useChatMessages = ( @@ -167,35 +167,6 @@ export const useChatMessages = (
const onShare = async (message: IChatMessage) => {
const title = getAuthorName(message?.userId, chatMembers)
let url = 'taskme-admin.com'
const options = Platform.select({
ios: {
activityItemSources: [
{
placeholderItem: {
type: 'text',
content: message.content?.message,
},
item: {
default: {
type: 'text',
content: message.content?.message,
},
message: null,
},
linkMetadata: {
title: title,
},
},
],
},
default: {
title,
subject: title,
message: `${message.content?.message} ${url}`,
},
})
if (message.type === MessageType.Text) {
if (!isMessageEqualURL(message.content?.message)) {
@ -207,7 +178,6 @@ export const useChatMessages = ( @@ -207,7 +178,6 @@ export const useChatMessages = (
fsService.shareFileOutside(
message.content?.fileUrl,
message.content?.name,
MessageType.Image,
)
}
@ -215,7 +185,6 @@ export const useChatMessages = ( @@ -215,7 +185,6 @@ export const useChatMessages = (
fsService.shareFileOutside(
message.content?.fileUrl,
message.content?.name,
MessageType.Video,
)
}
@ -223,7 +192,6 @@ export const useChatMessages = ( @@ -223,7 +192,6 @@ export const useChatMessages = (
fsService.shareFileOutside(
message.content?.fileUrl,
message.content?.name,
MessageType.Audio,
)
}
@ -231,7 +199,6 @@ export const useChatMessages = ( @@ -231,7 +199,6 @@ export const useChatMessages = (
fsService.shareFileOutside(
message.content?.fileUrl,
message.content?.name,
MessageType.File,
)
}
@ -255,7 +222,6 @@ export const useChatMessages = ( @@ -255,7 +222,6 @@ export const useChatMessages = (
fsService.shareFileOutside(
message.content?.originalMessage?.content?.fileUrl,
message.content?.originalMessage?.content?.name,
message.content?.originalMessage?.type,
)
}
}
@ -306,9 +272,12 @@ export const useChatMessages = ( @@ -306,9 +272,12 @@ export const useChatMessages = (
message.userId === selectAccount(store.getState()).id
const isOfflineMessage = _.isNaN(Number(message.id))
const isFakeMessage = message.isFake
const options = getChatMessageMenuOptions({
isOfflineMessage,
isOfflineMode: !isConnected,
isFakeMessage,
canDeleteForAll,
canPin,
canCopy,
@ -329,9 +298,7 @@ export const useChatMessages = ( @@ -329,9 +298,7 @@ export const useChatMessages = (
}
const onLoadNew = async (limit?: number) => {
const id = messages[messages.length - 1]?.id
await loadNew(limit)
// setTimeout(() => setScrollToId(id), 80)
}
// ****** APP EVENTS AND SOCKET SIGNALS HANDLERS *****
@ -362,11 +329,43 @@ export const useChatMessages = ( @@ -362,11 +329,43 @@ export const useChatMessages = (
return updatedItems
}
const onNewOneMessage = (message: IChatMessage, offlineKey?: string) => {
const processNewMessageWithUniqueKey = async (message: IChatMessage) => {
const updatedMessages = await fakeMessageManager.addProcessingMsgs(
messages,
chatId as number,
)
if (!_.isNaN(Number(message.id)))
socket.emit('chat/read-message', {
userId: accountId,
messagesIds: [message.id],
chatId,
})
if (message.userId === accountId) setScrollToId(message.id)
return updatedMessages
}
const onNewOneMessage = async (
message: IChatMessage,
offlineKey?: string,
) => {
if (
message?.chatId?.toString() === chatId.toString() &&
!messagesContainsItem(message?.id)
) {
if (message.uniqueKey) {
const updatedMessages = await processNewMessageWithUniqueKey(
message,
)
return _setItems([
...updatedMessages,
message as Omit<IChatMessage, 'id'> & { id: number },
])
}
if (offlineKey && messagesContainsItem(offlineKey))
_setItems(
messages.map(it => {
@ -602,6 +601,16 @@ export const useChatMessages = ( @@ -602,6 +601,16 @@ export const useChatMessages = (
[chatId],
)
useEventsListener(
'deleteFakeMessage',
data => {
return _setItems(
messages.filter(it => it.uniqueKey !== data.uniqueKey),
)
},
[messages],
)
useSocketListener(
'chat/new-message',
data => {

8
src/modules/chats/hooks/use-create-text-message.hook.ts

@ -81,7 +81,9 @@ export const useCreateTextMessage = ({ @@ -81,7 +81,9 @@ export const useCreateTextMessage = ({
})
setEditedMessage(null)
} else {
await chatMessageManager.sendTextMessage.bind(chatMessageManager)(data)
await chatMessageManager.sendTextMessage.bind(
chatMessageManager,
)(data)
}
} catch (e) {
console.log('SEND MESSAGE ERROR', e)
@ -104,7 +106,9 @@ export const useCreateTextMessage = ({ @@ -104,7 +106,9 @@ export const useCreateTextMessage = ({
const fileStat = await fsService.getFileStat(filePath)
fileStat.type = 'image/jpg'
await chatMessageManager.storeImageMessage.bind(chatMessageManager)({
await chatMessageManager.storeImageMessage.bind(
chatMessageManager,
)({
file: fileStat,
chatId: Number(chatId),
fileName: fileStat.name,

2
src/modules/chats/screens/chat.tsx

@ -254,7 +254,7 @@ export const ChatConversation = () => { @@ -254,7 +254,7 @@ export const ChatConversation = () => {
isDisabled={isSending}
onPressSend={sendMessage}
onSendVoice={onSendVoiceMsg}
isSending={isSending || isFileSending || isStickerSending}
isSending={isFileSending || isStickerSending}
isMenuOpen={isMenuOpen}
withAttachmentsBtn={true}
microphoneEnabled={true}

2
src/modules/chats/transforms/chat-messages.transforms.ts

@ -191,6 +191,8 @@ export const transformMessage = ( @@ -191,6 +191,8 @@ export const transformMessage = (
isPined: item.isPined,
forwardedFrom,
content,
uniqueKey: item.uniqueKey,
isFake: item.isFake,
}
}

6
src/services/app.service.ts

@ -3,7 +3,13 @@ import { simpleDispatch } from '@/store/store-helpers' @@ -3,7 +3,13 @@ import { simpleDispatch } from '@/store/store-helpers'
import { ChatBgKeys, StorageKey } from '@/shared/enums'
import { storageService } from './system/storage.service'
const clearFakeMsgsStorage = async () => {
await storageService.del(StorageKey.Messages)
}
const initApp = async () => {
await clearFakeMsgsStorage()
const currentChatBg = await storageService.get(StorageKey.ChatBgId)
simpleDispatch(

1
src/shared/components/plugins/chat/chat-bar.component.tsx

@ -146,6 +146,7 @@ export const ChatBar: FC<ChatBarProps> = props => { @@ -146,6 +146,7 @@ export const ChatBar: FC<ChatBarProps> = props => {
props.onPressSend()
}}
onSendVoice={props.onSendVoice}
disabled={_.isEmpty(props.message)}
/>
)
}

16
src/shared/components/plugins/chat/chat-item.component.tsx

@ -62,6 +62,8 @@ export const ChatItem: FC<ChatItemProps> = ({ @@ -62,6 +62,8 @@ export const ChatItem: FC<ChatItemProps> = ({
[props.id],
)
const isTemporaryFakeMessage = useMemo(() => props.isFake, [props.isFake])
const select = () => selectMessage(props)
return (
@ -132,7 +134,6 @@ export const ChatItem: FC<ChatItemProps> = ({ @@ -132,7 +134,6 @@ export const ChatItem: FC<ChatItemProps> = ({
props.onRepliedPress(repliedMessage?.id)
}}
/>
{!props.isMy ? (
<Txt
style={[styles.name, { paddingHorizontal }]}
@ -143,10 +144,17 @@ export const ChatItem: FC<ChatItemProps> = ({ @@ -143,10 +144,17 @@ export const ChatItem: FC<ChatItemProps> = ({
: `${props.author?.name}`}
</Txt>
) : null}
{props.children}
<View style={[styles.footerRow, { paddingHorizontal }]}>
<Txt style={styles.time}>{props.time}</Txt>
{isTemporaryFakeMessage && (
<IconComponent
style={styles.fakeLoader}
name={'spin5'}
size={$size(15)}
/>
)}
{!isOfflineMessage && (
<IconComponent
style={[
@ -248,6 +256,10 @@ const createStyles = (theme: PartialTheme) => @@ -248,6 +256,10 @@ const createStyles = (theme: PartialTheme) =>
justifyContent: 'flex-start',
alignItems: 'center',
},
fakeLoader: {
marginLeft: 10,
color: theme.$loaderPrimary,
},
tick: {
marginLeft: 10,
},

5
src/shared/components/plugins/chat/chat-send-button.component.tsx

@ -8,6 +8,7 @@ import Svg, { Path } from 'react-native-svg' @@ -8,6 +8,7 @@ import Svg, { Path } from 'react-native-svg'
interface ChatSendButtonProps {
onSend: () => void
onSendVoice: (path: string) => void
disabled?: boolean
}
export const ChatSendButton: FC<ChatSendButtonProps> = props => {
@ -34,8 +35,8 @@ export const ChatSendButton: FC<ChatSendButtonProps> = props => { @@ -34,8 +35,8 @@ export const ChatSendButton: FC<ChatSendButtonProps> = props => {
onPress={() =>
isMic
? appEvents.emit('openRecordVoiceModal', {
send: props.onSendVoice,
})
send: props.onSendVoice,
})
: props.onSend()
}>
<Animated.View

4
src/shared/components/plugins/chat/edit-bar-section.component.tsx

@ -15,13 +15,13 @@ interface IProps { @@ -15,13 +15,13 @@ interface IProps {
export const EditBarSection = ({ message, onPressClose }: IProps) => {
const { styles, theme } = useTheme(createStyles)
if (!message) return null
const text = useMemo(() => {
const res = getMessagePreviewText(message)
return String(res).substring(0, 60)
}, [message])
if (!message) return null
return (
<View style={styles.container}>
<View style={styles.mainSection}>

2
src/shared/components/plugins/chat/interfaces.ts

@ -23,6 +23,8 @@ export interface IChatMessage { @@ -23,6 +23,8 @@ export interface IChatMessage {
id: number
name: string
}
uniqueKey?: string
isFake?: boolean
}
export interface ISuggestionUser {

3
src/shared/components/plugins/chat/reply-bar-section.component.tsx

@ -15,11 +15,10 @@ interface IProps { @@ -15,11 +15,10 @@ interface IProps {
export const ReplyBarSection = ({ message, onPressClose, name }: IProps) => {
const { styles, theme } = useTheme(createStyles)
const text = useMemo(() => getMessagePreviewText(message), [message])
if (!message) return null
const text = useMemo(() => getMessagePreviewText(message), [message])
return (
<View style={styles.container}>
<View style={styles.mainSection}>

2
src/shared/enums/storage-keys.enum.ts

@ -5,4 +5,6 @@ export enum StorageKey { @@ -5,4 +5,6 @@ export enum StorageKey {
ChatBgId = 'ChatBgId',
CustomChatBg = 'CustomChatBg',
Chats = 'chats',
Messages = 'Messages',
}

3
src/shared/events/index.ts

@ -120,6 +120,9 @@ export type AppEvents = { @@ -120,6 +120,9 @@ export type AppEvents = {
reloadChatList: {}
reloadChatDetail: { chatId: number | string }
onNewMessage: { message: IChatMessage }
deleteFakeMessage: {
uniqueKey: string
}
onNeedReloadMessages: {}
onMessageUpdated: { message: IChatMessage }
onPinnedMessage: { messageId: number; chatId: number }

8
src/shared/interfaces/chats.interfaces.ts

@ -66,6 +66,10 @@ export interface IChatMessage { @@ -66,6 +66,10 @@ export interface IChatMessage {
isPined: boolean
createdAt: string
uniqueKey?: string
isFake?: boolean
}
export interface IChatMember {
@ -89,6 +93,6 @@ export interface IChatMember { @@ -89,6 +93,6 @@ export interface IChatMember {
}
export interface IChatInList extends IChat {
isSelected: boolean
isDisabled: boolean
isSelected: boolean
isDisabled: boolean
}

Loading…
Cancel
Save