Settings / Folders: Move "done" button from header to FAB (#3080)

This commit is contained in:
Alexander Zinchuk 2023-04-26 21:15:32 +04:00
parent 01bd8f8b5b
commit 1e0f4e654a
5 changed files with 42 additions and 30 deletions

View File

@ -186,11 +186,6 @@ const Settings: FC<OwnProps> = ({
currentScreen, onReset, onScreenSelect, currentScreen, onReset, onScreenSelect,
]); ]);
const handleSaveFilter = useCallback(() => {
foldersDispatch({ type: 'saveFilters' });
handleReset();
}, [foldersDispatch, handleReset]);
function renderCurrentSectionContent(isScreenActive: boolean, screen: SettingsScreens) { function renderCurrentSectionContent(isScreenActive: boolean, screen: SettingsScreens) {
const privacyAllowScreens: Record<number, boolean> = { const privacyAllowScreens: Record<number, boolean> = {
[SettingsScreens.PrivacyPhoneNumber]: PRIVACY_PHONE_NUMBER_SCREENS.includes(screen), [SettingsScreens.PrivacyPhoneNumber]: PRIVACY_PHONE_NUMBER_SCREENS.includes(screen),
@ -459,7 +454,6 @@ const Settings: FC<OwnProps> = ({
<SettingsHeader <SettingsHeader
currentScreen={currentScreen} currentScreen={currentScreen}
onReset={handleReset} onReset={handleReset}
onSaveFilter={handleSaveFilter}
onScreenSelect={onScreenSelect} onScreenSelect={onScreenSelect}
editedFolderId={foldersState.folderId} editedFolderId={foldersState.folderId}
/> />

View File

@ -19,7 +19,6 @@ type OwnProps = {
currentScreen: SettingsScreens; currentScreen: SettingsScreens;
editedFolderId?: number; editedFolderId?: number;
onReset: () => void; onReset: () => void;
onSaveFilter: () => void;
onScreenSelect: (screen: SettingsScreens) => void; onScreenSelect: (screen: SettingsScreens) => void;
}; };
@ -27,7 +26,6 @@ const SettingsHeader: FC<OwnProps> = ({
currentScreen, currentScreen,
editedFolderId, editedFolderId,
onReset, onReset,
onSaveFilter,
onScreenSelect, onScreenSelect,
}) => { }) => {
const { const {
@ -227,27 +225,14 @@ const SettingsHeader: FC<OwnProps> = ({
case SettingsScreens.FoldersExcludedChats: case SettingsScreens.FoldersExcludedChats:
case SettingsScreens.FoldersExcludedChatsFromChatList: case SettingsScreens.FoldersExcludedChatsFromChatList:
return ( return (
<div className="settings-main-header"> <h3>
{(currentScreen === SettingsScreens.FoldersIncludedChats {lang(
|| currentScreen === SettingsScreens.FoldersIncludedChatsFromChatList) ? ( currentScreen === SettingsScreens.FoldersIncludedChats
<h3>{lang('FilterInclude')}</h3> || currentScreen === SettingsScreens.FoldersIncludedChatsFromChatList
) : ( ? 'FilterInclude' : 'FilterExclude',
<h3>{lang('FilterExclude')}</h3> )}
)} </h3>
<Button
round
size="smaller"
color="translucent"
className="color-primary"
onClick={onSaveFilter}
ariaLabel={lang('AutoDeleteConfirm')}
>
<i className="icon icon-check" />
</Button>
</div>
); );
default: default:
return ( return (
<div className="settings-main-header"> <div className="settings-main-header">

View File

@ -66,6 +66,11 @@ const SettingsFolders: FC<OwnProps> = ({
currentScreen, onReset, onScreenSelect, currentScreen, onReset, onScreenSelect,
]); ]);
const handleSaveFilter = useCallback(() => {
dispatch({ type: 'saveFilters' });
handleReset();
}, [dispatch, handleReset]);
const handleCreateFolder = useCallback(() => { const handleCreateFolder = useCallback(() => {
dispatch({ type: 'reset' }); dispatch({ type: 'reset' });
onScreenSelect(SettingsScreens.FoldersCreateFolder); onScreenSelect(SettingsScreens.FoldersCreateFolder);
@ -144,6 +149,7 @@ const SettingsFolders: FC<OwnProps> = ({
state={state} state={state}
dispatch={dispatch} dispatch={dispatch}
onReset={handleReset} onReset={handleReset}
onSaveFilter={handleSaveFilter}
isActive={isActive} isActive={isActive}
/> />
); );
@ -155,6 +161,7 @@ const SettingsFolders: FC<OwnProps> = ({
state={state} state={state}
dispatch={dispatch} dispatch={dispatch}
onReset={handleReset} onReset={handleReset}
onSaveFilter={handleSaveFilter}
isActive={isActive} isActive={isActive}
/> />
); );

View File

@ -25,7 +25,8 @@ type OwnProps = {
state: FoldersState; state: FoldersState;
dispatch: FolderEditDispatch; dispatch: FolderEditDispatch;
isActive?: boolean; isActive?: boolean;
onReset: () => void; onReset: VoidFunction;
onSaveFilter: VoidFunction;
}; };
const SettingsFoldersChatFilters: FC<OwnProps> = ({ const SettingsFoldersChatFilters: FC<OwnProps> = ({
@ -34,6 +35,7 @@ const SettingsFoldersChatFilters: FC<OwnProps> = ({
dispatch, dispatch,
isActive, isActive,
onReset, onReset,
onSaveFilter,
}) => { }) => {
const { chatFilter } = state; const { chatFilter } = state;
const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true); const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true);
@ -122,6 +124,8 @@ const SettingsFoldersChatFilters: FC<OwnProps> = ({
onSelectedIdsChange={handleSelectedIdsChange} onSelectedIdsChange={handleSelectedIdsChange}
onSelectedChatTypesChange={handleSelectedChatTypesChange} onSelectedChatTypesChange={handleSelectedChatTypesChange}
onFilterChange={handleFilterChange} onFilterChange={handleFilterChange}
onSaveFilter={onSaveFilter}
isActive={isActive}
/> />
); );
}; };

View File

@ -1,6 +1,6 @@
import type { FC } from '../../../../lib/teact/teact'; import type { FC } from '../../../../lib/teact/teact';
import React, { import React, {
useCallback, useRef, useEffect, memo, useCallback, useRef, useEffect, memo, useState,
} from '../../../../lib/teact/teact'; } from '../../../../lib/teact/teact';
import { requestMutation } from '../../../../lib/fasterdom/fasterdom'; import { requestMutation } from '../../../../lib/fasterdom/fasterdom';
import { getActions, withGlobal } from '../../../../global'; import { getActions, withGlobal } from '../../../../global';
@ -24,6 +24,7 @@ import GroupChatInfo from '../../../common/GroupChatInfo';
import PickerSelectedItem from '../../../common/PickerSelectedItem'; import PickerSelectedItem from '../../../common/PickerSelectedItem';
import InfiniteScroll from '../../../ui/InfiniteScroll'; import InfiniteScroll from '../../../ui/InfiniteScroll';
import Loading from '../../../ui/Loading'; import Loading from '../../../ui/Loading';
import FloatingActionButton from '../../../ui/FloatingActionButton';
import '../../../common/Picker.scss'; import '../../../common/Picker.scss';
import './SettingsFoldersChatsPicker.scss'; import './SettingsFoldersChatsPicker.scss';
@ -38,6 +39,8 @@ type OwnProps = {
onSelectedIdsChange: (ids: string[]) => void; onSelectedIdsChange: (ids: string[]) => void;
onSelectedChatTypesChange: (types: string[]) => void; onSelectedChatTypesChange: (types: string[]) => void;
onFilterChange: (value: string) => void; onFilterChange: (value: string) => void;
onSaveFilter: VoidFunction;
isActive?: boolean;
}; };
// Focus slows down animation, also it breaks transition layout in Chrome // Focus slows down animation, also it breaks transition layout in Chrome
@ -61,12 +64,21 @@ const SettingsFoldersChatsPicker: FC<OwnProps & StateProps> = ({
onSelectedChatTypesChange, onSelectedChatTypesChange,
onFilterChange, onFilterChange,
maxChats, maxChats,
onSaveFilter,
isActive,
}) => { }) => {
const { openLimitReachedModal } = getActions(); const { openLimitReachedModal } = getActions();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const chatTypes = mode === 'included' ? INCLUDED_CHAT_TYPES : EXCLUDED_CHAT_TYPES; const chatTypes = mode === 'included' ? INCLUDED_CHAT_TYPES : EXCLUDED_CHAT_TYPES;
const shouldMinimize = selectedIds.length + selectedChatTypes.length > MAX_FULL_ITEMS; const shouldMinimize = selectedIds.length + selectedChatTypes.length > MAX_FULL_ITEMS;
const [isTouched, setIsTouched] = useState(false);
useEffect(() => {
if (!isActive) {
setIsTouched(false);
}
}, [isActive]);
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
@ -89,6 +101,7 @@ const SettingsFoldersChatsPicker: FC<OwnProps & StateProps> = ({
} }
newSelectedIds.push(id); newSelectedIds.push(id);
} }
setIsTouched(true);
onSelectedIdsChange(newSelectedIds); onSelectedIdsChange(newSelectedIds);
}, [selectedIds, onSelectedIdsChange, maxChats, mode, openLimitReachedModal]); }, [selectedIds, onSelectedIdsChange, maxChats, mode, openLimitReachedModal]);
@ -99,6 +112,7 @@ const SettingsFoldersChatsPicker: FC<OwnProps & StateProps> = ({
} else { } else {
newSelectedChatTypes.push(key); newSelectedChatTypes.push(key);
} }
setIsTouched(true);
onSelectedChatTypesChange(newSelectedChatTypes); onSelectedChatTypesChange(newSelectedChatTypes);
}, [selectedChatTypes, onSelectedChatTypesChange]); }, [selectedChatTypes, onSelectedChatTypesChange]);
@ -225,6 +239,14 @@ const SettingsFoldersChatsPicker: FC<OwnProps & StateProps> = ({
<Loading key="loading" /> <Loading key="loading" />
)} )}
</InfiniteScroll> </InfiniteScroll>
<FloatingActionButton
isShown={isTouched}
onClick={onSaveFilter}
ariaLabel={lang('Save')}
>
<i className="icon icon-check" />
</FloatingActionButton>
</div> </div>
); );
}; };