stream-chat-react-native-core 9.6.0 → 9.6.1-beta.2
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/components/Channel/Channel.js +3 -0
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/commonjs/components/MessageInput/components/InputButtons/AttachButton.js +8 -2
- package/lib/commonjs/components/MessageInput/components/InputButtons/AttachButton.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/EmojiPickerList.js +3 -2
- package/lib/commonjs/components/MessageMenu/EmojiPickerList.js.map +1 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js +6 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useScreenOrientation.js +13 -0
- package/lib/commonjs/hooks/useScreenOrientation.js.map +1 -0
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +3 -0
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/module/components/MessageInput/components/InputButtons/AttachButton.js +8 -2
- package/lib/module/components/MessageInput/components/InputButtons/AttachButton.js.map +1 -1
- package/lib/module/components/MessageMenu/EmojiPickerList.js +3 -2
- package/lib/module/components/MessageMenu/EmojiPickerList.js.map +1 -1
- package/lib/module/components/UIComponents/BottomSheetModal.js +6 -1
- package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/module/hooks/index.js +11 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useScreenOrientation.js +13 -0
- package/lib/module/hooks/useScreenOrientation.js.map +1 -0
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/components/InputButtons/AttachButton.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/EmojiPickerList.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +8 -0
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
- package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useScreenOrientation.d.ts +10 -0
- package/lib/typescript/hooks/useScreenOrientation.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Channel/Channel.tsx +3 -0
- package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +2 -0
- package/src/components/MessageInput/__tests__/AttachButton.test.tsx +31 -0
- package/src/components/MessageInput/components/InputButtons/AttachButton.tsx +12 -2
- package/src/components/MessageMenu/EmojiPickerList.tsx +4 -2
- package/src/components/UIComponents/BottomSheetModal.tsx +19 -2
- package/src/contexts/messageInputContext/MessageInputContext.tsx +9 -0
- package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +2 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useScreenOrientation.ts +15 -0
- package/src/version.json +1 -1
|
@@ -15,6 +15,7 @@ export * from './useSelectedChannelState';
|
|
|
15
15
|
export * from './useStreami18n';
|
|
16
16
|
export * from './useViewport';
|
|
17
17
|
export * from './useScreenDimensions';
|
|
18
|
+
export * from './useScreenOrientation';
|
|
18
19
|
export * from './useStateStore';
|
|
19
20
|
export * from './usePendingAttachmentUpload';
|
|
20
21
|
export * from './useStableCallback';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ScreenOrientation = 'landscape' | 'portrait';
|
|
2
|
+
/**
|
|
3
|
+
* A custom hook that derives the current screen orientation from the window
|
|
4
|
+
* dimensions. It updates automatically on device rotation via
|
|
5
|
+
* `useWindowDimensions`.
|
|
6
|
+
*
|
|
7
|
+
* @returns {ScreenOrientation} Either `'landscape'` or `'portrait'`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const useScreenOrientation: () => ScreenOrientation;
|
|
10
|
+
//# sourceMappingURL=useScreenOrientation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScreenOrientation.d.ts","sourceRoot":"","sources":["../../../src/hooks/useScreenOrientation.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAAO,iBAGvC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-chat-react-native-core",
|
|
3
3
|
"description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
|
|
4
|
-
"version": "9.6.
|
|
4
|
+
"version": "9.6.1-beta.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -218,6 +218,7 @@ export type ChannelPropsWithContext = Pick<ChannelContextValue, 'channel'> &
|
|
|
218
218
|
| 'compressImageQuality'
|
|
219
219
|
| 'createPollOptionGap'
|
|
220
220
|
| 'doFileUploadRequest'
|
|
221
|
+
| 'focusInputOnPickerClose'
|
|
221
222
|
| 'handleAttachButtonPress'
|
|
222
223
|
| 'hasCameraPicker'
|
|
223
224
|
| 'hasCommands'
|
|
@@ -423,6 +424,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
|
|
|
423
424
|
enableSwipeToReply = true,
|
|
424
425
|
enforceUniqueReaction = false,
|
|
425
426
|
FlatList = NativeHandlers.FlatList,
|
|
427
|
+
focusInputOnPickerClose = true,
|
|
426
428
|
forceAlignMessages,
|
|
427
429
|
getMessageGroupStyle,
|
|
428
430
|
handleAttachButtonPress,
|
|
@@ -1651,6 +1653,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
|
|
|
1651
1653
|
createPollOptionGap,
|
|
1652
1654
|
doFileUploadRequest,
|
|
1653
1655
|
editMessage,
|
|
1656
|
+
focusInputOnPickerClose,
|
|
1654
1657
|
handleAttachButtonPress,
|
|
1655
1658
|
hasCameraPicker,
|
|
1656
1659
|
hasCommands: hasCommands ?? !!clientChannelConfig?.commands?.length,
|
|
@@ -17,6 +17,7 @@ export const useCreateInputMessageInputContext = ({
|
|
|
17
17
|
createPollOptionGap,
|
|
18
18
|
doFileUploadRequest,
|
|
19
19
|
editMessage,
|
|
20
|
+
focusInputOnPickerClose,
|
|
20
21
|
handleAttachButtonPress,
|
|
21
22
|
hasCameraPicker,
|
|
22
23
|
hasCommands,
|
|
@@ -49,6 +50,7 @@ export const useCreateInputMessageInputContext = ({
|
|
|
49
50
|
createPollOptionGap,
|
|
50
51
|
doFileUploadRequest,
|
|
51
52
|
editMessage,
|
|
53
|
+
focusInputOnPickerClose,
|
|
52
54
|
handleAttachButtonPress,
|
|
53
55
|
hasCameraPicker,
|
|
54
56
|
hasCommands,
|
|
@@ -180,4 +180,35 @@ describe('AttachButton', () => {
|
|
|
180
180
|
expect(queryByTestId('attachment-picker-list')).toBeTruthy();
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
|
+
|
|
184
|
+
it('should close the attachment picker on second press when focusInputOnPickerClose is false', async () => {
|
|
185
|
+
jest.spyOn(NativeHandler, 'isImageMediaLibraryAvailable').mockImplementation(() => true);
|
|
186
|
+
|
|
187
|
+
const channelProps = { channel, focusInputOnPickerClose: false };
|
|
188
|
+
const props = {};
|
|
189
|
+
|
|
190
|
+
renderComponent({ channelProps, client, props });
|
|
191
|
+
|
|
192
|
+
const { queryByTestId } = screen;
|
|
193
|
+
|
|
194
|
+
await waitFor(() => {
|
|
195
|
+
expect(queryByTestId('attach-button')).toBeTruthy();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
act(() => {
|
|
199
|
+
fireEvent.press(screen.getByTestId('attach-button'));
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
await waitFor(() => {
|
|
203
|
+
expect(queryByTestId('attachment-picker-list')).toBeTruthy();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
act(() => {
|
|
207
|
+
fireEvent.press(screen.getByTestId('attach-button'));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await waitFor(() => {
|
|
211
|
+
expect(queryByTestId('attachment-picker-list')).toBeNull();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
183
214
|
});
|
|
@@ -92,13 +92,23 @@ export type AttachButtonProps = Partial<AttachButtonPropsWithContext>;
|
|
|
92
92
|
*/
|
|
93
93
|
export const AttachButton = (props: AttachButtonProps) => {
|
|
94
94
|
const { disableAttachmentPicker } = useAttachmentPickerContext();
|
|
95
|
-
const {
|
|
95
|
+
const {
|
|
96
|
+
closeAttachmentPicker,
|
|
97
|
+
focusInputOnPickerClose,
|
|
98
|
+
handleAttachButtonPress,
|
|
99
|
+
inputBoxRef,
|
|
100
|
+
openAttachmentPicker,
|
|
101
|
+
} = useMessageInputContext();
|
|
96
102
|
const { attachmentPickerStore } = useAttachmentPickerContext();
|
|
97
103
|
const { selectedPicker } = useAttachmentPickerState();
|
|
98
104
|
|
|
99
105
|
const toggleAttachmentPicker = useStableCallback(() => {
|
|
100
106
|
if (attachmentPickerStore.state.getLatestValue().selectedPicker) {
|
|
101
|
-
|
|
107
|
+
if (focusInputOnPickerClose) {
|
|
108
|
+
inputBoxRef.current?.focus();
|
|
109
|
+
} else {
|
|
110
|
+
closeAttachmentPicker();
|
|
111
|
+
}
|
|
102
112
|
} else {
|
|
103
113
|
openAttachmentPicker();
|
|
104
114
|
}
|
|
@@ -13,6 +13,7 @@ import { primitives } from '../../theme';
|
|
|
13
13
|
import { StreamBottomSheetModalFlatList } from '../UIComponents';
|
|
14
14
|
|
|
15
15
|
const EMOJI_SIZE = Platform.OS === 'ios' ? 32 : 28;
|
|
16
|
+
const EMOJI_CELL_SIZE = 54;
|
|
16
17
|
|
|
17
18
|
const emojiKeyExtractor = (item: string) => `unicode-${item}`;
|
|
18
19
|
|
|
@@ -54,6 +55,7 @@ export const EmojiPickerList = ({
|
|
|
54
55
|
renderFullInitially?: boolean;
|
|
55
56
|
}) => {
|
|
56
57
|
const styles = useStyles();
|
|
58
|
+
|
|
57
59
|
const onSelectEmoji = useStableCallback((emoji: string) => {
|
|
58
60
|
const scalarString = toUnicodeScalarString(emoji);
|
|
59
61
|
onSelectReaction(scalarString);
|
|
@@ -94,9 +96,9 @@ const useStyles = () => {
|
|
|
94
96
|
StyleSheet.create({
|
|
95
97
|
bottomSheetColumnWrapper: {
|
|
96
98
|
alignItems: 'center',
|
|
97
|
-
justifyContent: '
|
|
99
|
+
justifyContent: 'space-evenly',
|
|
98
100
|
width: '100%',
|
|
99
|
-
height:
|
|
101
|
+
height: EMOJI_CELL_SIZE,
|
|
100
102
|
},
|
|
101
103
|
bottomSheetContentContainer: { paddingBottom: 16 },
|
|
102
104
|
emojiContainer: {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
StyleSheet,
|
|
19
19
|
useWindowDimensions,
|
|
20
20
|
View,
|
|
21
|
+
type ModalProps,
|
|
21
22
|
} from 'react-native';
|
|
22
23
|
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
23
24
|
import Animated, {
|
|
@@ -43,9 +44,19 @@ import { useAnnounceOnShow } from '../../a11y/hooks/useAnnounceOnShow';
|
|
|
43
44
|
import { useResolvedModalAccessibilityProps } from '../../a11y/hooks/useResolvedModalAccessibilityProps';
|
|
44
45
|
import { BottomSheetProvider } from '../../contexts/bottomSheetContext/BottomSheetContext';
|
|
45
46
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
46
|
-
import { useStableCallback } from '../../hooks';
|
|
47
|
+
import { useScreenOrientation, useStableCallback } from '../../hooks';
|
|
47
48
|
import { primitives } from '../../theme';
|
|
48
49
|
|
|
50
|
+
const supportedOrientations: ModalProps['supportedOrientations'] = [
|
|
51
|
+
'portrait',
|
|
52
|
+
'portrait-upside-down',
|
|
53
|
+
'landscape',
|
|
54
|
+
'landscape-left',
|
|
55
|
+
'landscape-right',
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const LANDSCAPE_MAX_HEIGHT_RATIO = 0.9;
|
|
59
|
+
|
|
49
60
|
export type BottomSheetModalProps = {
|
|
50
61
|
/**
|
|
51
62
|
* Function to call when the modal is closed or dismissed.
|
|
@@ -90,11 +101,16 @@ const BottomSheetModalInner = (props: PropsWithChildren<BottomSheetModalProps>)
|
|
|
90
101
|
},
|
|
91
102
|
} = useTheme();
|
|
92
103
|
const styles = useStyles();
|
|
104
|
+
const isLandscape = useScreenOrientation() === 'landscape';
|
|
93
105
|
|
|
94
|
-
const
|
|
106
|
+
const availableHeight = Math.max(
|
|
95
107
|
0,
|
|
96
108
|
windowHeight - topInset - (Platform.OS === 'android' ? bottomInset + 16 : 0),
|
|
97
109
|
);
|
|
110
|
+
|
|
111
|
+
const maxHeight = isLandscape
|
|
112
|
+
? Math.round(availableHeight * LANDSCAPE_MAX_HEIGHT_RATIO)
|
|
113
|
+
: availableHeight;
|
|
98
114
|
const fixedBaseHeight = Math.min(height, maxHeight);
|
|
99
115
|
|
|
100
116
|
const contentHeight = useSharedValue<number | undefined>(undefined);
|
|
@@ -574,6 +590,7 @@ const BottomSheetModalInner = (props: PropsWithChildren<BottomSheetModalProps>)
|
|
|
574
590
|
<Modal
|
|
575
591
|
onDismiss={handleNativeModalDismiss}
|
|
576
592
|
onRequestClose={onClose}
|
|
593
|
+
supportedOrientations={supportedOrientations}
|
|
577
594
|
transparent
|
|
578
595
|
visible={visible && !isDismissing}
|
|
579
596
|
>
|
|
@@ -128,6 +128,15 @@ export type InputMessageInputContextValue = {
|
|
|
128
128
|
options?: UpdateMessageOptions;
|
|
129
129
|
}) => ReturnType<StreamChat['updateMessage']>;
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Controls what happens when the attach button is pressed while the attachment picker is open.
|
|
133
|
+
* When true (default), the message input is focused, toggling from the picker to the keyboard.
|
|
134
|
+
* When false, the attachment picker is closed without focusing the input.
|
|
135
|
+
* @type boolean
|
|
136
|
+
* @default true
|
|
137
|
+
*/
|
|
138
|
+
focusInputOnPickerClose: boolean;
|
|
139
|
+
|
|
131
140
|
/** When false, CameraSelectorIcon will be hidden */
|
|
132
141
|
hasCameraPicker: boolean;
|
|
133
142
|
|
|
@@ -18,6 +18,7 @@ export const useCreateMessageInputContext = ({
|
|
|
18
18
|
compressImageQuality,
|
|
19
19
|
createPollOptionGap,
|
|
20
20
|
editMessage,
|
|
21
|
+
focusInputOnPickerClose,
|
|
21
22
|
handleAttachButtonPress,
|
|
22
23
|
hasCameraPicker,
|
|
23
24
|
hasCommands,
|
|
@@ -61,6 +62,7 @@ export const useCreateMessageInputContext = ({
|
|
|
61
62
|
compressImageQuality,
|
|
62
63
|
createPollOptionGap,
|
|
63
64
|
editMessage,
|
|
65
|
+
focusInputOnPickerClose,
|
|
64
66
|
handleAttachButtonPress,
|
|
65
67
|
hasCameraPicker,
|
|
66
68
|
hasCommands,
|
package/src/hooks/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from './useSelectedChannelState';
|
|
|
15
15
|
export * from './useStreami18n';
|
|
16
16
|
export * from './useViewport';
|
|
17
17
|
export * from './useScreenDimensions';
|
|
18
|
+
export * from './useScreenOrientation';
|
|
18
19
|
export * from './useStateStore';
|
|
19
20
|
export * from './usePendingAttachmentUpload';
|
|
20
21
|
export * from './useStableCallback';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useWindowDimensions } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export type ScreenOrientation = 'landscape' | 'portrait';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A custom hook that derives the current screen orientation from the window
|
|
7
|
+
* dimensions. It updates automatically on device rotation via
|
|
8
|
+
* `useWindowDimensions`.
|
|
9
|
+
*
|
|
10
|
+
* @returns {ScreenOrientation} Either `'landscape'` or `'portrait'`.
|
|
11
|
+
*/
|
|
12
|
+
export const useScreenOrientation = (): ScreenOrientation => {
|
|
13
|
+
const { height, width } = useWindowDimensions();
|
|
14
|
+
return width > height ? 'landscape' : 'portrait';
|
|
15
|
+
};
|
package/src/version.json
CHANGED