mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-05-08 08:58:38 +01:00
Convert signal.js and preload.js to Typescript
This commit is contained in:
@@ -83,6 +83,10 @@ export type AttachmentType = {
|
||||
key?: string;
|
||||
};
|
||||
|
||||
export type AttachmentWithHydratedData = AttachmentType & {
|
||||
data: Uint8Array;
|
||||
};
|
||||
|
||||
export enum TextAttachmentStyleType {
|
||||
DEFAULT = 0,
|
||||
REGULAR = 1,
|
||||
@@ -379,19 +383,21 @@ export function hasData(attachment: AttachmentType): boolean {
|
||||
|
||||
export function loadData(
|
||||
readAttachmentData: (path: string) => Promise<Uint8Array>
|
||||
): (attachment?: AttachmentType) => Promise<AttachmentType> {
|
||||
): (attachment: AttachmentType) => Promise<AttachmentWithHydratedData> {
|
||||
if (!is.function_(readAttachmentData)) {
|
||||
throw new TypeError("'readAttachmentData' must be a function");
|
||||
}
|
||||
|
||||
return async (attachment?: AttachmentType): Promise<AttachmentType> => {
|
||||
return async (
|
||||
attachment: AttachmentType
|
||||
): Promise<AttachmentWithHydratedData> => {
|
||||
if (!isValid(attachment)) {
|
||||
throw new TypeError("'attachment' is not valid");
|
||||
}
|
||||
|
||||
const isAlreadyLoaded = Boolean(attachment.data);
|
||||
if (isAlreadyLoaded) {
|
||||
return attachment;
|
||||
return attachment as AttachmentWithHydratedData;
|
||||
}
|
||||
|
||||
if (!is.string(attachment.path)) {
|
||||
|
||||
+41
-22
@@ -4,7 +4,7 @@
|
||||
import { isFunction, isObject, isString, omit } from 'lodash';
|
||||
|
||||
import * as Contact from './EmbeddedContact';
|
||||
import type { AttachmentType } from './Attachment';
|
||||
import type { AttachmentType, AttachmentWithHydratedData } from './Attachment';
|
||||
import {
|
||||
autoOrientJPEG,
|
||||
captureDimensionsAndScreenshot,
|
||||
@@ -24,11 +24,10 @@ import type { EmbeddedContactType } from './EmbeddedContact';
|
||||
|
||||
import type {
|
||||
MessageAttributesType,
|
||||
PreviewMessageType,
|
||||
PreviewType,
|
||||
QuotedMessageType,
|
||||
StickerMessageType,
|
||||
} from '../model-types.d';
|
||||
import type { LinkPreviewType } from './message/LinkPreviews';
|
||||
import type { StickerType, StickerWithHydratedData } from './Stickers';
|
||||
|
||||
export { hasExpiration } from './Message';
|
||||
|
||||
@@ -45,7 +44,7 @@ export type ContextType = {
|
||||
width: number;
|
||||
height: number;
|
||||
}>;
|
||||
getRegionCode: () => string;
|
||||
getRegionCode: () => string | undefined;
|
||||
logger: LoggerType;
|
||||
makeImageThumbnail: (params: {
|
||||
size: number;
|
||||
@@ -65,12 +64,12 @@ export type ContextType = {
|
||||
maxVersion?: number;
|
||||
revokeObjectUrl: (objectUrl: string) => void;
|
||||
writeNewAttachmentData: (data: Uint8Array) => Promise<string>;
|
||||
writeNewStickerData: (sticker: StickerMessageType) => Promise<string>;
|
||||
writeNewStickerData: (data: Uint8Array) => Promise<string>;
|
||||
};
|
||||
|
||||
type WriteExistingAttachmentDataType = (
|
||||
attachment: Pick<AttachmentType, 'data' | 'path'>
|
||||
) => Promise<void>;
|
||||
) => Promise<string>;
|
||||
|
||||
export type ContextWithMessageType = ContextType & {
|
||||
message: MessageAttributesType;
|
||||
@@ -343,7 +342,7 @@ export const _mapPreviewAttachments =
|
||||
);
|
||||
}
|
||||
|
||||
const upgradeWithContext = async (preview: PreviewType) => {
|
||||
const upgradeWithContext = async (preview: LinkPreviewType) => {
|
||||
const { image } = preview;
|
||||
if (!image) {
|
||||
return preview;
|
||||
@@ -544,7 +543,17 @@ export const processNewAttachment = async (
|
||||
makeImageThumbnail,
|
||||
makeVideoScreenshot,
|
||||
logger,
|
||||
}: ContextType
|
||||
}: Pick<
|
||||
ContextType,
|
||||
| 'writeNewAttachmentData'
|
||||
| 'getAbsoluteAttachmentPath'
|
||||
| 'makeObjectUrl'
|
||||
| 'revokeObjectUrl'
|
||||
| 'getImageDimensions'
|
||||
| 'makeImageThumbnail'
|
||||
| 'makeVideoScreenshot'
|
||||
| 'logger'
|
||||
>
|
||||
): Promise<AttachmentType> => {
|
||||
if (!isFunction(writeNewAttachmentData)) {
|
||||
throw new TypeError('context.writeNewAttachmentData is required');
|
||||
@@ -595,13 +604,19 @@ export const processNewAttachment = async (
|
||||
};
|
||||
|
||||
export const processNewSticker = async (
|
||||
stickerData: StickerMessageType,
|
||||
stickerData: Uint8Array,
|
||||
{
|
||||
writeNewStickerData,
|
||||
getAbsoluteStickerPath,
|
||||
getImageDimensions,
|
||||
logger,
|
||||
}: ContextType
|
||||
}: Pick<
|
||||
ContextType,
|
||||
| 'writeNewStickerData'
|
||||
| 'getAbsoluteStickerPath'
|
||||
| 'getImageDimensions'
|
||||
| 'logger'
|
||||
>
|
||||
): Promise<{ path: string; width: number; height: number }> => {
|
||||
if (!isFunction(writeNewStickerData)) {
|
||||
throw new TypeError('context.writeNewStickerData is required');
|
||||
@@ -633,7 +648,7 @@ export const processNewSticker = async (
|
||||
|
||||
type LoadAttachmentType = (
|
||||
attachment: AttachmentType
|
||||
) => Promise<AttachmentType>;
|
||||
) => Promise<AttachmentWithHydratedData>;
|
||||
|
||||
export const createAttachmentLoader = (
|
||||
loadAttachmentData: LoadAttachmentType
|
||||
@@ -694,16 +709,16 @@ export const loadContactData = (
|
||||
loadAttachmentData: LoadAttachmentType
|
||||
): ((
|
||||
contact: Array<EmbeddedContactType> | undefined
|
||||
) => Promise<Array<EmbeddedContactType> | null>) => {
|
||||
) => Promise<Array<EmbeddedContactType> | undefined>) => {
|
||||
if (!isFunction(loadAttachmentData)) {
|
||||
throw new TypeError('loadContactData: loadAttachmentData is required');
|
||||
}
|
||||
|
||||
return async (
|
||||
contact: Array<EmbeddedContactType> | undefined
|
||||
): Promise<Array<EmbeddedContactType> | null> => {
|
||||
): Promise<Array<EmbeddedContactType> | undefined> => {
|
||||
if (!contact) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
@@ -736,12 +751,14 @@ export const loadContactData = (
|
||||
|
||||
export const loadPreviewData = (
|
||||
loadAttachmentData: LoadAttachmentType
|
||||
): ((preview: PreviewMessageType) => Promise<PreviewMessageType>) => {
|
||||
): ((
|
||||
preview: Array<LinkPreviewType> | undefined
|
||||
) => Promise<Array<LinkPreviewType>>) => {
|
||||
if (!isFunction(loadAttachmentData)) {
|
||||
throw new TypeError('loadPreviewData: loadAttachmentData is required');
|
||||
}
|
||||
|
||||
return async (preview: PreviewMessageType) => {
|
||||
return async (preview: Array<LinkPreviewType> | undefined) => {
|
||||
if (!preview || !preview.length) {
|
||||
return [];
|
||||
}
|
||||
@@ -763,14 +780,16 @@ export const loadPreviewData = (
|
||||
|
||||
export const loadStickerData = (
|
||||
loadAttachmentData: LoadAttachmentType
|
||||
): ((sticker: StickerMessageType) => Promise<StickerMessageType | null>) => {
|
||||
): ((
|
||||
sticker: StickerType | undefined
|
||||
) => Promise<StickerWithHydratedData | undefined>) => {
|
||||
if (!isFunction(loadAttachmentData)) {
|
||||
throw new TypeError('loadStickerData: loadAttachmentData is required');
|
||||
}
|
||||
|
||||
return async (sticker: StickerMessageType) => {
|
||||
return async (sticker: StickerType | undefined) => {
|
||||
if (!sticker || !sticker.data) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -966,8 +985,8 @@ export const createAttachmentDataWriter = ({
|
||||
};
|
||||
|
||||
const writePreviewImage = async (
|
||||
item: PreviewType
|
||||
): Promise<PreviewType> => {
|
||||
item: LinkPreviewType
|
||||
): Promise<LinkPreviewType> => {
|
||||
const { image } = item;
|
||||
if (!image) {
|
||||
return omit(item, ['image']);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import { themeSettingSchema } from './StorageUIKeys';
|
||||
import { environmentSchema } from '../environment';
|
||||
|
||||
const configRequiredStringSchema = z.string().nonempty();
|
||||
export type ConfigRequiredStringType = z.infer<
|
||||
typeof configRequiredStringSchema
|
||||
>;
|
||||
|
||||
const configOptionalStringSchema = configRequiredStringSchema.or(z.undefined());
|
||||
export type configOptionalStringType = z.infer<
|
||||
typeof configOptionalStringSchema
|
||||
>;
|
||||
|
||||
export const rendererConfigSchema = z.object({
|
||||
appInstance: configOptionalStringSchema,
|
||||
appStartInitialSpellcheckSetting: z.boolean(),
|
||||
buildCreation: z.number(),
|
||||
buildExpiration: z.number(),
|
||||
cdnUrl0: configRequiredStringSchema,
|
||||
cdnUrl2: configRequiredStringSchema,
|
||||
certificateAuthority: configRequiredStringSchema,
|
||||
contentProxyUrl: configRequiredStringSchema,
|
||||
crashDumpsPath: configRequiredStringSchema,
|
||||
directoryEnclaveId: configOptionalStringSchema,
|
||||
directoryTrustAnchor: configOptionalStringSchema,
|
||||
directoryUrl: configOptionalStringSchema,
|
||||
directoryV2CodeHashes: z.array(z.string().nonempty()).or(z.undefined()),
|
||||
directoryV2PublicKey: configOptionalStringSchema,
|
||||
directoryV2Url: configOptionalStringSchema,
|
||||
directoryVersion: z.number(),
|
||||
enableCI: z.boolean(),
|
||||
environment: environmentSchema,
|
||||
homePath: configRequiredStringSchema,
|
||||
hostname: configRequiredStringSchema,
|
||||
locale: configRequiredStringSchema,
|
||||
name: configRequiredStringSchema,
|
||||
nodeVersion: configRequiredStringSchema,
|
||||
proxyUrl: configOptionalStringSchema,
|
||||
reducedMotionSetting: z.boolean(),
|
||||
serverPublicParams: configRequiredStringSchema,
|
||||
serverTrustRoot: configRequiredStringSchema,
|
||||
serverUrl: configRequiredStringSchema,
|
||||
sfuUrl: configRequiredStringSchema,
|
||||
storageUrl: configRequiredStringSchema,
|
||||
theme: themeSettingSchema,
|
||||
updatesUrl: configRequiredStringSchema,
|
||||
userDataPath: configRequiredStringSchema,
|
||||
version: configRequiredStringSchema,
|
||||
|
||||
// Only used by main window
|
||||
isMainWindowFullScreen: z.boolean(),
|
||||
|
||||
// Only for tests
|
||||
argv: configOptionalStringSchema,
|
||||
|
||||
// Only for permission popup window
|
||||
forCalling: z.boolean(),
|
||||
forCamera: z.boolean(),
|
||||
});
|
||||
|
||||
export type RendererConfigType = z.infer<typeof rendererConfigSchema>;
|
||||
+38
-15
@@ -12,12 +12,12 @@ import { maybeParseUrl } from '../util/url';
|
||||
import * as Bytes from '../Bytes';
|
||||
import * as Errors from './errors';
|
||||
import { deriveStickerPackKey, decryptAttachment } from '../Crypto';
|
||||
import type { MIMEType } from './MIME';
|
||||
import { IMAGE_WEBP } from './MIME';
|
||||
import type { MIMEType } from './MIME';
|
||||
import { sniffImageMimeType } from '../util/sniffImageMimeType';
|
||||
import type { AttachmentType } from './Attachment';
|
||||
import type { AttachmentType, AttachmentWithHydratedData } from './Attachment';
|
||||
import type {
|
||||
StickerType,
|
||||
StickerType as StickerFromDBType,
|
||||
StickerPackType,
|
||||
StickerPackStatusType,
|
||||
} from '../sql/Interface';
|
||||
@@ -26,6 +26,20 @@ import { SignalService as Proto } from '../protobuf';
|
||||
import * as log from '../logging/log';
|
||||
import type { StickersStateType } from '../state/ducks/stickers';
|
||||
|
||||
export type StickerType = {
|
||||
packId: string;
|
||||
stickerId: number;
|
||||
packKey: string;
|
||||
emoji?: string;
|
||||
data?: AttachmentType;
|
||||
path?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
};
|
||||
export type StickerWithHydratedData = StickerType & {
|
||||
data: AttachmentWithHydratedData;
|
||||
};
|
||||
|
||||
export type RecentStickerType = Readonly<{
|
||||
stickerId: number;
|
||||
packId: string;
|
||||
@@ -300,11 +314,16 @@ async function downloadSticker(
|
||||
packKey: string,
|
||||
proto: Proto.StickerPack.ISticker,
|
||||
{ ephemeral }: { ephemeral?: boolean } = {}
|
||||
): Promise<Omit<StickerType, 'isCoverOnly'>> {
|
||||
): Promise<Omit<StickerFromDBType, 'isCoverOnly'>> {
|
||||
const { id, emoji } = proto;
|
||||
strictAssert(id !== undefined && id !== null, "Sticker id can't be null");
|
||||
|
||||
const ciphertext = await window.textsecure.messaging.getSticker(packId, id);
|
||||
const { messaging } = window.textsecure;
|
||||
if (!messaging) {
|
||||
throw new Error('messaging is not available!');
|
||||
}
|
||||
|
||||
const ciphertext = await messaging.getSticker(packId, id);
|
||||
const plaintext = decryptSticker(packKey, ciphertext);
|
||||
|
||||
const sticker = ephemeral
|
||||
@@ -401,9 +420,12 @@ export async function downloadEphemeralPack(
|
||||
};
|
||||
stickerPackAdded(placeholder);
|
||||
|
||||
const ciphertext = await window.textsecure.messaging.getStickerPackManifest(
|
||||
packId
|
||||
);
|
||||
const { messaging } = window.textsecure;
|
||||
if (!messaging) {
|
||||
throw new Error('messaging is not available!');
|
||||
}
|
||||
|
||||
const ciphertext = await messaging.getStickerPackManifest(packId);
|
||||
const plaintext = decryptSticker(packKey, ciphertext);
|
||||
const proto = Proto.StickerPack.decode(plaintext);
|
||||
const firstStickerProto = proto.stickers ? proto.stickers[0] : null;
|
||||
@@ -599,9 +621,12 @@ async function doDownloadStickerPack(
|
||||
};
|
||||
stickerPackAdded(placeholder);
|
||||
|
||||
const ciphertext = await window.textsecure.messaging.getStickerPackManifest(
|
||||
packId
|
||||
);
|
||||
const { messaging } = window.textsecure;
|
||||
if (!messaging) {
|
||||
throw new Error('messaging is not available!');
|
||||
}
|
||||
|
||||
const ciphertext = await messaging.getStickerPackManifest(packId);
|
||||
const plaintext = decryptSticker(packKey, ciphertext);
|
||||
const proto = Proto.StickerPack.decode(plaintext);
|
||||
const firstStickerProto = proto.stickers ? proto.stickers[0] : undefined;
|
||||
@@ -776,7 +801,7 @@ export function getStickerPackStatus(
|
||||
export function getSticker(
|
||||
packId: string,
|
||||
stickerId: number
|
||||
): StickerType | undefined {
|
||||
): StickerFromDBType | undefined {
|
||||
const pack = getStickerPack(packId);
|
||||
|
||||
if (!pack || !pack.stickers) {
|
||||
@@ -803,9 +828,7 @@ export async function copyStickerToAttachments(
|
||||
const { path, size } =
|
||||
await window.Signal.Migrations.copyIntoAttachmentsDirectory(absolutePath);
|
||||
|
||||
const { data } = await window.Signal.Migrations.loadAttachmentData({
|
||||
path,
|
||||
});
|
||||
const data = await window.Signal.Migrations.readAttachmentData(path);
|
||||
|
||||
let contentType: MIMEType;
|
||||
const sniffedMimeType = sniffImageMimeType(data);
|
||||
|
||||
Vendored
+3
-9
@@ -12,19 +12,15 @@ import type { PhoneNumberSharingMode } from '../util/phoneNumberSharingMode';
|
||||
import type { RetryItemType } from '../util/retryPlaceholders';
|
||||
import type { ConfigMapType as RemoteConfigType } from '../RemoteConfig';
|
||||
import type { SystemTraySetting } from './SystemTraySetting';
|
||||
import type {
|
||||
ExtendedStorageID,
|
||||
RemoteRecord,
|
||||
UnknownRecord,
|
||||
} from './StorageService';
|
||||
import type { ExtendedStorageID, UnknownRecord } from './StorageService';
|
||||
|
||||
import type { GroupCredentialType } from '../textsecure/WebAPI';
|
||||
import type {
|
||||
KeyPairType,
|
||||
SessionResetsType,
|
||||
StorageServiceCredentials,
|
||||
} from '../textsecure/Types.d';
|
||||
import { UUIDStringType } from './UUID';
|
||||
import type { ThemeSettingType } from './StorageUIKeys';
|
||||
|
||||
import { RegisteredChallengeType } from '../challenge';
|
||||
|
||||
export type SerializedCertificateType = {
|
||||
@@ -34,8 +30,6 @@ export type SerializedCertificateType = {
|
||||
|
||||
export type ZoomFactorType = 0.75 | 1 | 1.25 | 1.5 | 2 | number;
|
||||
|
||||
export type ThemeSettingType = 'system' | 'light' | 'dark';
|
||||
|
||||
export type NotificationSettingType = 'message' | 'name' | 'count' | 'off';
|
||||
|
||||
export type IdentityKeyMap = Record<
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { StorageAccessType } from './Storage.d';
|
||||
|
||||
export const themeSettingSchema = z.enum(['system', 'light', 'dark']);
|
||||
export type ThemeSettingType = z.infer<typeof themeSettingSchema>;
|
||||
|
||||
// Configuration keys that only affect UI
|
||||
export const STORAGE_UI_KEYS: ReadonlyArray<keyof StorageAccessType> = [
|
||||
'always-relay-calls',
|
||||
|
||||
+6
-4
@@ -23,12 +23,14 @@ export type RenderTextCallbackType = (options: {
|
||||
key: number;
|
||||
}) => JSX.Element | string;
|
||||
|
||||
export type ReplacementValuesType = {
|
||||
[key: string]: string | number | undefined;
|
||||
};
|
||||
export type ReplacementValuesType =
|
||||
| Array<string>
|
||||
| {
|
||||
[key: string]: string | number | undefined;
|
||||
};
|
||||
|
||||
export type LocalizerType = {
|
||||
(key: string, values?: Array<string> | ReplacementValuesType): string;
|
||||
(key: string, values?: ReplacementValuesType): string;
|
||||
getLocale(): string;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export type LinkPreviewType = {
|
||||
description?: string;
|
||||
domain: string;
|
||||
url: string;
|
||||
isStickerPack: boolean;
|
||||
isStickerPack?: boolean;
|
||||
image?: Readonly<AttachmentType>;
|
||||
date?: number;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user