Settings / Privacy: Options for calls, show exceptions (#1853)

This commit is contained in:
Alexander Zinchuk 2022-05-03 14:17:35 +01:00
parent dab1585014
commit b7aff1be7e
11 changed files with 174 additions and 37 deletions

View File

@ -53,6 +53,10 @@ export function buildPrivacyKey(key: GramJs.TypePrivacyKey): ApiPrivacyKey | und
return 'lastSeen';
case 'PrivacyKeyProfilePhoto':
return 'profilePhoto';
case 'PrivacyKeyPhoneCall':
return 'phoneCall';
case 'PrivacyKeyPhoneP2P':
return 'phoneP2P';
case 'PrivacyKeyForwards':
return 'forwards';
case 'PrivacyKeyChatInvite':

View File

@ -419,6 +419,12 @@ export function buildInputPrivacyKey(privacyKey: ApiPrivacyKey) {
case 'chatInvite':
return new GramJs.InputPrivacyKeyChatInvite();
case 'phoneCall':
return new GramJs.InputPrivacyKeyPhoneCall();
case 'phoneP2P':
return new GramJs.InputPrivacyKeyPhoneP2P();
}
return undefined;

View File

@ -2,7 +2,8 @@ import type {
GroupCallConnectionData,
GroupCallParticipant,
GroupCallConnectionState,
VideoState, VideoRotation,
VideoState,
VideoRotation,
} from '../../lib/secret-sauce';
import {
ApiChat,
@ -16,13 +17,13 @@ import {
} from './messages';
import { ApiUser, ApiUserFullInfo, ApiUserStatus } from './users';
import {
ApiEmojiInteraction,
ApiError, ApiInviteInfo, ApiNotifyException, ApiSessionData,
ApiEmojiInteraction, ApiError, ApiInviteInfo, ApiNotifyException, ApiSessionData,
} from './misc';
import {
ApiGroupCall, ApiPhoneCall,
} from './calls';
import { ApiBotMenuButton } from './bots';
import type { ApiPrivacyKey, PrivacyVisibility } from '../../types';
export type ApiUpdateReady = {
'@type': 'updateApiReady';
@ -398,9 +399,9 @@ export type ApiUpdatePaymentStateCompleted = {
export type ApiUpdatePrivacy = {
'@type': 'updatePrivacy';
key: 'phoneNumber' | 'lastSeen' | 'profilePhoto' | 'forwards' | 'chatInvite';
key: ApiPrivacyKey;
rules: {
visibility: 'everybody' | 'contacts' | 'nonContacts' | 'nobody';
visibility: PrivacyVisibility;
allowUserIds: string[];
allowChatIds: string[];
blockUserIds: string[];

View File

@ -136,6 +136,8 @@ const LeftColumn: FC<StateProps> = ({
case SettingsScreens.PrivacyPhoneNumber:
case SettingsScreens.PrivacyLastSeen:
case SettingsScreens.PrivacyProfilePhoto:
case SettingsScreens.PrivacyPhoneCall:
case SettingsScreens.PrivacyPhoneP2P:
case SettingsScreens.PrivacyForwarding:
case SettingsScreens.PrivacyGroupChats:
case SettingsScreens.PrivacyBlockedUsers:
@ -156,6 +158,14 @@ const LeftColumn: FC<StateProps> = ({
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
setSettingsScreen(SettingsScreens.PrivacyProfilePhoto);
return;
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
setSettingsScreen(SettingsScreens.PrivacyPhoneCall);
return;
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
setSettingsScreen(SettingsScreens.PrivacyPhoneP2P);
return;
case SettingsScreens.PrivacyForwardingAllowedContacts:
case SettingsScreens.PrivacyForwardingDeniedContacts:
setSettingsScreen(SettingsScreens.PrivacyForwarding);

View File

@ -80,6 +80,16 @@ const PRIVACY_PROFILE_PHOTO_SCREENS = [
SettingsScreens.PrivacyProfilePhotoDeniedContacts,
];
const PRIVACY_PHONE_CALL_SCREENS = [
SettingsScreens.PrivacyPhoneCallAllowedContacts,
SettingsScreens.PrivacyPhoneCallDeniedContacts,
];
const PRIVACY_PHONE_P2P_SCREENS = [
SettingsScreens.PrivacyPhoneP2PAllowedContacts,
SettingsScreens.PrivacyPhoneP2PDeniedContacts,
];
const PRIVACY_FORWARDING_SCREENS = [
SettingsScreens.PrivacyForwardingAllowedContacts,
SettingsScreens.PrivacyForwardingDeniedContacts,
@ -150,6 +160,8 @@ const Settings: FC<OwnProps> = ({
[SettingsScreens.PrivacyPhoneNumber]: PRIVACY_PHONE_NUMBER_SCREENS.includes(screen),
[SettingsScreens.PrivacyLastSeen]: PRIVACY_LAST_SEEN_PHONE_SCREENS.includes(screen),
[SettingsScreens.PrivacyProfilePhoto]: PRIVACY_PROFILE_PHOTO_SCREENS.includes(screen),
[SettingsScreens.PrivacyPhoneCall]: PRIVACY_PHONE_CALL_SCREENS.includes(screen),
[SettingsScreens.PrivacyPhoneP2P]: PRIVACY_PHONE_P2P_SCREENS.includes(screen),
[SettingsScreens.PrivacyForwarding]: PRIVACY_FORWARDING_SCREENS.includes(screen),
[SettingsScreens.PrivacyGroupChats]: PRIVACY_GROUP_CHATS_SCREENS.includes(screen),
};
@ -241,6 +253,8 @@ const Settings: FC<OwnProps> = ({
case SettingsScreens.PrivacyPhoneNumber:
case SettingsScreens.PrivacyLastSeen:
case SettingsScreens.PrivacyProfilePhoto:
case SettingsScreens.PrivacyPhoneCall:
case SettingsScreens.PrivacyPhoneP2P:
case SettingsScreens.PrivacyForwarding:
case SettingsScreens.PrivacyGroupChats:
return (
@ -255,6 +269,8 @@ const Settings: FC<OwnProps> = ({
case SettingsScreens.PrivacyPhoneNumberAllowedContacts:
case SettingsScreens.PrivacyLastSeenAllowedContacts:
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
case SettingsScreens.PrivacyForwardingAllowedContacts:
case SettingsScreens.PrivacyGroupChatsAllowedContacts:
return (
@ -270,6 +286,8 @@ const Settings: FC<OwnProps> = ({
case SettingsScreens.PrivacyPhoneNumberDeniedContacts:
case SettingsScreens.PrivacyLastSeenDeniedContacts:
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
case SettingsScreens.PrivacyForwardingDeniedContacts:
case SettingsScreens.PrivacyGroupChatsDeniedContacts:
return (

View File

@ -1,7 +1,7 @@
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global';
import { PrivacyVisibility, SettingsScreens } from '../../../types';
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -20,11 +20,13 @@ type StateProps = {
blockedCount: number;
isSensitiveEnabled?: boolean;
canChangeSensitive?: boolean;
visibilityPrivacyPhoneNumber?: PrivacyVisibility;
visibilityPrivacyLastSeen?: PrivacyVisibility;
visibilityPrivacyProfilePhoto?: PrivacyVisibility;
visibilityPrivacyForwarding?: PrivacyVisibility;
visibilityPrivacyGroupChats?: PrivacyVisibility;
privacyPhoneNumber?: ApiPrivacySettings;
privacyLastSeen?: ApiPrivacySettings;
privacyProfilePhoto?: ApiPrivacySettings;
privacyForwarding?: ApiPrivacySettings;
privacyGroupChats?: ApiPrivacySettings;
privacyPhoneCall?: ApiPrivacySettings;
privacyPhoneP2P?: ApiPrivacySettings;
};
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
@ -35,11 +37,13 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
blockedCount,
isSensitiveEnabled,
canChangeSensitive,
visibilityPrivacyPhoneNumber,
visibilityPrivacyLastSeen,
visibilityPrivacyProfilePhoto,
visibilityPrivacyForwarding,
visibilityPrivacyGroupChats,
privacyPhoneNumber,
privacyLastSeen,
privacyProfilePhoto,
privacyForwarding,
privacyGroupChats,
privacyPhoneCall,
privacyPhoneP2P,
}) => {
const {
@ -64,16 +68,25 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
onBack: onReset,
});
function getVisibilityValue(visibility?: PrivacyVisibility) {
function getVisibilityValue(setting?: ApiPrivacySettings) {
const { visibility } = setting || {};
const blockCount = setting ? setting.blockChatIds.length + setting.blockUserIds.length : 0;
const allowCount = setting ? setting.allowChatIds.length + setting.allowUserIds.length : 0;
const total = [];
if (blockCount) total.push(`-${blockCount}`);
if (allowCount) total.push(`+${allowCount}`);
const exceptionString = total.length ? `(${total.join(',')})` : '';
switch (visibility) {
case 'everybody':
return lang('P2PEverybody');
return `${lang('P2PEverybody')} ${exceptionString}`;
case 'contacts':
return lang('P2PContacts');
return `${lang('P2PContacts')} ${exceptionString}`;
case 'nobody':
return lang('P2PNobody');
return `${lang('P2PNobody')} ${exceptionString}`;
}
return undefined;
@ -126,7 +139,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
<div className="multiline-menu-item">
<span className="title">{lang('PrivacyPhoneTitle')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(visibilityPrivacyPhoneNumber)}
{getVisibilityValue(privacyPhoneNumber)}
</span>
</div>
</ListItem>
@ -139,7 +152,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
<div className="multiline-menu-item">
<span className="title">{lang('LastSeenTitle')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(visibilityPrivacyLastSeen)}
{getVisibilityValue(privacyLastSeen)}
</span>
</div>
</ListItem>
@ -152,7 +165,33 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
<div className="multiline-menu-item">
<span className="title">{lang('PrivacyProfilePhotoTitle')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(visibilityPrivacyProfilePhoto)}
{getVisibilityValue(privacyProfilePhoto)}
</span>
</div>
</ListItem>
<ListItem
narrow
className="no-icon"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onScreenSelect(SettingsScreens.PrivacyPhoneCall)}
>
<div className="multiline-menu-item">
<span className="title">{lang('WhoCanCallMe')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(privacyPhoneCall)}
</span>
</div>
</ListItem>
<ListItem
narrow
className="no-icon"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onScreenSelect(SettingsScreens.PrivacyPhoneP2P)}
>
<div className="multiline-menu-item">
<span className="title">{lang('PrivacyP2P')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(privacyPhoneP2P)}
</span>
</div>
</ListItem>
@ -165,7 +204,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
<div className="multiline-menu-item">
<span className="title">{lang('PrivacyForwardsTitle')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(visibilityPrivacyForwarding)}
{getVisibilityValue(privacyForwarding)}
</span>
</div>
</ListItem>
@ -178,7 +217,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
<div className="multiline-menu-item">
<span className="title">{lang('WhoCanAddMe')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(visibilityPrivacyGroupChats)}
{getVisibilityValue(privacyGroupChats)}
</span>
</div>
</ListItem>
@ -217,11 +256,13 @@ export default memo(withGlobal<OwnProps>(
blockedCount: blocked.totalCount,
isSensitiveEnabled,
canChangeSensitive,
visibilityPrivacyPhoneNumber: privacy.phoneNumber?.visibility,
visibilityPrivacyLastSeen: privacy.lastSeen?.visibility,
visibilityPrivacyProfilePhoto: privacy.profilePhoto?.visibility,
visibilityPrivacyForwarding: privacy.forwards?.visibility,
visibilityPrivacyGroupChats: privacy.chatInvite?.visibility,
privacyPhoneNumber: privacy.phoneNumber,
privacyLastSeen: privacy.lastSeen,
privacyProfilePhoto: privacy.profilePhoto,
privacyForwarding: privacy.forwards,
privacyGroupChats: privacy.chatInvite,
privacyPhoneCall: privacy.phoneCall,
privacyPhoneP2P: privacy.phoneP2P,
};
},
)(SettingsPrivacy));

View File

@ -79,6 +79,10 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
return lang('PrivacyForwardsTitle');
case SettingsScreens.PrivacyGroupChats:
return lang('WhoCanAddMe');
case SettingsScreens.PrivacyPhoneCall:
return lang('WhoCanCallMe');
case SettingsScreens.PrivacyPhoneP2P:
return lang('PrivacyP2P');
default:
return undefined;
}
@ -108,6 +112,10 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
return SettingsScreens.PrivacyProfilePhotoAllowedContacts;
case SettingsScreens.PrivacyForwarding:
return SettingsScreens.PrivacyForwardingAllowedContacts;
case SettingsScreens.PrivacyPhoneCall:
return SettingsScreens.PrivacyPhoneCallAllowedContacts;
case SettingsScreens.PrivacyPhoneP2P:
return SettingsScreens.PrivacyPhoneP2PAllowedContacts;
default:
return SettingsScreens.PrivacyGroupChatsAllowedContacts;
}
@ -123,6 +131,10 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
return SettingsScreens.PrivacyProfilePhotoDeniedContacts;
case SettingsScreens.PrivacyForwarding:
return SettingsScreens.PrivacyForwardingDeniedContacts;
case SettingsScreens.PrivacyPhoneCall:
return SettingsScreens.PrivacyPhoneCallDeniedContacts;
case SettingsScreens.PrivacyPhoneP2P:
return SettingsScreens.PrivacyPhoneP2PDeniedContacts;
default:
return SettingsScreens.PrivacyGroupChatsDeniedContacts;
}
@ -186,7 +198,7 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
>
<div className="multiline-menu-item full-size">
{allowedCount > 0 && <span className="date" dir="auto">+{allowedCount}</span>}
<span className="title">{lang('AlwaysShareWith')}</span>
<span className="title">{lang('AlwaysAllow')}</span>
<span className="subtitle">{lang('EditAdminAddUsers')}</span>
</div>
</ListItem>
@ -202,7 +214,7 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
>
<div className="multiline-menu-item full-size">
{blockCount > 0 && <span className="date" dir="auto">&minus;{blockCount}</span>}
<span className="title">{lang('NeverShareWith')}</span>
<span className="title">{lang('NeverAllow')}</span>
<span className="subtitle">{lang('EditAdminAddUsers')}</span>
</div>
</ListItem>
@ -234,6 +246,14 @@ export default memo(withGlobal<OwnProps>(
privacySettings = privacy.profilePhoto;
break;
case SettingsScreens.PrivacyPhoneCall:
privacySettings = privacy.phoneCall;
break;
case SettingsScreens.PrivacyPhoneP2P:
privacySettings = privacy.phoneP2P;
break;
case SettingsScreens.PrivacyForwarding:
privacySettings = privacy.forwards;
break;

View File

@ -103,7 +103,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
itemIds={displayedIds || []}
selectedIds={newSelectedContactIds}
filterValue={searchQuery}
filterPlaceholder={isAllowList ? lang('AlwaysShareWithPlaceholder') : lang('NeverShareWithPlaceholder')}
filterPlaceholder={isAllowList ? lang('AlwaysAllowPlaceholder') : lang('NeverAllowPlaceholder')}
searchInputId="new-group-picker-search"
onSelectedIdsChange={handleSelectedContactIdsChange}
onFilterChange={setSearchQuery}
@ -112,7 +112,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
<FloatingActionButton
isShown={isSubmitShown}
onClick={handleSubmit}
ariaLabel={isAllowList ? lang('AlwaysShareWithTitle') : lang('NeverShareWithTitle')}
ariaLabel={isAllowList ? lang('AlwaysAllow') : lang('NeverAllow')}
>
<i className="icon-arrow-right" />
</FloatingActionButton>
@ -132,6 +132,12 @@ function getCurrentPrivacySettings(global: GlobalState, screen: SettingsScreens)
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
return privacy.profilePhoto;
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
return privacy.phoneCall;
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
return privacy.phoneP2P;
case SettingsScreens.PrivacyForwardingAllowedContacts:
case SettingsScreens.PrivacyForwardingDeniedContacts:
return privacy.forwards;

View File

@ -22,6 +22,14 @@ export function getPrivacyKey(screen: SettingsScreens): ApiPrivacyKey | undefine
case SettingsScreens.PrivacyGroupChatsAllowedContacts:
case SettingsScreens.PrivacyGroupChatsDeniedContacts:
return 'chatInvite';
case SettingsScreens.PrivacyPhoneCall:
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
return 'phoneCall';
case SettingsScreens.PrivacyPhoneP2P:
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
return 'phoneP2P';
}
return undefined;

View File

@ -308,17 +308,31 @@ addActionHandler('loadLanguages', async () => {
addActionHandler('loadPrivacySettings', async (global) => {
const [
phoneNumberSettings, lastSeenSettings, profilePhotoSettings, forwardsSettings, chatInviteSettings,
phoneNumberSettings,
lastSeenSettings,
profilePhotoSettings,
forwardsSettings,
chatInviteSettings,
phoneCallSettings,
phoneP2PSettings,
] = await Promise.all([
callApi('fetchPrivacySettings', 'phoneNumber'),
callApi('fetchPrivacySettings', 'lastSeen'),
callApi('fetchPrivacySettings', 'profilePhoto'),
callApi('fetchPrivacySettings', 'forwards'),
callApi('fetchPrivacySettings', 'chatInvite'),
callApi('fetchPrivacySettings', 'phoneCall'),
callApi('fetchPrivacySettings', 'phoneP2P'),
]);
if (
!phoneNumberSettings || !lastSeenSettings || !profilePhotoSettings || !forwardsSettings || !chatInviteSettings
!phoneNumberSettings
|| !lastSeenSettings
|| !profilePhotoSettings
|| !forwardsSettings
|| !chatInviteSettings
|| !phoneCallSettings
|| !phoneP2PSettings
) {
return;
}
@ -335,6 +349,8 @@ addActionHandler('loadPrivacySettings', async (global) => {
profilePhoto: profilePhotoSettings,
forwards: forwardsSettings,
chatInvite: chatInviteSettings,
phoneCall: phoneCallSettings,
phoneP2P: phoneP2PSettings,
},
},
});

View File

@ -169,6 +169,8 @@ export enum SettingsScreens {
PrivacyPhoneNumber,
PrivacyLastSeen,
PrivacyProfilePhoto,
PrivacyPhoneCall,
PrivacyPhoneP2P,
PrivacyForwarding,
PrivacyGroupChats,
PrivacyPhoneNumberAllowedContacts,
@ -177,6 +179,10 @@ export enum SettingsScreens {
PrivacyLastSeenDeniedContacts,
PrivacyProfilePhotoAllowedContacts,
PrivacyProfilePhotoDeniedContacts,
PrivacyPhoneCallAllowedContacts,
PrivacyPhoneCallDeniedContacts,
PrivacyPhoneP2PAllowedContacts,
PrivacyPhoneP2PDeniedContacts,
PrivacyForwardingAllowedContacts,
PrivacyForwardingDeniedContacts,
PrivacyGroupChatsAllowedContacts,
@ -308,7 +314,8 @@ export enum NewChatMembersProgress {
export type ProfileTabType = 'members' | 'commonChats' | 'media' | 'documents' | 'links' | 'audio' | 'voice';
export type SharedMediaType = 'media' | 'documents' | 'links' | 'audio' | 'voice';
export type ApiPrivacyKey = 'phoneNumber' | 'lastSeen' | 'profilePhoto' | 'forwards' | 'chatInvite';
export type ApiPrivacyKey = 'phoneNumber' | 'lastSeen' | 'profilePhoto' |
'forwards' | 'chatInvite' | 'phoneCall' | 'phoneP2P';
export type PrivacyVisibility = 'everybody' | 'contacts' | 'nonContacts' | 'nobody';
export enum ProfileState {