Prefer type
to interface
and add an ESLint rule
This commit is contained in:
parent
c85c073669
commit
8a72607fa7
106 changed files with 431 additions and 375 deletions
30
.eslintrc.js
30
.eslintrc.js
|
@ -95,6 +95,36 @@ const rules = {
|
||||||
|
|
||||||
// Upgrade from a warning
|
// Upgrade from a warning
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'error',
|
'@typescript-eslint/explicit-module-boundary-types': 'error',
|
||||||
|
|
||||||
|
'no-restricted-syntax': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
selector: 'TSInterfaceDeclaration',
|
||||||
|
message:
|
||||||
|
'Prefer `type`. Interfaces are mutable and less powerful, so we prefer `type` for simplicity.',
|
||||||
|
},
|
||||||
|
// Defaults
|
||||||
|
{
|
||||||
|
selector: 'ForInStatement',
|
||||||
|
message:
|
||||||
|
'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
selector: 'ForOfStatement',
|
||||||
|
message:
|
||||||
|
'iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
selector: 'LabeledStatement',
|
||||||
|
message:
|
||||||
|
'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
selector: 'WithStatement',
|
||||||
|
message:
|
||||||
|
'`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { hot } from 'react-hot-loader/root';
|
import { hot } from 'react-hot-loader/root';
|
||||||
|
@ -11,6 +11,8 @@ import { store } from './store';
|
||||||
import { I18n } from './util/i18n';
|
import { I18n } from './util/i18n';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `window` here.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Window {
|
interface Window {
|
||||||
localeMessages: { [key: string]: { message: string } };
|
localeMessages: { [key: string]: { message: string } };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
|
@ -56,15 +56,15 @@ export const minStickers = 1;
|
||||||
export const maxStickers = 200;
|
export const maxStickers = 200;
|
||||||
export const maxByteSize = 300 * 1024;
|
export const maxByteSize = 300 * 1024;
|
||||||
|
|
||||||
interface StateStickerData {
|
type StateStickerData = {
|
||||||
readonly imageData?: StickerImageData;
|
readonly imageData?: StickerImageData;
|
||||||
readonly emoji?: EmojiPickDataType;
|
readonly emoji?: EmojiPickDataType;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface StateToastData {
|
type StateToastData = {
|
||||||
key: string;
|
key: string;
|
||||||
subs?: Array<number | string>;
|
subs?: Array<number | string>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
readonly order: Array<string>;
|
readonly order: Array<string>;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { Metadata } from 'sharp';
|
import { Metadata } from 'sharp';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `window`'s properties, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Window {
|
interface Window {
|
||||||
processStickerImage: ProcessStickerImageFn;
|
processStickerImage: ProcessStickerImageFn;
|
||||||
encryptAndUpload: EncryptAndUploadFn;
|
encryptAndUpload: EncryptAndUploadFn;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
@ -37,10 +37,10 @@ export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
} & Pick<React.HTMLProps<HTMLDivElement>, 'className'>;
|
} & Pick<React.HTMLProps<HTMLDivElement>, 'className'>;
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
imageBroken: boolean;
|
readonly imageBroken: boolean;
|
||||||
lastAvatarPath?: string;
|
readonly lastAvatarPath?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class Avatar extends React.Component<Props, State> {
|
export class Avatar extends React.Component<Props, State> {
|
||||||
public handleImageErrorBound: () => void;
|
public handleImageErrorBound: () => void;
|
||||||
|
|
|
@ -39,11 +39,11 @@ import {
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { missingCaseError } from '../util/missingCaseError';
|
import { missingCaseError } from '../util/missingCaseError';
|
||||||
|
|
||||||
interface MeType extends ConversationType {
|
type MeType = ConversationType & {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
activeCall?: ActiveCallType;
|
activeCall?: ActiveCallType;
|
||||||
availableCameras: Array<MediaDeviceInfo>;
|
availableCameras: Array<MediaDeviceInfo>;
|
||||||
cancelCall: (_: CancelCallType) => void;
|
cancelCall: (_: CancelCallType) => void;
|
||||||
|
@ -74,11 +74,11 @@ export interface PropsType {
|
||||||
togglePip: () => void;
|
togglePip: () => void;
|
||||||
toggleSettings: () => void;
|
toggleSettings: () => void;
|
||||||
toggleSpeakerView: () => void;
|
toggleSpeakerView: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface ActiveCallManagerPropsType extends PropsType {
|
type ActiveCallManagerPropsType = PropsType & {
|
||||||
activeCall: ActiveCallType;
|
activeCall: ActiveCallType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
|
const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
|
||||||
activeCall,
|
activeCall,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
@ -8,7 +8,7 @@ import { Intl } from './Intl';
|
||||||
import { ContactName } from './conversation/ContactName';
|
import { ContactName } from './conversation/ContactName';
|
||||||
import { ColorType } from '../types/Colors';
|
import { ColorType } from '../types/Colors';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
conversation: {
|
conversation: {
|
||||||
avatarPath?: string;
|
avatarPath?: string;
|
||||||
color?: ColorType;
|
color?: ColorType;
|
||||||
|
@ -19,7 +19,7 @@ interface Props {
|
||||||
};
|
};
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const AUTO_CLOSE_MS = 10000;
|
const AUTO_CLOSE_MS = 10000;
|
||||||
|
|
||||||
|
|
|
@ -41,24 +41,24 @@ const conversation = {
|
||||||
lastUpdated: Date.now(),
|
lastUpdated: Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
interface OverridePropsBase {
|
type OverridePropsBase = {
|
||||||
hasLocalAudio?: boolean;
|
hasLocalAudio?: boolean;
|
||||||
hasLocalVideo?: boolean;
|
hasLocalVideo?: boolean;
|
||||||
isInSpeakerView?: boolean;
|
isInSpeakerView?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface DirectCallOverrideProps extends OverridePropsBase {
|
type DirectCallOverrideProps = OverridePropsBase & {
|
||||||
callMode: CallMode.Direct;
|
callMode: CallMode.Direct;
|
||||||
callState?: CallState;
|
callState?: CallState;
|
||||||
hasRemoteVideo?: boolean;
|
hasRemoteVideo?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface GroupCallOverrideProps extends OverridePropsBase {
|
type GroupCallOverrideProps = OverridePropsBase & {
|
||||||
callMode: CallMode.Group;
|
callMode: CallMode.Group;
|
||||||
connectionState?: GroupCallConnectionState;
|
connectionState?: GroupCallConnectionState;
|
||||||
peekedParticipants?: Array<ConversationType>;
|
peekedParticipants?: Array<ConversationType>;
|
||||||
remoteParticipants?: Array<GroupCallRemoteParticipantType>;
|
remoteParticipants?: Array<GroupCallRemoteParticipantType>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const createActiveDirectCallProp = (
|
const createActiveDirectCallProp = (
|
||||||
overrideProps: DirectCallOverrideProps
|
overrideProps: DirectCallOverrideProps
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable react/no-array-index-key */
|
/* eslint-disable react/no-array-index-key */
|
||||||
|
@ -12,10 +12,10 @@ import { LocalizerType } from '../types/Util';
|
||||||
import { sortByTitle } from '../util/sortByTitle';
|
import { sortByTitle } from '../util/sortByTitle';
|
||||||
import { ConversationType } from '../state/ducks/conversations';
|
import { ConversationType } from '../state/ducks/conversations';
|
||||||
|
|
||||||
interface ParticipantType extends ConversationType {
|
type ParticipantType = ConversationType & {
|
||||||
hasAudio?: boolean;
|
hasAudio?: boolean;
|
||||||
hasVideo?: boolean;
|
hasVideo?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
readonly i18n: LocalizerType;
|
readonly i18n: LocalizerType;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -42,14 +42,14 @@ type PositionState =
|
||||||
offsetX: number;
|
offsetX: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface SnapCandidate {
|
type SnapCandidate = {
|
||||||
mode:
|
mode:
|
||||||
| PositionMode.SnapToBottom
|
| PositionMode.SnapToBottom
|
||||||
| PositionMode.SnapToLeft
|
| PositionMode.SnapToLeft
|
||||||
| PositionMode.SnapToRight
|
| PositionMode.SnapToRight
|
||||||
| PositionMode.SnapToTop;
|
| PositionMode.SnapToTop;
|
||||||
distanceToEdge: number;
|
distanceToEdge: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
activeCall: ActiveCallType;
|
activeCall: ActiveCallType;
|
||||||
|
|
|
@ -61,13 +61,13 @@ const NoVideo = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
activeCall: ActiveCallType;
|
activeCall: ActiveCallType;
|
||||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
setGroupCallVideoRequest: (_: Array<GroupCallVideoRequest>) => void;
|
setGroupCallVideoRequest: (_: Array<GroupCallVideoRequest>) => void;
|
||||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const CallingPipRemoteVideo = ({
|
export const CallingPipRemoteVideo = ({
|
||||||
activeCall,
|
activeCall,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -8,18 +8,18 @@ import { AttachmentType } from '../types/Attachment';
|
||||||
|
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
attachment: AttachmentType;
|
attachment: AttachmentType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
url: string;
|
url: string;
|
||||||
caption?: string;
|
caption?: string;
|
||||||
onSave?: (caption: string) => void;
|
onSave?: (caption: string) => void;
|
||||||
close?: () => void;
|
close?: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
caption: string;
|
caption: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class CaptionEditor extends React.Component<Props, State> {
|
export class CaptionEditor extends React.Component<Props, State> {
|
||||||
private readonly handleKeyDownBound: (
|
private readonly handleKeyDownBound: (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
@ -42,20 +42,20 @@ Quill.register('modules/emojiCompletion', EmojiCompletion);
|
||||||
Quill.register('modules/mentionCompletion', MentionCompletion);
|
Quill.register('modules/mentionCompletion', MentionCompletion);
|
||||||
Quill.register('modules/signalClipboard', SignalClipboard);
|
Quill.register('modules/signalClipboard', SignalClipboard);
|
||||||
|
|
||||||
interface HistoryStatic {
|
type HistoryStatic = {
|
||||||
undo(): void;
|
undo(): void;
|
||||||
clear(): void;
|
clear(): void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface InputApi {
|
export type InputApi = {
|
||||||
focus: () => void;
|
focus: () => void;
|
||||||
insertEmoji: (e: EmojiPickDataType) => void;
|
insertEmoji: (e: EmojiPickDataType) => void;
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
resetEmojiResults: () => void;
|
resetEmojiResults: () => void;
|
||||||
submit: () => void;
|
submit: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
readonly i18n: LocalizerType;
|
readonly i18n: LocalizerType;
|
||||||
readonly disabled?: boolean;
|
readonly disabled?: boolean;
|
||||||
readonly large?: boolean;
|
readonly large?: boolean;
|
||||||
|
@ -75,7 +75,7 @@ export interface Props {
|
||||||
onSubmit(message: string, mentions: Array<BodyRangeType>): unknown;
|
onSubmit(message: string, mentions: Array<BodyRangeType>): unknown;
|
||||||
getQuotedMessage(): unknown;
|
getQuotedMessage(): unknown;
|
||||||
clearQuotedMessage(): unknown;
|
clearQuotedMessage(): unknown;
|
||||||
}
|
};
|
||||||
|
|
||||||
const MAX_LENGTH = 64 * 1024;
|
const MAX_LENGTH = 64 * 1024;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -11,7 +11,7 @@ import { InContactsIcon } from './InContactsIcon';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { ColorType } from '../types/Colors';
|
import { ColorType } from '../types/Colors';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
avatarPath?: string;
|
avatarPath?: string;
|
||||||
color?: ColorType;
|
color?: ColorType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -23,7 +23,7 @@ interface Props {
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class ContactListItem extends React.Component<Props> {
|
export class ContactListItem extends React.Component<Props> {
|
||||||
public renderAvatar(): JSX.Element {
|
public renderAvatar(): JSX.Element {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
duration: number;
|
duration: number;
|
||||||
expiresAt: number;
|
expiresAt: number;
|
||||||
onComplete?: () => unknown;
|
onComplete?: () => unknown;
|
||||||
}
|
};
|
||||||
interface State {
|
type State = {
|
||||||
ratio: number;
|
ratio: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
const CIRCUMFERENCE = 11.013 * 2 * Math.PI;
|
const CIRCUMFERENCE = 11.013 * 2 * Math.PI;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
@ -8,12 +8,12 @@ import { ColorType } from '../types/Colors';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { Avatar } from './Avatar';
|
import { Avatar } from './Avatar';
|
||||||
|
|
||||||
interface PropsType {
|
type PropsType = {
|
||||||
conversation: ConversationType;
|
conversation: ConversationType;
|
||||||
hasRemoteVideo: boolean;
|
hasRemoteVideo: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const DirectCallRemoteParticipant: React.FC<PropsType> = ({
|
export const DirectCallRemoteParticipant: React.FC<PropsType> = ({
|
||||||
conversation,
|
conversation,
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
interface PropsType {
|
type PropsType = {
|
||||||
hasExpired: boolean;
|
hasExpired: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ExpiredBuildDialog = ({
|
export const ExpiredBuildDialog = ({
|
||||||
hasExpired,
|
hasExpired,
|
||||||
|
|
|
@ -16,12 +16,12 @@ const OVERFLOW_SCROLL_BUTTON_RATIO = 0.75;
|
||||||
// This should be an integer, as sub-pixel widths can cause performance issues.
|
// This should be an integer, as sub-pixel widths can cause performance issues.
|
||||||
export const OVERFLOW_PARTICIPANT_WIDTH = 140;
|
export const OVERFLOW_PARTICIPANT_WIDTH = 140;
|
||||||
|
|
||||||
interface PropsType {
|
type PropsType = {
|
||||||
getFrameBuffer: () => ArrayBuffer;
|
getFrameBuffer: () => ArrayBuffer;
|
||||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
overflowedParticipants: ReadonlyArray<GroupCallRemoteParticipantType>;
|
overflowedParticipants: ReadonlyArray<GroupCallRemoteParticipantType>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const GroupCallOverflowArea: FC<PropsType> = ({
|
export const GroupCallOverflowArea: FC<PropsType> = ({
|
||||||
getFrameBuffer,
|
getFrameBuffer,
|
||||||
|
|
|
@ -24,27 +24,27 @@ import { ContactName } from './conversation/ContactName';
|
||||||
import { useIntersectionObserver } from '../util/hooks';
|
import { useIntersectionObserver } from '../util/hooks';
|
||||||
import { MAX_FRAME_SIZE } from '../calling/constants';
|
import { MAX_FRAME_SIZE } from '../calling/constants';
|
||||||
|
|
||||||
interface BasePropsType {
|
type BasePropsType = {
|
||||||
getFrameBuffer: () => ArrayBuffer;
|
getFrameBuffer: () => ArrayBuffer;
|
||||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
remoteParticipant: GroupCallRemoteParticipantType;
|
remoteParticipant: GroupCallRemoteParticipantType;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface InPipPropsType {
|
type InPipPropsType = {
|
||||||
isInPip: true;
|
isInPip: true;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface InOverflowAreaPropsType {
|
type InOverflowAreaPropsType = {
|
||||||
height: number;
|
height: number;
|
||||||
isInPip?: false;
|
isInPip?: false;
|
||||||
width: number;
|
width: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface InGridPropsType extends InOverflowAreaPropsType {
|
type InGridPropsType = InOverflowAreaPropsType & {
|
||||||
left: number;
|
left: number;
|
||||||
top: number;
|
top: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsType = BasePropsType &
|
export type PropsType = BasePropsType &
|
||||||
(InPipPropsType | InOverflowAreaPropsType | InGridPropsType);
|
(InPipPropsType | InOverflowAreaPropsType | InGridPropsType);
|
||||||
|
|
|
@ -25,23 +25,23 @@ const PARTICIPANT_MARGIN = 10;
|
||||||
// We scale our video requests down for performance. This number is somewhat arbitrary.
|
// We scale our video requests down for performance. This number is somewhat arbitrary.
|
||||||
const VIDEO_REQUEST_SCALAR = 0.75;
|
const VIDEO_REQUEST_SCALAR = 0.75;
|
||||||
|
|
||||||
interface Dimensions {
|
type Dimensions = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface GridArrangement {
|
type GridArrangement = {
|
||||||
rows: Array<Array<GroupCallRemoteParticipantType>>;
|
rows: Array<Array<GroupCallRemoteParticipantType>>;
|
||||||
scalar: number;
|
scalar: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface PropsType {
|
type PropsType = {
|
||||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
isInSpeakerView: boolean;
|
isInSpeakerView: boolean;
|
||||||
remoteParticipants: ReadonlyArray<GroupCallRemoteParticipantType>;
|
remoteParticipants: ReadonlyArray<GroupCallRemoteParticipantType>;
|
||||||
setGroupCallVideoRequest: (_: Array<GroupCallVideoRequest>) => void;
|
setGroupCallVideoRequest: (_: Array<GroupCallVideoRequest>) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
// This component lays out group call remote participants. It uses a custom layout
|
// This component lays out group call remote participants. It uses a custom layout
|
||||||
// algorithm (in other words, nothing that the browser provides, like flexbox) in
|
// algorithm (in other words, nothing that the browser provides, like flexbox) in
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
@ -6,10 +6,10 @@ import classNames from 'classnames';
|
||||||
import { GroupCallConnectionState } from '../types/Calling';
|
import { GroupCallConnectionState } from '../types/Calling';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
interface PropsType {
|
type PropsType = {
|
||||||
connectionState: GroupCallConnectionState;
|
connectionState: GroupCallConnectionState;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
// In the future, this component should show toasts when users join or leave. See
|
// In the future, this component should show toasts when users join or leave. See
|
||||||
// DESKTOP-902.
|
// DESKTOP-902.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -8,13 +8,13 @@ import { ReplacementValuesType } from '../types/I18N';
|
||||||
|
|
||||||
export type FullJSXType = Array<JSX.Element | string> | JSX.Element | string;
|
export type FullJSXType = Array<JSX.Element | string> | JSX.Element | string;
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
/** The translation string id */
|
/** The translation string id */
|
||||||
id: string;
|
id: string;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
components?: Array<FullJSXType> | ReplacementValuesType<FullJSXType>;
|
components?: Array<FullJSXType> | ReplacementValuesType<FullJSXType>;
|
||||||
renderText?: RenderTextCallbackType;
|
renderText?: RenderTextCallbackType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class Intl extends React.Component<Props> {
|
export class Intl extends React.Component<Props> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { cleanId } from './_util';
|
import { cleanId } from './_util';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
conversations?: Array<ConversationListItemPropsType>;
|
conversations?: Array<ConversationListItemPropsType>;
|
||||||
archivedConversations?: Array<ConversationListItemPropsType>;
|
archivedConversations?: Array<ConversationListItemPropsType>;
|
||||||
pinnedConversations?: Array<ConversationListItemPropsType>;
|
pinnedConversations?: Array<ConversationListItemPropsType>;
|
||||||
|
@ -43,7 +43,7 @@ export interface PropsType {
|
||||||
renderNetworkStatus: () => JSX.Element;
|
renderNetworkStatus: () => JSX.Element;
|
||||||
renderRelinkDialog: () => JSX.Element;
|
renderRelinkDialog: () => JSX.Element;
|
||||||
renderUpdateDialog: () => JSX.Element;
|
renderUpdateDialog: () => JSX.Element;
|
||||||
}
|
};
|
||||||
|
|
||||||
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
|
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
|
||||||
type RowRendererParamsType = {
|
type RowRendererParamsType = {
|
||||||
|
@ -69,26 +69,26 @@ export enum HeaderType {
|
||||||
Chats,
|
Chats,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArchiveButtonRow {
|
type ArchiveButtonRow = {
|
||||||
type: RowType.ArchiveButton;
|
type: RowType.ArchiveButton;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface ConversationRow {
|
type ConversationRow = {
|
||||||
index: number;
|
index: number;
|
||||||
type:
|
type:
|
||||||
| RowType.ArchivedConversation
|
| RowType.ArchivedConversation
|
||||||
| RowType.Conversation
|
| RowType.Conversation
|
||||||
| RowType.PinnedConversation;
|
| RowType.PinnedConversation;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface HeaderRow {
|
type HeaderRow = {
|
||||||
headerType: HeaderType;
|
headerType: HeaderType;
|
||||||
type: RowType.Header;
|
type: RowType.Header;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface UndefinedRow {
|
type UndefinedRow = {
|
||||||
type: RowType.Undefined;
|
type: RowType.Undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
type Row = ArchiveButtonRow | ConversationRow | HeaderRow | UndefinedRow;
|
type Row = ArchiveButtonRow | ConversationRow | HeaderRow | UndefinedRow;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ const colorSVG = (url: string, color: string) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
close: () => void;
|
close: () => void;
|
||||||
contentType: MIME.MIMEType | undefined;
|
contentType: MIME.MIMEType | undefined;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -34,10 +34,10 @@ export interface Props {
|
||||||
onNext?: () => void;
|
onNext?: () => void;
|
||||||
onPrevious?: () => void;
|
onPrevious?: () => void;
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}
|
};
|
||||||
interface State {
|
type State = {
|
||||||
videoTime?: number;
|
videoTime?: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
const CONTROLS_WIDTH = 50;
|
const CONTROLS_WIDTH = 50;
|
||||||
const CONTROLS_SPACING = 10;
|
const CONTROLS_SPACING = 10;
|
||||||
|
@ -158,12 +158,12 @@ const styles = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IconButtonProps {
|
type IconButtonProps = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
type: 'save' | 'close' | 'previous' | 'next';
|
type: 'save' | 'close' | 'previous' | 'next';
|
||||||
}
|
};
|
||||||
|
|
||||||
const IconButton = ({ i18n, onClick, style, type }: IconButtonProps) => {
|
const IconButton = ({ i18n, onClick, style, type }: IconButtonProps) => {
|
||||||
const clickHandler = (event: React.MouseEvent<HTMLButtonElement>): void => {
|
const clickHandler = (event: React.MouseEvent<HTMLButtonElement>): void => {
|
||||||
|
|
|
@ -10,16 +10,16 @@ import { Message } from './conversation/media-gallery/types/Message';
|
||||||
import { AttachmentType } from '../types/Attachment';
|
import { AttachmentType } from '../types/Attachment';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
export interface MediaItemType {
|
export type MediaItemType = {
|
||||||
objectURL?: string;
|
objectURL?: string;
|
||||||
thumbnailObjectUrl?: string;
|
thumbnailObjectUrl?: string;
|
||||||
contentType?: MIME.MIMEType;
|
contentType?: MIME.MIMEType;
|
||||||
index: number;
|
index: number;
|
||||||
attachment: AttachmentType;
|
attachment: AttachmentType;
|
||||||
message: Message;
|
message: Message;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
close: () => void;
|
close: () => void;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
media: Array<MediaItemType>;
|
media: Array<MediaItemType>;
|
||||||
|
@ -29,11 +29,11 @@ export interface Props {
|
||||||
index: number;
|
index: number;
|
||||||
}) => void;
|
}) => void;
|
||||||
selectedIndex: number;
|
selectedIndex: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
selectedIndex: number;
|
selectedIndex: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class LightboxGallery extends React.Component<Props, State> {
|
export class LightboxGallery extends React.Component<Props, State> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -13,7 +13,7 @@ import { AvatarPopup } from './AvatarPopup';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { ColorType } from '../types/Colors';
|
import { ColorType } from '../types/Colors';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
searchConversationName?: string;
|
searchConversationName?: string;
|
||||||
searchConversationId?: string;
|
searchConversationId?: string;
|
||||||
|
@ -58,12 +58,12 @@ export interface PropsType {
|
||||||
clearSearch: () => void;
|
clearSearch: () => void;
|
||||||
|
|
||||||
showArchivedConversations: () => void;
|
showArchivedConversations: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface StateType {
|
type StateType = {
|
||||||
showingAvatarPopup: boolean;
|
showingAvatarPopup: boolean;
|
||||||
popperRoot: HTMLDivElement | null;
|
popperRoot: HTMLDivElement | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class MainHeader extends React.Component<PropsType, StateType> {
|
export class MainHeader extends React.Component<PropsType, StateType> {
|
||||||
private readonly inputRef: React.RefObject<HTMLInputElement>;
|
private readonly inputRef: React.RefObject<HTMLInputElement>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -11,10 +11,10 @@ import { SizeClassType } from './emoji/lib';
|
||||||
|
|
||||||
import { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
import { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
text: string;
|
text: string;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const renderNewLines: RenderTextCallbackType = ({ text, key }) => (
|
const renderNewLines: RenderTextCallbackType = ({ text, key }) => (
|
||||||
<AddNewLines key={key} text={text} />
|
<AddNewLines key={key} text={text} />
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -8,11 +8,11 @@ import { NetworkStateType } from '../state/ducks/network';
|
||||||
|
|
||||||
const FIVE_SECONDS = 5 * 1000;
|
const FIVE_SECONDS = 5 * 1000;
|
||||||
|
|
||||||
export interface PropsType extends NetworkStateType {
|
export type PropsType = NetworkStateType & {
|
||||||
hasNetworkDialog: boolean;
|
hasNetworkDialog: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
manualReconnect: () => void;
|
manualReconnect: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
type RenderDialogTypes = {
|
type RenderDialogTypes = {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
isRegistrationDone: boolean;
|
isRegistrationDone: boolean;
|
||||||
relinkDevice: () => void;
|
relinkDevice: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const RelinkDialog = ({
|
export const RelinkDialog = ({
|
||||||
i18n,
|
i18n,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -15,11 +15,11 @@ export const SpinnerDirections = [
|
||||||
] as const;
|
] as const;
|
||||||
export type SpinnerDirection = typeof SpinnerDirections[number];
|
export type SpinnerDirection = typeof SpinnerDirections[number];
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
size?: string;
|
size?: string;
|
||||||
svgSize: SpinnerSvgSize;
|
svgSize: SpinnerSvgSize;
|
||||||
direction?: SpinnerDirection;
|
direction?: SpinnerDirection;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const Spinner = ({ size, svgSize, direction }: Props): JSX.Element => (
|
export const Spinner = ({ size, svgSize, direction }: Props): JSX.Element => (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -7,11 +7,11 @@ import { Avatar } from './Avatar';
|
||||||
|
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
phoneNumber: string;
|
phoneNumber: string;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class StartNewConversation extends React.PureComponent<Props> {
|
export class StartNewConversation extends React.PureComponent<Props> {
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
|
|
@ -7,10 +7,10 @@ import { noop } from 'lodash';
|
||||||
import { Manager, Reference, Popper } from 'react-popper';
|
import { Manager, Reference, Popper } from 'react-popper';
|
||||||
import { Theme, themeClassName } from '../util/theme';
|
import { Theme, themeClassName } from '../util/theme';
|
||||||
|
|
||||||
interface EventWrapperPropsType {
|
type EventWrapperPropsType = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
onHoverChanged: (_: boolean) => void;
|
onHoverChanged: (_: boolean) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a
|
// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a
|
||||||
// disabled button. This uses native browser events to avoid that.
|
// disabled button. This uses native browser events to avoid that.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -7,7 +7,7 @@ import { Dialogs } from '../types/Dialogs';
|
||||||
import { Intl } from './Intl';
|
import { Intl } from './Intl';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
ackRender: () => void;
|
ackRender: () => void;
|
||||||
dialogType: Dialogs;
|
dialogType: Dialogs;
|
||||||
didSnooze: boolean;
|
didSnooze: boolean;
|
||||||
|
@ -17,7 +17,7 @@ export interface PropsType {
|
||||||
showEventsCount: number;
|
showEventsCount: number;
|
||||||
snoozeUpdate: () => void;
|
snoozeUpdate: () => void;
|
||||||
startUpdate: () => void;
|
startUpdate: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const UpdateDialog = ({
|
export const UpdateDialog = ({
|
||||||
ackRender,
|
ackRender,
|
||||||
|
|
|
@ -5,11 +5,11 @@ import React from 'react';
|
||||||
|
|
||||||
import { RenderTextCallbackType } from '../../types/Util';
|
import { RenderTextCallbackType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
text: string;
|
text: string;
|
||||||
/** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */
|
/** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */
|
||||||
renderNonNewLine?: RenderTextCallbackType;
|
renderNonNewLine?: RenderTextCallbackType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class AddNewLines extends React.Component<Props> {
|
export class AddNewLines extends React.Component<Props> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
|
|
|
@ -15,14 +15,14 @@ import {
|
||||||
isVideoAttachment,
|
isVideoAttachment,
|
||||||
} from '../../types/Attachment';
|
} from '../../types/Attachment';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
attachments: Array<AttachmentType>;
|
attachments: Array<AttachmentType>;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onClickAttachment: (attachment: AttachmentType) => void;
|
onClickAttachment: (attachment: AttachmentType) => void;
|
||||||
onCloseAttachment: (attachment: AttachmentType) => void;
|
onCloseAttachment: (attachment: AttachmentType) => void;
|
||||||
onAddAttachment: () => void;
|
onAddAttachment: () => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const IMAGE_WIDTH = 120;
|
const IMAGE_WIDTH = 120;
|
||||||
const IMAGE_HEIGHT = 120;
|
const IMAGE_HEIGHT = 120;
|
||||||
|
|
|
@ -14,14 +14,14 @@ import {
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { Tooltip, TooltipPlacement } from '../Tooltip';
|
import { Tooltip, TooltipPlacement } from '../Tooltip';
|
||||||
|
|
||||||
export interface PropsActionsType {
|
export type PropsActionsType = {
|
||||||
messageSizeChanged: (messageId: string, conversationId: string) => void;
|
messageSizeChanged: (messageId: string, conversationId: string) => void;
|
||||||
returnToActiveCall: () => void;
|
returnToActiveCall: () => void;
|
||||||
startCallingLobby: (_: {
|
startCallingLobby: (_: {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
isVideoCall: boolean;
|
isVideoCall: boolean;
|
||||||
}) => void;
|
}) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
type PropsHousekeeping = {
|
type PropsHousekeeping = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
|
|
@ -21,12 +21,12 @@ import {
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
contact: ContactType;
|
contact: ContactType;
|
||||||
hasSignalAccount: boolean;
|
hasSignalAccount: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onSendMessage: () => void;
|
onSendMessage: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
function getLabelForEmail(method: Email, i18n: LocalizerType): string {
|
function getLabelForEmail(method: Email, i18n: LocalizerType): string {
|
||||||
switch (method.type) {
|
switch (method.type) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -6,14 +6,14 @@ import React from 'react';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import { Emojify } from './Emojify';
|
import { Emojify } from './Emojify';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
title: string;
|
title: string;
|
||||||
module?: string;
|
module?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ContactName = ({ module, title }: PropsType): JSX.Element => {
|
export const ContactName = ({ module, title }: PropsType): JSX.Element => {
|
||||||
const prefix = module || 'module-contact-name';
|
const prefix = module || 'module-contact-name';
|
||||||
|
|
|
@ -32,7 +32,7 @@ export enum OutgoingCallButtonStyle {
|
||||||
Join,
|
Join,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PropsDataType {
|
export type PropsDataType = {
|
||||||
id: string;
|
id: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ export interface PropsDataType {
|
||||||
|
|
||||||
showBackButton?: boolean;
|
showBackButton?: boolean;
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle;
|
outgoingCallButtonStyle: OutgoingCallButtonStyle;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface PropsActionsType {
|
export type PropsActionsType = {
|
||||||
onSetMuteNotifications: (seconds: number) => void;
|
onSetMuteNotifications: (seconds: number) => void;
|
||||||
onSetDisappearingMessages: (seconds: number) => void;
|
onSetDisappearingMessages: (seconds: number) => void;
|
||||||
onDeleteMessages: () => void;
|
onDeleteMessages: () => void;
|
||||||
|
@ -78,11 +78,11 @@ export interface PropsActionsType {
|
||||||
onArchive: () => void;
|
onArchive: () => void;
|
||||||
onMarkUnread: () => void;
|
onMarkUnread: () => void;
|
||||||
onMoveToInbox: () => void;
|
onMoveToInbox: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface PropsHousekeepingType {
|
export type PropsHousekeepingType = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsType = PropsDataType &
|
export type PropsType = PropsDataType &
|
||||||
PropsActionsType &
|
PropsActionsType &
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
renderName,
|
renderName,
|
||||||
} from './_contactUtil';
|
} from './_contactUtil';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
contact: ContactType;
|
contact: ContactType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
isIncoming: boolean;
|
isIncoming: boolean;
|
||||||
|
@ -21,7 +21,7 @@ export interface Props {
|
||||||
withContentBelow: boolean;
|
withContentBelow: boolean;
|
||||||
tabIndex: number;
|
tabIndex: number;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class EmbeddedContact extends React.Component<Props> {
|
export class EmbeddedContact extends React.Component<Props> {
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
|
|
@ -40,13 +40,13 @@ function getImageTag({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
text: string;
|
text: string;
|
||||||
/** A class name to be added to the generated emoji images */
|
/** A class name to be added to the generated emoji images */
|
||||||
sizeClass?: SizeClassType;
|
sizeClass?: SizeClassType;
|
||||||
/** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */
|
/** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */
|
||||||
renderNonEmoji?: RenderTextCallbackType;
|
renderNonEmoji?: RenderTextCallbackType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class Emojify extends React.Component<Props> {
|
export class Emojify extends React.Component<Props> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
|
|
|
@ -6,14 +6,14 @@ import classNames from 'classnames';
|
||||||
|
|
||||||
import { getIncrement, getTimerBucket } from '../../util/timer';
|
import { getIncrement, getTimerBucket } from '../../util/timer';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
withImageNoCaption?: boolean;
|
withImageNoCaption?: boolean;
|
||||||
withSticker?: boolean;
|
withSticker?: boolean;
|
||||||
withTapToViewExpired?: boolean;
|
withTapToViewExpired?: boolean;
|
||||||
expirationLength: number;
|
expirationLength: number;
|
||||||
expirationTimestamp: number;
|
expirationTimestamp: number;
|
||||||
direction?: 'incoming' | 'outgoing';
|
direction?: 'incoming' | 'outgoing';
|
||||||
}
|
};
|
||||||
|
|
||||||
export class ExpireTimer extends React.Component<Props> {
|
export class ExpireTimer extends React.Component<Props> {
|
||||||
private interval: NodeJS.Timeout | null;
|
private interval: NodeJS.Timeout | null;
|
||||||
|
|
|
@ -10,21 +10,21 @@ import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
|
|
||||||
interface Contact {
|
type Contact = {
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
title: string;
|
title: string;
|
||||||
isMe?: boolean;
|
isMe?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ChangeType = 'add' | 'remove' | 'name' | 'avatar' | 'general';
|
export type ChangeType = 'add' | 'remove' | 'name' | 'avatar' | 'general';
|
||||||
|
|
||||||
interface Change {
|
type Change = {
|
||||||
type: ChangeType;
|
type: ChangeType;
|
||||||
newName?: string;
|
newName?: string;
|
||||||
contacts?: Array<Contact>;
|
contacts?: Array<Contact>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsData = {
|
export type PropsData = {
|
||||||
from: Contact;
|
from: Contact;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { Spinner } from '../Spinner';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import { AttachmentType } from '../../types/Attachment';
|
import { AttachmentType } from '../../types/Attachment';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
alt: string;
|
alt: string;
|
||||||
attachment: AttachmentType;
|
attachment: AttachmentType;
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -40,7 +40,7 @@ export interface Props {
|
||||||
onClick?: (attachment: AttachmentType) => void;
|
onClick?: (attachment: AttachmentType) => void;
|
||||||
onClickClose?: (attachment: AttachmentType) => void;
|
onClickClose?: (attachment: AttachmentType) => void;
|
||||||
onError?: () => void;
|
onError?: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class Image extends React.Component<Props> {
|
export class Image extends React.Component<Props> {
|
||||||
private canClick() {
|
private canClick() {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { Image } from './Image';
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
attachments: Array<AttachmentType>;
|
attachments: Array<AttachmentType>;
|
||||||
withContentAbove?: boolean;
|
withContentAbove?: boolean;
|
||||||
withContentBelow?: boolean;
|
withContentBelow?: boolean;
|
||||||
|
@ -31,7 +31,7 @@ export interface Props {
|
||||||
|
|
||||||
onError: () => void;
|
onError: () => void;
|
||||||
onClick?: (attachment: AttachmentType) => void;
|
onClick?: (attachment: AttachmentType) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ImageGrid = ({
|
export const ImageGrid = ({
|
||||||
attachments,
|
attachments,
|
||||||
|
|
|
@ -5,10 +5,10 @@ import * as React from 'react';
|
||||||
import moment, { Moment } from 'moment';
|
import moment, { Moment } from 'moment';
|
||||||
import { isLinkPreviewDateValid } from '../../linkPreviews/isLinkPreviewDateValid';
|
import { isLinkPreviewDateValid } from '../../linkPreviews/isLinkPreviewDateValid';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
date: null | number;
|
date: null | number;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const LinkPreviewDate: React.FC<Props> = ({
|
export const LinkPreviewDate: React.FC<Props> = ({
|
||||||
date,
|
date,
|
||||||
|
|
|
@ -36,11 +36,11 @@ const linkify = LinkifyIt()
|
||||||
'travel',
|
'travel',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
text: string;
|
text: string;
|
||||||
/** Allows you to customize now non-links are rendered. Simplest is just a <span>. */
|
/** Allows you to customize now non-links are rendered. Simplest is just a <span>. */
|
||||||
renderNonLink?: RenderTextCallbackType;
|
renderNonLink?: RenderTextCallbackType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const SUPPORTED_PROTOCOLS = /^(http|https):/i;
|
const SUPPORTED_PROTOCOLS = /^(http|https):/i;
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,9 @@ import { createRefMerger } from '../_util';
|
||||||
import { emojiToData } from '../emoji/lib';
|
import { emojiToData } from '../emoji/lib';
|
||||||
import { SmartReactionPicker } from '../../state/smart/ReactionPicker';
|
import { SmartReactionPicker } from '../../state/smart/ReactionPicker';
|
||||||
|
|
||||||
interface Trigger {
|
type Trigger = {
|
||||||
handleContextClick: (event: React.MouseEvent<HTMLDivElement>) => void;
|
handleContextClick: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const STICKER_SIZE = 200;
|
const STICKER_SIZE = 200;
|
||||||
const SELECTED_TIMEOUT = 1000;
|
const SELECTED_TIMEOUT = 1000;
|
||||||
|
@ -190,7 +190,7 @@ export type Props = PropsData &
|
||||||
PropsActions &
|
PropsActions &
|
||||||
Pick<ReactionPickerProps, 'renderEmojiPicker'>;
|
Pick<ReactionPickerProps, 'renderEmojiPicker'>;
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
expiring: boolean;
|
expiring: boolean;
|
||||||
expired: boolean;
|
expired: boolean;
|
||||||
imageBroken: boolean;
|
imageBroken: boolean;
|
||||||
|
@ -205,7 +205,7 @@ interface State {
|
||||||
|
|
||||||
containerWidth: number;
|
containerWidth: number;
|
||||||
canDeleteForEveryone: boolean;
|
canDeleteForEveryone: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
const EXPIRATION_CHECK_MINIMUM = 2000;
|
const EXPIRATION_CHECK_MINIMUM = 2000;
|
||||||
const EXPIRED_DELAY = 600;
|
const EXPIRED_DELAY = 600;
|
||||||
|
|
|
@ -20,7 +20,7 @@ type OpenConversationActionType = (
|
||||||
messageId?: string
|
messageId?: string
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
direction?: 'incoming' | 'outgoing';
|
direction?: 'incoming' | 'outgoing';
|
||||||
text: string;
|
text: string;
|
||||||
textPending?: boolean;
|
textPending?: boolean;
|
||||||
|
@ -31,7 +31,7 @@ export interface Props {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
bodyRanges?: BodyRangesType;
|
bodyRanges?: BodyRangesType;
|
||||||
openConversation?: OpenConversationActionType;
|
openConversation?: OpenConversationActionType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const renderEmoji = ({
|
const renderEmoji = ({
|
||||||
text,
|
text,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { Message, MessageStatusType, Props as MessageProps } from './Message';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import { ColorType } from '../../types/Colors';
|
import { ColorType } from '../../types/Colors';
|
||||||
|
|
||||||
interface Contact {
|
type Contact = {
|
||||||
status: MessageStatusType;
|
status: MessageStatusType;
|
||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -27,9 +27,9 @@ interface Contact {
|
||||||
|
|
||||||
onSendAnyway: () => void;
|
onSendAnyway: () => void;
|
||||||
onShowSafetyNumber: () => void;
|
onShowSafetyNumber: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
sentAt: number;
|
sentAt: number;
|
||||||
receivedAt: number;
|
receivedAt: number;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export interface Props {
|
||||||
contacts: Array<Contact>;
|
contacts: Array<Contact>;
|
||||||
|
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const _keyForError = (error: Error): string => {
|
const _keyForError = (error: Error): string => {
|
||||||
return `${error.name}-${error.message}`;
|
return `${error.name}-${error.message}`;
|
||||||
|
|
|
@ -11,11 +11,11 @@ import {
|
||||||
ProfileNameChangeType,
|
ProfileNameChangeType,
|
||||||
} from '../../util/getStringForProfileChange';
|
} from '../../util/getStringForProfileChange';
|
||||||
|
|
||||||
export interface PropsType {
|
export type PropsType = {
|
||||||
change: ProfileNameChangeType;
|
change: ProfileNameChangeType;
|
||||||
changedContact: ConversationType;
|
changedContact: ConversationType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function ProfileChangeNotification(props: PropsType): JSX.Element {
|
export function ProfileChangeNotification(props: PropsType): JSX.Element {
|
||||||
const { change, changedContact, i18n } = props;
|
const { change, changedContact, i18n } = props;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { ColorType } from '../../types/Colors';
|
||||||
import { ContactName } from './ContactName';
|
import { ContactName } from './ContactName';
|
||||||
import { getTextWithMentions } from '../../util/getTextWithMentions';
|
import { getTextWithMentions } from '../../util/getTextWithMentions';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
attachment?: QuotedAttachmentType;
|
attachment?: QuotedAttachmentType;
|
||||||
authorTitle: string;
|
authorTitle: string;
|
||||||
authorPhoneNumber?: string;
|
authorPhoneNumber?: string;
|
||||||
|
@ -29,25 +29,25 @@ export interface Props {
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
text: string;
|
text: string;
|
||||||
referencedMessageNotFound: boolean;
|
referencedMessageNotFound: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
imageBroken: boolean;
|
imageBroken: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface QuotedAttachmentType {
|
export type QuotedAttachmentType = {
|
||||||
contentType: MIME.MIMEType;
|
contentType: MIME.MIMEType;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
/** Not included in protobuf */
|
/** Not included in protobuf */
|
||||||
isVoiceMessage: boolean;
|
isVoiceMessage: boolean;
|
||||||
thumbnail?: Attachment;
|
thumbnail?: Attachment;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Attachment {
|
type Attachment = {
|
||||||
contentType: MIME.MIMEType;
|
contentType: MIME.MIMEType;
|
||||||
/** Not included in protobuf, and is loaded asynchronously */
|
/** Not included in protobuf, and is loaded asynchronously */
|
||||||
objectUrl?: string;
|
objectUrl?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
function validateQuote(quote: Props): boolean {
|
function validateQuote(quote: Props): boolean {
|
||||||
if (quote.text) {
|
if (quote.text) {
|
||||||
|
|
|
@ -46,12 +46,12 @@ const DEFAULT_EMOJI_ORDER = [
|
||||||
'rage',
|
'rage',
|
||||||
];
|
];
|
||||||
|
|
||||||
interface ReactionCategory {
|
type ReactionCategory = {
|
||||||
count: number;
|
count: number;
|
||||||
emoji?: string;
|
emoji?: string;
|
||||||
id: string;
|
id: string;
|
||||||
index: number;
|
index: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
type ReactionWithEmojiData = Reaction & EmojiData;
|
type ReactionWithEmojiData = Reaction & EmojiData;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import React from 'react';
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ResetSessionNotification = ({ i18n }: Props): JSX.Element => (
|
export const ResetSessionNotification = ({ i18n }: Props): JSX.Element => (
|
||||||
<div className="module-reset-session-notification">
|
<div className="module-reset-session-notification">
|
||||||
|
|
|
@ -7,13 +7,13 @@ import { ContactName } from './ContactName';
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface ContactType {
|
export type ContactType = {
|
||||||
id: string;
|
id: string;
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
title: string;
|
title: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsData = {
|
export type PropsData = {
|
||||||
isGroup: boolean;
|
isGroup: boolean;
|
||||||
|
|
|
@ -6,11 +6,11 @@ import React from 'react';
|
||||||
import { AttachmentType, getExtensionForDisplay } from '../../types/Attachment';
|
import { AttachmentType, getExtensionForDisplay } from '../../types/Attachment';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
attachment: AttachmentType;
|
attachment: AttachmentType;
|
||||||
onClose: (attachment: AttachmentType) => void;
|
onClose: (attachment: AttachmentType) => void;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const StagedGenericAttachment = ({
|
export const StagedGenericAttachment = ({
|
||||||
attachment,
|
attachment,
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { LinkPreviewDate } from './LinkPreviewDate';
|
||||||
import { AttachmentType, isImageAttachment } from '../../types/Attachment';
|
import { AttachmentType, isImageAttachment } from '../../types/Attachment';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
isLoaded: boolean;
|
isLoaded: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
description: null | string;
|
description: null | string;
|
||||||
|
@ -20,7 +20,7 @@ export interface Props {
|
||||||
|
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const StagedLinkPreview: React.FC<Props> = ({
|
export const StagedLinkPreview: React.FC<Props> = ({
|
||||||
isLoaded,
|
isLoaded,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const StagedPlaceholderAttachment = ({
|
export const StagedPlaceholderAttachment = ({
|
||||||
i18n,
|
i18n,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { formatRelativeTime } from '../../util/formatRelativeTime';
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
extended?: boolean;
|
extended?: boolean;
|
||||||
module?: string;
|
module?: string;
|
||||||
|
@ -19,7 +19,7 @@ export interface Props {
|
||||||
withUnread?: boolean;
|
withUnread?: boolean;
|
||||||
direction?: 'incoming' | 'outgoing';
|
direction?: 'incoming' | 'outgoing';
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
const UPDATE_FREQUENCY = 60 * 1000;
|
const UPDATE_FREQUENCY = 60 * 1000;
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ import classNames from 'classnames';
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
color?: string;
|
color?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const TypingAnimation = ({ i18n, color }: Props): JSX.Element => (
|
export const TypingAnimation = ({ i18n, color }: Props): JSX.Element => (
|
||||||
<div className="module-typing-animation" title={i18n('typingAlt')}>
|
<div className="module-typing-animation" title={i18n('typingAlt')}>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Avatar } from '../Avatar';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import { ColorType } from '../../types/Colors';
|
import { ColorType } from '../../types/Colors';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
avatarPath?: string;
|
avatarPath?: string;
|
||||||
color: ColorType;
|
color: ColorType;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -19,7 +19,7 @@ export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
conversationType: 'group' | 'direct';
|
conversationType: 'group' | 'direct';
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class TypingBubble extends React.PureComponent<Props> {
|
export class TypingBubble extends React.PureComponent<Props> {
|
||||||
public renderAvatar(): JSX.Element | null {
|
public renderAvatar(): JSX.Element | null {
|
||||||
|
|
|
@ -8,14 +8,14 @@ import { ContactName } from './ContactName';
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export interface ContactType {
|
export type ContactType = {
|
||||||
id: string;
|
id: string;
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
title: string;
|
title: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
isMe: boolean;
|
isMe: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsData = {
|
export type PropsData = {
|
||||||
canProcessNow: boolean;
|
canProcessNow: boolean;
|
||||||
|
|
|
@ -10,12 +10,12 @@ import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
|
|
||||||
interface Contact {
|
type Contact = {
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PropsData = {
|
export type PropsData = {
|
||||||
type: 'markVerified' | 'markNotVerified';
|
type: 'markVerified' | 'markNotVerified';
|
||||||
|
|
|
@ -10,13 +10,13 @@ import { MediaItemType } from '../../LightboxGallery';
|
||||||
import { missingCaseError } from '../../../util/missingCaseError';
|
import { missingCaseError } from '../../../util/missingCaseError';
|
||||||
import { LocalizerType } from '../../../types/Util';
|
import { LocalizerType } from '../../../types/Util';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
header?: string;
|
header?: string;
|
||||||
type: 'media' | 'documents';
|
type: 'media' | 'documents';
|
||||||
mediaItems: Array<MediaItemType>;
|
mediaItems: Array<MediaItemType>;
|
||||||
onItemClick?: (event: ItemClickEvent) => void;
|
onItemClick?: (event: ItemClickEvent) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class AttachmentSection extends React.Component<Props> {
|
export class AttachmentSection extends React.Component<Props> {
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import classNames from 'classnames';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import formatFileSize from 'filesize';
|
import formatFileSize from 'filesize';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
// Required
|
// Required
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ interface Props {
|
||||||
fileSize?: number;
|
fileSize?: number;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
shouldShowSeparator?: boolean;
|
shouldShowSeparator?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class DocumentListItem extends React.Component<Props> {
|
export class DocumentListItem extends React.Component<Props> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
label: string;
|
label: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const EmptyState = ({ label }: Props): JSX.Element => (
|
export const EmptyState = ({ label }: Props): JSX.Element => (
|
||||||
<div className="module-empty-state">{label}</div>
|
<div className="module-empty-state">{label}</div>
|
||||||
|
|
|
@ -15,23 +15,23 @@ import { LocalizerType } from '../../../types/Util';
|
||||||
|
|
||||||
import { MediaItemType } from '../../LightboxGallery';
|
import { MediaItemType } from '../../LightboxGallery';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
documents: Array<MediaItemType>;
|
documents: Array<MediaItemType>;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
media: Array<MediaItemType>;
|
media: Array<MediaItemType>;
|
||||||
|
|
||||||
onItemClick?: (event: ItemClickEvent) => void;
|
onItemClick?: (event: ItemClickEvent) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
selectedTab: 'media' | 'documents';
|
selectedTab: 'media' | 'documents';
|
||||||
}
|
};
|
||||||
|
|
||||||
const MONTH_FORMAT = 'MMMM YYYY';
|
const MONTH_FORMAT = 'MMMM YYYY';
|
||||||
|
|
||||||
interface TabSelectEvent {
|
type TabSelectEvent = {
|
||||||
type: 'media' | 'documents';
|
type: 'media' | 'documents';
|
||||||
}
|
};
|
||||||
|
|
||||||
const Tab = ({
|
const Tab = ({
|
||||||
isSelected,
|
isSelected,
|
||||||
|
|
|
@ -11,15 +11,15 @@ import {
|
||||||
import { LocalizerType } from '../../../types/Util';
|
import { LocalizerType } from '../../../types/Util';
|
||||||
import { MediaItemType } from '../../LightboxGallery';
|
import { MediaItemType } from '../../LightboxGallery';
|
||||||
|
|
||||||
export interface Props {
|
export type Props = {
|
||||||
mediaItem: MediaItemType;
|
mediaItem: MediaItemType;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
imageBroken: boolean;
|
imageBroken: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class MediaGridItem extends React.Component<Props, State> {
|
export class MediaGridItem extends React.Component<Props, State> {
|
||||||
private readonly onImageErrorBound: () => void;
|
private readonly onImageErrorBound: () => void;
|
||||||
|
|
|
@ -11,10 +11,10 @@ import { MediaItemType } from '../../LightboxGallery';
|
||||||
type StaticSectionType = 'today' | 'yesterday' | 'thisWeek' | 'thisMonth';
|
type StaticSectionType = 'today' | 'yesterday' | 'thisWeek' | 'thisMonth';
|
||||||
type YearMonthSectionType = 'yearMonth';
|
type YearMonthSectionType = 'yearMonth';
|
||||||
|
|
||||||
interface GenericSection<T> {
|
type GenericSection<T> = {
|
||||||
type: T;
|
type: T;
|
||||||
mediaItems: Array<MediaItemType>;
|
mediaItems: Array<MediaItemType>;
|
||||||
}
|
};
|
||||||
type StaticSection = GenericSection<StaticSectionType>;
|
type StaticSection = GenericSection<StaticSectionType>;
|
||||||
type YearMonthSection = GenericSection<YearMonthSectionType> & {
|
type YearMonthSection = GenericSection<YearMonthSectionType> & {
|
||||||
year: number;
|
year: number;
|
||||||
|
@ -93,11 +93,11 @@ const toSection = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface GenericMediaItemWithSection<T> {
|
type GenericMediaItemWithSection<T> = {
|
||||||
order: number;
|
order: number;
|
||||||
type: T;
|
type: T;
|
||||||
mediaItem: MediaItemType;
|
mediaItem: MediaItemType;
|
||||||
}
|
};
|
||||||
type MediaItemWithStaticSection = GenericMediaItemWithSection<
|
type MediaItemWithStaticSection = GenericMediaItemWithSection<
|
||||||
StaticSectionType
|
StaticSectionType
|
||||||
>;
|
>;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { AttachmentType } from '../../../../types/Attachment';
|
import { AttachmentType } from '../../../../types/Attachment';
|
||||||
import { Message } from './Message';
|
import { Message } from './Message';
|
||||||
|
|
||||||
export interface ItemClickEvent {
|
export type ItemClickEvent = {
|
||||||
message: Message;
|
message: Message;
|
||||||
attachment: AttachmentType;
|
attachment: AttachmentType;
|
||||||
type: 'media' | 'documents';
|
type: 'media' | 'documents';
|
||||||
}
|
};
|
||||||
|
|
|
@ -54,17 +54,17 @@ const emptyContentType = { type: null, charset: null };
|
||||||
|
|
||||||
type FetchFn = (href: string, init: RequestInit) => Promise<Response>;
|
type FetchFn = (href: string, init: RequestInit) => Promise<Response>;
|
||||||
|
|
||||||
export interface LinkPreviewMetadata {
|
export type LinkPreviewMetadata = {
|
||||||
title: string;
|
title: string;
|
||||||
description: null | string;
|
description: null | string;
|
||||||
date: null | number;
|
date: null | number;
|
||||||
imageHref: null | string;
|
imageHref: null | string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface LinkPreviewImage {
|
export type LinkPreviewImage = {
|
||||||
data: ArrayBuffer;
|
data: ArrayBuffer;
|
||||||
contentType: MIMEType;
|
contentType: MIMEType;
|
||||||
}
|
};
|
||||||
|
|
||||||
type ParsedContentType =
|
type ParsedContentType =
|
||||||
| { type: null; charset: null }
|
| { type: null; charset: null }
|
||||||
|
|
4
ts/model-types.d.ts
vendored
4
ts/model-types.d.ts
vendored
|
@ -41,10 +41,10 @@ export declare class DeletesModelType extends Backbone.Model<
|
||||||
|
|
||||||
type TaskResultType = any;
|
type TaskResultType = any;
|
||||||
|
|
||||||
export interface CustomError extends Error {
|
export type CustomError = Error & {
|
||||||
identifier?: string;
|
identifier?: string;
|
||||||
number?: string;
|
number?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type GroupMigrationType = {
|
export type GroupMigrationType = {
|
||||||
areWeInvited: boolean;
|
areWeInvited: boolean;
|
||||||
|
|
|
@ -76,10 +76,10 @@ const COLORS = [
|
||||||
|
|
||||||
const THREE_HOURS = 3 * 60 * 60 * 1000;
|
const THREE_HOURS = 3 * 60 * 60 * 1000;
|
||||||
|
|
||||||
interface CustomError extends Error {
|
type CustomError = Error & {
|
||||||
identifier?: string;
|
identifier?: string;
|
||||||
number?: string;
|
number?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class ConversationModel extends window.Backbone.Model<
|
export class ConversationModel extends window.Backbone.Model<
|
||||||
ConversationAttributesType
|
ConversationAttributesType
|
||||||
|
@ -4556,9 +4556,9 @@ window.Whisper.GroupMemberConversation = window.Backbone.Model.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface SortableByTitle {
|
type SortableByTitle = {
|
||||||
getTitle: () => string;
|
getTitle: () => string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const sortConversationTitles = (
|
const sortConversationTitles = (
|
||||||
left: SortableByTitle,
|
left: SortableByTitle,
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
interface Environment {
|
type Environment = {
|
||||||
isAppFocused: boolean;
|
isAppFocused: boolean;
|
||||||
isAudioNotificationEnabled: boolean;
|
isAudioNotificationEnabled: boolean;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
hasNotifications: boolean;
|
hasNotifications: boolean;
|
||||||
userSetting: UserSetting;
|
userSetting: UserSetting;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Status {
|
type Status = {
|
||||||
shouldClearNotifications: boolean;
|
shouldClearNotifications: boolean;
|
||||||
shouldPlayNotificationSound: boolean;
|
shouldPlayNotificationSound: boolean;
|
||||||
shouldShowNotifications: boolean;
|
shouldShowNotifications: boolean;
|
||||||
type: Type;
|
type: Type;
|
||||||
}
|
};
|
||||||
|
|
||||||
type UserSetting = 'off' | 'count' | 'name' | 'message';
|
type UserSetting = 'off' | 'count' | 'name' | 'message';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import Quill from 'quill';
|
import Quill from 'quill';
|
||||||
|
@ -22,11 +22,11 @@ import { getBlotTextPartitions, matchBlotTextPartitions } from '../util';
|
||||||
|
|
||||||
const Keyboard = Quill.import('modules/keyboard');
|
const Keyboard = Quill.import('modules/keyboard');
|
||||||
|
|
||||||
interface EmojiPickerOptions {
|
type EmojiPickerOptions = {
|
||||||
onPickEmoji: (emoji: EmojiPickDataType) => void;
|
onPickEmoji: (emoji: EmojiPickDataType) => void;
|
||||||
setEmojiPickerElement: (element: JSX.Element | null) => void;
|
setEmojiPickerElement: (element: JSX.Element | null) => void;
|
||||||
skinTone: number;
|
skinTone: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class EmojiCompletion {
|
export class EmojiCompletion {
|
||||||
results: Array<EmojiData>;
|
results: Array<EmojiData>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -15,14 +15,16 @@ import { LocalizerType } from '../../types/Util';
|
||||||
import { MemberRepository } from '../memberRepository';
|
import { MemberRepository } from '../memberRepository';
|
||||||
import { matchBlotTextPartitions } from '../util';
|
import { matchBlotTextPartitions } from '../util';
|
||||||
|
|
||||||
export interface MentionCompletionOptions {
|
export type MentionCompletionOptions = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
memberRepositoryRef: RefObject<MemberRepository>;
|
memberRepositoryRef: RefObject<MemberRepository>;
|
||||||
setMentionPickerElement: (element: JSX.Element | null) => void;
|
setMentionPickerElement: (element: JSX.Element | null) => void;
|
||||||
me?: ConversationType;
|
me?: ConversationType;
|
||||||
}
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `HTMLElement`'s properties, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface HTMLElement {
|
interface HTMLElement {
|
||||||
// Webkit-specific
|
// Webkit-specific
|
||||||
scrollIntoViewIfNeeded: (bringToCenter: boolean) => void;
|
scrollIntoViewIfNeeded: (bringToCenter: boolean) => void;
|
||||||
|
|
5
ts/quill/types.d.ts
vendored
5
ts/quill/types.d.ts
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import UpdatedDelta from 'quill-delta';
|
import UpdatedDelta from 'quill-delta';
|
||||||
|
@ -11,6 +11,8 @@ declare module 'react-quill' {
|
||||||
type DeltaStatic = UpdatedDelta;
|
type DeltaStatic = UpdatedDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to extend some existing interfaces.
|
||||||
|
/* eslint-disable no-restricted-syntax */
|
||||||
declare module 'quill' {
|
declare module 'quill' {
|
||||||
// this type is fixed in @types/quill, but our version of react-quill cannot
|
// this type is fixed in @types/quill, but our version of react-quill cannot
|
||||||
// use the version of quill that has this fix in its typings
|
// use the version of quill that has this fix in its typings
|
||||||
|
@ -76,3 +78,4 @@ declare module 'quill' {
|
||||||
bindings: Record<string | number, Array<unknown>>;
|
bindings: Record<string | number, Array<unknown>>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* eslint-enable no-restricted-syntax */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import emojiRegex from 'emoji-regex';
|
import emojiRegex from 'emoji-regex';
|
||||||
|
@ -9,10 +9,10 @@ import Op from 'quill-delta/dist/Op';
|
||||||
import { BodyRangeType } from '../types/Util';
|
import { BodyRangeType } from '../types/Util';
|
||||||
import { MentionBlot } from './mentions/blot';
|
import { MentionBlot } from './mentions/blot';
|
||||||
|
|
||||||
export interface MentionBlotValue {
|
export type MentionBlotValue = {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isMentionBlot = (blot: LeafBlot): blot is MentionBlot =>
|
export const isMentionBlot = (blot: LeafBlot): blot is MentionBlot =>
|
||||||
blot.value() && blot.value().mention;
|
blot.value() && blot.value().mention;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/ban-types */
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
|
@ -30,7 +30,7 @@ export type StickerPackType = any;
|
||||||
export type StickerType = any;
|
export type StickerType = any;
|
||||||
export type UnprocessedType = any;
|
export type UnprocessedType = any;
|
||||||
|
|
||||||
export interface DataInterface {
|
export type DataInterface = {
|
||||||
close: () => Promise<void>;
|
close: () => Promise<void>;
|
||||||
removeDB: () => Promise<void>;
|
removeDB: () => Promise<void>;
|
||||||
removeIndexedDBFiles: () => Promise<void>;
|
removeIndexedDBFiles: () => Promise<void>;
|
||||||
|
@ -188,7 +188,7 @@ export interface DataInterface {
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
options: { limit: number }
|
options: { limit: number }
|
||||||
) => Promise<Array<MessageType>>;
|
) => Promise<Array<MessageType>>;
|
||||||
}
|
};
|
||||||
|
|
||||||
// The reason for client/server divergence is the need to inject Backbone models and
|
// The reason for client/server divergence is the need to inject Backbone models and
|
||||||
// collections into data calls so those are the objects returned. This was necessary in
|
// collections into data calls so those are the objects returned. This was necessary in
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable no-nested-ternary */
|
/* eslint-disable no-nested-ternary */
|
||||||
|
@ -56,6 +56,8 @@ import {
|
||||||
} from './Interface';
|
} from './Interface';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `Function`'s properties, so we need to use an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Function {
|
interface Function {
|
||||||
needsSerial?: boolean;
|
needsSerial?: boolean;
|
||||||
}
|
}
|
||||||
|
|
6
ts/sqlcipher.d.ts
vendored
6
ts/sqlcipher.d.ts
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
// Taken from:
|
// Taken from:
|
||||||
|
@ -35,10 +35,10 @@ declare module '@journeyapps/sqlcipher' {
|
||||||
): Database;
|
): Database;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface RunResult extends Statement {
|
export type RunResult = Statement & {
|
||||||
lastID: number;
|
lastID: number;
|
||||||
changes: number;
|
changes: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class Statement {
|
export class Statement {
|
||||||
bind(callback?: (err: Error | null) => void): this;
|
bind(callback?: (err: Error | null) => void): this;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
@ -17,7 +17,8 @@ import { createLogger } from 'redux-logger';
|
||||||
import { reducer, StateType } from './reducer';
|
import { reducer, StateType } from './reducer';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// We want to extend `window`'s properties, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax, @typescript-eslint/no-unused-vars
|
||||||
interface Console {
|
interface Console {
|
||||||
_log: Console['log'];
|
_log: Console['log'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,24 +30,24 @@ import { LatestQueue } from '../../util/LatestQueue';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
export interface GroupCallPeekInfoType {
|
export type GroupCallPeekInfoType = {
|
||||||
uuids: Array<string>;
|
uuids: Array<string>;
|
||||||
creatorUuid?: string;
|
creatorUuid?: string;
|
||||||
eraId?: string;
|
eraId?: string;
|
||||||
maxDevices: number;
|
maxDevices: number;
|
||||||
deviceCount: number;
|
deviceCount: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface GroupCallParticipantInfoType {
|
export type GroupCallParticipantInfoType = {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
demuxId: number;
|
demuxId: number;
|
||||||
hasRemoteAudio: boolean;
|
hasRemoteAudio: boolean;
|
||||||
hasRemoteVideo: boolean;
|
hasRemoteVideo: boolean;
|
||||||
speakerTime?: number;
|
speakerTime?: number;
|
||||||
videoAspectRatio: number;
|
videoAspectRatio: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface DirectCallStateType {
|
export type DirectCallStateType = {
|
||||||
callMode: CallMode.Direct;
|
callMode: CallMode.Direct;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
callState?: CallState;
|
callState?: CallState;
|
||||||
|
@ -55,18 +55,18 @@ export interface DirectCallStateType {
|
||||||
isIncoming: boolean;
|
isIncoming: boolean;
|
||||||
isVideoCall: boolean;
|
isVideoCall: boolean;
|
||||||
hasRemoteVideo?: boolean;
|
hasRemoteVideo?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface GroupCallStateType {
|
export type GroupCallStateType = {
|
||||||
callMode: CallMode.Group;
|
callMode: CallMode.Group;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
connectionState: GroupCallConnectionState;
|
connectionState: GroupCallConnectionState;
|
||||||
joinState: GroupCallJoinState;
|
joinState: GroupCallJoinState;
|
||||||
peekInfo: GroupCallPeekInfoType;
|
peekInfo: GroupCallPeekInfoType;
|
||||||
remoteParticipants: Array<GroupCallParticipantInfoType>;
|
remoteParticipants: Array<GroupCallParticipantInfoType>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface ActiveCallStateType {
|
export type ActiveCallStateType = {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
hasLocalAudio: boolean;
|
hasLocalAudio: boolean;
|
||||||
hasLocalVideo: boolean;
|
hasLocalVideo: boolean;
|
||||||
|
@ -76,11 +76,11 @@ export interface ActiveCallStateType {
|
||||||
safetyNumberChangedUuids: Array<string>;
|
safetyNumberChangedUuids: Array<string>;
|
||||||
settingsDialogOpen: boolean;
|
settingsDialogOpen: boolean;
|
||||||
showParticipantsList: boolean;
|
showParticipantsList: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface CallsByConversationType {
|
export type CallsByConversationType = {
|
||||||
[conversationId: string]: DirectCallStateType | GroupCallStateType;
|
[conversationId: string]: DirectCallStateType | GroupCallStateType;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type CallingStateType = MediaDeviceSettings & {
|
export type CallingStateType = MediaDeviceSettings & {
|
||||||
callsByConversation: CallsByConversationType;
|
callsByConversation: CallsByConversationType;
|
||||||
|
@ -145,15 +145,15 @@ type PeekNotConnectedGroupCallType = {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface StartDirectCallType {
|
type StartDirectCallType = {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
hasLocalAudio: boolean;
|
hasLocalAudio: boolean;
|
||||||
hasLocalVideo: boolean;
|
hasLocalVideo: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface StartCallType extends StartDirectCallType {
|
export type StartCallType = StartDirectCallType & {
|
||||||
callMode: CallMode.Direct | CallMode.Group;
|
callMode: CallMode.Direct | CallMode.Group;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type RemoteVideoChangeType = {
|
export type RemoteVideoChangeType = {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
@ -20,7 +20,7 @@ import { getOwn } from '../../util/getOwn';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { isGroupCallingEnabled } from '../../util/isGroupCallingEnabled';
|
import { isGroupCallingEnabled } from '../../util/isGroupCallingEnabled';
|
||||||
|
|
||||||
export interface OwnProps {
|
export type OwnProps = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
onDeleteMessages: () => void;
|
onDeleteMessages: () => void;
|
||||||
|
@ -39,7 +39,7 @@ export interface OwnProps {
|
||||||
onMarkUnread: () => void;
|
onMarkUnread: () => void;
|
||||||
onMoveToInbox: () => void;
|
onMoveToInbox: () => void;
|
||||||
onShowSafetyNumber: () => void;
|
onShowSafetyNumber: () => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
const getOutgoingCallButtonStyle = (
|
const getOutgoingCallButtonStyle = (
|
||||||
conversation: ConversationType,
|
conversation: ConversationType,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -6,10 +6,10 @@ import { assert } from 'chai';
|
||||||
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
||||||
|
|
||||||
describe('assignWithNoUnnecessaryAllocation', () => {
|
describe('assignWithNoUnnecessaryAllocation', () => {
|
||||||
interface Person {
|
type Person = {
|
||||||
name?: string;
|
name?: string;
|
||||||
age?: number;
|
age?: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
it('returns the same object if there are no modifications', () => {
|
it('returns the same object if there are no modifications', () => {
|
||||||
const empty = {};
|
const empty = {};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -69,14 +69,14 @@ const memberRepositoryRef: RefObject<MemberRepository> = {
|
||||||
|
|
||||||
const matcher = matchMention(memberRepositoryRef);
|
const matcher = matchMention(memberRepositoryRef);
|
||||||
|
|
||||||
interface Mention {
|
type Mention = {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface MentionInsert {
|
type MentionInsert = {
|
||||||
mention: Mention;
|
mention: Mention;
|
||||||
}
|
};
|
||||||
|
|
||||||
const isMention = (insert?: unknown): insert is MentionInsert => {
|
const isMention = (insert?: unknown): insert is MentionInsert => {
|
||||||
if (insert) {
|
if (insert) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
@ -9,6 +9,8 @@ import { ByteBufferClass } from '../window.d';
|
||||||
declare global {
|
declare global {
|
||||||
// this is fixed in already, and won't be necessary when the new definitions
|
// this is fixed in already, and won't be necessary when the new definitions
|
||||||
// files are used: https://github.com/microsoft/TSJS-lib-generator/pull/843
|
// files are used: https://github.com/microsoft/TSJS-lib-generator/pull/843
|
||||||
|
// We want to extend `SubtleCrypto`, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
export interface SubtleCrypto {
|
export interface SubtleCrypto {
|
||||||
decrypt(
|
decrypt(
|
||||||
algorithm:
|
algorithm:
|
||||||
|
@ -108,10 +110,10 @@ const PROFILE_KEY_LENGTH = 32; // bytes
|
||||||
const PROFILE_TAG_LENGTH = 128; // bits
|
const PROFILE_TAG_LENGTH = 128; // bits
|
||||||
const PROFILE_NAME_PADDED_LENGTH = 53; // bytes
|
const PROFILE_NAME_PADDED_LENGTH = 53; // bytes
|
||||||
|
|
||||||
interface EncryptedAttachment {
|
type EncryptedAttachment = {
|
||||||
ciphertext: ArrayBuffer;
|
ciphertext: ArrayBuffer;
|
||||||
digest: ArrayBuffer;
|
digest: ArrayBuffer;
|
||||||
}
|
};
|
||||||
|
|
||||||
async function verifyDigest(
|
async function verifyDigest(
|
||||||
data: ArrayBuffer,
|
data: ArrayBuffer,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/ban-types */
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
|
@ -49,6 +49,8 @@ const GROUPV2_ID_LENGTH = 32;
|
||||||
const RETRY_TIMEOUT = 2 * 60 * 1000;
|
const RETRY_TIMEOUT = 2 * 60 * 1000;
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `Event`, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Event {
|
interface Event {
|
||||||
code?: string | number;
|
code?: string | number;
|
||||||
configuration?: any;
|
configuration?: any;
|
||||||
|
@ -79,6 +81,8 @@ declare global {
|
||||||
typing?: any;
|
typing?: any;
|
||||||
verified?: any;
|
verified?: any;
|
||||||
}
|
}
|
||||||
|
// We want to extend `Error`, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Error {
|
interface Error {
|
||||||
reason?: any;
|
reason?: any;
|
||||||
stackForLog?: string;
|
stackForLog?: string;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable no-nested-ternary */
|
/* eslint-disable no-nested-ternary */
|
||||||
|
@ -70,10 +70,10 @@ export type SendOptionsType = {
|
||||||
online?: boolean;
|
online?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface CustomError extends Error {
|
export type CustomError = Error & {
|
||||||
identifier?: string;
|
identifier?: string;
|
||||||
number?: string;
|
number?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type CallbackResultType = {
|
export type CallbackResultType = {
|
||||||
successfulIdentifiers?: Array<any>;
|
successfulIdentifiers?: Array<any>;
|
||||||
|
@ -105,9 +105,9 @@ type GroupV1InfoType = {
|
||||||
members: Array<string>;
|
members: Array<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface GroupCallUpdateType {
|
type GroupCallUpdateType = {
|
||||||
eraId: string;
|
eraId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
type MessageOptionsType = {
|
type MessageOptionsType = {
|
||||||
attachments?: Array<AttachmentType> | null;
|
attachments?: Array<AttachmentType> | null;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import utils from './Helpers';
|
import utils from './Helpers';
|
||||||
|
|
||||||
// Default implmentation working with localStorage
|
// Default implmentation working with localStorage
|
||||||
const localStorageImpl = {
|
const localStorageImpl: StorageInterface = {
|
||||||
put(key: string, value: any) {
|
put(key: string, value: any) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
throw new Error('Tried to store undefined');
|
throw new Error('Tried to store undefined');
|
||||||
|
@ -26,14 +26,14 @@ const localStorageImpl = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface StorageInterface {
|
export type StorageInterface = {
|
||||||
put(key: string, value: any): void | Promise<void>;
|
put(key: string, value: any): void | Promise<void>;
|
||||||
get(key: string, defaultValue: any): any;
|
get(key: string, defaultValue: any): any;
|
||||||
remove(key: string): void | Promise<void>;
|
remove(key: string): void | Promise<void>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const Storage = {
|
const Storage = {
|
||||||
impl: localStorageImpl as StorageInterface,
|
impl: localStorageImpl,
|
||||||
|
|
||||||
put(key: string, value: unknown): Promise<void> | void {
|
put(key: string, value: unknown): Promise<void> | void {
|
||||||
return Storage.impl.put(key, value);
|
return Storage.impl.put(key, value);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
|
@ -586,6 +586,8 @@ async function _outerAjax(url: string | null, options: PromiseAjaxOptionsType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `Error`, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Error {
|
interface Error {
|
||||||
code?: number | string;
|
code?: number | string;
|
||||||
response?: any;
|
response?: any;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
|
@ -20,7 +20,7 @@ const MIN_HEIGHT = 50;
|
||||||
|
|
||||||
// Used for display
|
// Used for display
|
||||||
|
|
||||||
export interface AttachmentType {
|
export type AttachmentType = {
|
||||||
blurHash?: string;
|
blurHash?: string;
|
||||||
caption?: string;
|
caption?: string;
|
||||||
contentType: MIME.MIMEType;
|
contentType: MIME.MIMEType;
|
||||||
|
@ -47,7 +47,7 @@ export interface AttachmentType {
|
||||||
url: string;
|
url: string;
|
||||||
contentType: MIME.MIMEType;
|
contentType: MIME.MIMEType;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
// UI-focused functions
|
// UI-focused functions
|
||||||
|
|
||||||
|
@ -288,9 +288,9 @@ export type Attachment = {
|
||||||
// digest?: ArrayBuffer;
|
// digest?: ArrayBuffer;
|
||||||
} & Partial<AttachmentSchemaVersion3>;
|
} & Partial<AttachmentSchemaVersion3>;
|
||||||
|
|
||||||
interface AttachmentSchemaVersion3 {
|
type AttachmentSchemaVersion3 = {
|
||||||
path: string;
|
path: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isVisualMedia = (attachment: Attachment): boolean => {
|
export const isVisualMedia = (attachment: Attachment): boolean => {
|
||||||
const { contentType } = attachment;
|
const { contentType } = attachment;
|
||||||
|
|
|
@ -10,7 +10,7 @@ export enum CallMode {
|
||||||
Group = 'Group',
|
Group = 'Group',
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActiveCallBaseType {
|
type ActiveCallBaseType = {
|
||||||
conversation: ConversationType;
|
conversation: ConversationType;
|
||||||
hasLocalAudio: boolean;
|
hasLocalAudio: boolean;
|
||||||
hasLocalVideo: boolean;
|
hasLocalVideo: boolean;
|
||||||
|
@ -20,9 +20,9 @@ interface ActiveCallBaseType {
|
||||||
settingsDialogOpen: boolean;
|
settingsDialogOpen: boolean;
|
||||||
showParticipantsList: boolean;
|
showParticipantsList: boolean;
|
||||||
showSafetyNumberDialog?: boolean;
|
showSafetyNumberDialog?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface ActiveDirectCallType extends ActiveCallBaseType {
|
type ActiveDirectCallType = ActiveCallBaseType & {
|
||||||
callMode: CallMode.Direct;
|
callMode: CallMode.Direct;
|
||||||
callState?: CallState;
|
callState?: CallState;
|
||||||
callEndedReason?: CallEndedReason;
|
callEndedReason?: CallEndedReason;
|
||||||
|
@ -32,9 +32,9 @@ interface ActiveDirectCallType extends ActiveCallBaseType {
|
||||||
hasRemoteVideo: boolean;
|
hasRemoteVideo: boolean;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
|
|
||||||
interface ActiveGroupCallType extends ActiveCallBaseType {
|
type ActiveGroupCallType = ActiveCallBaseType & {
|
||||||
callMode: CallMode.Group;
|
callMode: CallMode.Group;
|
||||||
connectionState: GroupCallConnectionState;
|
connectionState: GroupCallConnectionState;
|
||||||
conversationsWithSafetyNumberChanges: Array<ConversationType>;
|
conversationsWithSafetyNumberChanges: Array<ConversationType>;
|
||||||
|
@ -43,7 +43,7 @@ interface ActiveGroupCallType extends ActiveCallBaseType {
|
||||||
deviceCount: number;
|
deviceCount: number;
|
||||||
peekedParticipants: Array<ConversationType>;
|
peekedParticipants: Array<ConversationType>;
|
||||||
remoteParticipants: Array<GroupCallRemoteParticipantType>;
|
remoteParticipants: Array<GroupCallRemoteParticipantType>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ActiveCallType = ActiveDirectCallType | ActiveGroupCallType;
|
export type ActiveCallType = ActiveDirectCallType | ActiveGroupCallType;
|
||||||
|
|
||||||
|
@ -96,28 +96,28 @@ export enum GroupCallJoinState {
|
||||||
Joined = 2,
|
Joined = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupCallRemoteParticipantType extends ConversationType {
|
export type GroupCallRemoteParticipantType = ConversationType & {
|
||||||
demuxId: number;
|
demuxId: number;
|
||||||
hasRemoteAudio: boolean;
|
hasRemoteAudio: boolean;
|
||||||
hasRemoteVideo: boolean;
|
hasRemoteVideo: boolean;
|
||||||
speakerTime?: number;
|
speakerTime?: number;
|
||||||
videoAspectRatio: number;
|
videoAspectRatio: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Similar to RingRTC's `VideoRequest` but without the `framerate` property.
|
// Similar to RingRTC's `VideoRequest` but without the `framerate` property.
|
||||||
export interface GroupCallVideoRequest {
|
export type GroupCallVideoRequest = {
|
||||||
demuxId: number;
|
demuxId: number;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Should match RingRTC's VideoFrameSource
|
// Should match RingRTC's VideoFrameSource
|
||||||
export interface VideoFrameSource {
|
export type VideoFrameSource = {
|
||||||
receiveVideoFrame(buffer: ArrayBuffer): [number, number] | undefined;
|
receiveVideoFrame(buffer: ArrayBuffer): [number, number] | undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Must be kept in sync with RingRTC.AudioDevice
|
// Must be kept in sync with RingRTC.AudioDevice
|
||||||
export interface AudioDevice {
|
export type AudioDevice = {
|
||||||
// Device name.
|
// Device name.
|
||||||
name: string;
|
name: string;
|
||||||
// Index of this device, starting from 0.
|
// Index of this device, starting from 0.
|
||||||
|
@ -126,7 +126,7 @@ export interface AudioDevice {
|
||||||
uniqueId: string;
|
uniqueId: string;
|
||||||
// If present, the identifier of a localized string to substitute for the device name.
|
// If present, the identifier of a localized string to substitute for the device name.
|
||||||
i18nKey?: string;
|
i18nKey?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export enum CallingDeviceType {
|
export enum CallingDeviceType {
|
||||||
CAMERA,
|
CAMERA,
|
||||||
|
@ -143,21 +143,21 @@ export type MediaDeviceSettings = {
|
||||||
selectedCamera: string | undefined;
|
selectedCamera: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface DirectCallHistoryDetailsType {
|
type DirectCallHistoryDetailsType = {
|
||||||
callMode: CallMode.Direct;
|
callMode: CallMode.Direct;
|
||||||
wasIncoming: boolean;
|
wasIncoming: boolean;
|
||||||
wasVideoCall: boolean;
|
wasVideoCall: boolean;
|
||||||
wasDeclined: boolean;
|
wasDeclined: boolean;
|
||||||
acceptedTime?: number;
|
acceptedTime?: number;
|
||||||
endedTime: number;
|
endedTime: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface GroupCallHistoryDetailsType {
|
type GroupCallHistoryDetailsType = {
|
||||||
callMode: CallMode.Group;
|
callMode: CallMode.Group;
|
||||||
creatorUuid: string;
|
creatorUuid: string;
|
||||||
eraId: string;
|
eraId: string;
|
||||||
startedTime: number;
|
startedTime: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type CallHistoryDetailsType =
|
export type CallHistoryDetailsType =
|
||||||
| DirectCallHistoryDetailsType
|
| DirectCallHistoryDetailsType
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { format as formatPhoneNumber } from './PhoneNumber';
|
import { format as formatPhoneNumber } from './PhoneNumber';
|
||||||
|
|
||||||
export interface ContactType {
|
export type ContactType = {
|
||||||
name?: Name;
|
name?: Name;
|
||||||
number?: Array<Phone>;
|
number?: Array<Phone>;
|
||||||
email?: Array<Email>;
|
email?: Array<Email>;
|
||||||
|
@ -11,16 +11,16 @@ export interface ContactType {
|
||||||
avatar?: Avatar;
|
avatar?: Avatar;
|
||||||
organization?: string;
|
organization?: string;
|
||||||
signalAccount?: string;
|
signalAccount?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Name {
|
type Name = {
|
||||||
givenName?: string;
|
givenName?: string;
|
||||||
familyName?: string;
|
familyName?: string;
|
||||||
prefix?: string;
|
prefix?: string;
|
||||||
suffix?: string;
|
suffix?: string;
|
||||||
middleName?: string;
|
middleName?: string;
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export enum ContactFormType {
|
export enum ContactFormType {
|
||||||
HOME = 1,
|
HOME = 1,
|
||||||
|
@ -35,19 +35,19 @@ export enum AddressType {
|
||||||
CUSTOM = 3,
|
CUSTOM = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Phone {
|
export type Phone = {
|
||||||
value: string;
|
value: string;
|
||||||
type: ContactFormType;
|
type: ContactFormType;
|
||||||
label?: string;
|
label?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface Email {
|
export type Email = {
|
||||||
value: string;
|
value: string;
|
||||||
type: ContactFormType;
|
type: ContactFormType;
|
||||||
label?: string;
|
label?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface PostalAddress {
|
export type PostalAddress = {
|
||||||
type: AddressType;
|
type: AddressType;
|
||||||
label?: string;
|
label?: string;
|
||||||
street?: string;
|
street?: string;
|
||||||
|
@ -57,18 +57,18 @@ export interface PostalAddress {
|
||||||
region?: string;
|
region?: string;
|
||||||
postcode?: string;
|
postcode?: string;
|
||||||
country?: string;
|
country?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Avatar {
|
type Avatar = {
|
||||||
avatar: Attachment;
|
avatar: Attachment;
|
||||||
isProfile: boolean;
|
isProfile: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Attachment {
|
type Attachment = {
|
||||||
path?: string;
|
path?: string;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
pending?: boolean;
|
pending?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function contactSelector(
|
export function contactSelector(
|
||||||
contact: ContactType,
|
contact: ContactType,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
export interface BodyRangeType {
|
export type BodyRangeType = {
|
||||||
start: number;
|
start: number;
|
||||||
length: number;
|
length: number;
|
||||||
mentionUuid: string;
|
mentionUuid: string;
|
||||||
replacementText: string;
|
replacementText: string;
|
||||||
conversationID?: string;
|
conversationID?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type BodyRangesType = Array<BodyRangeType>;
|
export type BodyRangesType = Array<BodyRangeType>;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { AttachmentType } from '../Attachment';
|
import { AttachmentType } from '../Attachment';
|
||||||
|
|
||||||
export interface LinkPreviewType {
|
export type LinkPreviewType = {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
domain: string;
|
domain: string;
|
||||||
|
@ -11,4 +11,4 @@ export interface LinkPreviewType {
|
||||||
isStickerPack: boolean;
|
isStickerPack: boolean;
|
||||||
image?: AttachmentType;
|
image?: AttachmentType;
|
||||||
date?: number;
|
date?: number;
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
// Copyright 2018-2020 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as MIME from '../types/MIME';
|
import * as MIME from '../types/MIME';
|
||||||
|
|
||||||
interface MIMETypeSupportMap {
|
type MIMETypeSupportMap = Record<string, boolean>;
|
||||||
[key: string]: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See: https://en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support
|
// See: https://en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support
|
||||||
const SUPPORTED_IMAGE_MIME_TYPES: MIMETypeSupportMap = {
|
const SUPPORTED_IMAGE_MIME_TYPES: MIMETypeSupportMap = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2020 Signal Messenger, LLC
|
// Copyright 2019-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
|
@ -6,6 +6,8 @@ import PQueue from 'p-queue';
|
||||||
import { sleep } from './sleep';
|
import { sleep } from './sleep';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
// We want to extend `window`'s properties, so we need an interface.
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
interface Window {
|
interface Window {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
batchers: Array<BatcherType<any>>;
|
batchers: Array<BatcherType<any>>;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { CallMode } from '../types/Calling';
|
import { CallMode } from '../types/Calling';
|
||||||
import { missingCaseError } from './missingCaseError';
|
import { missingCaseError } from './missingCaseError';
|
||||||
|
|
||||||
interface DirectCallNotificationType {
|
type DirectCallNotificationType = {
|
||||||
callMode: CallMode.Direct;
|
callMode: CallMode.Direct;
|
||||||
wasIncoming: boolean;
|
wasIncoming: boolean;
|
||||||
wasVideoCall: boolean;
|
wasVideoCall: boolean;
|
||||||
wasDeclined: boolean;
|
wasDeclined: boolean;
|
||||||
acceptedTime?: number;
|
acceptedTime?: number;
|
||||||
endedTime: number;
|
endedTime: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface GroupCallNotificationType {
|
type GroupCallNotificationType = {
|
||||||
activeCallConversationId?: string;
|
activeCallConversationId?: string;
|
||||||
callMode: CallMode.Group;
|
callMode: CallMode.Group;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
@ -27,7 +27,7 @@ interface GroupCallNotificationType {
|
||||||
deviceCount: number;
|
deviceCount: number;
|
||||||
maxDevices: number;
|
maxDevices: number;
|
||||||
startedTime: number;
|
startedTime: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type CallingNotificationType =
|
export type CallingNotificationType =
|
||||||
| DirectCallNotificationType
|
| DirectCallNotificationType
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
||||||
|
@ -6,9 +6,9 @@ const ACTL_CHUNK_BYTES = new TextEncoder().encode('acTL');
|
||||||
const IDAT_CHUNK_BYTES = new TextEncoder().encode('IDAT');
|
const IDAT_CHUNK_BYTES = new TextEncoder().encode('IDAT');
|
||||||
const MAX_BYTES_TO_READ = 1024 * 1024;
|
const MAX_BYTES_TO_READ = 1024 * 1024;
|
||||||
|
|
||||||
interface AnimatedPngData {
|
type AnimatedPngData = {
|
||||||
numPlays: number;
|
numPlays: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a naïve implementation. It only performs two checks:
|
* This is a naïve implementation. It only performs two checks:
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue