Skip to content

Commit

Permalink
Merge pull request #38942 from lukemorawski/BaseShareLogList_refactor
Browse files Browse the repository at this point in the history
BaseShareLogList list refactor
  • Loading branch information
cristipaval authored Apr 5, 2024
2 parents 5ba54d1 + 5194168 commit e68084d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 90 deletions.
118 changes: 41 additions & 77 deletions src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,52 @@
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import React, {useMemo} from 'react';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import {useBetas} from '@components/OnyxProvider';
import {useOptionsList} from '@components/OptionListContextProvider';
import OptionsSelector from '@components/OptionsSelector';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import UserListItem from '@components/SelectionList/UserListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {Report} from '@src/types/onyx';
import type {BaseShareLogListOnyxProps, BaseShareLogListProps} from './types';
import type {BaseShareLogListProps} from './types';

function BaseShareLogList({betas, onAttachLogToReport}: BaseShareLogListProps) {
const [searchValue, setSearchValue] = useState('');
const [searchOptions, setSearchOptions] = useState<Pick<OptionsListUtils.GetOptions, 'recentReports' | 'personalDetails' | 'userToInvite'>>({
recentReports: [],
personalDetails: [],
userToInvite: null,
});
function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) {
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');
const {isOffline} = useNetwork();
const {translate} = useLocalize();
const styles = useThemeStyles();
const isMounted = useRef(false);
const betas = useBetas();
const {options, areOptionsInitialized} = useOptionsList();
const updateOptions = useCallback(() => {

const searchOptions = useMemo(() => {
if (!areOptionsInitialized) {
return {
recentReports: [],
personalDetails: [],
userToInvite: undefined,
headerMessage: '',
};
}
const {
recentReports: localRecentReports,
personalDetails: localPersonalDetails,
userToInvite: localUserToInvite,
} = OptionsListUtils.getShareLogOptions(options, searchValue.trim(), betas ?? []);
} = OptionsListUtils.getShareLogOptions(options, debouncedSearchValue.trim(), betas ?? []);

setSearchOptions({
const header = OptionsListUtils.getHeaderMessage((localRecentReports?.length || 0) + (localPersonalDetails?.length || 0) !== 0, Boolean(localUserToInvite), debouncedSearchValue);

return {
recentReports: localRecentReports,
personalDetails: localPersonalDetails,
userToInvite: localUserToInvite,
});
}, [betas, options, searchValue]);

useEffect(() => {
if (!areOptionsInitialized) {
return;
}

updateOptions();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [options, areOptionsInitialized]);

useEffect(() => {
if (!isMounted.current) {
isMounted.current = true;
return;
}

updateOptions();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchValue]);
headerMessage: header,
};
}, [areOptionsInitialized, options, debouncedSearchValue, betas]);

const sections = useMemo(() => {
const sectionsList = [];
Expand All @@ -84,17 +71,7 @@ function BaseShareLogList({betas, onAttachLogToReport}: BaseShareLogListProps) {
}

return sectionsList;
}, [searchOptions.personalDetails, searchOptions.recentReports, searchOptions.userToInvite, translate]);

const headerMessage = OptionsListUtils.getHeaderMessage(
searchOptions.recentReports.length + searchOptions.personalDetails.length !== 0,
Boolean(searchOptions.userToInvite),
searchValue,
);

const onChangeText = (value = '') => {
setSearchValue(value);
};
}, [searchOptions?.personalDetails, searchOptions?.recentReports, searchOptions?.userToInvite, translate]);

const attachLogToReport = (option: Report) => {
if (!option.reportID) {
Expand All @@ -110,28 +87,23 @@ function BaseShareLogList({betas, onAttachLogToReport}: BaseShareLogListProps) {
testID={BaseShareLogList.displayName}
includeSafeAreaPaddingBottom={false}
>
{({safeAreaPaddingBottomStyle}) => (
{({didScreenTransitionEnd}) => (
<>
<HeaderWithBackButton
title={translate('initialSettingsPage.debugConsole.shareLog')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_CONSOLE)}
/>
<View style={[styles.flex1, styles.w100, styles.pRelative]}>
<OptionsSelector
// @ts-expect-error TODO: remove this comment once OptionsSelector (https://github.com/Expensify/App/issues/25125) is migrated to TS
sections={sections}
onSelectRow={attachLogToReport}
onChangeText={onChangeText}
value={searchValue}
headerMessage={headerMessage}
showTitleTooltip
shouldShowOptions={areOptionsInitialized}
textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')}
textInputAlert={isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''}
safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle}
autoFocus
/>
</View>
<SelectionList
ListItem={UserListItem}
sections={didScreenTransitionEnd ? sections : CONST.EMPTY_ARRAY}
onSelectRow={attachLogToReport}
onChangeText={setSearchValue}
textInputValue={searchValue}
headerMessage={searchOptions.headerMessage}
textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')}
textInputHint={isOffline ? `${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}` : ''}
showLoadingPlaceholder={!didScreenTransitionEnd}
/>
</>
)}
</ScreenWrapper>
Expand All @@ -140,12 +112,4 @@ function BaseShareLogList({betas, onAttachLogToReport}: BaseShareLogListProps) {

BaseShareLogList.displayName = 'ShareLogPage';

export default withOnyx<BaseShareLogListProps, BaseShareLogListOnyxProps>({
reports: {
key: ONYXKEYS.COLLECTION.REPORT,
},
betas: {
key: ONYXKEYS.BETAS,
initialValue: [],
},
})(BaseShareLogList);
export default BaseShareLogList;
15 changes: 2 additions & 13 deletions src/pages/settings/AboutPage/ShareLogList/types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import type {Beta, Report} from '@src/types/onyx';

type BaseShareLogListOnyxProps = {
/** Beta features list */
betas: OnyxEntry<Beta[]>;

/** All reports shared with the user */
reports: OnyxCollection<Report>;
};

type ShareLogListProps = {
/** The source of the log file to share */
logSource: string;
};

type BaseShareLogListProps = BaseShareLogListOnyxProps & {
type BaseShareLogListProps = {
onAttachLogToReport: (reportID: string, filename: string) => void;
};

export type {BaseShareLogListOnyxProps, BaseShareLogListProps, ShareLogListProps};
export type {BaseShareLogListProps, ShareLogListProps};

0 comments on commit e68084d

Please sign in to comment.