PNP Settings
This commit is contained in:
parent
5bcf71ef2c
commit
5d110964b9
27 changed files with 562 additions and 149 deletions
|
@ -5429,23 +5429,75 @@
|
|||
},
|
||||
"Preferences__who-can--title": {
|
||||
"message": "Who can...",
|
||||
"description": "Title for the 'who can do X' setting"
|
||||
"description": "(deleted 2022/02/14) Title for the 'who can do X' setting"
|
||||
},
|
||||
"Preferences__privacy--description": {
|
||||
"message": "To change these settings, open the Signal app on your mobile device and navigate to Settings > Privacy",
|
||||
"description": "Description for the 'who can do X' setting"
|
||||
"description": "(deleted 2022/02/14) Description for the 'who can do X' setting"
|
||||
},
|
||||
"Preferences__who-can--everybody": {
|
||||
"message": "Everybody",
|
||||
"description": "Option for who can see my X select"
|
||||
"description": "(deleted 2022/02/14) Option for who can see my X select"
|
||||
},
|
||||
"Preferences__who-can--contacts": {
|
||||
"message": "My Contacts",
|
||||
"description": "Option for who can see my X select"
|
||||
"description": "(deleted 2022/02/14) Option for who can see my X select"
|
||||
},
|
||||
"Preferences__who-can--nobody": {
|
||||
"message": "Nobody",
|
||||
"description": "Option for who can see my X select"
|
||||
"description": "(deleted 2022/02/14) Option for who can see my X select"
|
||||
},
|
||||
"icu:Preferences__pnp__row--title": {
|
||||
"messageformat": "Phone Number",
|
||||
"description": "Title of Phone Number row in Privacy section of Preferences window"
|
||||
},
|
||||
"icu:Preferences__pnp__row--body": {
|
||||
"messageformat": "Choose who can see your phone number and who can contact you on Signal with it.",
|
||||
"description": "Body of Phone Number row in Privacy section of Preferences window"
|
||||
},
|
||||
"icu:Preferences__pnp__sharing--title": {
|
||||
"messageformat": "Who can see my number",
|
||||
"description": "Title for the phone number sharing setting row"
|
||||
},
|
||||
"icu:Preferences__pnp__sharing--description--everyone": {
|
||||
"messageformat": "Your phone number will be visible to people and groups you message. People who have your number in their phone contacts will also see it on Signal.",
|
||||
"description": "Description for the phone number sharing setting row when the value is Everyone"
|
||||
},
|
||||
"icu:Preferences__pnp__sharing--description--nobody": {
|
||||
"messageformat": "Nobody will see your phone number on Signal.",
|
||||
"description": "Description for the phone number sharing setting row when the value is Nobody"
|
||||
},
|
||||
"icu:Preferences__pnp--page-title": {
|
||||
"messageformat": "Phone Number",
|
||||
"description": "Title of the page in Phone Number Privacy settings"
|
||||
},
|
||||
"icu:Preferences__pnp__sharing__everyone": {
|
||||
"messageformat": "Everyone",
|
||||
"description": "Option for sharing phone number with everyone"
|
||||
},
|
||||
"icu:Preferences__pnp__sharing__nobody": {
|
||||
"messageformat": "Nobody",
|
||||
"description": "Option for sharing phone number with nobody"
|
||||
},
|
||||
"icu:Preferences__pnp__discoverability--title": {
|
||||
"messageformat": "Who can find me by number",
|
||||
"description": "Title for the phone number discoverability setting row"
|
||||
},
|
||||
"icu:Preferences__pnp__discoverability--description--everyone": {
|
||||
"messageformat": "Anyone who has your phone number in their contacts will see you as a contact on Signal. Others will be able to reach you with your phone number when they start a new chat or group.",
|
||||
"description": "Description for the phone number discoverability setting row wth the value is everyone"
|
||||
},
|
||||
"icu:Preferences__pnp__discoverability--description--nobody": {
|
||||
"messageformat": "Nobody on Signal will be able to reach you with your phone number.",
|
||||
"description": "Description for the phone number discoverability setting row wth the value is nobody"
|
||||
},
|
||||
"icu:Preferences__pnp__discoverability__everyone": {
|
||||
"messageformat": "Everyone",
|
||||
"description": "Option for letting everyone discover you by phone number"
|
||||
},
|
||||
"icu:Preferences__pnp__discoverability__nobody": {
|
||||
"messageformat": "Nobody",
|
||||
"description": "Option for letting nobody discover you by phone number"
|
||||
},
|
||||
"Preferences--messaging": {
|
||||
"message": "Messaging",
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="ts/set_os_class.js"></script>
|
||||
<script type="application/javascript" src="ts/windows/init.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1268,7 +1268,7 @@ async function showSettingsWindow() {
|
|||
frame: true,
|
||||
resizable: false,
|
||||
title: getResolvedMessagesLocale().i18n('signalDesktopPreferences'),
|
||||
titleBarStyle: nonMainTitleBarStyle,
|
||||
titleBarStyle: mainTitleBarStyle,
|
||||
titleBarOverlay,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: await getBackgroundColor(),
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
type="application/javascript"
|
||||
src="ts/windows/applyTheme.js"
|
||||
></script>
|
||||
<script type="text/javascript" src="ts/set_os_class.js"></script>
|
||||
<script type="application/javascript" src="ts/windows/init.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
"danger:local": "./danger/danger.sh local --base main",
|
||||
"danger:ci": "./danger/danger.sh ci --base origin/main",
|
||||
"format": "pprettier --write '**/*.{ts,tsx,d.ts,js,json,html,scss,md,yml,yaml}' '!node_modules/**'",
|
||||
"svgo": "svgo images/**/*.svg",
|
||||
"svgo": "svgo --multipass images/**/*.svg",
|
||||
"transpile": "run-p check:types build:esbuild",
|
||||
"check:types": "tsc --noEmit",
|
||||
"clean-transpile-once": "rimraf app/**/*.js app/*.js sticker-creator/**/*.js sticker-creator/*.js ts/**/*.js ts/*.js tsconfig.tsbuildinfo",
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
type="application/javascript"
|
||||
src="ts/windows/applyTheme.js"
|
||||
></script>
|
||||
<script type="text/javascript" src="ts/set_os_class.js"></script>
|
||||
<script type="application/javascript" src="ts/windows/init.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="text/javascript" src="../../js/components.js"></script>
|
||||
<script type="text/javascript" src="../../ts/set_os_class.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
height: 20px;
|
||||
width: 20px;
|
||||
|
||||
input[type='checkbox'] {
|
||||
input {
|
||||
cursor: pointer;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
|
@ -39,25 +39,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:checked {
|
||||
&::before {
|
||||
background: $color-ultramarine;
|
||||
border: 1.5px solid $color-ultramarine;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border: solid $color-white;
|
||||
border-width: 0 2px 2px 0;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 11px;
|
||||
left: 7px;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
transform: rotate(45deg);
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
&:disabled {
|
||||
cursor: inherit;
|
||||
}
|
||||
|
@ -87,6 +68,98 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:checked {
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
&:checked {
|
||||
&::before {
|
||||
background: $color-ultramarine;
|
||||
border: 1.5px solid $color-ultramarine;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border: solid $color-white;
|
||||
border-width: 0 2px 2px 0;
|
||||
height: 11px;
|
||||
left: 7px;
|
||||
top: 3px;
|
||||
transform: rotate(45deg);
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type='radio'] {
|
||||
&:checked {
|
||||
&::before {
|
||||
border: 2px solid $color-ultramarine;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: $color-ultramarine;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--small {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
|
||||
input {
|
||||
&::before {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
&:checked {
|
||||
&::before {
|
||||
background: $color-ultramarine;
|
||||
border: 1.5px solid $color-ultramarine;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border: solid $color-white;
|
||||
border-width: 0 2px 2px 0;
|
||||
height: 10px;
|
||||
left: 7px;
|
||||
top: 3px;
|
||||
transform: rotate(45deg);
|
||||
width: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type='radio'] {
|
||||
&:checked {
|
||||
&::before {
|
||||
border: 2px solid $color-ultramarine;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: $color-ultramarine;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
.Preferences {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
@include light-theme {
|
||||
background: $color-white;
|
||||
}
|
||||
|
@ -23,7 +24,7 @@
|
|||
}
|
||||
|
||||
&__page-selector {
|
||||
padding-top: 76px;
|
||||
padding-top: calc(24px + var(--title-bar-drag-area-height));
|
||||
min-width: 240px;
|
||||
@include light-theme {
|
||||
background: $color-gray-02;
|
||||
|
@ -133,10 +134,19 @@
|
|||
@include font-body-1-bold;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 76px;
|
||||
padding: 42px 0 14px 0;
|
||||
height: 48px;
|
||||
margin-top: var(--title-bar-drag-area-height);
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
|
||||
border-bottom: 1px solid $color-gray-15;
|
||||
@include light-theme {
|
||||
border-color: $color-gray-15;
|
||||
}
|
||||
@include dark-theme {
|
||||
border-color: $color-gray-65;
|
||||
}
|
||||
|
||||
&--header {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
|
@ -144,7 +154,7 @@
|
|||
}
|
||||
|
||||
&__settings-row {
|
||||
padding-bottom: 12px;
|
||||
padding-bottom: 20px;
|
||||
|
||||
h3 {
|
||||
@include font-body-1-bold;
|
||||
|
@ -164,6 +174,30 @@
|
|||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
&__link {
|
||||
@include button-reset;
|
||||
padding: 0px 0 28px 0;
|
||||
width: 100%;
|
||||
|
||||
h3 {
|
||||
@include font-body-1;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&__link:not(:last-child) {
|
||||
border-bottom: 1px solid $color-gray-15;
|
||||
@include light-theme {
|
||||
border-color: $color-gray-15;
|
||||
}
|
||||
@include dark-theme {
|
||||
border-color: $color-gray-65;
|
||||
}
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
&__control {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
@ -255,4 +289,15 @@
|
|||
&__stories-off {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
&__settings-radio__label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
&:last-child {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
ts/OS.ts
10
ts/OS.ts
|
@ -36,3 +36,13 @@ export const getName = (): string => {
|
|||
}
|
||||
return 'Linux';
|
||||
};
|
||||
|
||||
export const getClassName = (): string => {
|
||||
if (isMacOS()) {
|
||||
return 'os-macos';
|
||||
}
|
||||
if (isWindows()) {
|
||||
return 'os-windows';
|
||||
}
|
||||
return 'os-linux';
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@ import React from 'react';
|
|||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import type { Props } from './CircleCheckbox';
|
||||
import { CircleCheckbox } from './CircleCheckbox';
|
||||
import { CircleCheckbox, Variant } from './CircleCheckbox';
|
||||
|
||||
const createProps = (): Props => ({
|
||||
checked: false,
|
||||
|
@ -28,3 +28,53 @@ export function Checked(): JSX.Element {
|
|||
export function Disabled(): JSX.Element {
|
||||
return <CircleCheckbox {...createProps()} disabled />;
|
||||
}
|
||||
|
||||
export function SmallNormal(): JSX.Element {
|
||||
return <CircleCheckbox variant={Variant.Small} {...createProps()} />;
|
||||
}
|
||||
|
||||
export function SmallChecked(): JSX.Element {
|
||||
return <CircleCheckbox variant={Variant.Small} {...createProps()} checked />;
|
||||
}
|
||||
|
||||
export function SmallDisabled(): JSX.Element {
|
||||
return <CircleCheckbox variant={Variant.Small} {...createProps()} disabled />;
|
||||
}
|
||||
|
||||
export function RadioNormal(): JSX.Element {
|
||||
return <CircleCheckbox isRadio {...createProps()} />;
|
||||
}
|
||||
|
||||
export function RadioChecked(): JSX.Element {
|
||||
return <CircleCheckbox isRadio {...createProps()} checked />;
|
||||
}
|
||||
|
||||
export function RadioDisabled(): JSX.Element {
|
||||
return <CircleCheckbox isRadio {...createProps()} disabled />;
|
||||
}
|
||||
|
||||
export function SmallRadioNormal(): JSX.Element {
|
||||
return <CircleCheckbox variant={Variant.Small} isRadio {...createProps()} />;
|
||||
}
|
||||
|
||||
export function SmallRadioChecked(): JSX.Element {
|
||||
return (
|
||||
<CircleCheckbox
|
||||
variant={Variant.Small}
|
||||
isRadio
|
||||
{...createProps()}
|
||||
checked
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function SmallRadioDisabled(): JSX.Element {
|
||||
return (
|
||||
<CircleCheckbox
|
||||
variant={Variant.Small}
|
||||
isRadio
|
||||
{...createProps()}
|
||||
disabled
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,24 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { getClassNamesFor } from '../util/getClassNamesFor';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
|
||||
export enum Variant {
|
||||
Normal = 'Normal',
|
||||
Small = 'Small',
|
||||
}
|
||||
|
||||
export type Props = {
|
||||
id?: string;
|
||||
variant?: Variant;
|
||||
checked?: boolean;
|
||||
disabled?: boolean;
|
||||
isRadio?: boolean;
|
||||
name?: string;
|
||||
moduleClassName?: string;
|
||||
onChange?: (value: boolean) => unknown;
|
||||
onClick?: () => unknown;
|
||||
};
|
||||
|
@ -24,17 +33,28 @@ export type Props = {
|
|||
*/
|
||||
export function CircleCheckbox({
|
||||
id,
|
||||
variant = Variant.Normal,
|
||||
checked,
|
||||
disabled,
|
||||
isRadio,
|
||||
moduleClassName,
|
||||
name,
|
||||
onChange,
|
||||
onClick,
|
||||
}: Props): JSX.Element {
|
||||
const getClassName = getClassNamesFor('CircleCheckbox');
|
||||
const getClassName = getClassNamesFor('CircleCheckbox', moduleClassName);
|
||||
|
||||
let variantModifier: string;
|
||||
if (variant === Variant.Normal) {
|
||||
variantModifier = getClassName('__checkbox--normal');
|
||||
} else if (variant === Variant.Small) {
|
||||
variantModifier = getClassName('__checkbox--small');
|
||||
} else {
|
||||
throw missingCaseError(variant);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={getClassName('__checkbox')}>
|
||||
<div className={classNames(getClassName('__checkbox'), variantModifier)}>
|
||||
<input
|
||||
checked={Boolean(checked)}
|
||||
disabled={disabled}
|
||||
|
|
|
@ -96,7 +96,7 @@ const getDefaultArgs = (): PropsDataType => ({
|
|||
isAutoLaunchSupported: true,
|
||||
isHideMenuBarSupported: true,
|
||||
isNotificationAttentionSupported: true,
|
||||
isPhoneNumberSharingSupported: false,
|
||||
isPhoneNumberSharingSupported: true,
|
||||
isSyncSupported: true,
|
||||
isSystemTraySupported: true,
|
||||
isMinimizeToAndStartInSystemTraySupported: true,
|
||||
|
@ -163,6 +163,8 @@ export default {
|
|||
onSpellCheckChange: { action: true },
|
||||
onThemeChange: { action: true },
|
||||
onUniversalExpireTimerChange: { action: true },
|
||||
onWhoCanSeeMeChange: { action: true },
|
||||
onWhoCanFindMeChange: { action: true },
|
||||
onZoomFactorChange: { action: true },
|
||||
removeCustomColor: { action: true },
|
||||
removeCustomColorOnConversations: { action: true },
|
||||
|
@ -195,3 +197,23 @@ CustomUniversalExpireTimer.args = {
|
|||
CustomUniversalExpireTimer.story = {
|
||||
name: 'Custom universalExpireTimer',
|
||||
};
|
||||
|
||||
export const PNPSharingDisabled = Template.bind({});
|
||||
PNPSharingDisabled.args = {
|
||||
whoCanSeeMe: PhoneNumberSharingMode.Nobody,
|
||||
whoCanFindMe: PhoneNumberDiscoverability.Discoverable,
|
||||
isPhoneNumberSharingSupported: true,
|
||||
};
|
||||
PNPSharingDisabled.story = {
|
||||
name: 'PNP Sharing Disabled',
|
||||
};
|
||||
|
||||
export const PNPDiscoverabilityDisabled = Template.bind({});
|
||||
PNPDiscoverabilityDisabled.args = {
|
||||
whoCanSeeMe: PhoneNumberSharingMode.Nobody,
|
||||
whoCanFindMe: PhoneNumberDiscoverability.NotDiscoverable,
|
||||
isPhoneNumberSharingSupported: true,
|
||||
};
|
||||
PNPDiscoverabilityDisabled.story = {
|
||||
name: 'PNP Discoverability Disabled',
|
||||
};
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import React, { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import type { AudioDevice } from '@signalapp/ringrtc';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import type { MediaDeviceSettings } from '../types/Calling';
|
||||
import type {
|
||||
|
@ -17,6 +18,10 @@ import type { ThemeSettingType } from '../types/StorageUIKeys';
|
|||
import { Button, ButtonVariant } from './Button';
|
||||
import { ChatColorPicker } from './ChatColorPicker';
|
||||
import { Checkbox } from './Checkbox';
|
||||
import {
|
||||
CircleCheckbox,
|
||||
Variant as CircleCheckboxVariant,
|
||||
} from './CircleCheckbox';
|
||||
import { ConfirmationDialog } from './ConfirmationDialog';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import type {
|
||||
|
@ -159,6 +164,8 @@ type PropsFunctionType = {
|
|||
onSpellCheckChange: CheckboxChangeHandlerType;
|
||||
onThemeChange: SelectChangeHandlerType<ThemeType>;
|
||||
onUniversalExpireTimerChange: SelectChangeHandlerType<number>;
|
||||
onWhoCanSeeMeChange: SelectChangeHandlerType<PhoneNumberSharingMode>;
|
||||
onWhoCanFindMeChange: SelectChangeHandlerType<PhoneNumberDiscoverability>;
|
||||
onZoomFactorChange: SelectChangeHandlerType<ZoomFactorType>;
|
||||
|
||||
// Localization
|
||||
|
@ -178,6 +185,7 @@ enum Page {
|
|||
|
||||
// Sub pages
|
||||
ChatColor = 'ChatColor',
|
||||
PNP = 'PNP',
|
||||
}
|
||||
|
||||
const DEFAULT_ZOOM_FACTORS = [
|
||||
|
@ -278,6 +286,8 @@ export function Preferences({
|
|||
onSpellCheckChange,
|
||||
onThemeChange,
|
||||
onUniversalExpireTimerChange,
|
||||
onWhoCanSeeMeChange,
|
||||
onWhoCanFindMeChange,
|
||||
onZoomFactorChange,
|
||||
removeCustomColor,
|
||||
removeCustomColorOnConversations,
|
||||
|
@ -845,6 +855,20 @@ export function Preferences({
|
|||
{i18n('Preferences__button--privacy')}
|
||||
</div>
|
||||
</div>
|
||||
{isPhoneNumberSharingSupported ? (
|
||||
<button
|
||||
type="button"
|
||||
className="Preferences__link"
|
||||
onClick={() => setPage(Page.PNP)}
|
||||
>
|
||||
<h3 className="Preferences__padding">
|
||||
{i18n('icu:Preferences__pnp__row--title')}
|
||||
</h3>
|
||||
<div className="Preferences__padding Preferences__description">
|
||||
{i18n('icu:Preferences__pnp__row--body')}
|
||||
</div>
|
||||
</button>
|
||||
) : null}
|
||||
<SettingsRow>
|
||||
<Control
|
||||
left={i18n('Preferences--blocked')}
|
||||
|
@ -859,61 +883,6 @@ export function Preferences({
|
|||
}
|
||||
/>
|
||||
</SettingsRow>
|
||||
{isPhoneNumberSharingSupported ? (
|
||||
<SettingsRow title={i18n('Preferences__who-can--title')}>
|
||||
<Control
|
||||
left={i18n('Preferences--see-me')}
|
||||
right={
|
||||
<Select
|
||||
ariaLabel={i18n('Preferences--see-me')}
|
||||
disabled
|
||||
onChange={noop}
|
||||
options={[
|
||||
{
|
||||
text: i18n('Preferences__who-can--everybody'),
|
||||
value: PhoneNumberSharingMode.Everybody,
|
||||
},
|
||||
{
|
||||
text: i18n('Preferences__who-can--contacts'),
|
||||
value: PhoneNumberSharingMode.ContactsOnly,
|
||||
},
|
||||
{
|
||||
text: i18n('Preferences__who-can--nobody'),
|
||||
value: PhoneNumberSharingMode.Nobody,
|
||||
},
|
||||
]}
|
||||
value={whoCanSeeMe}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Control
|
||||
left={i18n('Preferences--find-me')}
|
||||
right={
|
||||
<Select
|
||||
ariaLabel={i18n('Preferences--find-me')}
|
||||
disabled
|
||||
onChange={noop}
|
||||
options={[
|
||||
{
|
||||
text: i18n('Preferences__who-can--everybody'),
|
||||
value: PhoneNumberDiscoverability.Discoverable,
|
||||
},
|
||||
{
|
||||
text: i18n('Preferences__who-can--nobody'),
|
||||
value: PhoneNumberDiscoverability.NotDiscoverable,
|
||||
},
|
||||
]}
|
||||
value={whoCanFindMe}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<div className="Preferences__padding">
|
||||
<div className="Preferences__description">
|
||||
{i18n('Preferences__privacy--description')}
|
||||
</div>
|
||||
</div>
|
||||
</SettingsRow>
|
||||
) : null}
|
||||
<SettingsRow title={i18n('Preferences--messaging')}>
|
||||
<Checkbox
|
||||
checked={hasReadReceipts}
|
||||
|
@ -1120,6 +1089,82 @@ export function Preferences({
|
|||
/>
|
||||
</>
|
||||
);
|
||||
} else if (page === Page.PNP) {
|
||||
settings = (
|
||||
<>
|
||||
<div className="Preferences__title">
|
||||
<button
|
||||
aria-label={i18n('goBack')}
|
||||
className="Preferences__back-icon"
|
||||
onClick={() => setPage(Page.Privacy)}
|
||||
type="button"
|
||||
/>
|
||||
<div className="Preferences__title--header">
|
||||
{i18n('icu:Preferences__pnp--page-title')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SettingsRow title={i18n('icu:Preferences__pnp__sharing--title')}>
|
||||
<SettingsRadio
|
||||
onChange={onWhoCanSeeMeChange}
|
||||
options={[
|
||||
{
|
||||
text: i18n('icu:Preferences__pnp__sharing__everyone'),
|
||||
value: PhoneNumberSharingMode.Everybody,
|
||||
},
|
||||
{
|
||||
text: i18n('icu:Preferences__pnp__sharing__nobody'),
|
||||
value: PhoneNumberSharingMode.Nobody,
|
||||
},
|
||||
]}
|
||||
value={whoCanSeeMe}
|
||||
/>
|
||||
<div className="Preferences__padding">
|
||||
<div className="Preferences__description">
|
||||
{whoCanSeeMe === PhoneNumberSharingMode.Everybody
|
||||
? i18n('icu:Preferences__pnp__sharing--description--everyone')
|
||||
: i18n('icu:Preferences__pnp__sharing--description--nobody')}
|
||||
</div>
|
||||
</div>
|
||||
</SettingsRow>
|
||||
|
||||
<SettingsRow
|
||||
title={i18n('icu:Preferences__pnp__discoverability--title')}
|
||||
>
|
||||
<SettingsRadio
|
||||
onChange={onWhoCanFindMeChange}
|
||||
options={[
|
||||
{
|
||||
text: i18n('icu:Preferences__pnp__discoverability__everyone'),
|
||||
value: PhoneNumberDiscoverability.Discoverable,
|
||||
},
|
||||
...(whoCanSeeMe === PhoneNumberSharingMode.Nobody
|
||||
? [
|
||||
{
|
||||
text: i18n(
|
||||
'icu:Preferences__pnp__discoverability__nobody'
|
||||
),
|
||||
value: PhoneNumberDiscoverability.NotDiscoverable,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]}
|
||||
value={whoCanFindMe}
|
||||
/>
|
||||
<div className="Preferences__padding">
|
||||
<div className="Preferences__description">
|
||||
{whoCanFindMe === PhoneNumberDiscoverability.Discoverable
|
||||
? i18n(
|
||||
'icu:Preferences__pnp__discoverability--description--everyone'
|
||||
)
|
||||
: i18n(
|
||||
'icu:Preferences__pnp__discoverability--description--nobody'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</SettingsRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1128,6 +1173,7 @@ export function Preferences({
|
|||
theme={theme}
|
||||
executeMenuRole={executeMenuRole}
|
||||
>
|
||||
<div className="module-title-bar-drag-area" />
|
||||
<div className="Preferences">
|
||||
<div className="Preferences__page-selector">
|
||||
<button
|
||||
|
@ -1191,7 +1237,8 @@ export function Preferences({
|
|||
className={classNames({
|
||||
Preferences__button: true,
|
||||
'Preferences__button--privacy': true,
|
||||
'Preferences__button--selected': page === Page.Privacy,
|
||||
'Preferences__button--selected':
|
||||
page === Page.Privacy || page === Page.PNP,
|
||||
})}
|
||||
onClick={() => setPage(Page.Privacy)}
|
||||
>
|
||||
|
@ -1207,12 +1254,14 @@ export function Preferences({
|
|||
function SettingsRow({
|
||||
children,
|
||||
title,
|
||||
className,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
title?: string;
|
||||
className?: string;
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<div className="Preferences__settings-row">
|
||||
<div className={classNames('Preferences__settings-row', className)}>
|
||||
{title && <h3 className="Preferences__padding">{title}</h3>}
|
||||
{children}
|
||||
</div>
|
||||
|
@ -1250,6 +1299,49 @@ function Control({
|
|||
return <div className="Preferences__control">{content}</div>;
|
||||
}
|
||||
|
||||
type SettingsRadioOptionType<Enum> = Readonly<{
|
||||
text: string;
|
||||
value: Enum;
|
||||
}>;
|
||||
|
||||
function SettingsRadio<Enum>({
|
||||
value,
|
||||
options,
|
||||
onChange,
|
||||
}: {
|
||||
value: Enum;
|
||||
options: ReadonlyArray<SettingsRadioOptionType<Enum>>;
|
||||
onChange: (value: Enum) => void;
|
||||
}): JSX.Element {
|
||||
const htmlIds = useMemo(() => {
|
||||
return Array.from({ length: options.length }, () => uuid());
|
||||
}, [options.length]);
|
||||
|
||||
return (
|
||||
<div className="Preferences__padding">
|
||||
{options.map(({ text, value: optionValue }, i) => {
|
||||
const htmlId = htmlIds[i];
|
||||
return (
|
||||
<label
|
||||
className="Preferences__settings-radio__label"
|
||||
key={htmlId}
|
||||
htmlFor={htmlId}
|
||||
>
|
||||
<CircleCheckbox
|
||||
isRadio
|
||||
variant={CircleCheckboxVariant.Small}
|
||||
id={htmlId}
|
||||
checked={value === optionValue}
|
||||
onChange={() => onChange(optionValue)}
|
||||
/>
|
||||
{text}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function localizeDefault(i18n: LocalizerType, deviceLabel: string): string {
|
||||
return deviceLabel.toLowerCase().startsWith('default')
|
||||
? deviceLabel.replace(
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import type { LocalizerType } from '../../../types/Util';
|
||||
import { getMuteOptions } from '../../../util/getMuteOptions';
|
||||
import { parseIntOrThrow } from '../../../util/parseIntOrThrow';
|
||||
import { Checkbox } from '../../Checkbox';
|
||||
import { CircleCheckbox, Variant } from '../../CircleCheckbox';
|
||||
import { Modal } from '../../Modal';
|
||||
import { Button, ButtonVariant } from '../../Button';
|
||||
|
||||
|
@ -30,11 +31,13 @@ export function ConversationNotificationsModal({
|
|||
}: PropsType): JSX.Element {
|
||||
const muteOptions = useMemo(
|
||||
() =>
|
||||
getMuteOptions(muteExpiresAt, i18n).map(({ disabled, name, value }) => ({
|
||||
disabled,
|
||||
text: name,
|
||||
value,
|
||||
})),
|
||||
getMuteOptions(muteExpiresAt, i18n)
|
||||
.map(({ disabled, name, value }) => ({
|
||||
disabled,
|
||||
text: name,
|
||||
value,
|
||||
}))
|
||||
.filter(x => x.value > 0),
|
||||
[i18n, muteExpiresAt]
|
||||
);
|
||||
|
||||
|
@ -49,6 +52,10 @@ export function ConversationNotificationsModal({
|
|||
onClose();
|
||||
};
|
||||
|
||||
const htmlIds = useMemo(() => {
|
||||
return Array.from({ length: muteOptions.length }, () => uuid());
|
||||
}, [muteOptions.length]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
modalName="ConversationNotificationsModal"
|
||||
|
@ -67,20 +74,25 @@ export function ConversationNotificationsModal({
|
|||
</>
|
||||
}
|
||||
>
|
||||
{muteOptions
|
||||
.filter(x => x.value > 0)
|
||||
.map(option => (
|
||||
<Checkbox
|
||||
{muteOptions.map((option, i) => (
|
||||
<label
|
||||
className="Preferences__settings-radio__label"
|
||||
key={htmlIds[i]}
|
||||
htmlFor={htmlIds[i]}
|
||||
>
|
||||
<CircleCheckbox
|
||||
id={htmlIds[i]}
|
||||
checked={muteExpirationValue === option.value}
|
||||
variant={Variant.Small}
|
||||
disabled={option.disabled}
|
||||
isRadio
|
||||
key={option.value}
|
||||
label={option.text}
|
||||
moduleClassName="ConversationDetails__radio"
|
||||
name="mute"
|
||||
onChange={value => value && setMuteExpirationValue(option.value)}
|
||||
/>
|
||||
))}
|
||||
{option.text}
|
||||
</label>
|
||||
))}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -67,8 +67,6 @@ export class SettingsChannel extends EventEmitter {
|
|||
// Getters only. These are set by the primary device
|
||||
this.installSetting('blockedCount', { setter: false });
|
||||
this.installSetting('linkPreviewSetting', { setter: false });
|
||||
this.installSetting('phoneNumberDiscoverabilitySetting', { setter: false });
|
||||
this.installSetting('phoneNumberSharingSetting', { setter: false });
|
||||
this.installSetting('readReceiptSetting', { setter: false });
|
||||
this.installSetting('typingIndicatorSetting', { setter: false });
|
||||
|
||||
|
@ -109,6 +107,9 @@ export class SettingsChannel extends EventEmitter {
|
|||
this.installSetting('hasStoriesDisabled');
|
||||
this.installSetting('zoomFactor');
|
||||
|
||||
this.installSetting('phoneNumberDiscoverabilitySetting');
|
||||
this.installSetting('phoneNumberSharingSetting');
|
||||
|
||||
installPermissionsHandler({ session, userConfig });
|
||||
|
||||
// These ones are different because its single source of truth is userConfig,
|
||||
|
|
|
@ -296,9 +296,6 @@ export function toAccountRecord(
|
|||
PHONE_NUMBER_SHARING_MODE_ENUM.EVERYBODY;
|
||||
break;
|
||||
case PhoneNumberSharingMode.ContactsOnly:
|
||||
accountRecord.phoneNumberSharingMode =
|
||||
PHONE_NUMBER_SHARING_MODE_ENUM.CONTACTS_ONLY;
|
||||
break;
|
||||
case PhoneNumberSharingMode.Nobody:
|
||||
accountRecord.phoneNumberSharingMode =
|
||||
PHONE_NUMBER_SHARING_MODE_ENUM.NOBODY;
|
||||
|
@ -1222,8 +1219,6 @@ export async function mergeAccountRecord(
|
|||
phoneNumberSharingModeToStore = PhoneNumberSharingMode.Everybody;
|
||||
break;
|
||||
case PHONE_NUMBER_SHARING_MODE_ENUM.CONTACTS_ONLY:
|
||||
phoneNumberSharingModeToStore = PhoneNumberSharingMode.ContactsOnly;
|
||||
break;
|
||||
case PHONE_NUMBER_SHARING_MODE_ENUM.NOBODY:
|
||||
phoneNumberSharingModeToStore = PhoneNumberSharingMode.Nobody;
|
||||
break;
|
||||
|
|
|
@ -7,7 +7,7 @@ import type { MenuItemConstructorOptions } from 'electron';
|
|||
|
||||
import type { MenuActionType } from '../../types/menu';
|
||||
import { App } from '../../components/App';
|
||||
import { getName as getOSName } from '../../OS';
|
||||
import { getName as getOSName, getClassName as getOSClassName } from '../../OS';
|
||||
import { SmartCallManager } from './CallManager';
|
||||
import { SmartGlobalModalContainer } from './GlobalModalContainer';
|
||||
import { SmartLightbox } from './Lightbox';
|
||||
|
@ -39,18 +39,6 @@ function renderInbox(): JSX.Element {
|
|||
const mapStateToProps = (state: StateType) => {
|
||||
const i18n = getIntl(state);
|
||||
|
||||
const { osName } = state.user;
|
||||
|
||||
let osClassName = '';
|
||||
|
||||
if (osName === 'windows') {
|
||||
osClassName = 'os-windows';
|
||||
} else if (osName === 'macos') {
|
||||
osClassName = 'os-macos';
|
||||
} else if (osName === 'linux') {
|
||||
osClassName = 'os-linux';
|
||||
}
|
||||
|
||||
return {
|
||||
...state.app,
|
||||
i18n,
|
||||
|
@ -60,7 +48,7 @@ const mapStateToProps = (state: StateType) => {
|
|||
menuOptions: getMenuOptions(state),
|
||||
hasCustomTitleBar: window.SignalContext.OS.hasCustomTitleBar(),
|
||||
OS: getOSName(),
|
||||
osClassName,
|
||||
osClassName: getOSClassName(),
|
||||
hideMenuBar: getHideMenuBar(state),
|
||||
renderCallManager: () => (
|
||||
<ModalContainer className="module-calling__modal-container">
|
||||
|
|
|
@ -494,6 +494,7 @@ const URL_CALLS = {
|
|||
keys: 'v2/keys',
|
||||
messages: 'v1/messages',
|
||||
multiRecipient: 'v1/messages/multi_recipient',
|
||||
phoneNumberDiscoverability: 'v2/accounts/phone_number_discoverability',
|
||||
profile: 'v1/profile',
|
||||
registerCapabilities: 'v1/devices/capabilities',
|
||||
reportMessage: 'v1/messages/report',
|
||||
|
@ -541,6 +542,9 @@ const WEBSOCKET_CALLS = new Set<keyof typeof URL_CALLS>([
|
|||
|
||||
// Storage
|
||||
'storageToken',
|
||||
|
||||
// Account V2
|
||||
'phoneNumberDiscoverability',
|
||||
]);
|
||||
|
||||
type InitializeOptionsType = {
|
||||
|
@ -979,6 +983,7 @@ export type WebAPIType = {
|
|||
urgent?: boolean;
|
||||
}
|
||||
) => Promise<MultiRecipient200ResponseType>;
|
||||
setPhoneNumberDiscoverability: (newValue: boolean) => Promise<void>;
|
||||
setSignedPreKey: (
|
||||
signedPreKey: SignedPreKeyType,
|
||||
uuidKind: UUIDKind
|
||||
|
@ -1272,6 +1277,7 @@ export function initialize({
|
|||
sendMessages,
|
||||
sendMessagesUnauth,
|
||||
sendWithSenderKey,
|
||||
setPhoneNumberDiscoverability,
|
||||
setSignedPreKey,
|
||||
startRegistration,
|
||||
unregisterRequestHandler,
|
||||
|
@ -2027,6 +2033,16 @@ export function initialize({
|
|||
});
|
||||
}
|
||||
|
||||
async function setPhoneNumberDiscoverability(newValue: boolean) {
|
||||
await _ajax({
|
||||
call: 'phoneNumberDiscoverability',
|
||||
httpType: 'PUT',
|
||||
jsonData: {
|
||||
discoverableByPhoneNumber: newValue,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function setSignedPreKey(
|
||||
signedPreKey: SignedPreKeyType,
|
||||
uuidKind: UUIDKind
|
||||
|
|
|
@ -28,7 +28,7 @@ import { renderClearingDataView } from '../shims/renderClearingDataView';
|
|||
import * as universalExpireTimer from './universalExpireTimer';
|
||||
import { PhoneNumberDiscoverability } from './phoneNumberDiscoverability';
|
||||
import { PhoneNumberSharingMode } from './phoneNumberSharingMode';
|
||||
import { assertDev } from './assert';
|
||||
import { strictAssert, assertDev } from './assert';
|
||||
import * as durations from './durations';
|
||||
import type { DurationInSeconds } from './durations';
|
||||
import { isPhoneNumberSharingEnabled } from './isPhoneNumberSharingEnabled';
|
||||
|
@ -136,8 +136,6 @@ type ValuesWithSetters = Omit<
|
|||
| 'blockedCount'
|
||||
| 'defaultConversationColor'
|
||||
| 'linkPreviewSetting'
|
||||
| 'phoneNumberDiscoverabilitySetting'
|
||||
| 'phoneNumberSharingSetting'
|
||||
| 'readReceiptSetting'
|
||||
| 'typingIndicatorSetting'
|
||||
| 'deviceName'
|
||||
|
@ -177,6 +175,18 @@ export type IPCEventsType = IPCEventsGettersType &
|
|||
export function createIPCEvents(
|
||||
overrideEvents: Partial<IPCEventsType> = {}
|
||||
): IPCEventsType {
|
||||
const setPhoneNumberDiscoverabilitySetting = async (
|
||||
newValue: PhoneNumberDiscoverability
|
||||
): Promise<void> => {
|
||||
strictAssert(window.textsecure.server, 'WebAPI must be available');
|
||||
await window.storage.put('phoneNumberDiscoverability', newValue);
|
||||
await window.textsecure.server.setPhoneNumberDiscoverability(
|
||||
newValue === PhoneNumberDiscoverability.Discoverable
|
||||
);
|
||||
const account = window.ConversationController.getOurConversationOrThrow();
|
||||
account.captureChange('phoneNumberDiscoverability');
|
||||
};
|
||||
|
||||
return {
|
||||
getDeviceName: () => window.textsecure.storage.user.getDeviceName(),
|
||||
|
||||
|
@ -185,6 +195,22 @@ export function createIPCEvents(
|
|||
webFrame.setZoomFactor(zoomFactor);
|
||||
},
|
||||
|
||||
setPhoneNumberDiscoverabilitySetting,
|
||||
setPhoneNumberSharingSetting: async (newValue: PhoneNumberSharingMode) => {
|
||||
const account = window.ConversationController.getOurConversationOrThrow();
|
||||
const promises = new Array<Promise<void>>();
|
||||
promises.push(window.storage.put('phoneNumberSharingMode', newValue));
|
||||
if (newValue === PhoneNumberSharingMode.Everybody) {
|
||||
promises.push(
|
||||
setPhoneNumberDiscoverabilitySetting(
|
||||
PhoneNumberDiscoverability.Discoverable
|
||||
)
|
||||
);
|
||||
}
|
||||
account.captureChange('phoneNumberSharingMode');
|
||||
await Promise.all(promises);
|
||||
},
|
||||
|
||||
getHasStoriesDisabled: () =>
|
||||
window.storage.get('hasStoriesDisabled', false),
|
||||
setHasStoriesDisabled: async (value: boolean) => {
|
||||
|
@ -202,6 +228,8 @@ export function createIPCEvents(
|
|||
},
|
||||
setStoryViewReceiptsEnabled: async (value: boolean) => {
|
||||
await window.storage.put('storyViewReceiptsEnabled', value);
|
||||
const account = window.ConversationController.getOurConversationOrThrow();
|
||||
account.captureChange('storyViewReceiptsEnabled');
|
||||
},
|
||||
|
||||
getPreferredAudioInputDevice: () =>
|
||||
|
|
|
@ -4,5 +4,8 @@
|
|||
import * as RemoteConfig from '../RemoteConfig';
|
||||
|
||||
export function isPhoneNumberSharingEnabled(): boolean {
|
||||
return Boolean(RemoteConfig.isEnabled('desktop.internalUser'));
|
||||
return Boolean(
|
||||
RemoteConfig.isEnabled('desktop.internalUser') ||
|
||||
RemoteConfig.isEnabled('desktop.pnp')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
import type { ConversationAttributesType } from '../model-types.d';
|
||||
|
||||
import { makeEnumParser } from './enum';
|
||||
import { isInSystemContacts } from './isInSystemContacts';
|
||||
import { missingCaseError } from './missingCaseError';
|
||||
import { isDirectConversation, isMe } from './whatTypeOfConversation';
|
||||
|
||||
|
@ -35,7 +34,6 @@ export const shouldSharePhoneNumberWith = (
|
|||
case PhoneNumberSharingMode.Everybody:
|
||||
return true;
|
||||
case PhoneNumberSharingMode.ContactsOnly:
|
||||
return isInSystemContacts(conversation);
|
||||
case PhoneNumberSharingMode.Nobody:
|
||||
return false;
|
||||
default:
|
||||
|
|
|
@ -29,7 +29,13 @@ import { createSetting } from '../util/preload';
|
|||
import { initialize as initializeLogging } from '../logging/set_up_renderer_logging';
|
||||
import { waitForSettingsChange } from './waitForSettingsChange';
|
||||
import { createNativeThemeListener } from '../context/createNativeThemeListener';
|
||||
import { isWindows, isLinux, isMacOS, hasCustomTitleBar } from '../OS';
|
||||
import {
|
||||
isWindows,
|
||||
isLinux,
|
||||
isMacOS,
|
||||
hasCustomTitleBar,
|
||||
getClassName,
|
||||
} from '../OS';
|
||||
|
||||
const activeWindowService = new ActiveWindowService();
|
||||
activeWindowService.initialize(window.document, ipcRenderer);
|
||||
|
@ -79,6 +85,7 @@ export type SignalContextType = {
|
|||
isLinux: typeof isLinux;
|
||||
isMacOS: typeof isMacOS;
|
||||
hasCustomTitleBar: typeof hasCustomTitleBar;
|
||||
getClassName: typeof getClassName;
|
||||
};
|
||||
config: RendererConfigType;
|
||||
getAppInstance: () => string | undefined;
|
||||
|
@ -108,6 +115,7 @@ export const SignalContext: SignalContextType = {
|
|||
isLinux,
|
||||
isMacOS,
|
||||
hasCustomTitleBar,
|
||||
getClassName,
|
||||
},
|
||||
bytes: new Bytes(),
|
||||
config,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
document.body.classList.add(window.SignalContext.OS.getClassName());
|
||||
if (window.SignalContext.OS.hasCustomTitleBar()) {
|
||||
document.body.classList.add('os-has-custom-titlebar');
|
||||
}
|
||||
|
||||
if (window.SignalContext.renderWindow) {
|
||||
window.SignalContext.renderWindow();
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,7 @@ import '../../backbone/reliable_trigger';
|
|||
|
||||
import type { FeatureFlagType } from '../../window.d';
|
||||
import type { StorageAccessType } from '../../types/Storage.d';
|
||||
import type { CdsLookupOptionsType } from '../../textsecure/WebAPI';
|
||||
import { start as startConversationController } from '../../ConversationController';
|
||||
import { MessageController } from '../../util/MessageController';
|
||||
import { Environment, getEnvironment } from '../../environment';
|
||||
|
@ -46,6 +47,8 @@ startConversationController();
|
|||
if (!isProduction(window.SignalContext.getVersion())) {
|
||||
const SignalDebug = {
|
||||
Data: window.Signal.Data,
|
||||
cdsLookup: (options: CdsLookupOptionsType) =>
|
||||
window.textsecure.server?.cdsLookup(options),
|
||||
getConversation: (id: string) => window.ConversationController.get(id),
|
||||
getMessageById: (id: string) => window.MessageController.getById(id),
|
||||
getReduxState: () => window.reduxStore.getState(),
|
||||
|
|
|
@ -24,12 +24,6 @@ installSetting('blockedCount', {
|
|||
installSetting('linkPreviewSetting', {
|
||||
setter: false,
|
||||
});
|
||||
installSetting('phoneNumberDiscoverabilitySetting', {
|
||||
setter: false,
|
||||
});
|
||||
installSetting('phoneNumberSharingSetting', {
|
||||
setter: false,
|
||||
});
|
||||
installSetting('readReceiptSetting', {
|
||||
setter: false,
|
||||
});
|
||||
|
@ -63,6 +57,8 @@ installSetting('sentMediaQualitySetting');
|
|||
installSetting('themeSetting');
|
||||
installSetting('universalExpireTimer');
|
||||
installSetting('zoomFactor');
|
||||
installSetting('phoneNumberDiscoverabilitySetting');
|
||||
installSetting('phoneNumberSharingSetting');
|
||||
|
||||
// Media Settings
|
||||
installCallback('getAvailableIODevices');
|
||||
|
|
|
@ -58,12 +58,9 @@ const settingLinkPreview = createSetting('linkPreviewSetting', {
|
|||
setter: false,
|
||||
});
|
||||
const settingPhoneNumberDiscoverability = createSetting(
|
||||
'phoneNumberDiscoverabilitySetting',
|
||||
{ setter: false }
|
||||
'phoneNumberDiscoverabilitySetting'
|
||||
);
|
||||
const settingPhoneNumberSharing = createSetting('phoneNumberSharingSetting', {
|
||||
setter: false,
|
||||
});
|
||||
const settingPhoneNumberSharing = createSetting('phoneNumberSharingSetting');
|
||||
const settingReadReceipts = createSetting('readReceiptSetting', {
|
||||
setter: false,
|
||||
});
|
||||
|
@ -363,6 +360,9 @@ const renderPreferences = async () => {
|
|||
);
|
||||
},
|
||||
|
||||
onWhoCanFindMeChange: reRender(settingPhoneNumberDiscoverability.setValue),
|
||||
onWhoCanSeeMeChange: reRender(settingPhoneNumberSharing.setValue),
|
||||
|
||||
// Zoom factor change doesn't require immediate rerender since it will:
|
||||
// 1. Update the zoom factor in the main window
|
||||
// 2. Trigger `preferred-size-changed` in the main process
|
||||
|
|
Loading…
Reference in a new issue