Skip to content

Commit

Permalink
fix(uikit): support compatibility for removing AppState listener unde…
Browse files Browse the repository at this point in the history
…r 0.65
  • Loading branch information
bang9 committed Jan 25, 2023
1 parent 0aa38d1 commit b122691
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 52 deletions.
20 changes: 7 additions & 13 deletions packages/uikit-react-native/src/contexts/SendbirdChatCtx.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react';
import { AppState, AppStateStatus } from 'react-native';
import React, { useCallback, useState } from 'react';

import { useAppFeatures } from '@sendbird/uikit-chat-hooks';
import type {
Expand All @@ -8,7 +7,7 @@ import type {
SendbirdUser,
SendbirdUserUpdateParams,
} from '@sendbird/uikit-utils';
import { confirmAndMarkAsDelivered, useForceUpdate } from '@sendbird/uikit-utils';
import { confirmAndMarkAsDelivered, useAppState, useForceUpdate } from '@sendbird/uikit-utils';

import type EmojiManager from '../libs/EmojiManager';
import type ImageCompressionConfig from '../libs/ImageCompressionConfig';
Expand Down Expand Up @@ -123,16 +122,11 @@ export const SendbirdChatProvider = ({
[sdkInstance, appFeatures.deliveryReceiptEnabled],
);

useEffect(() => {
const listener = (status: AppStateStatus) => {
// 'active' | 'background' | 'inactive' | 'unknown' | 'extension';
if (status === 'active') sdkInstance.connectionState === 'CLOSED' && sdkInstance.setForegroundState();
else if (status === 'background') sdkInstance.connectionState === 'OPEN' && sdkInstance.setBackgroundState();
};

const subscriber = AppState.addEventListener('change', listener);
return () => subscriber.remove();
}, [sdkInstance]);
useAppState('change', (status) => {
// 'active' | 'background' | 'inactive' | 'unknown' | 'extension';
if (status === 'active') sdkInstance.connectionState === 'CLOSED' && sdkInstance.setForegroundState();
else if (status === 'background') sdkInstance.connectionState === 'OPEN' && sdkInstance.setBackgroundState();
});

const value: Context = {
sdk: sdkInstance,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect } from 'react';
import { AppState } from 'react-native';
import React from 'react';

import { useGroupChannelList } from '@sendbird/uikit-chat-hooks';
import { PASS, useFreshCallback } from '@sendbird/uikit-utils';
import { PASS, useAppState, useFreshCallback } from '@sendbird/uikit-utils';

import StatusComposition from '../components/StatusComposition';
import GroupChannelPreviewContainer from '../containers/GroupChannelPreviewContainer';
Expand Down Expand Up @@ -34,12 +33,9 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
});

if (features.deliveryReceiptEnabled) {
useEffect(() => {
const listener = AppState.addEventListener('change', (status) => {
if (status === 'active') groupChannels.forEach(markAsDeliveredWithChannel);
});
return () => listener.remove();
}, []);
useAppState('change', (status) => {
if (status === 'active') groupChannels.forEach(markAsDeliveredWithChannel);
});
}

const _renderGroupChannelPreview: GroupChannelListProps['List']['renderGroupChannelPreview'] = useFreshCallback(
Expand Down
1 change: 1 addition & 0 deletions packages/uikit-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
},
"devDependencies": {
"@types/react": "*",
"@types/react-native": "*",
"react": "17.0.2",
"react-native": "0.67.4",
"react-native-builder-bob": "^0.18.0",
Expand Down
31 changes: 1 addition & 30 deletions packages/uikit-utils/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { DependencyList } from 'react';
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';

type Destructor = () => void;
type AsyncEffectCallback = () => void | Destructor | Promise<void> | Promise<Destructor>;
Expand Down Expand Up @@ -73,31 +72,3 @@ export const useFreshCallback = <T extends (...args: any[]) => any>(callback: T)
ref.current = callback;
return useCallback(((...args) => ref.current(...args)) as T, []);
};

type EdgePaddingMap = {
left: 'paddingLeft';
right: 'paddingRight';
top: 'paddingTop';
bottom: 'paddingBottom';
};
const edgePaddingMap: EdgePaddingMap = {
left: 'paddingLeft',
right: 'paddingRight',
top: 'paddingTop',
bottom: 'paddingBottom',
};
export const useSafeAreaPadding = <
T extends keyof EdgeInsets,
Result extends { [key in EdgePaddingMap[T]]: EdgeInsets[T] },
>(
edges: T[],
): Result => {
const safeAreaInsets = useSafeAreaInsets();
return useMemo(() => {
return edges.reduce((map, edge) => {
const paddingKey = edgePaddingMap[edge];
map[paddingKey] = safeAreaInsets[edge];
return map;
}, {} as { [key in EdgePaddingMap[T]]: EdgeInsets[T] });
}, edges) as Result;
};
56 changes: 56 additions & 0 deletions packages/uikit-utils/src/hooks/react-native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useEffect, useMemo, useRef } from 'react';
import { AppState, AppStateEvent, AppStateStatus } from 'react-native';
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';

type EdgePaddingMap = {
left: 'paddingLeft';
right: 'paddingRight';
top: 'paddingTop';
bottom: 'paddingBottom';
};
const edgePaddingMap: EdgePaddingMap = {
left: 'paddingLeft',
right: 'paddingRight',
top: 'paddingTop',
bottom: 'paddingBottom',
};

export const useSafeAreaPadding = <
T extends keyof EdgeInsets,
Result extends { [key in EdgePaddingMap[T]]: EdgeInsets[T] },
>(
edges: T[],
): Result => {
const safeAreaInsets = useSafeAreaInsets();
return useMemo(() => {
return edges.reduce((map, edge) => {
const paddingKey = edgePaddingMap[edge];
map[paddingKey] = safeAreaInsets[edge];
return map;
}, {} as { [key in EdgePaddingMap[T]]: EdgeInsets[T] });
}, edges) as Result;
};

type AppStateListener = (status: AppStateStatus) => void;

export const useAppState = (type: AppStateEvent, listener: AppStateListener) => {
const callbackRef = useRef<AppStateListener>(listener);
callbackRef.current = listener;

useEffect(() => {
const eventListener = (state: AppStateStatus) => callbackRef.current(state);
const subscriber = AppState.addEventListener(type, eventListener);

return () => {
// @ts-ignore
if (subscriber?.remove) {
subscriber.remove();
}
// @ts-ignore
else if (AppState.removeEventListener) {
// @ts-ignore
AppState.removeEventListener(type, eventListener);
}
};
}, []);
};
1 change: 1 addition & 0 deletions packages/uikit-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export { BufferedRequest } from './shared/bufferedRequest';
export * from './shared';

export * from './hooks';
export * from './hooks/react-native';
export * from './ui-format/groupChannel';
export * from './ui-format/common';
export * from './sendbird/channel';
Expand Down

0 comments on commit b122691

Please sign in to comment.