@ethora/chat-component-rn 26.5.16 → 26.5.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/assets/EmptyChatIllustration.js +106 -0
- package/lib/commonjs/assets/EmptyChatIllustration.js.map +1 -0
- package/lib/commonjs/assets/icons.js +13 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/DropdownMenu/DropdownMenu.js +2 -1
- package/lib/commonjs/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +2 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +5 -2
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChooseChatMessage.js +9 -2
- package/lib/commonjs/components/MainComponents/ChooseChatMessage.js.map +1 -1
- package/lib/commonjs/components/MainComponents/EditWrapper.js +12 -4
- package/lib/commonjs/components/MainComponents/EditWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +2 -1
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/NoMessagesPlaceholder.js +11 -3
- package/lib/commonjs/components/MainComponents/NoMessagesPlaceholder.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js +12 -7
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js +4 -0
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +2 -1
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Avatar.js +16 -7
- package/lib/commonjs/components/MessageBubble/Avatar.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Message.js +16 -1
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +9 -0
- package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
- package/lib/commonjs/components/styled/Button.js +4 -2
- package/lib/commonjs/components/styled/Button.js.map +1 -1
- package/lib/commonjs/components/styled/DateLabel.js +12 -4
- package/lib/commonjs/components/styled/DateLabel.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +4 -3
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +12 -1
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/getAvatarColor.js +33 -0
- package/lib/commonjs/helpers/getAvatarColor.js.map +1 -0
- package/lib/commonjs/helpers/getDateLabelColor.js +9 -0
- package/lib/commonjs/helpers/getDateLabelColor.js.map +1 -0
- package/lib/commonjs/helpers/getIconColor.js +9 -0
- package/lib/commonjs/helpers/getIconColor.js.map +1 -0
- package/lib/commonjs/helpers/getSenderNameColor.js +9 -0
- package/lib/commonjs/helpers/getSenderNameColor.js.map +1 -0
- package/lib/commonjs/helpers/historyPreloadScheduler.js +118 -113
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/hooks/useChatFonts.js +137 -0
- package/lib/commonjs/hooks/useChatFonts.js.map +1 -0
- package/lib/commonjs/hooks/useSendMessage.js +72 -22
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js +4 -2
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/commonjs/main.js +7 -0
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/outboundQueue.js +22 -4
- package/lib/commonjs/networking/outboundQueue.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +50 -0
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js +22 -0
- package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +22 -2
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/assets/EmptyChatIllustration.js +99 -0
- package/lib/module/assets/EmptyChatIllustration.js.map +1 -0
- package/lib/module/assets/icons.js +13 -2
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/DropdownMenu/DropdownMenu.js +2 -1
- package/lib/module/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +2 -1
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +5 -2
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChooseChatMessage.js +9 -2
- package/lib/module/components/MainComponents/ChooseChatMessage.js.map +1 -1
- package/lib/module/components/MainComponents/EditWrapper.js +12 -4
- package/lib/module/components/MainComponents/EditWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +2 -1
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/NoMessagesPlaceholder.js +11 -3
- package/lib/module/components/MainComponents/NoMessagesPlaceholder.js.map +1 -1
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js +12 -7
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/module/components/MainComponents/ReduxWrapper.js +4 -0
- package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +2 -1
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/MessageBubble/Avatar.js +16 -7
- package/lib/module/components/MessageBubble/Avatar.js.map +1 -1
- package/lib/module/components/MessageBubble/Message.js +16 -1
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +9 -0
- package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
- package/lib/module/components/styled/Button.js +4 -2
- package/lib/module/components/styled/Button.js.map +1 -1
- package/lib/module/components/styled/DateLabel.js +12 -4
- package/lib/module/components/styled/DateLabel.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +4 -3
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/context/xmppProvider.js +13 -2
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/getAvatarColor.js +28 -0
- package/lib/module/helpers/getAvatarColor.js.map +1 -0
- package/lib/module/helpers/getDateLabelColor.js +4 -0
- package/lib/module/helpers/getDateLabelColor.js.map +1 -0
- package/lib/module/helpers/getIconColor.js +4 -0
- package/lib/module/helpers/getIconColor.js.map +1 -0
- package/lib/module/helpers/getSenderNameColor.js +4 -0
- package/lib/module/helpers/getSenderNameColor.js.map +1 -0
- package/lib/module/helpers/historyPreloadScheduler.js +119 -114
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/hooks/useChatFonts.js +132 -0
- package/lib/module/hooks/useChatFonts.js.map +1 -0
- package/lib/module/hooks/useSendMessage.js +72 -22
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js +4 -2
- package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/module/main.js +2 -0
- package/lib/module/main.js.map +1 -1
- package/lib/module/networking/outboundQueue.js +21 -4
- package/lib/module/networking/outboundQueue.js.map +1 -1
- package/lib/module/networking/xmppClient.js +50 -0
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/Middleware/newMessageMidlleware.js +22 -0
- package/lib/module/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +20 -1
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/typescript/assets/EmptyChatIllustration.d.ts +10 -0
- package/lib/typescript/assets/EmptyChatIllustration.d.ts.map +1 -0
- package/lib/typescript/assets/icons.d.ts +3 -12
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChooseChatMessage.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/EditWrapper.d.ts +5 -1
- package/lib/typescript/components/MainComponents/EditWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/NoMessagesPlaceholder.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ProfileImagePlaceholder.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Avatar.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts.map +1 -1
- package/lib/typescript/components/styled/Button.d.ts +1 -0
- package/lib/typescript/components/styled/Button.d.ts.map +1 -1
- package/lib/typescript/components/styled/DateLabel.d.ts +9 -8
- package/lib/typescript/components/styled/DateLabel.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/getAvatarColor.d.ts +7 -0
- package/lib/typescript/helpers/getAvatarColor.d.ts.map +1 -0
- package/lib/typescript/helpers/getDateLabelColor.d.ts +8 -0
- package/lib/typescript/helpers/getDateLabelColor.d.ts.map +1 -0
- package/lib/typescript/helpers/getIconColor.d.ts +8 -0
- package/lib/typescript/helpers/getIconColor.d.ts.map +1 -0
- package/lib/typescript/helpers/getSenderNameColor.d.ts +8 -0
- package/lib/typescript/helpers/getSenderNameColor.d.ts.map +1 -0
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
- package/lib/typescript/hooks/useChatFonts.d.ts +23 -0
- package/lib/typescript/hooks/useChatFonts.d.ts.map +1 -0
- package/lib/typescript/hooks/useSendMessage.d.ts +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts +1 -0
- package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
- package/lib/typescript/main.d.ts +2 -1
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/outboundQueue.d.ts +16 -1
- package/lib/typescript/networking/outboundQueue.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +3 -0
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/newMessageMidlleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +3 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/types/models/message.model.d.ts +1 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +53 -0
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/assets/EmptyChatIllustration.tsx +49 -0
- package/src/assets/icons.tsx +64 -81
- package/src/components/DropdownMenu/DropdownMenu.tsx +2 -1
- package/src/components/MainComponents/ChatHeader.tsx +2 -1
- package/src/components/MainComponents/ChatRoom.tsx +5 -2
- package/src/components/MainComponents/ChooseChatMessage.tsx +5 -2
- package/src/components/MainComponents/EditWrapper.tsx +9 -6
- package/src/components/MainComponents/MessageList.tsx +2 -1
- package/src/components/MainComponents/NoMessagesPlaceholder.tsx +4 -1
- package/src/components/MainComponents/ProfileImagePlaceholder.tsx +14 -7
- package/src/components/MainComponents/ReduxWrapper.tsx +4 -0
- package/src/components/MainComponents/RoomList.tsx +2 -1
- package/src/components/MessageBubble/Avatar.tsx +18 -9
- package/src/components/MessageBubble/Message.tsx +16 -1
- package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +6 -0
- package/src/components/styled/Button.tsx +5 -1
- package/src/components/styled/DateLabel.tsx +10 -7
- package/src/components/styled/SendInput.tsx +4 -3
- package/src/context/xmppProvider.tsx +11 -1
- package/src/helpers/getAvatarColor.ts +31 -0
- package/src/helpers/getDateLabelColor.ts +3 -0
- package/src/helpers/getIconColor.ts +3 -0
- package/src/helpers/getSenderNameColor.ts +3 -0
- package/src/helpers/historyPreloadScheduler.ts +7 -1
- package/src/hooks/useChatFonts.ts +153 -0
- package/src/hooks/useSendMessage.tsx +101 -58
- package/src/hooks/useUnreadMessagesCounter.ts +5 -2
- package/src/main.ts +4 -0
- package/src/networking/outboundQueue.ts +25 -4
- package/src/networking/xmppClient.ts +47 -0
- package/src/roomStore/Middleware/newMessageMidlleware.tsx +25 -0
- package/src/roomStore/roomsSlice.ts +26 -1
- package/src/types/models/message.model.ts +3 -0
- package/src/types/types.ts +59 -1
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { BurgerMenuIcon } from '../../assets/icons';
|
|
13
13
|
import { IConfig } from '../../types/types';
|
|
14
14
|
import Button from '../styled/Button';
|
|
15
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
15
16
|
|
|
16
17
|
const positionMenu = {
|
|
17
18
|
right: { top: 95, right: 10 },
|
|
@@ -104,7 +105,7 @@ const DropdownMenu: React.FC<DropdownMenuProps> = ({
|
|
|
104
105
|
}}
|
|
105
106
|
color="black"
|
|
106
107
|
unstyled
|
|
107
|
-
EndIcon={<BurgerMenuIcon color={config
|
|
108
|
+
EndIcon={<BurgerMenuIcon color={getIconColor(config)} />}
|
|
108
109
|
onPress={toggleMenu}
|
|
109
110
|
/>
|
|
110
111
|
)}
|
|
@@ -27,6 +27,7 @@ import { RoomMenu } from '../MenuRoom/MenuRoom';
|
|
|
27
27
|
import { useRoomState } from '../../hooks/useRoomState';
|
|
28
28
|
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
29
29
|
import { View, StyleSheet, Text, Keyboard } from 'react-native';
|
|
30
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
30
31
|
|
|
31
32
|
interface ChatHeaderProps {
|
|
32
33
|
currentRoom: IRoom;
|
|
@@ -89,7 +90,7 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
|
|
|
89
90
|
style={styles.menuButton}
|
|
90
91
|
color="black"
|
|
91
92
|
unstyled
|
|
92
|
-
EndIcon={<BurgerMenuIcon color={config
|
|
93
|
+
EndIcon={<BurgerMenuIcon color={getIconColor(config)} />}
|
|
93
94
|
onPress={handleHeaderChatMenu}
|
|
94
95
|
/>
|
|
95
96
|
</View>
|
|
@@ -18,7 +18,8 @@ import ChatHeader from './ChatHeader';
|
|
|
18
18
|
import NoMessagesPlaceholder from './NoMessagesPlaceholder';
|
|
19
19
|
import NewChatModal from '../Modals/NewChatModal/NewChatModal';
|
|
20
20
|
import { EditWrapper } from './EditWrapper';
|
|
21
|
-
import {
|
|
21
|
+
import { EmptyChatIllustration } from '../../assets/EmptyChatIllustration';
|
|
22
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
22
23
|
import { ChooseChatMessage } from './ChooseChatMessage';
|
|
23
24
|
import { useRoomUrl } from '../../hooks/useRoomUrl';
|
|
24
25
|
import { useSendMessage } from '../../hooks/useSendMessage';
|
|
@@ -320,7 +321,9 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
|
|
|
320
321
|
alignItems: 'center',
|
|
321
322
|
}}
|
|
322
323
|
>
|
|
323
|
-
<
|
|
324
|
+
<EmptyChatIllustration
|
|
325
|
+
color={getIconColor(configWithEventHandlers)}
|
|
326
|
+
/>
|
|
324
327
|
</View>
|
|
325
328
|
) : !roomMessages || roomMessages.length === 0 ? (
|
|
326
329
|
<View
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { styled } from 'styled-components/native';
|
|
2
|
-
import {
|
|
2
|
+
import { EmptyChatIllustration } from '../../assets/EmptyChatIllustration';
|
|
3
|
+
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
4
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
3
5
|
|
|
4
6
|
export const ChooseChatMessageContainer = styled.View`
|
|
5
7
|
height: 100%;
|
|
@@ -30,9 +32,10 @@ export const ChooseChatDescription = styled.Text`
|
|
|
30
32
|
`;
|
|
31
33
|
|
|
32
34
|
export const ChooseChatMessage = () => {
|
|
35
|
+
const { config } = useChatSettingState();
|
|
33
36
|
return (
|
|
34
37
|
<ChooseChatMessageContainer>
|
|
35
|
-
<
|
|
38
|
+
<EmptyChatIllustration color={getIconColor(config)} />
|
|
36
39
|
<ChooseChatMessageContainerBoxText>
|
|
37
40
|
<ChooseChatTitle>Start a Conversation</ChooseChatTitle>
|
|
38
41
|
<ChooseChatDescription>
|
|
@@ -2,9 +2,11 @@ import React, { FC } from 'react';
|
|
|
2
2
|
import { EditIcon } from '../../assets/icons';
|
|
3
3
|
import { styled } from 'styled-components/native';
|
|
4
4
|
import { Text, TouchableOpacity, View } from 'react-native';
|
|
5
|
+
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
6
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
5
7
|
|
|
6
|
-
export const EditContainer = styled.View
|
|
7
|
-
background-color: #
|
|
8
|
+
export const EditContainer = styled.View<{ accentColor?: string }>`
|
|
9
|
+
background-color: ${({ accentColor }) => (accentColor || '#0052cd') + '0d'};
|
|
8
10
|
padding: 12px 24px;
|
|
9
11
|
flex-direction: row;
|
|
10
12
|
align-items: center;
|
|
@@ -36,9 +38,10 @@ interface EditWrapperProps {
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
export const EditWrapper: FC<EditWrapperProps> = ({ text, onClose }) => {
|
|
39
|
-
|
|
41
|
+
const { config } = useChatSettingState();
|
|
42
|
+
const iconColor = getIconColor(config);
|
|
40
43
|
return (
|
|
41
|
-
<EditContainer>
|
|
44
|
+
<EditContainer accentColor={iconColor}>
|
|
42
45
|
<EditInfoBox>
|
|
43
46
|
<View
|
|
44
47
|
style={{
|
|
@@ -46,11 +49,11 @@ export const EditWrapper: FC<EditWrapperProps> = ({ text, onClose }) => {
|
|
|
46
49
|
paddingRight: 20,
|
|
47
50
|
paddingLeft: 0,
|
|
48
51
|
borderRightWidth: 1,
|
|
49
|
-
borderRightColor:
|
|
52
|
+
borderRightColor: iconColor,
|
|
50
53
|
borderStyle: 'solid',
|
|
51
54
|
}}
|
|
52
55
|
>
|
|
53
|
-
<EditIcon color=
|
|
56
|
+
<EditIcon color={iconColor} />
|
|
54
57
|
</View>
|
|
55
58
|
<View style={{ paddingLeft: 20 }}>
|
|
56
59
|
<EditTitle>Edit Message</EditTitle>
|
|
@@ -27,6 +27,7 @@ import { useRoomState } from '../../hooks/useRoomState';
|
|
|
27
27
|
import Loader from '../styled/Loader';
|
|
28
28
|
import { ArowDownIcon } from '../../assets/icons';
|
|
29
29
|
import CustomTypingIndicator from '../styled/StyledInputComponents/CustomTypingIndicator';
|
|
30
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
30
31
|
|
|
31
32
|
interface MessageListProps<TMessage extends IMessage> {
|
|
32
33
|
CustomMessage?: React.ComponentType<{
|
|
@@ -453,7 +454,7 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
453
454
|
<TouchableOpacity
|
|
454
455
|
style={[
|
|
455
456
|
styles.newMessageIndicator,
|
|
456
|
-
{ backgroundColor: config
|
|
457
|
+
{ backgroundColor: getIconColor(config) },
|
|
457
458
|
]}
|
|
458
459
|
onPress={handleNewMessageIndicatorPress}
|
|
459
460
|
>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Text, View } from 'react-native';
|
|
2
2
|
import { NoMessages } from '../../assets/icons';
|
|
3
|
+
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
4
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
3
5
|
|
|
4
6
|
const NoMessagesPlaceholder = () => {
|
|
7
|
+
const { config } = useChatSettingState();
|
|
5
8
|
return (
|
|
6
9
|
<View
|
|
7
10
|
style={{
|
|
@@ -11,7 +14,7 @@ const NoMessagesPlaceholder = () => {
|
|
|
11
14
|
}}
|
|
12
15
|
>
|
|
13
16
|
<View style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
14
|
-
|
|
17
|
+
<NoMessages color={getIconColor(config)} />
|
|
15
18
|
<View
|
|
16
19
|
style={{
|
|
17
20
|
flexDirection: 'column',
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
RemoveButtonText,
|
|
12
12
|
Wrapper,
|
|
13
13
|
} from '../styled/StyledComponents';
|
|
14
|
-
import {
|
|
14
|
+
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
15
|
+
import {
|
|
16
|
+
getAvatarColor,
|
|
17
|
+
getAvatarTextColor,
|
|
18
|
+
} from '../../helpers/getAvatarColor';
|
|
15
19
|
|
|
16
20
|
interface ProfileImagePlaceholderProps {
|
|
17
21
|
name?: string;
|
|
@@ -49,12 +53,13 @@ export const ProfileImagePlaceholder: React.FC<
|
|
|
49
53
|
placeholderIcon,
|
|
50
54
|
disableOverlay,
|
|
51
55
|
}) => {
|
|
56
|
+
const { config } = useChatSettingState();
|
|
52
57
|
const backgroundColor = useMemo(() => {
|
|
53
58
|
if(!name) {
|
|
54
59
|
return { backgroundColor: 'transparent' };
|
|
55
60
|
}
|
|
56
|
-
return
|
|
57
|
-
}, [name]);
|
|
61
|
+
return { backgroundColor: getAvatarColor(name, config) };
|
|
62
|
+
}, [name, config]);
|
|
58
63
|
|
|
59
64
|
const getTwoUppercaseLetters = (fullName: string) => {
|
|
60
65
|
if (!fullName) {return '';}
|
|
@@ -120,10 +125,12 @@ export const ProfileImagePlaceholder: React.FC<
|
|
|
120
125
|
) : placeholderIcon ? (
|
|
121
126
|
placeholderIcon
|
|
122
127
|
) : (
|
|
123
|
-
// Black initials on the pastel hash-
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
// Black initials on the light pastel hash-colors; a dark
|
|
129
|
+
// configured colors.avatar flips them to white.
|
|
130
|
+
<InitialsText
|
|
131
|
+
size={size}
|
|
132
|
+
color={getAvatarTextColor(backgroundColor?.backgroundColor)}
|
|
133
|
+
>
|
|
127
134
|
{getInitials()}
|
|
128
135
|
</InitialsText>
|
|
129
136
|
)}
|
|
@@ -10,6 +10,7 @@ import {ToastProvider} from '../../context/ToastContext';
|
|
|
10
10
|
import LoginWrapper from './LoginWrapper';
|
|
11
11
|
import '../../helpers/storeConsole';
|
|
12
12
|
import {installPromiseRejectionTracker} from '../../utils/installPromiseRejectionTracker';
|
|
13
|
+
import {useChatFonts} from '../../hooks/useChatFonts';
|
|
13
14
|
|
|
14
15
|
// Mount-time, dev-only — wire a global unhandled-promise-rejection
|
|
15
16
|
// tracker so any future leak surfaces with a real stack trace in Metro
|
|
@@ -33,6 +34,9 @@ export const ReduxWrapper: React.FC<ChatWrapperProps> = React.memo(
|
|
|
33
34
|
return props.config;
|
|
34
35
|
}, [props.config]);
|
|
35
36
|
|
|
37
|
+
// Load + apply the host-provided font (no-op when typography is unset).
|
|
38
|
+
useChatFonts(memoizedConfig?.typography);
|
|
39
|
+
|
|
36
40
|
// Host apps that own their keyboard handling (their own
|
|
37
41
|
// KeyboardProvider + KeyboardAvoidingView around <Chat>) set
|
|
38
42
|
// `disableKeyboardAvoidingView` — drop the built-in KeyboardProvider
|
|
@@ -24,6 +24,7 @@ import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
|
24
24
|
import Button from '../styled/Button';
|
|
25
25
|
import { HeaderRoomList } from '../Header/HeaderRoomList';
|
|
26
26
|
import { HeaderRoomListMenu } from '../Menu/HeaderRoomListMenu';
|
|
27
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
27
28
|
|
|
28
29
|
const LONG_PRESS_THRESHOLD = 200;
|
|
29
30
|
|
|
@@ -165,7 +166,7 @@ const RoomList: React.FC<RoomListProps> = ({
|
|
|
165
166
|
}}
|
|
166
167
|
color="black"
|
|
167
168
|
unstyled
|
|
168
|
-
EndIcon={<BurgerMenuIcon color={config
|
|
169
|
+
EndIcon={<BurgerMenuIcon color={getIconColor(config)} />}
|
|
169
170
|
onPress={() => setOpen(!open)}
|
|
170
171
|
/>
|
|
171
172
|
)}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import styled from 'styled-components/native';
|
|
3
|
-
import {
|
|
3
|
+
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
4
|
+
import {
|
|
5
|
+
getAvatarColor,
|
|
6
|
+
getAvatarTextColor,
|
|
7
|
+
} from '../../helpers/getAvatarColor';
|
|
4
8
|
|
|
5
9
|
interface AvatarProps {
|
|
6
10
|
username?: string | null;
|
|
@@ -23,13 +27,13 @@ const AvatarCircle = styled.View<{ bgColor?: string }>`
|
|
|
23
27
|
elevation: 4;
|
|
24
28
|
`;
|
|
25
29
|
|
|
26
|
-
const AvatarText = styled.Text
|
|
30
|
+
const AvatarText = styled.Text<{ color?: string }>`
|
|
27
31
|
font-size: 16px;
|
|
28
32
|
font-weight: bold;
|
|
29
|
-
// Pastel backgrounds from
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
color: #141414;
|
|
33
|
+
// Pastel backgrounds from the hash palette are all light, so the
|
|
34
|
+
// default is dark text; a configured colors.avatar may be dark, in
|
|
35
|
+
// which case getAvatarTextColor flips this to white.
|
|
36
|
+
color: ${({ color }) => color || '#141414'};
|
|
33
37
|
`;
|
|
34
38
|
|
|
35
39
|
export const Avatar: React.FC<AvatarProps> = ({
|
|
@@ -38,12 +42,15 @@ export const Avatar: React.FC<AvatarProps> = ({
|
|
|
38
42
|
lastName,
|
|
39
43
|
style,
|
|
40
44
|
}) => {
|
|
45
|
+
const { config } = useChatSettingState();
|
|
41
46
|
const backgroundColor = useMemo(() => {
|
|
42
47
|
if (!username && !firstName) {
|
|
43
48
|
return { backgroundColor: 'transparent' };
|
|
44
49
|
}
|
|
45
|
-
return
|
|
46
|
-
|
|
50
|
+
return {
|
|
51
|
+
backgroundColor: getAvatarColor(username || firstName, config),
|
|
52
|
+
};
|
|
53
|
+
}, [username, firstName, config]);
|
|
47
54
|
|
|
48
55
|
const getInitials = () => {
|
|
49
56
|
const isAlphabetic = (char: string) => /^[a-zA-Zа-яА-ЯёЁ]$/.test(char);
|
|
@@ -78,7 +85,9 @@ export const Avatar: React.FC<AvatarProps> = ({
|
|
|
78
85
|
|
|
79
86
|
return (
|
|
80
87
|
<AvatarCircle style={style} bgColor={backgroundColor?.backgroundColor}>
|
|
81
|
-
<AvatarText
|
|
88
|
+
<AvatarText color={getAvatarTextColor(backgroundColor?.backgroundColor)}>
|
|
89
|
+
{getInitials()}
|
|
90
|
+
</AvatarText>
|
|
82
91
|
</AvatarCircle>
|
|
83
92
|
);
|
|
84
93
|
};
|
|
@@ -28,6 +28,7 @@ import MediaMessage from '../MainComponents/MediaMessage';
|
|
|
28
28
|
import MessageTranslations from './MessageTranslations';
|
|
29
29
|
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
30
30
|
import { parseMessageBody } from '../../helpers/parseMessageBody';
|
|
31
|
+
import { getSenderNameColor } from '../../helpers/getSenderNameColor';
|
|
31
32
|
import { useMessageHeapState } from '../../hooks/useMessageHeapState';
|
|
32
33
|
import { DoubleTick } from '../../assets/icons';
|
|
33
34
|
import { useXmppClient } from '../../context/xmppProvider';
|
|
@@ -367,7 +368,7 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
|
|
|
367
368
|
backgroundMessage={config?.messageColor?.backgroundMessage}
|
|
368
369
|
>
|
|
369
370
|
{!isUser && (
|
|
370
|
-
<CustomUserName color={config
|
|
371
|
+
<CustomUserName color={getSenderNameColor(config)} media={message?.isMediafile === 'true'}>
|
|
371
372
|
{message.user.name}
|
|
372
373
|
</CustomUserName>
|
|
373
374
|
)}
|
|
@@ -425,6 +426,9 @@ const Message: React.FC<MessageProps> = ({ message, isUser, isReply }) => {
|
|
|
425
426
|
! Failed — tap to retry
|
|
426
427
|
</Text>
|
|
427
428
|
)}
|
|
429
|
+
{message?.isEdited && !message?.isDeleted && (
|
|
430
|
+
<Text style={styles.editedText}>edited</Text>
|
|
431
|
+
)}
|
|
428
432
|
<Text style={styles.timestampText}>
|
|
429
433
|
{new Date(message.date).toLocaleTimeString([], {
|
|
430
434
|
hour: '2-digit',
|
|
@@ -525,4 +529,15 @@ const styles = StyleSheet.create({
|
|
|
525
529
|
includeFontPadding: false,
|
|
526
530
|
textAlignVertical: 'center',
|
|
527
531
|
},
|
|
532
|
+
// Small muted "edited" marker shown before the timestamp (Slack/WhatsApp
|
|
533
|
+
// style). Italic + same muted grey so it reads as metadata, not content.
|
|
534
|
+
editedText: {
|
|
535
|
+
fontSize: 11,
|
|
536
|
+
lineHeight: 16,
|
|
537
|
+
color: '#999',
|
|
538
|
+
fontStyle: 'italic',
|
|
539
|
+
marginRight: 6,
|
|
540
|
+
includeFontPadding: false,
|
|
541
|
+
textAlignVertical: 'center',
|
|
542
|
+
},
|
|
528
543
|
});
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
import { TextareaInput } from '../../styled/StyledInputComponents/StyledInputComponents';
|
|
11
11
|
import Button from '../../styled/Button';
|
|
12
12
|
import { Modal, Text, TextInput, View, StyleSheet } from 'react-native';
|
|
13
|
+
import { useChatSettingState } from '../../../hooks/useChatSettingState';
|
|
14
|
+
import { getIconColor } from '../../../helpers/getIconColor';
|
|
13
15
|
|
|
14
16
|
interface ModalWrapperProps {
|
|
15
17
|
iconTitle?: any;
|
|
@@ -44,6 +46,7 @@ export const ModalWrapper: FC<ModalWrapperProps> = ({
|
|
|
44
46
|
compact = false,
|
|
45
47
|
}) => {
|
|
46
48
|
const textareaRef = useRef<TextInput>(null);
|
|
49
|
+
const { config } = useChatSettingState();
|
|
47
50
|
|
|
48
51
|
// const handleInput = () => {
|
|
49
52
|
// const textarea = textareaRef.current;
|
|
@@ -73,6 +76,9 @@ export const ModalWrapper: FC<ModalWrapperProps> = ({
|
|
|
73
76
|
style={{ width: '100%' }}
|
|
74
77
|
unstyled
|
|
75
78
|
variant="outlined"
|
|
79
|
+
// Outlined Button draws its border from `backgroundColor`
|
|
80
|
+
// (defaults to the hardcoded blue) — feed it the themed color.
|
|
81
|
+
borderColor={getIconColor(config)}
|
|
76
82
|
/>
|
|
77
83
|
{buttonText && (
|
|
78
84
|
<Button
|
|
@@ -15,11 +15,12 @@ import { getTintedColor } from '../../helpers/getTintedColor';
|
|
|
15
15
|
const CustomButton = styled(TouchableOpacity)<{
|
|
16
16
|
disabled: boolean;
|
|
17
17
|
backgroundColor?: string;
|
|
18
|
+
borderColor?: string;
|
|
18
19
|
unstyled?: boolean;
|
|
19
20
|
variant?: 'default' | 'filled' | 'outlined';
|
|
20
21
|
}>`
|
|
21
22
|
border-width: ${({ variant }) => (variant === 'outlined' ? 1 : 0)}px;
|
|
22
|
-
border-color: ${({
|
|
23
|
+
border-color: ${({ borderColor }) => borderColor || '#0052CD'};
|
|
23
24
|
border-radius: 20px;
|
|
24
25
|
background-color: ${({ variant, backgroundColor }) =>
|
|
25
26
|
variant === 'filled' ? backgroundColor || '#0052CD' : 'transparent'};
|
|
@@ -52,6 +53,7 @@ export interface ButtonProps {
|
|
|
52
53
|
unstyled?: boolean;
|
|
53
54
|
variant?: 'default' | 'filled' | 'outlined';
|
|
54
55
|
backgroundColor?: string;
|
|
56
|
+
borderColor?: string;
|
|
55
57
|
color?: string;
|
|
56
58
|
style?: ViewStyle;
|
|
57
59
|
onPress?: () => void;
|
|
@@ -71,6 +73,7 @@ const Button: React.FC<ButtonProps> = ({
|
|
|
71
73
|
unstyled = false,
|
|
72
74
|
variant = 'default',
|
|
73
75
|
backgroundColor,
|
|
76
|
+
borderColor,
|
|
74
77
|
onPress,
|
|
75
78
|
StartIcon,
|
|
76
79
|
style: containerStyle,
|
|
@@ -90,6 +93,7 @@ const Button: React.FC<ButtonProps> = ({
|
|
|
90
93
|
onPress={onPress}
|
|
91
94
|
variant={variant}
|
|
92
95
|
backgroundColor={backgroundColor}
|
|
96
|
+
borderColor={borderColor}
|
|
93
97
|
>
|
|
94
98
|
{loading && <Loader size={24} />}
|
|
95
99
|
{!loading && StartIcon && <View style={styles.icon}>{StartIcon}</View>}
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import styled from 'styled-components/native';
|
|
3
3
|
import { Line } from './StyledComponents';
|
|
4
4
|
import { Text } from 'react-native';
|
|
5
|
+
import { getDateLabelColor } from '../../helpers/getDateLabelColor';
|
|
5
6
|
|
|
6
7
|
interface DateLabelProps {
|
|
7
8
|
date: Date;
|
|
8
|
-
colors?: { primary?: string; secondary?: string };
|
|
9
|
+
colors?: { primary?: string; secondary?: string; dateLabel?: string };
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
const Container = styled.View`
|
|
@@ -19,7 +20,7 @@ const Container = styled.View`
|
|
|
19
20
|
`;
|
|
20
21
|
|
|
21
22
|
export const StyledDateLabel = styled.View<{
|
|
22
|
-
|
|
23
|
+
bgColor?: string;
|
|
23
24
|
}>`
|
|
24
25
|
margin: 0;
|
|
25
26
|
border-radius: 118px;
|
|
@@ -27,11 +28,11 @@ export const StyledDateLabel = styled.View<{
|
|
|
27
28
|
flex-direction: row;
|
|
28
29
|
align-items: center;
|
|
29
30
|
justify-content: center;
|
|
30
|
-
background-color: ${(
|
|
31
|
+
background-color: ${({ bgColor }) => bgColor || '#e7edf9'};
|
|
31
32
|
`;
|
|
32
33
|
|
|
33
|
-
export const StyledDateText = styled.Text<{
|
|
34
|
-
color: ${(
|
|
34
|
+
export const StyledDateText = styled.Text<{ color?: string }>`
|
|
35
|
+
color: ${({ color }) => color || '#0052cd'};
|
|
35
36
|
font-size: 12px;
|
|
36
37
|
font-weight: 400;
|
|
37
38
|
line-height: 14px;
|
|
@@ -63,11 +64,13 @@ const DateLabel: React.FC<DateLabelProps> = ({ date, colors }) => {
|
|
|
63
64
|
label = date.toLocaleDateString('en-US', options);
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
const textColor = getDateLabelColor({ colors });
|
|
68
|
+
|
|
66
69
|
return (
|
|
67
70
|
<Container>
|
|
68
71
|
<Line />
|
|
69
|
-
<StyledDateLabel
|
|
70
|
-
<StyledDateText
|
|
72
|
+
<StyledDateLabel bgColor={colors?.secondary}>
|
|
73
|
+
<StyledDateText color={textColor}>{label}</StyledDateText>
|
|
71
74
|
</StyledDateLabel>
|
|
72
75
|
<Line />
|
|
73
76
|
</Container>
|
|
@@ -12,6 +12,7 @@ import { SendIcon, AttachIcon, RecordIcon } from '../../assets/icons';
|
|
|
12
12
|
import { KeyboardAvoidingView, Platform, View, Text, TouchableOpacity, Alert, Linking } from 'react-native';
|
|
13
13
|
import AttachSheet from '../Modals/AttachSheet/AttachSheet';
|
|
14
14
|
import { MediaFilePreview } from './MediaFilePreview';
|
|
15
|
+
import { getIconColor } from '../../helpers/getIconColor';
|
|
15
16
|
import * as ImagePicker from 'expo-image-picker';
|
|
16
17
|
import * as DocumentPicker from 'expo-document-picker';
|
|
17
18
|
import * as ImageManipulator from 'expo-image-manipulator';
|
|
@@ -486,7 +487,7 @@ const SendInput: React.FC<SendInputProps> = ({
|
|
|
486
487
|
}}
|
|
487
488
|
activeOpacity={0.7}
|
|
488
489
|
>
|
|
489
|
-
<AttachIcon color={config
|
|
490
|
+
<AttachIcon color={getIconColor(config)} />
|
|
490
491
|
</TouchableOpacity>
|
|
491
492
|
)}
|
|
492
493
|
<MessageInput
|
|
@@ -615,7 +616,7 @@ const SendInput: React.FC<SendInputProps> = ({
|
|
|
615
616
|
marginLeft: 0,
|
|
616
617
|
marginRight: 0,
|
|
617
618
|
backgroundColor: filled
|
|
618
|
-
? config
|
|
619
|
+
? getIconColor(config)
|
|
619
620
|
: 'transparent',
|
|
620
621
|
opacity: filled ? 1 : 0.5,
|
|
621
622
|
}}
|
|
@@ -629,7 +630,7 @@ const SendInput: React.FC<SendInputProps> = ({
|
|
|
629
630
|
onCamera={handleCameraSelection}
|
|
630
631
|
onGallery={handleGallerySelection}
|
|
631
632
|
onDocument={handleFileSelection}
|
|
632
|
-
primaryColor={config
|
|
633
|
+
primaryColor={getIconColor(config)}
|
|
633
634
|
/>
|
|
634
635
|
</InputContainer>
|
|
635
636
|
);
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
setLastViewedTimestamp,
|
|
46
46
|
deleteRoomMessage,
|
|
47
47
|
msgSortableMs,
|
|
48
|
+
setUnreadSyncing,
|
|
48
49
|
} from '../roomStore/roomsSlice';
|
|
49
50
|
import { runHistoryPreloadScheduler } from '../helpers/historyPreloadScheduler';
|
|
50
51
|
import { asyncLocalStorage } from '../hooks/useLocalStorage';
|
|
@@ -272,6 +273,7 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
272
273
|
devPushLog('warn', 'initBeforeLoad: time budget exceeded → failed');
|
|
273
274
|
abortController.abort();
|
|
274
275
|
inflightBootstrapKeyRef.current = '';
|
|
276
|
+
store.dispatch(setUnreadSyncing(false));
|
|
275
277
|
setProviderBootstrapStatus('failed');
|
|
276
278
|
}, BOOTSTRAP_BUDGET_MS);
|
|
277
279
|
const clearBudget = () => {
|
|
@@ -304,6 +306,7 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
304
306
|
}
|
|
305
307
|
inflightBootstrapKeyRef.current = key;
|
|
306
308
|
setProviderBootstrapStatus('running');
|
|
309
|
+
store.dispatch(setUnreadSyncing(true));
|
|
307
310
|
devPushLog('rn', 'initBeforeLoad: running', {
|
|
308
311
|
appId: config?.appId,
|
|
309
312
|
baseUrl: config?.baseUrl,
|
|
@@ -338,6 +341,7 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
338
341
|
});
|
|
339
342
|
setProviderBootstrapStatus('failed');
|
|
340
343
|
inflightBootstrapKeyRef.current = '';
|
|
344
|
+
store.dispatch(setUnreadSyncing(false));
|
|
341
345
|
return;
|
|
342
346
|
}
|
|
343
347
|
|
|
@@ -447,6 +451,7 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
447
451
|
});
|
|
448
452
|
inflightBootstrapKeyRef.current = '';
|
|
449
453
|
clearBudget();
|
|
454
|
+
store.dispatch(setUnreadSyncing(false));
|
|
450
455
|
setProviderBootstrapStatus('failed');
|
|
451
456
|
}
|
|
452
457
|
};
|
|
@@ -502,9 +507,12 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
502
507
|
if (!client) {return;}
|
|
503
508
|
const id = setInterval(() => {
|
|
504
509
|
if (AppState.currentState !== 'active') {return;}
|
|
505
|
-
if (client.
|
|
510
|
+
if (client.suppressReconnect) {return;}
|
|
511
|
+
if (client.status !== 'online') {
|
|
506
512
|
devPushLog('rn', `watchdog: client ${client.status} → forceReconnect`);
|
|
507
513
|
client.forceReconnect();
|
|
514
|
+
} else {
|
|
515
|
+
client.ensureStreamAlive?.();
|
|
508
516
|
}
|
|
509
517
|
}, 30000);
|
|
510
518
|
return () => clearInterval(id);
|
|
@@ -708,6 +716,8 @@ export const XmppProvider: React.FC<XmppProviderProps> = ({ children, config, is
|
|
|
708
716
|
if (client.status === 'offline' || client.status === 'error') {
|
|
709
717
|
devPushLog('rn', `NetInfo: reachable & client ${client.status} → forceReconnect`);
|
|
710
718
|
client.forceReconnect();
|
|
719
|
+
} else if (client.status === 'online') {
|
|
720
|
+
client.ensureStreamAlive?.();
|
|
711
721
|
}
|
|
712
722
|
});
|
|
713
723
|
return () => unsub();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { nameToColor } from './hashcolor';
|
|
2
|
+
|
|
3
|
+
// Background for initials avatars. When `colors.avatar` is set in the
|
|
4
|
+
// config every avatar uses it; otherwise each user keeps their per-name
|
|
5
|
+
// pastel from the hash palette (the current default).
|
|
6
|
+
export const getAvatarColor = (
|
|
7
|
+
name?: string | null,
|
|
8
|
+
config?: { colors?: { avatar?: string } }
|
|
9
|
+
) => config?.colors?.avatar || nameToColor(name || '')?.backgroundColor;
|
|
10
|
+
|
|
11
|
+
// The default pastels are all light, so initials are dark (#141414). A
|
|
12
|
+
// configured avatar color may be dark (e.g. brand primary) — flip the
|
|
13
|
+
// initials to white when the background is too dark to read on.
|
|
14
|
+
export const getAvatarTextColor = (bg?: string) => {
|
|
15
|
+
if (!bg || !bg.startsWith('#')) {
|
|
16
|
+
return '#141414';
|
|
17
|
+
}
|
|
18
|
+
let hex = bg.slice(1);
|
|
19
|
+
if (hex.length === 3) {
|
|
20
|
+
hex = hex
|
|
21
|
+
.split('')
|
|
22
|
+
.map((c) => c + c)
|
|
23
|
+
.join('');
|
|
24
|
+
}
|
|
25
|
+
const num = parseInt(hex.slice(0, 6), 16);
|
|
26
|
+
const r = (num >> 16) & 255;
|
|
27
|
+
const g = (num >> 8) & 255;
|
|
28
|
+
const b = num & 255;
|
|
29
|
+
const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
30
|
+
return luminance > 150 ? '#141414' : '#FFFFFF';
|
|
31
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AppState } from 'react-native';
|
|
2
2
|
import XmppClient from '../networking/xmppClient';
|
|
3
3
|
import { store } from '../roomStore';
|
|
4
|
-
import { applyRoomsPreloadBatch } from '../roomStore/roomsSlice';
|
|
4
|
+
import { applyRoomsPreloadBatch, setUnreadSyncing } from '../roomStore/roomsSlice';
|
|
5
5
|
import { IMessage, IRoom } from '../types/types';
|
|
6
6
|
|
|
7
7
|
interface HistoryPreloadSchedulerOptions {
|
|
@@ -112,6 +112,9 @@ export const runHistoryPreloadScheduler = async (
|
|
|
112
112
|
|
|
113
113
|
if (signal?.aborted) {return;}
|
|
114
114
|
|
|
115
|
+
store.dispatch(setUnreadSyncing(true));
|
|
116
|
+
try {
|
|
117
|
+
|
|
115
118
|
const state = store.getState();
|
|
116
119
|
const rooms = (state.rooms.rooms || {}) as Record<string, IRoom>;
|
|
117
120
|
const defaultSet = new Set(defaultRoomJids);
|
|
@@ -276,6 +279,9 @@ export const runHistoryPreloadScheduler = async (
|
|
|
276
279
|
// Yield to JS event loop (no requestIdleCallback in RN).
|
|
277
280
|
await new Promise((r) => setTimeout(r, 0));
|
|
278
281
|
}
|
|
282
|
+
} finally {
|
|
283
|
+
store.dispatch(setUnreadSyncing(false));
|
|
284
|
+
}
|
|
279
285
|
};
|
|
280
286
|
|
|
281
287
|
export default runHistoryPreloadScheduler;
|