Settings: Add more privacy options and support (#3832)
This commit is contained in:
parent
acc962bcf5
commit
4efae0816c
@ -148,6 +148,7 @@ export function buildApiUsernames(mtpPeer: GramJs.User | GramJs.Channel | GramJs
|
||||
|
||||
export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySettings {
|
||||
let visibility: PrivacyVisibility | undefined;
|
||||
let isUnspecified: boolean | undefined;
|
||||
let allowUserIds: string[] | undefined;
|
||||
let allowChatIds: string[] | undefined;
|
||||
let blockUserIds: string[] | undefined;
|
||||
@ -165,7 +166,6 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
|
||||
} else if (rule instanceof GramJs.PrivacyValueDisallowAll) {
|
||||
visibility ||= 'nobody';
|
||||
} else if (rule instanceof GramJs.PrivacyValueAllowUsers) {
|
||||
visibility ||= 'selectedContacts';
|
||||
allowUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
||||
} else if (rule instanceof GramJs.PrivacyValueDisallowUsers) {
|
||||
blockUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
||||
@ -179,10 +179,12 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
|
||||
if (!visibility) {
|
||||
// Disallow by default
|
||||
visibility = 'nobody';
|
||||
isUnspecified = true;
|
||||
}
|
||||
|
||||
return {
|
||||
visibility,
|
||||
isUnspecified,
|
||||
allowUserIds: allowUserIds || [],
|
||||
allowChatIds: allowChatIds || [],
|
||||
blockUserIds: blockUserIds || [],
|
||||
|
||||
@ -64,6 +64,8 @@ export function buildPrivacyKey(key: GramJs.TypePrivacyKey): ApiPrivacyKey | und
|
||||
switch (key.className) {
|
||||
case 'PrivacyKeyPhoneNumber':
|
||||
return 'phoneNumber';
|
||||
case 'PrivacyKeyAddedByPhone':
|
||||
return 'addByPhone';
|
||||
case 'PrivacyKeyStatusTimestamp':
|
||||
return 'lastSeen';
|
||||
case 'PrivacyKeyProfilePhoto':
|
||||
|
||||
@ -2,7 +2,7 @@ import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import { generateRandomBytes, readBigIntFromBuffer } from '../../../lib/gramjs/Helpers';
|
||||
|
||||
import type { ApiPrivacyKey, PrivacyVisibility } from '../../../types';
|
||||
import type { ApiInputPrivacyRules, ApiPrivacyKey } from '../../../types';
|
||||
import type {
|
||||
ApiBotApp,
|
||||
ApiChatAdminRights,
|
||||
@ -25,7 +25,6 @@ import type {
|
||||
ApiStorySkipped,
|
||||
ApiThemeParameters,
|
||||
ApiTypeReplyTo,
|
||||
ApiUser,
|
||||
ApiVideo,
|
||||
} from '../../types';
|
||||
import {
|
||||
@ -458,6 +457,9 @@ export function buildInputPrivacyKey(privacyKey: ApiPrivacyKey) {
|
||||
case 'phoneNumber':
|
||||
return new GramJs.InputPrivacyKeyPhoneNumber();
|
||||
|
||||
case 'addByPhone':
|
||||
return new GramJs.InputPrivacyKeyAddedByPhone();
|
||||
|
||||
case 'lastSeen':
|
||||
return new GramJs.InputPrivacyKeyStatusTimestamp();
|
||||
|
||||
@ -478,6 +480,9 @@ export function buildInputPrivacyKey(privacyKey: ApiPrivacyKey) {
|
||||
|
||||
case 'voiceMessages':
|
||||
return new GramJs.InputPrivacyKeyVoiceMessages();
|
||||
|
||||
case 'bio':
|
||||
return new GramJs.InputPrivacyKeyAbout();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -660,63 +665,54 @@ export function buildInputReplyTo(replyingTo: ApiTypeReplyTo) {
|
||||
}
|
||||
|
||||
export function buildInputPrivacyRules(
|
||||
visibility: PrivacyVisibility,
|
||||
allowedUserList?: ApiUser[],
|
||||
deniedUserList?: ApiUser[],
|
||||
rules: ApiInputPrivacyRules,
|
||||
) {
|
||||
const rules: GramJs.TypeInputPrivacyRule[] = [];
|
||||
const privacyRules: GramJs.TypeInputPrivacyRule[] = [];
|
||||
|
||||
switch (visibility) {
|
||||
case 'everybody':
|
||||
case 'contacts': {
|
||||
if (visibility === 'contacts') {
|
||||
rules.push(new GramJs.InputPrivacyValueAllowContacts());
|
||||
}
|
||||
|
||||
if (visibility === 'everybody') {
|
||||
rules.push(new GramJs.InputPrivacyValueAllowAll());
|
||||
}
|
||||
|
||||
const users = deniedUserList?.reduce<GramJs.InputUser[]>((acc, { id, accessHash }) => {
|
||||
acc.push(new GramJs.InputPeerUser({
|
||||
userId: buildMtpPeerId(id, 'user'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
}));
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
if (users?.length) {
|
||||
rules.push(new GramJs.InputPrivacyValueDisallowUsers({ users }));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'closeFriends':
|
||||
rules.push(new GramJs.InputPrivacyValueAllowCloseFriends());
|
||||
break;
|
||||
|
||||
case 'nonContacts':
|
||||
rules.push(new GramJs.InputPrivacyValueDisallowContacts());
|
||||
break;
|
||||
|
||||
case 'selectedContacts': {
|
||||
const users = (allowedUserList || []).reduce<GramJs.InputUser[]>((acc, { id, accessHash }) => {
|
||||
acc.push(new GramJs.InputPeerUser({
|
||||
userId: buildMtpPeerId(id, 'user'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
}));
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
rules.push(new GramJs.InputPrivacyValueAllowUsers({ users }));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'nobody':
|
||||
rules.push(new GramJs.InputPrivacyValueDisallowAll());
|
||||
break;
|
||||
if (rules.allowedUsers?.length) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowUsers({
|
||||
users: rules.allowedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.allowedChats?.length) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowChatParticipants({
|
||||
chats: rules.allowedChats.map(({ id, type }) => (
|
||||
buildMtpPeerId(id, type === 'chatTypeBasicGroup' ? 'chat' : 'channel')
|
||||
)),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedUsers?.length) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowUsers({
|
||||
users: rules.blockedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedChats?.length) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowChatParticipants({
|
||||
chats: rules.blockedChats.map(({ id, type }) => (
|
||||
buildMtpPeerId(id, type === 'chatTypeBasicGroup' ? 'chat' : 'channel')
|
||||
)),
|
||||
}));
|
||||
}
|
||||
|
||||
return rules;
|
||||
if (!rules.isUnspecified) {
|
||||
switch (rules.visibility) {
|
||||
case 'everybody':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowAll());
|
||||
break;
|
||||
|
||||
case 'contacts':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowContacts());
|
||||
break;
|
||||
|
||||
case 'nonContacts':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowContacts());
|
||||
break;
|
||||
|
||||
case 'nobody':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowAll());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return privacyRules;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { LANG_PACKS } from '../../../config';
|
||||
import type { ApiPrivacyKey, InputPrivacyRules, LangCode } from '../../../types';
|
||||
import type { ApiInputPrivacyRules, ApiPrivacyKey, LangCode } from '../../../types';
|
||||
import type {
|
||||
ApiAppConfig,
|
||||
ApiConfig,
|
||||
@ -33,6 +33,7 @@ import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputEntity, buildInputPeer, buildInputPhoto,
|
||||
buildInputPrivacyKey,
|
||||
buildInputPrivacyRules,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb, addPhotoToLocalDb } from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
@ -506,48 +507,10 @@ export function unregisterDevice(token: string) {
|
||||
}
|
||||
|
||||
export async function setPrivacySettings(
|
||||
privacyKey: ApiPrivacyKey, rules: InputPrivacyRules,
|
||||
privacyKey: ApiPrivacyKey, rules: ApiInputPrivacyRules,
|
||||
) {
|
||||
const key = buildInputPrivacyKey(privacyKey);
|
||||
const privacyRules: GramJs.TypeInputPrivacyRule[] = [];
|
||||
|
||||
if (rules.allowedUsers) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowUsers({
|
||||
users: rules.allowedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.allowedChats) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowChatParticipants({
|
||||
chats: rules.allowedChats.map(({ id }) => buildInputEntity(id) as BigInt.BigInteger),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedUsers) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowUsers({
|
||||
users: rules.blockedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedChats) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowChatParticipants({
|
||||
chats: rules.blockedChats.map(({ id }) => buildInputEntity(id) as BigInt.BigInteger),
|
||||
}));
|
||||
}
|
||||
switch (rules.visibility) {
|
||||
case 'everybody':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowAll());
|
||||
break;
|
||||
|
||||
case 'contacts':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowContacts());
|
||||
break;
|
||||
|
||||
case 'nonContacts':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowContacts());
|
||||
break;
|
||||
|
||||
case 'nobody':
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowAll());
|
||||
break;
|
||||
}
|
||||
const privacyRules = buildInputPrivacyRules(rules);
|
||||
|
||||
const result = await invokeRequest(new GramJs.account.SetPrivacy({ key, rules: privacyRules }));
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { PrivacyVisibility } from '../../../types';
|
||||
import type { ApiInputPrivacyRules } from '../../../types';
|
||||
import type {
|
||||
ApiReaction, ApiReportReason, ApiStealthMode,
|
||||
ApiTypeStory, ApiUser, ApiUserStories,
|
||||
@ -306,16 +306,15 @@ export function reportStory({
|
||||
}
|
||||
|
||||
export function editStoryPrivacy({
|
||||
id, visibility, allowedUserList, deniedUserList,
|
||||
id,
|
||||
privacy,
|
||||
}: {
|
||||
id: number;
|
||||
visibility: PrivacyVisibility;
|
||||
allowedUserList?: ApiUser[];
|
||||
deniedUserList?: ApiUser[];
|
||||
privacy: ApiInputPrivacyRules;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.stories.EditStory({
|
||||
id,
|
||||
privacyRules: buildInputPrivacyRules(visibility, allowedUserList, deniedUserList),
|
||||
privacyRules: buildInputPrivacyRules(privacy),
|
||||
}), {
|
||||
shouldReturnTrue: true,
|
||||
});
|
||||
|
||||
1
src/assets/font-icons/ask-support.svg
Normal file
1
src/assets/font-icons/ask-support.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M16 1.33c-8.046 0-14.667 6.006-14.667 13.552l.007.434c.116 3.6 1.671 6.751 4.393 9.131l.199.167-.097.133-.222.265-.614.685c-.395.465-.636.84-.771 1.492-.301 1.449.51 2.688 1.708 3.19 1.309.547 3.955.306 5.685-.662l.398-.231c.51-.308.945-.619 1.369-.968l.298-.253.524.069c.59.066 1.188.1 1.79.1 8.045 0 14.666-6.007 14.666-13.552C30.666 7.336 24.045 1.33 16 1.33Zm0 2.667c6.627 0 12 4.873 12 10.885s-5.373 10.885-12 10.885c-1.016 0-2.003-.115-2.945-.33-.113-.026-.235.039-.395.169l-.271.239-.349.318-.286.246-.336.265a9.433 9.433 0 0 1-1.099.716c-1.28.716-3.053.654-3.353.529-.205-.086-.151-.232.037-.462l.263-.294.219-.239.242-.275c.165-.196.338-.418.501-.669.779-1.191.457-2.609.108-2.864C5.605 21.121 4 18.31 4 14.882 4 8.87 9.372 3.997 16 3.997Z"/><path d="M11.333 14.667a2 2 0 1 1-3.999.001 2 2 0 0 1 3.999-.001ZM18 14.667a2 2 0 1 1-3.999.001A2 2 0 0 1 18 14.667ZM24.667 14.667a2 2 0 1 1-3.999.001 2 2 0 0 1 3.999-.001Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1001 B |
1
src/assets/font-icons/privacy-policy.svg
Normal file
1
src/assets/font-icons/privacy-policy.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M21.316 10.431c.224-.216.617-.391.89-.43l.017-.001h.006c.282.004.679.14.923.323l.013.01.007.007.005.005.001.001c.195.203.366.55.417.796l.002.017.001.005v.002a1.91 1.91 0 0 1-.196.875l-.016.025-.002.003-.002.002-.003.005-.098.129-7.696 8.866c-.211.206-.57.379-.824.425l-.016.003h-.015a1.83 1.83 0 0 1-.883-.239l-.029-.021-.006-.005-.002-.002-.007-.006-.127-.111-3.307-3.335c-.196-.229-.369-.62-.369-.922 0-.306.188-.71.382-.935l.011-.012.007-.007.002-.001.004-.004a1.82 1.82 0 0 1 .815-.367l.014-.001h.01c.258 0 .633.117.854.256l.004.002.004.003.016.013.009.007.121.107 2.293 2.311 6.77-7.799Z"/><path d="m28.999 8.27-.001-.02v-.021H29l-.001-.084-.002-.085v-.04l-.001-.068-.001-.069-.003-.001-.004-.001-.002-.026a3.677 3.677 0 0 0-.175-.852 3.5 3.5 0 0 0-.367-.776 3.379 3.379 0 0 0-.643-.699 3.133 3.133 0 0 0-.8-.483l-9.973-3.852A3.04 3.04 0 0 0 15.999 1a3.056 3.056 0 0 0-1.022.19L5.008 5.041a3.287 3.287 0 0 0-1.444 1.172 3.567 3.567 0 0 0-.401.876 3.611 3.611 0 0 0-.161.966c-.009.796.017 2.25.227 4.066.209 1.817.602 3.996 1.328 6.243a25.567 25.567 0 0 0 1.519 3.688 21.36 21.36 0 0 0 1.98 3.19 18.629 18.629 0 0 0 3.054 3.17 17.86 17.86 0 0 0 3.675 2.315c.185.084.387.152.593.2.207.047.418.073.621.073s.411-.025.616-.071a3.11 3.11 0 0 0 .591-.198 17.889 17.889 0 0 0 3.678-2.317 18.543 18.543 0 0 0 3.058-3.171 21.499 21.499 0 0 0 1.981-3.19 25.614 25.614 0 0 0 1.519-3.688c.696-2.155 1.086-4.246 1.302-6.015.215-1.769.257-3.216.255-4.08ZM16.144 28.098l-.034.018-.035.014h-.006l-.01.001-.023.001h-.037a.27.27 0 0 1-.059-.005.317.317 0 0 1-.067-.026c-2.461-1.137-4.317-2.775-5.725-4.644-1.408-1.869-2.367-3.969-3.033-6.028-.67-2.051-1.026-4.042-1.212-5.694a29.995 29.995 0 0 1-.196-3.658v-.004h.001c-.004-.019-.002-.04 0-.061.003-.02.004-.041.013-.059.008-.014.01-.03.022-.049.013-.019.005-.01.021-.035 0 0 .017-.022.018-.026.001-.004.016-.02.018-.025a.091.091 0 0 1 .021-.023.158.158 0 0 1 .023-.02s.075-.034.1-.043l9.958-3.85s.069-.021.076-.021c.008 0 .056.007.071.01a.276.276 0 0 1 .057.018l9.988 3.857.044-.003.006.011.007.011.005.009.005.008a.86.86 0 0 1 .034.045l.045.064a.168.168 0 0 1 .052.141v.072a29.76 29.76 0 0 1-.196 3.645c-.187 1.646-.542 3.631-1.212 5.682-.664 2.053-1.623 4.147-3.028 6.014-1.405 1.866-3.254 3.508-5.702 4.648l-.01.005Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@ -182,8 +182,10 @@ function LeftColumn({
|
||||
return;
|
||||
|
||||
case SettingsScreens.PrivacyPhoneNumber:
|
||||
case SettingsScreens.PrivacyAddByPhone:
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
case SettingsScreens.PrivacyBio:
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
case SettingsScreens.PrivacyPhoneP2P:
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
@ -233,6 +235,10 @@ function LeftColumn({
|
||||
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
|
||||
setSettingsScreen(SettingsScreens.PrivacyProfilePhoto);
|
||||
return;
|
||||
case SettingsScreens.PrivacyBioAllowedContacts:
|
||||
case SettingsScreens.PrivacyBioDeniedContacts:
|
||||
setSettingsScreen(SettingsScreens.PrivacyBio);
|
||||
return;
|
||||
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
|
||||
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
|
||||
setSettingsScreen(SettingsScreens.PrivacyPhoneCall);
|
||||
|
||||
@ -106,8 +106,15 @@
|
||||
}
|
||||
|
||||
.settings-main-menu {
|
||||
padding: 0 0.5rem 0.75rem;
|
||||
padding: 0.5rem;
|
||||
background-color: var(--color-background);
|
||||
box-shadow: inset 0 -0.0625rem 0 0 var(--color-background-secondary-accent);
|
||||
border-bottom: 0.625rem solid var(--color-background-secondary);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
> .ChatExtra {
|
||||
padding: 0 0.5rem 0.3125rem;
|
||||
|
||||
@ -99,6 +99,11 @@ const PRIVACY_PROFILE_PHOTO_SCREENS = [
|
||||
SettingsScreens.PrivacyProfilePhotoDeniedContacts,
|
||||
];
|
||||
|
||||
const PRIVACY_BIO_SCREENS = [
|
||||
SettingsScreens.PrivacyBioAllowedContacts,
|
||||
SettingsScreens.PrivacyBioDeniedContacts,
|
||||
];
|
||||
|
||||
const PRIVACY_PHONE_CALL_SCREENS = [
|
||||
SettingsScreens.PrivacyPhoneCallAllowedContacts,
|
||||
SettingsScreens.PrivacyPhoneCallDeniedContacts,
|
||||
@ -190,6 +195,7 @@ 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.PrivacyBio]: PRIVACY_BIO_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),
|
||||
@ -314,8 +320,8 @@ const Settings: FC<OwnProps> = ({
|
||||
case SettingsScreens.PrivacyPhoneNumber:
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
case SettingsScreens.PrivacyBio:
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
case SettingsScreens.PrivacyPhoneP2P:
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
case SettingsScreens.PrivacyVoiceMessages:
|
||||
case SettingsScreens.PrivacyGroupChats:
|
||||
@ -331,6 +337,7 @@ const Settings: FC<OwnProps> = ({
|
||||
case SettingsScreens.PrivacyPhoneNumberAllowedContacts:
|
||||
case SettingsScreens.PrivacyLastSeenAllowedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
|
||||
case SettingsScreens.PrivacyBioAllowedContacts:
|
||||
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
|
||||
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
|
||||
case SettingsScreens.PrivacyForwardingAllowedContacts:
|
||||
@ -349,6 +356,7 @@ const Settings: FC<OwnProps> = ({
|
||||
case SettingsScreens.PrivacyPhoneNumberDeniedContacts:
|
||||
case SettingsScreens.PrivacyLastSeenDeniedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
|
||||
case SettingsScreens.PrivacyBioDeniedContacts:
|
||||
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
|
||||
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
|
||||
case SettingsScreens.PrivacyForwardingDeniedContacts:
|
||||
|
||||
@ -113,20 +113,21 @@ const SettingsHeader: FC<OwnProps> = ({
|
||||
return <h3>{lang('PrivacyLastSeen')}</h3>;
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
return <h3>{lang('Privacy.ProfilePhoto')}</h3>;
|
||||
case SettingsScreens.PrivacyBio:
|
||||
return <h3>{lang('PrivacyBio')}</h3>;
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
return <h3>{lang('PrivacyForwards')}</h3>;
|
||||
case SettingsScreens.PrivacyVoiceMessages:
|
||||
return <h3>{lang('PrivacyVoiceMessages')}</h3>;
|
||||
case SettingsScreens.PrivacyGroupChats:
|
||||
return <h3>{lang('AutodownloadGroupChats')}</h3>;
|
||||
case SettingsScreens.PrivacyPhoneP2P:
|
||||
return <h3>{lang('PrivacyP2P')}</h3>;
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
return <h3>{lang('Calls')}</h3>;
|
||||
|
||||
case SettingsScreens.PrivacyPhoneNumberAllowedContacts:
|
||||
case SettingsScreens.PrivacyLastSeenAllowedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
|
||||
case SettingsScreens.PrivacyBioAllowedContacts:
|
||||
case SettingsScreens.PrivacyForwardingAllowedContacts:
|
||||
case SettingsScreens.PrivacyVoiceMessagesAllowedContacts:
|
||||
case SettingsScreens.PrivacyGroupChatsAllowedContacts:
|
||||
@ -136,6 +137,7 @@ const SettingsHeader: FC<OwnProps> = ({
|
||||
case SettingsScreens.PrivacyPhoneNumberDeniedContacts:
|
||||
case SettingsScreens.PrivacyLastSeenDeniedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
|
||||
case SettingsScreens.PrivacyBioDeniedContacts:
|
||||
case SettingsScreens.PrivacyForwardingDeniedContacts:
|
||||
case SettingsScreens.PrivacyVoiceMessagesDeniedContacts:
|
||||
case SettingsScreens.PrivacyGroupChatsDeniedContacts:
|
||||
|
||||
@ -4,14 +4,18 @@ import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
import { FAQ_URL, PRIVACY_URL } from '../../../config';
|
||||
import { selectIsPremiumPurchaseBlocked } from '../../../global/selectors';
|
||||
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import ChatExtra from '../../common/ChatExtra';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import ProfileInfo from '../../common/ProfileInfo';
|
||||
import ConfirmDialog from '../../ui/ConfirmDialog';
|
||||
import ListItem from '../../ui/ListItem';
|
||||
|
||||
type OwnProps = {
|
||||
@ -38,8 +42,12 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
|
||||
loadProfilePhotos,
|
||||
loadAuthorizations,
|
||||
openPremiumModal,
|
||||
openSupportChat,
|
||||
openUrl,
|
||||
} = getActions();
|
||||
|
||||
const [isSupportDialogOpen, openSupportDialog, closeSupportDialog] = useFlag(false);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
useEffect(() => {
|
||||
@ -57,6 +65,11 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
|
||||
loadAuthorizations();
|
||||
}, []);
|
||||
|
||||
const handleOpenSupport = useLastCallback(() => {
|
||||
openSupportChat();
|
||||
closeSupportDialog();
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="settings-content custom-scroll">
|
||||
<div className="settings-main-menu">
|
||||
@ -138,6 +151,8 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
|
||||
>
|
||||
{lang('StickersName')}
|
||||
</ListItem>
|
||||
</div>
|
||||
<div className="settings-main-menu">
|
||||
{canBuyPremium && (
|
||||
<ListItem
|
||||
leftElement={<PremiumIcon withGradient big />}
|
||||
@ -149,6 +164,36 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
<div className="settings-main-menu">
|
||||
<ListItem
|
||||
icon="ask-support"
|
||||
onClick={openSupportDialog}
|
||||
>
|
||||
{lang('AskAQuestion')}
|
||||
</ListItem>
|
||||
<ListItem
|
||||
icon="help"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => openUrl({ url: FAQ_URL })}
|
||||
>
|
||||
{lang('TelegramFaq')}
|
||||
</ListItem>
|
||||
<ListItem
|
||||
icon="privacy-policy"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => openUrl({ url: PRIVACY_URL })}
|
||||
>
|
||||
{lang('PrivacyPolicy')}
|
||||
</ListItem>
|
||||
</div>
|
||||
<ConfirmDialog
|
||||
isOpen={isSupportDialogOpen}
|
||||
confirmLabel={lang('lng_settings_ask_ok')}
|
||||
title={lang('AskAQuestion')}
|
||||
text={lang('lng_settings_ask_sure')}
|
||||
confirmHandler={handleOpenSupport}
|
||||
onClose={closeSupportDialog}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -38,7 +38,7 @@ type StateProps = {
|
||||
privacyVoiceMessages?: ApiPrivacySettings;
|
||||
privacyGroupChats?: ApiPrivacySettings;
|
||||
privacyPhoneCall?: ApiPrivacySettings;
|
||||
privacyPhoneP2P?: ApiPrivacySettings;
|
||||
privacyBio?: ApiPrivacySettings;
|
||||
};
|
||||
|
||||
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
@ -53,6 +53,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
canDisplayAutoarchiveSetting,
|
||||
shouldArchiveAndMuteNewNonContact,
|
||||
canDisplayChatInTitle,
|
||||
canSetPasscode,
|
||||
privacyPhoneNumber,
|
||||
privacyLastSeen,
|
||||
privacyProfilePhoto,
|
||||
@ -60,10 +61,9 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
privacyVoiceMessages,
|
||||
privacyGroupChats,
|
||||
privacyPhoneCall,
|
||||
privacyPhoneP2P,
|
||||
privacyBio,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
canSetPasscode,
|
||||
}) => {
|
||||
const {
|
||||
loadPrivacySettings,
|
||||
@ -250,25 +250,12 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
narrow
|
||||
className="no-icon"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => onScreenSelect(SettingsScreens.PrivacyPhoneCall)}
|
||||
onClick={() => onScreenSelect(SettingsScreens.PrivacyBio)}
|
||||
>
|
||||
<div className="multiline-menu-item">
|
||||
<span className="title">{lang('WhoCanCallMe')}</span>
|
||||
<span className="title">{lang('PrivacyBio')}</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)}
|
||||
{getVisibilityValue(privacyBio)}
|
||||
</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
@ -287,16 +274,14 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
</ListItem>
|
||||
<ListItem
|
||||
narrow
|
||||
disabled={!isCurrentUserPremium}
|
||||
allowDisabledClick
|
||||
rightElement={!isCurrentUserPremium && <i className="icon icon-lock-badge settings-icon-locked" />}
|
||||
className="no-icon"
|
||||
onClick={handleVoiceMessagesClick}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => onScreenSelect(SettingsScreens.PrivacyPhoneCall)}
|
||||
>
|
||||
<div className="multiline-menu-item">
|
||||
<span className="title">{lang('PrivacyVoiceMessagesTitle')}</span>
|
||||
<span className="title">{lang('WhoCanCallMe')}</span>
|
||||
<span className="subtitle" dir="auto">
|
||||
{getVisibilityValue(privacyVoiceMessages)}
|
||||
{getVisibilityValue(privacyPhoneCall)}
|
||||
</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
@ -313,6 +298,21 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
narrow
|
||||
disabled={!isCurrentUserPremium}
|
||||
allowDisabledClick
|
||||
rightElement={!isCurrentUserPremium && <i className="icon icon-lock-badge settings-icon-locked" />}
|
||||
className="no-icon"
|
||||
onClick={handleVoiceMessagesClick}
|
||||
>
|
||||
<div className="multiline-menu-item">
|
||||
<span className="title">{lang('PrivacyVoiceMessagesTitle')}</span>
|
||||
<span className="subtitle" dir="auto">
|
||||
{getVisibilityValue(privacyVoiceMessages)}
|
||||
</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
</div>
|
||||
|
||||
{canDisplayAutoarchiveSetting && (
|
||||
@ -392,7 +392,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
privacyVoiceMessages: privacy.voiceMessages,
|
||||
privacyGroupChats: privacy.chatInvite,
|
||||
privacyPhoneCall: privacy.phoneCall,
|
||||
privacyPhoneP2P: privacy.phoneP2P,
|
||||
privacyBio: privacy.bio,
|
||||
canDisplayChatInTitle,
|
||||
canSetPasscode: selectCanSetPasscode(global),
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import type { FC } from '../../../lib/teact/teact';
|
||||
import React, { memo, useCallback, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiChat, ApiPhoto, ApiUser } from '../../../api/types';
|
||||
import type { ApiPhoto } from '../../../api/types';
|
||||
import type { ApiPrivacySettings } from '../../../types';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
@ -11,6 +11,7 @@ import { getPrivacyKey } from './helpers/privacy';
|
||||
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import ListItem from '../../ui/ListItem';
|
||||
import RadioGroup from '../../ui/RadioGroup';
|
||||
@ -23,57 +24,131 @@ type OwnProps = {
|
||||
onReset: () => void;
|
||||
};
|
||||
|
||||
type StateProps =
|
||||
Partial<ApiPrivacySettings> & {
|
||||
chatsById?: Record<string, ApiChat>;
|
||||
usersById?: Record<string, ApiUser>;
|
||||
currentUserId: string;
|
||||
hasCurrentUserFullInfo?: boolean;
|
||||
currentUserFallbackPhoto?: ApiPhoto;
|
||||
};
|
||||
type StateProps = {
|
||||
currentUserId: string;
|
||||
hasCurrentUserFullInfo?: boolean;
|
||||
currentUserFallbackPhoto?: ApiPhoto;
|
||||
primaryPrivacy?: ApiPrivacySettings;
|
||||
secondaryPrivacy?: ApiPrivacySettings;
|
||||
};
|
||||
|
||||
const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||
screen,
|
||||
isActive,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
visibility,
|
||||
allowUserIds,
|
||||
allowChatIds,
|
||||
blockUserIds,
|
||||
blockChatIds,
|
||||
chatsById,
|
||||
primaryPrivacy,
|
||||
secondaryPrivacy,
|
||||
currentUserId,
|
||||
hasCurrentUserFullInfo,
|
||||
currentUserFallbackPhoto,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
}) => {
|
||||
const { setPrivacyVisibility } = getActions();
|
||||
useHistoryBack({
|
||||
isActive,
|
||||
onBack: onReset,
|
||||
});
|
||||
|
||||
const secondaryScreen = useMemo(() => {
|
||||
switch (screen) {
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
return SettingsScreens.PrivacyPhoneP2P;
|
||||
case SettingsScreens.PrivacyPhoneNumber: {
|
||||
return primaryPrivacy?.visibility === 'nobody' ? SettingsScreens.PrivacyAddByPhone : undefined;
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}, [primaryPrivacy, screen]);
|
||||
|
||||
return (
|
||||
<div className="settings-content custom-scroll">
|
||||
<PrivacySubsection
|
||||
screen={screen}
|
||||
privacy={primaryPrivacy}
|
||||
onScreenSelect={onScreenSelect}
|
||||
/>
|
||||
{screen === SettingsScreens.PrivacyProfilePhoto && primaryPrivacy?.visibility !== 'everybody' && (
|
||||
<SettingsPrivacyPublicProfilePhoto
|
||||
currentUserId={currentUserId}
|
||||
hasCurrentUserFullInfo={hasCurrentUserFullInfo}
|
||||
currentUserFallbackPhoto={currentUserFallbackPhoto}
|
||||
/>
|
||||
)}
|
||||
{secondaryScreen && (
|
||||
<PrivacySubsection
|
||||
screen={secondaryScreen}
|
||||
privacy={secondaryPrivacy}
|
||||
onScreenSelect={onScreenSelect}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function PrivacySubsection({
|
||||
screen,
|
||||
privacy,
|
||||
onScreenSelect,
|
||||
}: {
|
||||
screen: SettingsScreens;
|
||||
privacy?: ApiPrivacySettings;
|
||||
onScreenSelect: (screen: SettingsScreens) => void;
|
||||
}) {
|
||||
const { setPrivacyVisibility } = getActions();
|
||||
const lang = useLang();
|
||||
|
||||
const visibilityOptions = useMemo(() => {
|
||||
return [
|
||||
const hasNobody = screen !== SettingsScreens.PrivacyAddByPhone;
|
||||
const options = [
|
||||
{ value: 'everybody', label: lang('P2PEverybody') },
|
||||
{ value: 'contacts', label: lang('P2PContacts') },
|
||||
{ value: 'nobody', label: lang('P2PNobody') },
|
||||
];
|
||||
}, [lang]);
|
||||
if (hasNobody) {
|
||||
options.push({ value: 'nobody', label: lang('P2PNobody') });
|
||||
}
|
||||
return options;
|
||||
}, [lang, screen]);
|
||||
|
||||
const exceptionLists = {
|
||||
shouldShowDenied: visibility !== 'nobody',
|
||||
shouldShowAllowed: visibility !== 'everybody',
|
||||
};
|
||||
const primaryExceptionLists = useMemo(() => {
|
||||
if (screen === SettingsScreens.PrivacyAddByPhone) {
|
||||
return {
|
||||
shouldShowDenied: false,
|
||||
shouldShowAllowed: false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
shouldShowDenied: privacy?.visibility !== 'nobody',
|
||||
shouldShowAllowed: privacy?.visibility !== 'everybody',
|
||||
};
|
||||
}, [privacy, screen]);
|
||||
|
||||
const privacyKey = getPrivacyKey(screen);
|
||||
|
||||
const descriptionText = useMemo(() => {
|
||||
switch (screen) {
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
return lang('CustomHelp');
|
||||
case SettingsScreens.PrivacyAddByPhone: {
|
||||
return privacy?.visibility === 'everybody' ? lang('PrivacyPhoneInfo') : lang('PrivacyPhoneInfo3');
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}, [lang, screen, privacy]);
|
||||
|
||||
const headerText = useMemo(() => {
|
||||
switch (screen) {
|
||||
case SettingsScreens.PrivacyPhoneNumber:
|
||||
return lang('PrivacyPhoneTitle');
|
||||
case SettingsScreens.PrivacyAddByPhone:
|
||||
return lang('PrivacyPhoneTitle2');
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
return lang('LastSeenTitle');
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
return lang('PrivacyProfilePhotoTitle');
|
||||
case SettingsScreens.PrivacyBio:
|
||||
return lang('PrivacyBioTitle');
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
return lang('PrivacyForwardsTitle');
|
||||
case SettingsScreens.PrivacyVoiceMessages:
|
||||
@ -89,19 +164,34 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
}, [lang, screen]);
|
||||
|
||||
useHistoryBack({
|
||||
isActive,
|
||||
onBack: onReset,
|
||||
const prepareSubtitle = useLastCallback((userIds?: string[], chatIds?: string[]) => {
|
||||
const userIdsCount = userIds?.length || 0;
|
||||
const chatIdsCount = chatIds?.length || 0;
|
||||
|
||||
if (!userIdsCount && !chatIdsCount) {
|
||||
return lang('EditAdminAddUsers');
|
||||
}
|
||||
|
||||
const userCountString = userIdsCount > 0 ? lang('Users', userIdsCount) : undefined;
|
||||
const chatCountString = chatIdsCount > 0 ? lang('Chats', chatIdsCount) : undefined;
|
||||
|
||||
return [userCountString, chatCountString].filter(Boolean).join(', ');
|
||||
});
|
||||
|
||||
const descriptionText = useMemo(() => {
|
||||
switch (screen) {
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
return lang('CustomHelp');
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}, [lang, screen]);
|
||||
const allowedString = useMemo(() => {
|
||||
return prepareSubtitle(privacy?.allowUserIds, privacy?.allowChatIds);
|
||||
}, [privacy]);
|
||||
|
||||
const blockString = useMemo(() => {
|
||||
return prepareSubtitle(privacy?.blockUserIds, privacy?.blockChatIds);
|
||||
}, [privacy]);
|
||||
|
||||
const handleVisibilityChange = useCallback((value) => {
|
||||
setPrivacyVisibility({
|
||||
privacyKey: privacyKey!,
|
||||
visibility: value,
|
||||
});
|
||||
}, [privacyKey]);
|
||||
|
||||
const allowedContactsScreen = (() => {
|
||||
switch (screen) {
|
||||
@ -111,6 +201,8 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||
return SettingsScreens.PrivacyLastSeenAllowedContacts;
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
return SettingsScreens.PrivacyProfilePhotoAllowedContacts;
|
||||
case SettingsScreens.PrivacyBio:
|
||||
return SettingsScreens.PrivacyBioAllowedContacts;
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
return SettingsScreens.PrivacyForwardingAllowedContacts;
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
@ -132,6 +224,8 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||
return SettingsScreens.PrivacyLastSeenDeniedContacts;
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
return SettingsScreens.PrivacyProfilePhotoDeniedContacts;
|
||||
case SettingsScreens.PrivacyBio:
|
||||
return SettingsScreens.PrivacyBioDeniedContacts;
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
return SettingsScreens.PrivacyForwardingDeniedContacts;
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
@ -145,105 +239,68 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
})();
|
||||
|
||||
const allowedCount = useMemo(() => {
|
||||
if (!allowUserIds || !allowChatIds || !chatsById) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return allowChatIds.reduce((result, chatId) => {
|
||||
return result + (chatsById[chatId] ? chatsById[chatId].membersCount! : 0);
|
||||
}, allowUserIds.length);
|
||||
}, [allowChatIds, allowUserIds, chatsById]);
|
||||
|
||||
const blockCount = useMemo(() => {
|
||||
if (!blockUserIds || !blockChatIds || !chatsById) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return blockChatIds.reduce((result, chatId) => {
|
||||
return result + (chatsById[chatId] ? chatsById[chatId].membersCount! : 0);
|
||||
}, blockUserIds.length);
|
||||
}, [blockChatIds, blockUserIds, chatsById]);
|
||||
|
||||
const handleVisibilityChange = useCallback((value) => {
|
||||
setPrivacyVisibility({
|
||||
privacyKey: privacyKey!,
|
||||
visibility: value,
|
||||
});
|
||||
}, [privacyKey, setPrivacyVisibility]);
|
||||
|
||||
return (
|
||||
<div className="settings-content custom-scroll">
|
||||
<>
|
||||
<div className="settings-item">
|
||||
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{headerText}</h4>
|
||||
|
||||
<RadioGroup
|
||||
name={`visibility-${privacyKey}`}
|
||||
options={visibilityOptions}
|
||||
onChange={handleVisibilityChange}
|
||||
selected={visibility}
|
||||
selected={privacy?.visibility}
|
||||
/>
|
||||
|
||||
{descriptionText && (
|
||||
<p className="settings-item-description-larger" dir={lang.isRtl ? 'rtl' : undefined}>{descriptionText}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="settings-item">
|
||||
<h4 className="settings-item-header mb-4" dir={lang.isRtl ? 'rtl' : undefined}>{lang('PrivacyExceptions')}</h4>
|
||||
|
||||
{exceptionLists.shouldShowAllowed && (
|
||||
<ListItem
|
||||
narrow
|
||||
icon="add-user"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => {
|
||||
onScreenSelect(allowedContactsScreen);
|
||||
}}
|
||||
>
|
||||
<div className="multiline-menu-item full-size">
|
||||
{allowedCount > 0 && <span className="date" dir="auto">+{allowedCount}</span>}
|
||||
<span className="title">{lang('AlwaysAllow')}</span>
|
||||
<span className="subtitle">{lang('EditAdminAddUsers')}</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
)}
|
||||
{exceptionLists.shouldShowDenied && (
|
||||
<ListItem
|
||||
narrow
|
||||
icon="delete-user"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => {
|
||||
onScreenSelect(deniedContactsScreen);
|
||||
}}
|
||||
>
|
||||
<div className="multiline-menu-item full-size">
|
||||
{blockCount > 0 && <span className="date" dir="auto">−{blockCount}</span>}
|
||||
<span className="title">{lang('NeverAllow')}</span>
|
||||
<span className="subtitle">{lang('EditAdminAddUsers')}</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{screen === SettingsScreens.PrivacyProfilePhoto && exceptionLists.shouldShowAllowed && (
|
||||
<SettingsPrivacyPublicProfilePhoto
|
||||
currentUserId={currentUserId}
|
||||
hasCurrentUserFullInfo={hasCurrentUserFullInfo}
|
||||
currentUserFallbackPhoto={currentUserFallbackPhoto}
|
||||
/>
|
||||
{(primaryExceptionLists.shouldShowAllowed || primaryExceptionLists.shouldShowDenied) && (
|
||||
<div className="settings-item">
|
||||
<h4 className="settings-item-header mb-4" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{lang('PrivacyExceptions')}
|
||||
</h4>
|
||||
{primaryExceptionLists.shouldShowAllowed && (
|
||||
<ListItem
|
||||
narrow
|
||||
icon="add-user"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => {
|
||||
onScreenSelect(allowedContactsScreen);
|
||||
}}
|
||||
>
|
||||
<div className="multiline-menu-item full-size">
|
||||
<span className="title">{lang('AlwaysAllow')}</span>
|
||||
<span className="subtitle">{allowedString}</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
)}
|
||||
{primaryExceptionLists.shouldShowDenied && (
|
||||
<ListItem
|
||||
narrow
|
||||
icon="delete-user"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => {
|
||||
onScreenSelect(deniedContactsScreen);
|
||||
}}
|
||||
>
|
||||
<div className="multiline-menu-item full-size">
|
||||
<span className="title">{lang('NeverAllow')}</span>
|
||||
<span className="subtitle">{blockString}</span>
|
||||
</div>
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { screen }): StateProps => {
|
||||
let privacySettings: ApiPrivacySettings | undefined;
|
||||
let primaryPrivacy: ApiPrivacySettings | undefined;
|
||||
let secondaryPrivacy: ApiPrivacySettings | undefined;
|
||||
|
||||
const {
|
||||
currentUserId,
|
||||
chats: { byId: chatsById },
|
||||
settings: { privacy },
|
||||
} = global;
|
||||
|
||||
@ -251,39 +308,42 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
switch (screen) {
|
||||
case SettingsScreens.PrivacyPhoneNumber:
|
||||
privacySettings = privacy.phoneNumber;
|
||||
primaryPrivacy = privacy.phoneNumber;
|
||||
secondaryPrivacy = privacy.addByPhone;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyLastSeen:
|
||||
privacySettings = privacy.lastSeen;
|
||||
primaryPrivacy = privacy.lastSeen;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyProfilePhoto:
|
||||
privacySettings = privacy.profilePhoto;
|
||||
primaryPrivacy = privacy.profilePhoto;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
privacySettings = privacy.phoneCall;
|
||||
case SettingsScreens.PrivacyBio:
|
||||
primaryPrivacy = privacy.bio;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyPhoneP2P:
|
||||
privacySettings = privacy.phoneP2P;
|
||||
case SettingsScreens.PrivacyPhoneCall:
|
||||
primaryPrivacy = privacy.phoneCall;
|
||||
secondaryPrivacy = privacy.phoneP2P;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
privacySettings = privacy.forwards;
|
||||
primaryPrivacy = privacy.forwards;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyVoiceMessages:
|
||||
privacySettings = privacy.voiceMessages;
|
||||
primaryPrivacy = privacy.voiceMessages;
|
||||
break;
|
||||
|
||||
case SettingsScreens.PrivacyGroupChats:
|
||||
privacySettings = privacy.chatInvite;
|
||||
primaryPrivacy = privacy.chatInvite;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!privacySettings) {
|
||||
if (!primaryPrivacy) {
|
||||
return {
|
||||
currentUserId: currentUserId!,
|
||||
hasCurrentUserFullInfo: Boolean(currentUserFullInfo),
|
||||
@ -292,8 +352,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
}
|
||||
|
||||
return {
|
||||
...privacySettings,
|
||||
chatsById,
|
||||
primaryPrivacy,
|
||||
secondaryPrivacy,
|
||||
currentUserId: currentUserId!,
|
||||
hasCurrentUserFullInfo: Boolean(currentUserFullInfo),
|
||||
currentUserFallbackPhoto: currentUserFullInfo?.fallbackPhoto,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useCallback, useMemo, useState,
|
||||
memo, useCallback, useEffect, useMemo, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
@ -9,7 +9,7 @@ import type { ApiPrivacySettings } from '../../../types';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
import { ALL_FOLDER_ID, ARCHIVED_FOLDER_ID } from '../../../config';
|
||||
import { filterChatsByName, isUserId } from '../../../global/helpers';
|
||||
import { filterChatsByName } from '../../../global/helpers';
|
||||
import { unique } from '../../../util/iteratees';
|
||||
import { getPrivacyKey } from './helpers/privacy';
|
||||
|
||||
@ -37,10 +37,10 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
|
||||
isAllowList,
|
||||
screen,
|
||||
isActive,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
currentUserId,
|
||||
settings,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
}) => {
|
||||
const { setPrivacySettings } = getActions();
|
||||
|
||||
@ -61,6 +61,11 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
|
||||
const [isSubmitShown, setIsSubmitShown] = useState<boolean>(false);
|
||||
const [newSelectedContactIds, setNewSelectedContactIds] = useState<string[]>(selectedContactIds);
|
||||
|
||||
// Reset selected contact ids on change from other client when screen is not active
|
||||
useEffect(() => {
|
||||
if (!isActive) setNewSelectedContactIds(selectedContactIds);
|
||||
}, [isActive, selectedContactIds]);
|
||||
|
||||
const folderAllOrderedIds = useFolderManagerForOrderedIds(ALL_FOLDER_ID);
|
||||
const folderArchivedOrderedIds = useFolderManagerForOrderedIds(ARCHIVED_FOLDER_ID);
|
||||
const displayedIds = useMemo(() => {
|
||||
@ -68,11 +73,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
|
||||
const chatIds = unique([...folderAllOrderedIds || [], ...folderArchivedOrderedIds || []])
|
||||
.filter((chatId) => {
|
||||
const chat = chatsById[chatId];
|
||||
|
||||
return chat && isUserId(chat.id) && chat.id !== currentUserId;
|
||||
});
|
||||
.filter((chatId) => chatId !== currentUserId);
|
||||
|
||||
return unique([
|
||||
...selectedContactIds,
|
||||
@ -89,7 +90,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
|
||||
setPrivacySettings({
|
||||
privacyKey: getPrivacyKey(screen)!,
|
||||
isAllowList: Boolean(isAllowList),
|
||||
contactsIds: newSelectedContactIds,
|
||||
updatedIds: newSelectedContactIds,
|
||||
});
|
||||
|
||||
onScreenSelect(SettingsScreens.Privacy);
|
||||
@ -136,6 +137,9 @@ function getCurrentPrivacySettings(global: GlobalState, screen: SettingsScreens)
|
||||
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
|
||||
return privacy.profilePhoto;
|
||||
case SettingsScreens.PrivacyBioAllowedContacts:
|
||||
case SettingsScreens.PrivacyBioDeniedContacts:
|
||||
return privacy.bio;
|
||||
case SettingsScreens.PrivacyPhoneCallAllowedContacts:
|
||||
case SettingsScreens.PrivacyPhoneCallDeniedContacts:
|
||||
return privacy.phoneCall;
|
||||
|
||||
@ -15,6 +15,10 @@ export function getPrivacyKey(screen: SettingsScreens): ApiPrivacyKey | undefine
|
||||
case SettingsScreens.PrivacyProfilePhotoAllowedContacts:
|
||||
case SettingsScreens.PrivacyProfilePhotoDeniedContacts:
|
||||
return 'profilePhoto';
|
||||
case SettingsScreens.PrivacyBio:
|
||||
case SettingsScreens.PrivacyBioAllowedContacts:
|
||||
case SettingsScreens.PrivacyBioDeniedContacts:
|
||||
return 'bio';
|
||||
case SettingsScreens.PrivacyForwarding:
|
||||
case SettingsScreens.PrivacyForwardingAllowedContacts:
|
||||
case SettingsScreens.PrivacyForwardingDeniedContacts:
|
||||
@ -35,6 +39,8 @@ export function getPrivacyKey(screen: SettingsScreens): ApiPrivacyKey | undefine
|
||||
case SettingsScreens.PrivacyPhoneP2PAllowedContacts:
|
||||
case SettingsScreens.PrivacyPhoneP2PDeniedContacts:
|
||||
return 'phoneP2P';
|
||||
case SettingsScreens.PrivacyAddByPhone:
|
||||
return 'addByPhone';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
@ -439,12 +439,12 @@ function Story({
|
||||
const handleInfoPrivacyClick = useLastCallback(() => {
|
||||
const visibility = !isLoadedStory || story.isPublic
|
||||
? undefined
|
||||
: story.isForContacts ? 'contacts' : (story.isForCloseFriends ? 'closeFriends' : 'selectedContacts');
|
||||
: story.isForContacts ? 'contacts' : (story.isForCloseFriends ? 'closeFriends' : 'nobody');
|
||||
|
||||
let message;
|
||||
const myName = getUserFirstOrLastName(user);
|
||||
switch (visibility) {
|
||||
case 'selectedContacts':
|
||||
case 'nobody':
|
||||
message = lang('StorySelectedContactsHint', myName);
|
||||
break;
|
||||
case 'contacts':
|
||||
@ -560,7 +560,7 @@ function Story({
|
||||
case 'closeFriends':
|
||||
privacyIcon = 'favorite-filled';
|
||||
break;
|
||||
case 'selectedContacts':
|
||||
case 'nobody':
|
||||
privacyIcon = 'group-filled';
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -69,7 +69,7 @@ const OPTIONS: PrivacyOption[] = [{
|
||||
actions: 'closeFriends',
|
||||
}, {
|
||||
name: 'StoryPrivacyOptionSelectedContacts',
|
||||
value: 'selectedContacts',
|
||||
value: 'nobody',
|
||||
color: ['#FFB743', '#F69A36'],
|
||||
icon: 'group-filled',
|
||||
actions: 'allowUserIds',
|
||||
|
||||
@ -293,6 +293,8 @@ export const DEFAULT_LANG_CODE = 'en';
|
||||
export const DEFAULT_LANG_PACK = 'android';
|
||||
export const LANG_PACKS = ['android', 'ios', 'tdesktop', 'macos'] as const;
|
||||
export const FEEDBACK_URL = 'https://bugs.telegram.org/?tag_ids=41&sort=time';
|
||||
export const FAQ_URL = 'https://telegram.org/faq';
|
||||
export const PRIVACY_URL = 'https://telegram.org/privacy';
|
||||
export const MINI_APP_TOS_URL = 'https://telegram.org/tos/mini-apps';
|
||||
export const GENERAL_TOPIC_ID = 1;
|
||||
export const STORY_EXPIRE_PERIOD = 86400; // 1 day
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import type { ApiUser, ApiUsername } from '../../../api/types';
|
||||
import type {
|
||||
ApiPrivacySettings,
|
||||
InputPrivacyContact, InputPrivacyRules, PrivacyVisibility,
|
||||
} from '../../../types';
|
||||
import type { ActionReturnType, GlobalState } from '../../types';
|
||||
import type { ActionReturnType } from '../../types';
|
||||
import {
|
||||
ProfileEditProgress,
|
||||
UPLOADING_WALLPAPER_SLUG,
|
||||
@ -17,7 +16,7 @@ import { requestPermission, subscribe, unsubscribe } from '../../../util/notific
|
||||
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { isUserId } from '../../helpers';
|
||||
import { buildApiInputPrivacyRules } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addBlockedUser, addNotifyExceptions, addUsers, removeBlockedUser, replaceSettings, updateChat, updateChats,
|
||||
@ -413,6 +412,7 @@ addActionHandler('loadLanguages', async (global): Promise<void> => {
|
||||
addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
const result = await Promise.all([
|
||||
callApi('fetchPrivacySettings', 'phoneNumber'),
|
||||
callApi('fetchPrivacySettings', 'addByPhone'),
|
||||
callApi('fetchPrivacySettings', 'lastSeen'),
|
||||
callApi('fetchPrivacySettings', 'profilePhoto'),
|
||||
callApi('fetchPrivacySettings', 'forwards'),
|
||||
@ -420,6 +420,7 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
callApi('fetchPrivacySettings', 'phoneCall'),
|
||||
callApi('fetchPrivacySettings', 'phoneP2P'),
|
||||
callApi('fetchPrivacySettings', 'voiceMessages'),
|
||||
callApi('fetchPrivacySettings', 'bio'),
|
||||
]);
|
||||
|
||||
if (result.some((e) => e === undefined)) {
|
||||
@ -428,6 +429,7 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
|
||||
const [
|
||||
phoneNumberSettings,
|
||||
addByPhoneSettings,
|
||||
lastSeenSettings,
|
||||
profilePhotoSettings,
|
||||
forwardsSettings,
|
||||
@ -435,6 +437,7 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
phoneCallSettings,
|
||||
phoneP2PSettings,
|
||||
voiceMessagesSettings,
|
||||
bioSettings,
|
||||
] = result as {
|
||||
users: ApiUser[];
|
||||
rules: ApiPrivacySettings;
|
||||
@ -451,6 +454,7 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
privacy: {
|
||||
...global.settings.privacy,
|
||||
phoneNumber: phoneNumberSettings.rules,
|
||||
addByPhone: addByPhoneSettings.rules,
|
||||
lastSeen: lastSeenSettings.rules,
|
||||
profilePhoto: profilePhotoSettings.rules,
|
||||
forwards: forwardsSettings.rules,
|
||||
@ -458,6 +462,7 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
phoneCall: phoneCallSettings.rules,
|
||||
phoneP2P: phoneP2PSettings.rules,
|
||||
voiceMessages: voiceMessagesSettings.rules,
|
||||
bio: bioSettings.rules,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -475,10 +480,10 @@ addActionHandler('setPrivacyVisibility', async (global, actions, payload): Promi
|
||||
return;
|
||||
}
|
||||
|
||||
const rules = buildInputPrivacyRules(global, {
|
||||
const rules = buildApiInputPrivacyRules(global, {
|
||||
visibility,
|
||||
allowedIds: [...settings.allowUserIds, ...settings.allowChatIds],
|
||||
deniedIds: [...settings.blockUserIds, ...settings.blockChatIds],
|
||||
blockedIds: [...settings.blockUserIds, ...settings.blockChatIds],
|
||||
});
|
||||
|
||||
const result = await callApi('setPrivacySettings', privacyKey, rules);
|
||||
@ -502,7 +507,7 @@ addActionHandler('setPrivacyVisibility', async (global, actions, payload): Promi
|
||||
});
|
||||
|
||||
addActionHandler('setPrivacySettings', async (global, actions, payload): Promise<void> => {
|
||||
const { privacyKey, isAllowList, contactsIds } = payload!;
|
||||
const { privacyKey, isAllowList, updatedIds } = payload!;
|
||||
const {
|
||||
privacy: { [privacyKey]: settings },
|
||||
} = global.settings;
|
||||
@ -511,10 +516,11 @@ addActionHandler('setPrivacySettings', async (global, actions, payload): Promise
|
||||
return;
|
||||
}
|
||||
|
||||
const rules = buildInputPrivacyRules(global, {
|
||||
const rules = buildApiInputPrivacyRules(global, {
|
||||
visibility: settings.visibility,
|
||||
allowedIds: isAllowList ? contactsIds : [...settings.allowUserIds, ...settings.allowChatIds],
|
||||
deniedIds: !isAllowList ? contactsIds : [...settings.blockUserIds, ...settings.blockChatIds],
|
||||
isUnspecified: settings.isUnspecified,
|
||||
allowedIds: isAllowList ? updatedIds : [...settings.allowUserIds, ...settings.allowChatIds],
|
||||
blockedIds: !isAllowList ? updatedIds : [...settings.blockUserIds, ...settings.blockChatIds],
|
||||
});
|
||||
|
||||
const result = await callApi('setPrivacySettings', privacyKey, rules);
|
||||
@ -537,74 +543,6 @@ addActionHandler('setPrivacySettings', async (global, actions, payload): Promise
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
function buildInputPrivacyRules(global: GlobalState, {
|
||||
visibility,
|
||||
allowedIds,
|
||||
deniedIds,
|
||||
}: {
|
||||
visibility: PrivacyVisibility;
|
||||
allowedIds: string[];
|
||||
deniedIds: string[];
|
||||
}): InputPrivacyRules {
|
||||
const {
|
||||
users: { byId: usersById },
|
||||
chats: { byId: chatsById },
|
||||
} = global;
|
||||
|
||||
const rules: InputPrivacyRules = {
|
||||
visibility,
|
||||
};
|
||||
let users: InputPrivacyContact[];
|
||||
let chats: InputPrivacyContact[];
|
||||
|
||||
const collectUsers = (userId: string) => {
|
||||
if (!isUserId(userId)) {
|
||||
return undefined;
|
||||
}
|
||||
const { id, accessHash } = usersById[userId] || {};
|
||||
if (!id) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { id, accessHash };
|
||||
};
|
||||
|
||||
const collectChats = (userId: string) => {
|
||||
if (isUserId(userId)) {
|
||||
return undefined;
|
||||
}
|
||||
const chat = chatsById[userId];
|
||||
|
||||
return chat ? { id: chat.id } : undefined;
|
||||
};
|
||||
|
||||
if (visibility === 'contacts' || visibility === 'nobody') {
|
||||
users = allowedIds.map(collectUsers).filter(Boolean) as InputPrivacyContact[];
|
||||
chats = allowedIds.map(collectChats).filter(Boolean) as InputPrivacyContact[];
|
||||
|
||||
if (users.length > 0) {
|
||||
rules.allowedUsers = users;
|
||||
}
|
||||
if (chats.length > 0) {
|
||||
rules.allowedChats = chats;
|
||||
}
|
||||
}
|
||||
|
||||
if (visibility === 'everybody' || visibility === 'contacts') {
|
||||
users = deniedIds.map(collectUsers).filter(Boolean) as InputPrivacyContact[];
|
||||
chats = deniedIds.map(collectChats).filter(Boolean) as InputPrivacyContact[];
|
||||
|
||||
if (users.length > 0) {
|
||||
rules.blockedUsers = users;
|
||||
}
|
||||
if (chats.length > 0) {
|
||||
rules.blockedChats = chats;
|
||||
}
|
||||
}
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
addActionHandler('updateIsOnline', (global, actions, payload): ActionReturnType => {
|
||||
if (global.connectionState !== 'connectionStateReady') return;
|
||||
callApi('updateIsOnline', payload);
|
||||
|
||||
@ -6,7 +6,7 @@ import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { translate } from '../../../util/langProvider';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { getStoryKey } from '../../helpers';
|
||||
import { buildApiInputPrivacyRules, getStoryKey } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addStories,
|
||||
@ -378,13 +378,19 @@ addActionHandler('editStoryPrivacy', (global, actions, payload): ActionReturnTyp
|
||||
privacy,
|
||||
} = payload;
|
||||
|
||||
const allowedUserList = privacy.allowUserIds?.map((userId) => selectUser(global, userId)).filter(Boolean);
|
||||
const deniedUserList = privacy.blockUserIds?.map((userId) => selectUser(global, userId)).filter(Boolean);
|
||||
const allowedIds = [...privacy.allowUserIds, ...privacy.allowChatIds];
|
||||
const blockedIds = [...privacy.blockUserIds, ...privacy.blockChatIds];
|
||||
|
||||
const inputPrivacy = buildApiInputPrivacyRules(global, {
|
||||
visibility: privacy.visibility,
|
||||
isUnspecified: privacy.isUnspecified,
|
||||
allowedIds,
|
||||
blockedIds,
|
||||
});
|
||||
|
||||
void callApi('editStoryPrivacy', {
|
||||
id: storyId,
|
||||
visibility: privacy.visibility,
|
||||
allowedUserList,
|
||||
deniedUserList,
|
||||
privacy: inputPrivacy,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -9,3 +9,4 @@ export * from './reactions';
|
||||
export * from './bots';
|
||||
export * from './media';
|
||||
export * from './symbols';
|
||||
export * from './misc';
|
||||
|
||||
36
src/global/helpers/misc.ts
Normal file
36
src/global/helpers/misc.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import type { ApiInputPrivacyRules, PrivacyVisibility } from '../../types';
|
||||
import type { GlobalState } from '../types';
|
||||
|
||||
import { partition } from '../../util/iteratees';
|
||||
import { isUserId } from './chats';
|
||||
|
||||
export function buildApiInputPrivacyRules(global: GlobalState, {
|
||||
visibility,
|
||||
isUnspecified,
|
||||
allowedIds,
|
||||
blockedIds,
|
||||
}: {
|
||||
visibility: PrivacyVisibility;
|
||||
isUnspecified?: boolean;
|
||||
allowedIds: string[];
|
||||
blockedIds: string[];
|
||||
}): ApiInputPrivacyRules {
|
||||
const {
|
||||
users: { byId: usersById },
|
||||
chats: { byId: chatsById },
|
||||
} = global;
|
||||
|
||||
const [allowedUserIds, allowedChatIds] = partition(allowedIds, isUserId);
|
||||
const [blockedUserIds, blockedChatIds] = partition(blockedIds, isUserId);
|
||||
|
||||
const rules: ApiInputPrivacyRules = {
|
||||
visibility,
|
||||
isUnspecified,
|
||||
allowedUsers: allowedUserIds.map((userId) => usersById[userId]).filter(Boolean),
|
||||
allowedChats: allowedChatIds.map((chatId) => chatsById[chatId]).filter(Boolean),
|
||||
blockedUsers: blockedUserIds.map((userId) => usersById[userId]).filter(Boolean),
|
||||
blockedChats: blockedChatIds.map((chatId) => chatsById[chatId]).filter(Boolean),
|
||||
};
|
||||
|
||||
return rules;
|
||||
}
|
||||
@ -1064,7 +1064,7 @@ export interface ActionPayloads {
|
||||
setPrivacySettings: {
|
||||
privacyKey: ApiPrivacyKey;
|
||||
isAllowList: boolean;
|
||||
contactsIds: string[];
|
||||
updatedIds: string[];
|
||||
};
|
||||
loadNotificationExceptions: undefined;
|
||||
setThemeSettings: { theme: ThemeKey } & Partial<IThemeSettings>;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,8 +3,8 @@ $icons-font: "icons";
|
||||
|
||||
@font-face {
|
||||
font-family: $icons-font;
|
||||
src: url("./icons.woff2?2fc8ce731efb721947ab7acfba88eb91") format("woff2"),
|
||||
url("./icons.woff?2fc8ce731efb721947ab7acfba88eb91") format("woff");
|
||||
src: url("./icons.woff2?2e8e2fec4b27141c4d298083615a0665") format("woff2"),
|
||||
url("./icons.woff?2e8e2fec4b27141c4d298083615a0665") format("woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -52,204 +52,206 @@ $icons-map: (
|
||||
"arrow-down": "\f10f",
|
||||
"arrow-left": "\f110",
|
||||
"arrow-right": "\f111",
|
||||
"attach": "\f112",
|
||||
"avatar-archived-chats": "\f113",
|
||||
"avatar-deleted-account": "\f114",
|
||||
"avatar-saved-messages": "\f115",
|
||||
"bold": "\f116",
|
||||
"bot-command": "\f117",
|
||||
"bot-commands-filled": "\f118",
|
||||
"bots": "\f119",
|
||||
"bug": "\f11a",
|
||||
"calendar-filter": "\f11b",
|
||||
"calendar": "\f11c",
|
||||
"camera-add": "\f11d",
|
||||
"camera": "\f11e",
|
||||
"car": "\f11f",
|
||||
"card": "\f120",
|
||||
"channel-filled": "\f121",
|
||||
"channel": "\f122",
|
||||
"channelviews": "\f123",
|
||||
"chat-badge": "\f124",
|
||||
"chats-badge": "\f125",
|
||||
"check": "\f126",
|
||||
"close-circle": "\f127",
|
||||
"close-topic": "\f128",
|
||||
"close": "\f129",
|
||||
"cloud-download": "\f12a",
|
||||
"collapse": "\f12b",
|
||||
"colorize": "\f12c",
|
||||
"comments-sticker": "\f12d",
|
||||
"comments": "\f12e",
|
||||
"copy-media": "\f12f",
|
||||
"copy": "\f130",
|
||||
"darkmode": "\f131",
|
||||
"data": "\f132",
|
||||
"delete-filled": "\f133",
|
||||
"delete-left": "\f134",
|
||||
"delete-user": "\f135",
|
||||
"delete": "\f136",
|
||||
"document": "\f137",
|
||||
"double-badge": "\f138",
|
||||
"down": "\f139",
|
||||
"download": "\f13a",
|
||||
"eats": "\f13b",
|
||||
"edit": "\f13c",
|
||||
"email": "\f13d",
|
||||
"enter": "\f13e",
|
||||
"expand": "\f13f",
|
||||
"eye-closed-outline": "\f140",
|
||||
"eye-closed": "\f141",
|
||||
"eye-outline": "\f142",
|
||||
"eye": "\f143",
|
||||
"favorite-filled": "\f144",
|
||||
"favorite": "\f145",
|
||||
"file-badge": "\f146",
|
||||
"flag": "\f147",
|
||||
"folder-badge": "\f148",
|
||||
"folder": "\f149",
|
||||
"fontsize": "\f14a",
|
||||
"forums": "\f14b",
|
||||
"forward": "\f14c",
|
||||
"fullscreen": "\f14d",
|
||||
"gifs": "\f14e",
|
||||
"gift": "\f14f",
|
||||
"group-filled": "\f150",
|
||||
"group": "\f151",
|
||||
"grouped-disable": "\f152",
|
||||
"grouped": "\f153",
|
||||
"hand-stop": "\f154",
|
||||
"hashtag": "\f155",
|
||||
"heart-outline": "\f156",
|
||||
"heart": "\f157",
|
||||
"help": "\f158",
|
||||
"info-filled": "\f159",
|
||||
"info": "\f15a",
|
||||
"install": "\f15b",
|
||||
"italic": "\f15c",
|
||||
"key": "\f15d",
|
||||
"keyboard": "\f15e",
|
||||
"lamp": "\f15f",
|
||||
"language": "\f160",
|
||||
"large-pause": "\f161",
|
||||
"large-play": "\f162",
|
||||
"link-badge": "\f163",
|
||||
"link-broken": "\f164",
|
||||
"link": "\f165",
|
||||
"location": "\f166",
|
||||
"lock-badge": "\f167",
|
||||
"lock": "\f168",
|
||||
"logout": "\f169",
|
||||
"loop": "\f16a",
|
||||
"mention": "\f16b",
|
||||
"message-failed": "\f16c",
|
||||
"message-pending": "\f16d",
|
||||
"message-read": "\f16e",
|
||||
"message-succeeded": "\f16f",
|
||||
"message": "\f170",
|
||||
"microphone-alt": "\f171",
|
||||
"microphone": "\f172",
|
||||
"monospace": "\f173",
|
||||
"more-circle": "\f174",
|
||||
"more": "\f175",
|
||||
"mute": "\f176",
|
||||
"muted": "\f177",
|
||||
"new-chat-filled": "\f178",
|
||||
"next": "\f179",
|
||||
"noise-suppression": "\f17a",
|
||||
"non-contacts": "\f17b",
|
||||
"open-in-new-tab": "\f17c",
|
||||
"password-off": "\f17d",
|
||||
"pause": "\f17e",
|
||||
"permissions": "\f17f",
|
||||
"phone-discard-outline": "\f180",
|
||||
"phone-discard": "\f181",
|
||||
"phone": "\f182",
|
||||
"photo": "\f183",
|
||||
"pin-badge": "\f184",
|
||||
"pin-list": "\f185",
|
||||
"pin": "\f186",
|
||||
"pinned-chat": "\f187",
|
||||
"pinned-message": "\f188",
|
||||
"pip": "\f189",
|
||||
"play-story": "\f18a",
|
||||
"play": "\f18b",
|
||||
"poll": "\f18c",
|
||||
"premium": "\f18d",
|
||||
"previous": "\f18e",
|
||||
"readchats": "\f18f",
|
||||
"recent": "\f190",
|
||||
"reload": "\f191",
|
||||
"remove": "\f192",
|
||||
"reopen-topic": "\f193",
|
||||
"replace": "\f194",
|
||||
"replies": "\f195",
|
||||
"reply-filled": "\f196",
|
||||
"reply": "\f197",
|
||||
"revote": "\f198",
|
||||
"save-story": "\f199",
|
||||
"saved-messages": "\f19a",
|
||||
"schedule": "\f19b",
|
||||
"search": "\f19c",
|
||||
"select": "\f19d",
|
||||
"send-outline": "\f19e",
|
||||
"send": "\f19f",
|
||||
"settings-filled": "\f1a0",
|
||||
"settings": "\f1a1",
|
||||
"share-filled": "\f1a2",
|
||||
"share-screen-outlined": "\f1a3",
|
||||
"share-screen-stop": "\f1a4",
|
||||
"share-screen": "\f1a5",
|
||||
"sidebar": "\f1a6",
|
||||
"skip-next": "\f1a7",
|
||||
"skip-previous": "\f1a8",
|
||||
"smallscreen": "\f1a9",
|
||||
"smile": "\f1aa",
|
||||
"sort": "\f1ab",
|
||||
"speaker-muted-story": "\f1ac",
|
||||
"speaker-outline": "\f1ad",
|
||||
"speaker-story": "\f1ae",
|
||||
"speaker": "\f1af",
|
||||
"spoiler-disable": "\f1b0",
|
||||
"spoiler": "\f1b1",
|
||||
"sport": "\f1b2",
|
||||
"stats": "\f1b3",
|
||||
"stealth-future": "\f1b4",
|
||||
"stealth-past": "\f1b5",
|
||||
"stickers": "\f1b6",
|
||||
"stop-raising-hand": "\f1b7",
|
||||
"stop": "\f1b8",
|
||||
"story-caption": "\f1b9",
|
||||
"story-expired": "\f1ba",
|
||||
"story-priority": "\f1bb",
|
||||
"story-reply": "\f1bc",
|
||||
"strikethrough": "\f1bd",
|
||||
"timer": "\f1be",
|
||||
"transcribe": "\f1bf",
|
||||
"truck": "\f1c0",
|
||||
"unarchive": "\f1c1",
|
||||
"underlined": "\f1c2",
|
||||
"unlock-badge": "\f1c3",
|
||||
"unlock": "\f1c4",
|
||||
"unmute": "\f1c5",
|
||||
"unpin": "\f1c6",
|
||||
"unread": "\f1c7",
|
||||
"up": "\f1c8",
|
||||
"user-filled": "\f1c9",
|
||||
"user-online": "\f1ca",
|
||||
"user": "\f1cb",
|
||||
"video-outlined": "\f1cc",
|
||||
"video-stop": "\f1cd",
|
||||
"video": "\f1ce",
|
||||
"voice-chat": "\f1cf",
|
||||
"volume-1": "\f1d0",
|
||||
"volume-2": "\f1d1",
|
||||
"volume-3": "\f1d2",
|
||||
"web": "\f1d3",
|
||||
"webapp": "\f1d4",
|
||||
"word-wrap": "\f1d5",
|
||||
"zoom-in": "\f1d6",
|
||||
"zoom-out": "\f1d7",
|
||||
"ask-support": "\f112",
|
||||
"attach": "\f113",
|
||||
"avatar-archived-chats": "\f114",
|
||||
"avatar-deleted-account": "\f115",
|
||||
"avatar-saved-messages": "\f116",
|
||||
"bold": "\f117",
|
||||
"bot-command": "\f118",
|
||||
"bot-commands-filled": "\f119",
|
||||
"bots": "\f11a",
|
||||
"bug": "\f11b",
|
||||
"calendar-filter": "\f11c",
|
||||
"calendar": "\f11d",
|
||||
"camera-add": "\f11e",
|
||||
"camera": "\f11f",
|
||||
"car": "\f120",
|
||||
"card": "\f121",
|
||||
"channel-filled": "\f122",
|
||||
"channel": "\f123",
|
||||
"channelviews": "\f124",
|
||||
"chat-badge": "\f125",
|
||||
"chats-badge": "\f126",
|
||||
"check": "\f127",
|
||||
"close-circle": "\f128",
|
||||
"close-topic": "\f129",
|
||||
"close": "\f12a",
|
||||
"cloud-download": "\f12b",
|
||||
"collapse": "\f12c",
|
||||
"colorize": "\f12d",
|
||||
"comments-sticker": "\f12e",
|
||||
"comments": "\f12f",
|
||||
"copy-media": "\f130",
|
||||
"copy": "\f131",
|
||||
"darkmode": "\f132",
|
||||
"data": "\f133",
|
||||
"delete-filled": "\f134",
|
||||
"delete-left": "\f135",
|
||||
"delete-user": "\f136",
|
||||
"delete": "\f137",
|
||||
"document": "\f138",
|
||||
"double-badge": "\f139",
|
||||
"down": "\f13a",
|
||||
"download": "\f13b",
|
||||
"eats": "\f13c",
|
||||
"edit": "\f13d",
|
||||
"email": "\f13e",
|
||||
"enter": "\f13f",
|
||||
"expand": "\f140",
|
||||
"eye-closed-outline": "\f141",
|
||||
"eye-closed": "\f142",
|
||||
"eye-outline": "\f143",
|
||||
"eye": "\f144",
|
||||
"favorite-filled": "\f145",
|
||||
"favorite": "\f146",
|
||||
"file-badge": "\f147",
|
||||
"flag": "\f148",
|
||||
"folder-badge": "\f149",
|
||||
"folder": "\f14a",
|
||||
"fontsize": "\f14b",
|
||||
"forums": "\f14c",
|
||||
"forward": "\f14d",
|
||||
"fullscreen": "\f14e",
|
||||
"gifs": "\f14f",
|
||||
"gift": "\f150",
|
||||
"group-filled": "\f151",
|
||||
"group": "\f152",
|
||||
"grouped-disable": "\f153",
|
||||
"grouped": "\f154",
|
||||
"hand-stop": "\f155",
|
||||
"hashtag": "\f156",
|
||||
"heart-outline": "\f157",
|
||||
"heart": "\f158",
|
||||
"help": "\f159",
|
||||
"info-filled": "\f15a",
|
||||
"info": "\f15b",
|
||||
"install": "\f15c",
|
||||
"italic": "\f15d",
|
||||
"key": "\f15e",
|
||||
"keyboard": "\f15f",
|
||||
"lamp": "\f160",
|
||||
"language": "\f161",
|
||||
"large-pause": "\f162",
|
||||
"large-play": "\f163",
|
||||
"link-badge": "\f164",
|
||||
"link-broken": "\f165",
|
||||
"link": "\f166",
|
||||
"location": "\f167",
|
||||
"lock-badge": "\f168",
|
||||
"lock": "\f169",
|
||||
"logout": "\f16a",
|
||||
"loop": "\f16b",
|
||||
"mention": "\f16c",
|
||||
"message-failed": "\f16d",
|
||||
"message-pending": "\f16e",
|
||||
"message-read": "\f16f",
|
||||
"message-succeeded": "\f170",
|
||||
"message": "\f171",
|
||||
"microphone-alt": "\f172",
|
||||
"microphone": "\f173",
|
||||
"monospace": "\f174",
|
||||
"more-circle": "\f175",
|
||||
"more": "\f176",
|
||||
"mute": "\f177",
|
||||
"muted": "\f178",
|
||||
"new-chat-filled": "\f179",
|
||||
"next": "\f17a",
|
||||
"noise-suppression": "\f17b",
|
||||
"non-contacts": "\f17c",
|
||||
"open-in-new-tab": "\f17d",
|
||||
"password-off": "\f17e",
|
||||
"pause": "\f17f",
|
||||
"permissions": "\f180",
|
||||
"phone-discard-outline": "\f181",
|
||||
"phone-discard": "\f182",
|
||||
"phone": "\f183",
|
||||
"photo": "\f184",
|
||||
"pin-badge": "\f185",
|
||||
"pin-list": "\f186",
|
||||
"pin": "\f187",
|
||||
"pinned-chat": "\f188",
|
||||
"pinned-message": "\f189",
|
||||
"pip": "\f18a",
|
||||
"play-story": "\f18b",
|
||||
"play": "\f18c",
|
||||
"poll": "\f18d",
|
||||
"premium": "\f18e",
|
||||
"previous": "\f18f",
|
||||
"privacy-policy": "\f190",
|
||||
"readchats": "\f191",
|
||||
"recent": "\f192",
|
||||
"reload": "\f193",
|
||||
"remove": "\f194",
|
||||
"reopen-topic": "\f195",
|
||||
"replace": "\f196",
|
||||
"replies": "\f197",
|
||||
"reply-filled": "\f198",
|
||||
"reply": "\f199",
|
||||
"revote": "\f19a",
|
||||
"save-story": "\f19b",
|
||||
"saved-messages": "\f19c",
|
||||
"schedule": "\f19d",
|
||||
"search": "\f19e",
|
||||
"select": "\f19f",
|
||||
"send-outline": "\f1a0",
|
||||
"send": "\f1a1",
|
||||
"settings-filled": "\f1a2",
|
||||
"settings": "\f1a3",
|
||||
"share-filled": "\f1a4",
|
||||
"share-screen-outlined": "\f1a5",
|
||||
"share-screen-stop": "\f1a6",
|
||||
"share-screen": "\f1a7",
|
||||
"sidebar": "\f1a8",
|
||||
"skip-next": "\f1a9",
|
||||
"skip-previous": "\f1aa",
|
||||
"smallscreen": "\f1ab",
|
||||
"smile": "\f1ac",
|
||||
"sort": "\f1ad",
|
||||
"speaker-muted-story": "\f1ae",
|
||||
"speaker-outline": "\f1af",
|
||||
"speaker-story": "\f1b0",
|
||||
"speaker": "\f1b1",
|
||||
"spoiler-disable": "\f1b2",
|
||||
"spoiler": "\f1b3",
|
||||
"sport": "\f1b4",
|
||||
"stats": "\f1b5",
|
||||
"stealth-future": "\f1b6",
|
||||
"stealth-past": "\f1b7",
|
||||
"stickers": "\f1b8",
|
||||
"stop-raising-hand": "\f1b9",
|
||||
"stop": "\f1ba",
|
||||
"story-caption": "\f1bb",
|
||||
"story-expired": "\f1bc",
|
||||
"story-priority": "\f1bd",
|
||||
"story-reply": "\f1be",
|
||||
"strikethrough": "\f1bf",
|
||||
"timer": "\f1c0",
|
||||
"transcribe": "\f1c1",
|
||||
"truck": "\f1c2",
|
||||
"unarchive": "\f1c3",
|
||||
"underlined": "\f1c4",
|
||||
"unlock-badge": "\f1c5",
|
||||
"unlock": "\f1c6",
|
||||
"unmute": "\f1c7",
|
||||
"unpin": "\f1c8",
|
||||
"unread": "\f1c9",
|
||||
"up": "\f1ca",
|
||||
"user-filled": "\f1cb",
|
||||
"user-online": "\f1cc",
|
||||
"user": "\f1cd",
|
||||
"video-outlined": "\f1ce",
|
||||
"video-stop": "\f1cf",
|
||||
"video": "\f1d0",
|
||||
"voice-chat": "\f1d1",
|
||||
"volume-1": "\f1d2",
|
||||
"volume-2": "\f1d3",
|
||||
"volume-3": "\f1d4",
|
||||
"web": "\f1d5",
|
||||
"webapp": "\f1d6",
|
||||
"word-wrap": "\f1d7",
|
||||
"zoom-in": "\f1d8",
|
||||
"zoom-out": "\f1d9",
|
||||
);
|
||||
|
||||
.icon-active-sessions::before {
|
||||
@ -303,6 +305,9 @@ $icons-map: (
|
||||
.icon-arrow-right::before {
|
||||
content: map.get($icons-map, "arrow-right");
|
||||
}
|
||||
.icon-ask-support::before {
|
||||
content: map.get($icons-map, "ask-support");
|
||||
}
|
||||
.icon-attach::before {
|
||||
content: map.get($icons-map, "attach");
|
||||
}
|
||||
@ -678,6 +683,9 @@ $icons-map: (
|
||||
.icon-previous::before {
|
||||
content: map.get($icons-map, "previous");
|
||||
}
|
||||
.icon-privacy-policy::before {
|
||||
content: map.get($icons-map, "privacy-policy");
|
||||
}
|
||||
.icon-readchats::before {
|
||||
content: map.get($icons-map, "readchats");
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -16,6 +16,7 @@ export type FontIconName =
|
||||
| 'arrow-down'
|
||||
| 'arrow-left'
|
||||
| 'arrow-right'
|
||||
| 'ask-support'
|
||||
| 'attach'
|
||||
| 'avatar-archived-chats'
|
||||
| 'avatar-deleted-account'
|
||||
@ -141,6 +142,7 @@ export type FontIconName =
|
||||
| 'poll'
|
||||
| 'premium'
|
||||
| 'previous'
|
||||
| 'privacy-policy'
|
||||
| 'readchats'
|
||||
| 'recent'
|
||||
| 'reload'
|
||||
|
||||
@ -3,9 +3,10 @@ import type { TeactNode } from '../lib/teact/teact';
|
||||
import type {
|
||||
ApiBotInlineMediaResult, ApiBotInlineResult, ApiBotInlineSwitchPm,
|
||||
ApiBotInlineSwitchWebview,
|
||||
ApiChat,
|
||||
ApiChatInviteImporter,
|
||||
ApiExportedInvite,
|
||||
ApiLanguage, ApiMessage, ApiReaction, ApiStickerSet,
|
||||
ApiLanguage, ApiMessage, ApiReaction, ApiStickerSet, ApiUser,
|
||||
} from '../api/types';
|
||||
|
||||
export type TextPart = TeactNode;
|
||||
@ -112,23 +113,20 @@ export interface ISettings extends NotifySettings, Record<string, any> {
|
||||
|
||||
export interface ApiPrivacySettings {
|
||||
visibility: PrivacyVisibility;
|
||||
isUnspecified?: boolean;
|
||||
allowUserIds: string[];
|
||||
allowChatIds: string[];
|
||||
blockUserIds: string[];
|
||||
blockChatIds: string[];
|
||||
}
|
||||
|
||||
export interface InputPrivacyContact {
|
||||
id: string;
|
||||
accessHash?: string;
|
||||
}
|
||||
|
||||
export interface InputPrivacyRules {
|
||||
export interface ApiInputPrivacyRules {
|
||||
visibility: PrivacyVisibility;
|
||||
allowedUsers?: InputPrivacyContact[];
|
||||
allowedChats?: InputPrivacyContact[];
|
||||
blockedUsers?: InputPrivacyContact[];
|
||||
blockedChats?: InputPrivacyContact[];
|
||||
isUnspecified?: boolean;
|
||||
allowedUsers?: ApiUser[];
|
||||
allowedChats?: ApiChat[];
|
||||
blockedUsers?: ApiUser[];
|
||||
blockedChats?: ApiChat[];
|
||||
}
|
||||
|
||||
export type IAnchorPosition = {
|
||||
@ -173,8 +171,10 @@ export enum SettingsScreens {
|
||||
GeneralChatBackgroundColor,
|
||||
Privacy,
|
||||
PrivacyPhoneNumber,
|
||||
PrivacyAddByPhone,
|
||||
PrivacyLastSeen,
|
||||
PrivacyProfilePhoto,
|
||||
PrivacyBio,
|
||||
PrivacyPhoneCall,
|
||||
PrivacyPhoneP2P,
|
||||
PrivacyForwarding,
|
||||
@ -186,6 +186,8 @@ export enum SettingsScreens {
|
||||
PrivacyLastSeenDeniedContacts,
|
||||
PrivacyProfilePhotoAllowedContacts,
|
||||
PrivacyProfilePhotoDeniedContacts,
|
||||
PrivacyBioAllowedContacts,
|
||||
PrivacyBioDeniedContacts,
|
||||
PrivacyPhoneCallAllowedContacts,
|
||||
PrivacyPhoneCallDeniedContacts,
|
||||
PrivacyPhoneP2PAllowedContacts,
|
||||
@ -354,10 +356,9 @@ export type ProfileTabType = (
|
||||
'members' | 'commonChats' | 'media' | 'documents' | 'links' | 'audio' | 'voice' | 'stories' | 'storiesArchive'
|
||||
);
|
||||
export type SharedMediaType = 'media' | 'documents' | 'links' | 'audio' | 'voice';
|
||||
export type ApiPrivacyKey = 'phoneNumber' | 'lastSeen' | 'profilePhoto' | 'voiceMessages' |
|
||||
'forwards' | 'chatInvite' | 'phoneCall' | 'phoneP2P';
|
||||
export type PrivacyVisibility = 'everybody' | 'contacts' | 'closeFriends' | 'selectedContacts' | 'nonContacts' |
|
||||
'nobody';
|
||||
export type ApiPrivacyKey = 'phoneNumber' | 'addByPhone' | 'lastSeen' | 'profilePhoto' | 'voiceMessages' |
|
||||
'forwards' | 'chatInvite' | 'phoneCall' | 'phoneP2P' | 'bio';
|
||||
export type PrivacyVisibility = 'everybody' | 'contacts' | 'closeFriends' | 'nonContacts' | 'nobody';
|
||||
|
||||
export enum ProfileState {
|
||||
Profile,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user