@ethora/chat-component-rn 26.7.2 → 26.7.4
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/CHANGELOG.md +45 -0
- package/README.md +9 -8
- package/lib/commonjs/assets/icons.js +7 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/Header/HeaderRoomList.js +20 -6
- package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +86 -7
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +18 -0
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +11 -4
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js +5 -5
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +62 -32
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +208 -70
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +307 -99
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +544 -200
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +226 -0
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +6 -2
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js +8 -0
- package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js +202 -104
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js +556 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js +210 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +507 -244
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +74 -46
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/commonjs/components/Modals/styledModalComponents.js +9 -2
- package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +17 -7
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +80 -1
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/StyledComponents.js +9 -3
- package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +12 -0
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/getChatBackground.js +23 -0
- package/lib/commonjs/helpers/getChatBackground.js.map +1 -0
- package/lib/commonjs/helpers/historyPreloadScheduler.js +65 -2
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/helpers/mediaLibraryRuntime.js +31 -0
- package/lib/commonjs/helpers/mediaLibraryRuntime.js.map +1 -0
- package/lib/commonjs/helpers/shallowEqual.js +36 -0
- package/lib/commonjs/helpers/shallowEqual.js.map +1 -0
- package/lib/commonjs/helpers/sheetGestures.js +32 -0
- package/lib/commonjs/helpers/sheetGestures.js.map +1 -0
- package/lib/commonjs/hooks/useChatWrapperInit.js +15 -0
- package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/commonjs/hooks/useComposing.js +27 -0
- package/lib/commonjs/hooks/useComposing.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +27 -1
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js +6 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/commonjs/i18n/strings.js +121 -1
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/networking/api-requests/user.api.js +59 -0
- package/lib/commonjs/networking/api-requests/user.api.js.map +1 -1
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +6 -2
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js +3 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +2 -2
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/assets/icons.js +6 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/Header/HeaderRoomList.js +20 -6
- package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +87 -8
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +19 -1
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +11 -4
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js +5 -5
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +62 -32
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/Menu/HeaderRoomListMenu.js +211 -73
- package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js +298 -102
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +547 -204
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +223 -0
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +6 -2
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/Modals/Modal/Modal.js +9 -1
- package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js +205 -106
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js +548 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js +205 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +509 -248
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +76 -48
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/module/components/Modals/styledModalComponents.js +9 -2
- package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/module/components/RoomComponents/ChatRoomItem.js +17 -7
- package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +80 -1
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/StyledComponents.js +9 -3
- package/lib/module/components/styled/StyledComponents.js.map +1 -1
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/module/context/xmppProvider.js +12 -0
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/getChatBackground.js +18 -0
- package/lib/module/helpers/getChatBackground.js.map +1 -0
- package/lib/module/helpers/historyPreloadScheduler.js +66 -3
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/helpers/mediaLibraryRuntime.js +25 -0
- package/lib/module/helpers/mediaLibraryRuntime.js.map +1 -0
- package/lib/module/helpers/shallowEqual.js +31 -0
- package/lib/module/helpers/shallowEqual.js.map +1 -0
- package/lib/module/helpers/sheetGestures.js +26 -0
- package/lib/module/helpers/sheetGestures.js.map +1 -0
- package/lib/module/hooks/useChatWrapperInit.js +15 -0
- package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/module/hooks/useComposing.js +28 -1
- package/lib/module/hooks/useComposing.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +28 -2
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js +6 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/module/i18n/strings.js +121 -1
- package/lib/module/i18n/strings.js.map +1 -1
- package/lib/module/networking/api-requests/user.api.js +56 -0
- package/lib/module/networking/api-requests/user.api.js.map +1 -1
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +6 -2
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/chatSettingsSlice.js +3 -1
- package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +1 -1
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/typescript/assets/icons.d.ts +12 -0
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts +10 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
- package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts +9 -0
- package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts +10 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts +9 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts.map +1 -0
- package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts +1 -1
- package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts +75 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts.map +1 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts +25 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts.map +1 -0
- package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts +6 -1
- package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts +16 -0
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts +1 -0
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledInputComponents/StyledInputComponents.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/getChatBackground.d.ts +15 -0
- package/lib/typescript/helpers/getChatBackground.d.ts.map +1 -0
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
- package/lib/typescript/helpers/mediaLibraryRuntime.d.ts +3 -0
- package/lib/typescript/helpers/mediaLibraryRuntime.d.ts.map +1 -0
- package/lib/typescript/helpers/shallowEqual.d.ts +11 -0
- package/lib/typescript/helpers/shallowEqual.d.ts.map +1 -0
- package/lib/typescript/helpers/sheetGestures.d.ts +20 -0
- package/lib/typescript/helpers/sheetGestures.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
- package/lib/typescript/hooks/useComposing.d.ts.map +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/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/user.api.d.ts +27 -0
- package/lib/typescript/networking/api-requests/user.api.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +1 -0
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +1 -0
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +1 -0
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +9 -5
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/assets/icons.tsx +29 -9
- package/src/components/Header/HeaderRoomList.tsx +20 -5
- package/src/components/MainComponents/ChatRoom.tsx +92 -8
- package/src/components/MainComponents/ChatWrapper.tsx +19 -1
- package/src/components/MainComponents/MessageList.tsx +21 -3
- package/src/components/MainComponents/ProfileImagePlaceholder.tsx +5 -5
- package/src/components/MainComponents/RoomList.tsx +65 -34
- package/src/components/Menu/HeaderRoomListMenu.tsx +209 -64
- package/src/components/Modals/AttachSheet/AttachSheet.tsx +318 -86
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +599 -278
- package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +244 -0
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +4 -2
- package/src/components/Modals/Modal/Modal.tsx +7 -0
- package/src/components/Modals/NewChatModal/NewChatModal.tsx +219 -117
- package/src/components/Modals/ProfileHeader/ProfileHeader.tsx +615 -0
- package/src/components/Modals/ProfileHeader/ProfileMenu.tsx +217 -0
- package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +14 -4
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +617 -307
- package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +75 -58
- package/src/components/Modals/styledModalComponents.tsx +9 -2
- package/src/components/RoomComponents/ChatRoomItem.tsx +14 -7
- package/src/components/styled/SendInput.tsx +83 -2
- package/src/components/styled/StyledComponents.ts +9 -3
- package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +11 -4
- package/src/context/xmppProvider.tsx +14 -0
- package/src/helpers/getChatBackground.ts +18 -0
- package/src/helpers/historyPreloadScheduler.ts +80 -3
- package/src/helpers/mediaLibraryRuntime.ts +25 -0
- package/src/helpers/shallowEqual.ts +33 -0
- package/src/helpers/sheetGestures.ts +25 -0
- package/src/hooks/useChatWrapperInit.ts +15 -0
- package/src/hooks/useComposing.tsx +37 -1
- package/src/hooks/useSendMessage.tsx +32 -2
- package/src/hooks/useUnreadMessagesCounter.ts +11 -0
- package/src/i18n/strings.ts +121 -1
- package/src/networking/api-requests/user.api.ts +71 -0
- package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +17 -3
- package/src/networking/xmppClient.ts +5 -1
- package/src/roomStore/chatSettingsSlice.ts +3 -1
- package/src/roomStore/roomsSlice.ts +1 -1
- package/src/types/types.ts +16 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC, useMemo } from 'react';
|
|
1
|
+
import React, { FC, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Alert,
|
|
4
4
|
Animated,
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
TouchableWithoutFeedback,
|
|
8
8
|
StyleSheet,
|
|
9
9
|
Dimensions,
|
|
10
|
+
Modal,
|
|
11
|
+
PanResponder,
|
|
10
12
|
View,
|
|
11
13
|
} from 'react-native';
|
|
12
14
|
import {
|
|
@@ -16,10 +18,15 @@ import {
|
|
|
16
18
|
SettingIcon,
|
|
17
19
|
} from '../../assets/icons';
|
|
18
20
|
import { useDispatch } from 'react-redux';
|
|
21
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
19
22
|
import { setActiveModal } from '../../roomStore/chatSettingsSlice';
|
|
20
23
|
import { MODAL_TYPES } from '../../helpers/constants/MODAL_TYPES';
|
|
21
24
|
import { useChatSettingState } from '../../hooks/useChatSettingState';
|
|
22
25
|
import { useLogout } from '../../hooks/useLogout';
|
|
26
|
+
import {
|
|
27
|
+
shouldClaimVerticalDrag,
|
|
28
|
+
shouldDismissOnDrag,
|
|
29
|
+
} from '../../helpers/sheetGestures';
|
|
23
30
|
import type { IConfig } from '../../types/types';
|
|
24
31
|
|
|
25
32
|
type LogoutConfig = NonNullable<IConfig['logout']>;
|
|
@@ -85,7 +92,7 @@ export const runLogoutFlow = async (
|
|
|
85
92
|
}
|
|
86
93
|
};
|
|
87
94
|
|
|
88
|
-
const {
|
|
95
|
+
const { height: windowHeight } = Dimensions.get('window');
|
|
89
96
|
|
|
90
97
|
interface HeaderRoomListMenuProps {
|
|
91
98
|
isDrawerOpen: boolean;
|
|
@@ -106,11 +113,102 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
|
|
|
106
113
|
const logoutConfig = config?.logout?.enabled ? config.logout : undefined;
|
|
107
114
|
const primaryColor = config?.colors?.primary ?? '#0052CD';
|
|
108
115
|
|
|
109
|
-
const
|
|
116
|
+
const insets = useSafeAreaInsets();
|
|
117
|
+
// Measured, so the sheet is exactly as tall as its rows and starts
|
|
118
|
+
// fully off-screen no matter how many options the host enables.
|
|
119
|
+
const [sheetHeight, setSheetHeight] = useState(windowHeight * 0.4);
|
|
120
|
+
// Finger offset, layered on top of the open/close animation the parent
|
|
121
|
+
// drives. Reset once the sheet is unmounted, so a swipe-dismissed sheet
|
|
122
|
+
// never snaps back into view on its way out.
|
|
123
|
+
const dragY = useRef(new Animated.Value(0)).current;
|
|
124
|
+
const sheetHeightRef = useRef(sheetHeight);
|
|
125
|
+
sheetHeightRef.current = sheetHeight;
|
|
126
|
+
|
|
127
|
+
// closeDrawer is a fresh function each render; the responder is built
|
|
128
|
+
// once, so it reads the current one through a ref rather than the one it
|
|
129
|
+
// closed over on mount.
|
|
130
|
+
const closeDrawerRef = useRef(closeDrawer);
|
|
131
|
+
closeDrawerRef.current = closeDrawer;
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!isDrawerOpen) {
|
|
135
|
+
dragY.setValue(0);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Hand `dragY` to the native driver up front. The open/close value is
|
|
139
|
+
// already native (the parent animates it that way), and a transform
|
|
140
|
+
// that mixes a native node with a JS-only one drops the JS updates on
|
|
141
|
+
// the floor — which is exactly a drag that moves nothing.
|
|
142
|
+
Animated.timing(dragY, {
|
|
143
|
+
toValue: 0,
|
|
144
|
+
duration: 0,
|
|
145
|
+
useNativeDriver: true,
|
|
146
|
+
}).start();
|
|
147
|
+
}, [isDrawerOpen, dragY]);
|
|
148
|
+
|
|
149
|
+
const openTranslateY = drawerAnimation.interpolate({
|
|
110
150
|
inputRange: [0, 1],
|
|
111
|
-
outputRange: [
|
|
151
|
+
outputRange: [sheetHeight, 0],
|
|
112
152
|
});
|
|
113
153
|
|
|
154
|
+
const dismissByDrag = () => {
|
|
155
|
+
Animated.timing(dragY, {
|
|
156
|
+
toValue: sheetHeightRef.current,
|
|
157
|
+
duration: 180,
|
|
158
|
+
useNativeDriver: true,
|
|
159
|
+
}).start();
|
|
160
|
+
closeDrawerRef.current();
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const makeDragResponder = (claimOnStart: boolean) =>
|
|
164
|
+
PanResponder.create({
|
|
165
|
+
// The grab area claims on touch-DOWN: nothing to negotiate against,
|
|
166
|
+
// so a pull on the handle always drags.
|
|
167
|
+
onStartShouldSetPanResponder: () => claimOnStart,
|
|
168
|
+
// CAPTURE matters on the body: a drag that starts on a row makes
|
|
169
|
+
// that row's Touchable the responder on touch-down, and a plain
|
|
170
|
+
// `onMoveShouldSetPanResponder` is never consulted afterwards.
|
|
171
|
+
// Capturing on the first clearly-vertical movement takes the gesture
|
|
172
|
+
// back, while a tap (dy ≈ 0) still reaches the row.
|
|
173
|
+
onMoveShouldSetPanResponderCapture: (_evt, g) =>
|
|
174
|
+
claimOnStart || shouldClaimVerticalDrag(g.dy, g.dx),
|
|
175
|
+
onMoveShouldSetPanResponder: (_evt, g) =>
|
|
176
|
+
claimOnStart || shouldClaimVerticalDrag(g.dy, g.dx),
|
|
177
|
+
onPanResponderTerminationRequest: () => false,
|
|
178
|
+
onPanResponderMove: (_evt, g) => {
|
|
179
|
+
dragY.setValue(Math.max(0, g.dy));
|
|
180
|
+
},
|
|
181
|
+
onPanResponderRelease: (_evt, g) => {
|
|
182
|
+
if (shouldDismissOnDrag(g.dy, g.vy)) {
|
|
183
|
+
dismissByDrag();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
Animated.spring(dragY, {
|
|
187
|
+
toValue: 0,
|
|
188
|
+
tension: 90,
|
|
189
|
+
friction: 14,
|
|
190
|
+
useNativeDriver: true,
|
|
191
|
+
}).start();
|
|
192
|
+
},
|
|
193
|
+
onPanResponderTerminate: () => {
|
|
194
|
+
Animated.spring(dragY, {
|
|
195
|
+
toValue: 0,
|
|
196
|
+
tension: 90,
|
|
197
|
+
friction: 14,
|
|
198
|
+
useNativeDriver: true,
|
|
199
|
+
}).start();
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Built once — `useRef(expr)` would re-run PanResponder.create every
|
|
204
|
+
// render and throw the result away.
|
|
205
|
+
const bodyPanRef = useRef<ReturnType<typeof makeDragResponder> | null>(null);
|
|
206
|
+
const handlePanRef = useRef<ReturnType<typeof makeDragResponder> | null>(null);
|
|
207
|
+
if (!bodyPanRef.current) {bodyPanRef.current = makeDragResponder(false);}
|
|
208
|
+
if (!handlePanRef.current) {handlePanRef.current = makeDragResponder(true);}
|
|
209
|
+
const pan = bodyPanRef.current;
|
|
210
|
+
const handlePan = handlePanRef.current;
|
|
211
|
+
|
|
114
212
|
const menuOptions = useMemo(() => {
|
|
115
213
|
const options: {
|
|
116
214
|
label: string;
|
|
@@ -122,7 +220,7 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
|
|
|
122
220
|
}[] = [
|
|
123
221
|
{
|
|
124
222
|
label: 'New Chat',
|
|
125
|
-
icon: <AddNewIcon color=
|
|
223
|
+
icon: <AddNewIcon color={primaryColor} />,
|
|
126
224
|
onClick: () => {
|
|
127
225
|
dispatch(setActiveModal(MODAL_TYPES.NEW_CHAT));
|
|
128
226
|
console.log('New chat clicked');
|
|
@@ -131,7 +229,7 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
|
|
|
131
229
|
},
|
|
132
230
|
{
|
|
133
231
|
label: 'Profile',
|
|
134
|
-
icon: <ProfileIcon color=
|
|
232
|
+
icon: <ProfileIcon color={primaryColor} />,
|
|
135
233
|
onClick: () => {
|
|
136
234
|
dispatch(setActiveModal(MODAL_TYPES.PROFILE));
|
|
137
235
|
console.log('Profile clicked');
|
|
@@ -139,7 +237,7 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
|
|
|
139
237
|
},
|
|
140
238
|
{
|
|
141
239
|
label: 'Settings',
|
|
142
|
-
icon: <SettingIcon color=
|
|
240
|
+
icon: <SettingIcon color={primaryColor} />,
|
|
143
241
|
onClick: () => {
|
|
144
242
|
dispatch(setActiveModal(MODAL_TYPES.SETTINGS));
|
|
145
243
|
console.log('Settings clicked');
|
|
@@ -162,47 +260,80 @@ export const HeaderRoomListMenu: FC<HeaderRoomListMenuProps> = ({
|
|
|
162
260
|
}, [dispatch, logoutConfig, performLogout, primaryColor, closeDrawer]);
|
|
163
261
|
|
|
164
262
|
return (
|
|
165
|
-
|
|
263
|
+
// Presented through a real <Modal>: as an in-tree overlay the sheet was
|
|
264
|
+
// bounded by the room list's own container, so it stopped short of the
|
|
265
|
+
// screen's bottom edge (that pale strip under it) and the dim never
|
|
266
|
+
// reached the host's chrome.
|
|
267
|
+
<Modal
|
|
268
|
+
transparent
|
|
269
|
+
visible={isDrawerOpen}
|
|
270
|
+
animationType="none"
|
|
271
|
+
statusBarTranslucent
|
|
272
|
+
onRequestClose={closeDrawer}
|
|
273
|
+
>
|
|
274
|
+
<TouchableWithoutFeedback onPress={closeDrawer}>
|
|
275
|
+
<Animated.View
|
|
276
|
+
style={[styles.overlay, { opacity: overlayAnimation }]}
|
|
277
|
+
/>
|
|
278
|
+
</TouchableWithoutFeedback>
|
|
279
|
+
{/* A bottom sheet rather than the old full-height right-hand drawer:
|
|
280
|
+
* three rows never needed the whole screen, and coming up from the
|
|
281
|
+
* bottom keeps them within thumb reach. Inset by 2pt all round so a
|
|
282
|
+
* sliver of the dimmed screen shows around it. */}
|
|
166
283
|
<Animated.View
|
|
284
|
+
testID="header-menu-sheet"
|
|
285
|
+
onLayout={(e) => {
|
|
286
|
+
const measured = e.nativeEvent.layout.height;
|
|
287
|
+
if (measured > 0) {setSheetHeight(measured);}
|
|
288
|
+
}}
|
|
167
289
|
style={[
|
|
168
|
-
styles.
|
|
169
|
-
{
|
|
290
|
+
styles.sheet,
|
|
291
|
+
{
|
|
292
|
+
paddingBottom: insets.bottom + 20,
|
|
293
|
+
// Two entries rather than Animated.add: the parent's value is
|
|
294
|
+
// driven natively, and stacking the transforms keeps each node
|
|
295
|
+
// on its own driver instead of mixing them in one expression.
|
|
296
|
+
transform: [{ translateY: openTranslateY }, { translateY: dragY }],
|
|
297
|
+
},
|
|
170
298
|
]}
|
|
299
|
+
{...pan.panHandlers}
|
|
171
300
|
>
|
|
172
|
-
{
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
>
|
|
184
|
-
<
|
|
185
|
-
style={
|
|
186
|
-
|
|
187
|
-
|
|
301
|
+
{/* Full-width grab area, not just the 40pt pill: it claims the
|
|
302
|
+
* gesture the moment it is touched. */}
|
|
303
|
+
<View
|
|
304
|
+
testID="header-menu-grabber"
|
|
305
|
+
style={styles.grabArea}
|
|
306
|
+
{...handlePan.panHandlers}
|
|
307
|
+
>
|
|
308
|
+
<View style={styles.grabber} />
|
|
309
|
+
</View>
|
|
310
|
+
<View style={styles.card}>
|
|
311
|
+
{menuOptions.map((option, index) => (
|
|
312
|
+
<View key={index} style={styles.menuItemWrapper}>
|
|
313
|
+
<TouchableOpacity
|
|
314
|
+
style={styles.menuItem}
|
|
315
|
+
testID={`header-menu-${option.label}`}
|
|
316
|
+
activeOpacity={0.6}
|
|
317
|
+
onPress={() => {
|
|
318
|
+
option.onClick();
|
|
319
|
+
if (!option.closesDrawer) {
|
|
320
|
+
closeDrawer();
|
|
321
|
+
}
|
|
188
322
|
}}
|
|
189
323
|
>
|
|
190
|
-
{option.icon}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
324
|
+
<View style={styles.iconSlot}>{option.icon}</View>
|
|
325
|
+
<Text style={[styles.label, option?.styles]}>
|
|
326
|
+
{option.label}
|
|
327
|
+
</Text>
|
|
328
|
+
</TouchableOpacity>
|
|
329
|
+
{index < menuOptions.length - 1 && (
|
|
330
|
+
<View style={styles.divider} />
|
|
331
|
+
)}
|
|
332
|
+
</View>
|
|
333
|
+
))}
|
|
334
|
+
</View>
|
|
197
335
|
</Animated.View>
|
|
198
|
-
|
|
199
|
-
<TouchableWithoutFeedback onPress={closeDrawer}>
|
|
200
|
-
<Animated.View
|
|
201
|
-
style={[styles.overlay, { opacity: overlayAnimation }]}
|
|
202
|
-
/>
|
|
203
|
-
</TouchableWithoutFeedback>
|
|
204
|
-
)}
|
|
205
|
-
</>
|
|
336
|
+
</Modal>
|
|
206
337
|
);
|
|
207
338
|
};
|
|
208
339
|
|
|
@@ -214,40 +345,54 @@ const styles = StyleSheet.create({
|
|
|
214
345
|
menuItem: {
|
|
215
346
|
flexDirection: 'row',
|
|
216
347
|
alignItems: 'center',
|
|
217
|
-
|
|
348
|
+
paddingVertical: 18,
|
|
349
|
+
paddingHorizontal: 16,
|
|
350
|
+
},
|
|
351
|
+
iconSlot: {
|
|
352
|
+
width: 26,
|
|
353
|
+
alignItems: 'center',
|
|
218
354
|
},
|
|
219
355
|
label: {
|
|
220
356
|
fontSize: 16,
|
|
221
|
-
|
|
357
|
+
fontWeight: '500',
|
|
358
|
+
color: '#141414',
|
|
359
|
+
marginLeft: 12,
|
|
222
360
|
},
|
|
223
361
|
divider: {
|
|
224
|
-
height:
|
|
225
|
-
|
|
226
|
-
backgroundColor: '#
|
|
362
|
+
height: StyleSheet.hairlineWidth,
|
|
363
|
+
marginLeft: 54,
|
|
364
|
+
backgroundColor: '#E4E4E9',
|
|
227
365
|
},
|
|
228
|
-
|
|
366
|
+
sheet: {
|
|
229
367
|
position: 'absolute',
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
368
|
+
// Inset rather than flush: the dimmed screen stays visible as a thin
|
|
369
|
+
// line around the sheet.
|
|
370
|
+
left: 3,
|
|
371
|
+
right: 3,
|
|
372
|
+
bottom: 3,
|
|
373
|
+
paddingTop: 8,
|
|
374
|
+
backgroundColor: '#FFFFFF',
|
|
375
|
+
borderRadius: 20,
|
|
236
376
|
shadowColor: '#000',
|
|
237
|
-
shadowOpacity: 0.
|
|
238
|
-
shadowOffset: { width:
|
|
239
|
-
shadowRadius:
|
|
240
|
-
elevation:
|
|
377
|
+
shadowOpacity: 0.12,
|
|
378
|
+
shadowOffset: { width: 0, height: -3 },
|
|
379
|
+
shadowRadius: 12,
|
|
380
|
+
elevation: 12,
|
|
241
381
|
zIndex: 999,
|
|
242
382
|
},
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
383
|
+
grabArea: {
|
|
384
|
+
alignItems: 'center',
|
|
385
|
+
paddingTop: 6,
|
|
386
|
+
paddingBottom: 12,
|
|
387
|
+
},
|
|
388
|
+
grabber: {
|
|
389
|
+
width: 40,
|
|
390
|
+
height: 4,
|
|
391
|
+
borderRadius: 2,
|
|
392
|
+
backgroundColor: '#C9CBD1',
|
|
247
393
|
},
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
marginBottom: 10,
|
|
394
|
+
card: {
|
|
395
|
+
overflow: 'hidden',
|
|
251
396
|
},
|
|
252
397
|
overlay: {
|
|
253
398
|
position: 'absolute',
|