TelegramPWA/src/components/left/settings/SettingsPrivacyVisibilityExceptionList.tsx
2021-11-05 22:03:02 +03:00

201 lines
6.0 KiB
TypeScript

import React, {
FC, memo, useCallback, useMemo, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../global/types';
import { ApiChat } from '../../../api/types';
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
import useLang from '../../../hooks/useLang';
import { pick } from '../../../util/iteratees';
import searchWords from '../../../util/searchWords';
import { getPrivacyKey } from './helper/privacy';
import {
getChatTitle, isChatGroup, isUserId, prepareChatList,
} from '../../../modules/helpers';
import useHistoryBack from '../../../hooks/useHistoryBack';
import Picker from '../../common/Picker';
import FloatingActionButton from '../../ui/FloatingActionButton';
export type OwnProps = {
isAllowList?: boolean;
screen: SettingsScreens;
isActive?: boolean;
onScreenSelect: (screen: SettingsScreens) => void;
onReset: () => void;
};
type StateProps = {
currentUserId?: string;
chatsById: Record<string, ApiChat>;
listIds?: string[];
orderedPinnedIds?: string[];
archivedListIds?: string[];
archivedPinnedIds?: string[];
settings?: ApiPrivacySettings;
};
type DispatchProps = Pick<GlobalActions, 'setPrivacySettings'>;
const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & DispatchProps> = ({
currentUserId,
isAllowList,
screen,
settings,
chatsById,
listIds,
orderedPinnedIds,
archivedListIds,
archivedPinnedIds,
setPrivacySettings,
isActive,
onScreenSelect,
onReset,
}) => {
const lang = useLang();
const selectedContactIds = useMemo(() => {
if (!settings) {
return [];
}
if (isAllowList) {
return [...settings.allowUserIds, ...settings.allowChatIds];
} else {
return [...settings.blockUserIds, ...settings.blockChatIds];
}
}, [isAllowList, settings]);
const [searchQuery, setSearchQuery] = useState<string>('');
const [isSubmitShown, setIsSubmitShown] = useState<boolean>(false);
const [newSelectedContactIds, setNewSelectedContactIds] = useState<string[]>(selectedContactIds);
const chats = useMemo(() => {
const activeChatArrays = listIds
? prepareChatList(chatsById, listIds, orderedPinnedIds, 'all')
: undefined;
const archivedChatArrays = archivedListIds
? prepareChatList(chatsById, archivedListIds, archivedPinnedIds, 'archived')
: undefined;
if (!activeChatArrays && !archivedChatArrays) {
return undefined;
}
return [
...(activeChatArrays
? [
...activeChatArrays.pinnedChats,
...activeChatArrays.otherChats,
]
: []
),
...(archivedChatArrays ? archivedChatArrays.otherChats : []),
];
}, [chatsById, listIds, orderedPinnedIds, archivedListIds, archivedPinnedIds]);
const displayedIds = useMemo(() => {
if (!chats) {
return undefined;
}
return chats
.filter((chat) => (
((isUserId(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
&& (
!searchQuery
|| searchWords(getChatTitle(lang, chat), searchQuery)
|| selectedContactIds.includes(chat.id)
)
))
.map(({ id }) => id);
}, [chats, currentUserId, lang, searchQuery, selectedContactIds]);
const handleSelectedContactIdsChange = useCallback((value: string[]) => {
setNewSelectedContactIds(value);
setIsSubmitShown(true);
}, []);
const handleSubmit = useCallback(() => {
setPrivacySettings({
privacyKey: getPrivacyKey(screen),
isAllowList: Boolean(isAllowList),
contactsIds: newSelectedContactIds,
});
onScreenSelect(SettingsScreens.Privacy);
}, [isAllowList, newSelectedContactIds, onScreenSelect, screen, setPrivacySettings]);
useHistoryBack(isActive, onReset, onScreenSelect, screen);
return (
<div className="NewChat-inner step-1">
<Picker
itemIds={displayedIds || []}
selectedIds={newSelectedContactIds}
filterValue={searchQuery}
filterPlaceholder={isAllowList ? lang('AlwaysShareWithPlaceholder') : lang('NeverShareWithPlaceholder')}
searchInputId="new-group-picker-search"
onSelectedIdsChange={handleSelectedContactIdsChange}
onFilterChange={setSearchQuery}
/>
<FloatingActionButton
isShown={isSubmitShown}
onClick={handleSubmit}
ariaLabel={isAllowList ? lang('AlwaysShareWithTitle') : lang('NeverShareWithTitle')}
>
<i className="icon-arrow-right" />
</FloatingActionButton>
</div>
);
};
function getCurrentPrivacySettings(global: GlobalState, screen: SettingsScreens) {
const { privacy } = global.settings;
switch (screen) {
case SettingsScreens.PrivacyPhoneNumberAllowedContacts:
case SettingsScreens.PrivacyPhoneNumberDeniedContacts:
return privacy.phoneNumber;
case SettingsScreens.PrivacyLastSeenAllowedContacts:
case SettingsScreens.PrivacyLastSeenDeniedContacts:
return privacy.lastSeen;
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
return privacy.profilePhoto;
case SettingsScreens.PrivacyForwardingAllowedContacts:
case SettingsScreens.PrivacyForwardingDeniedContacts:
return privacy.forwards;
case SettingsScreens.PrivacyGroupChatsDeniedContacts:
case SettingsScreens.PrivacyGroupChatsAllowedContacts:
return privacy.chatInvite;
}
return undefined;
}
export default memo(withGlobal<OwnProps>(
(global, { screen }): StateProps => {
const {
chats: {
byId: chatsById,
listIds,
orderedPinnedIds,
},
currentUserId,
} = global;
return {
currentUserId,
chatsById,
listIds: listIds.active,
orderedPinnedIds: orderedPinnedIds.active,
archivedPinnedIds: orderedPinnedIds.archived,
archivedListIds: listIds.archived,
settings: getCurrentPrivacySettings(global, screen),
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setPrivacySettings']),
)(SettingsPrivacyVisibilityExceptionList));