Remove Sticker Creator in favor of Web App

This commit is contained in:
Fedor Indutny 2023-03-15 17:59:30 -07:00 committed by GitHub
parent 78f0626e68
commit f84b6a31dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
117 changed files with 67 additions and 5269 deletions

View file

@ -1082,7 +1082,6 @@ export async function startApp(): Promise<void> {
devTools: false,
includeSetup: false,
isProduction: true,
isStaging: false,
platform: 'unknown',
};

View file

@ -34,9 +34,6 @@ export type PropsType = Readonly<{
executeMenuRole: ExecuteMenuRoleType;
titleBarDoubleClick?: () => void;
children: ReactNode;
// Needs to be overridden in sticker-creator
iconSrc?: string;
}> &
(MenuPropsType | { hasMenu?: false });
@ -132,7 +129,6 @@ export function TitleBarContainer(props: PropsType): JSX.Element {
titleBarDoubleClick,
children,
hasMenu,
iconSrc = 'images/icon_32.png',
} = props;
const isWindowActive = useIsWindowActive();
@ -238,7 +234,6 @@ export function TitleBarContainer(props: PropsType): JSX.Element {
showDebugLog: () => executeMenuAction('showDebugLog'),
showKeyboardShortcuts: () => executeMenuAction('showKeyboardShortcuts'),
showSettings: () => executeMenuAction('showSettings'),
showStickerCreator: () => executeMenuAction('showStickerCreator'),
showWindow: () => executeMenuAction('showWindow'),
},
i18n
@ -261,7 +256,7 @@ export function TitleBarContainer(props: PropsType): JSX.Element {
<TitleBar
className="TitleBarContainer__title"
platform="win32"
iconSrc={iconSrc}
iconSrc="images/icon_32.png"
theme={titleBarTheme}
maximized={isMaximized}
menu={maybeMenu}

View file

@ -126,7 +126,6 @@ export function getEmptyState(): UserStateType {
devTools: false,
includeSetup: false,
isProduction: true,
isStaging: false,
platform: 'unknown',
},
osName,

View file

@ -23,7 +23,6 @@ const showAbout = stub();
const showDebugLog = stub();
const showKeyboardShortcuts = stub();
const showSettings = stub();
const showStickerCreator = stub();
const showWindow = stub();
const getExpectedEditMenu = (
@ -121,7 +120,7 @@ const EXPECTED_MACOS: MenuListType = [
{
label: '&File',
submenu: [
{ label: 'Create/upload sticker pack', click: showStickerCreator },
{ label: 'Create/upload sticker pack', click: openArtCreator },
{ type: 'separator' },
{ accelerator: 'CmdOrCtrl+W', label: 'Close Window', role: 'close' },
],
@ -146,7 +145,7 @@ const EXPECTED_WINDOWS: MenuListType = [
{
label: '&File',
submenu: [
{ label: 'Create/upload sticker pack', click: showStickerCreator },
{ label: 'Create/upload sticker pack', click: openArtCreator },
{
label: 'Preferences…',
accelerator: 'CommandOrControl+,',
@ -226,7 +225,6 @@ describe('createTemplate', () => {
showDebugLog,
showKeyboardShortcuts,
showSettings,
showStickerCreator,
showWindow,
};
@ -238,7 +236,6 @@ describe('createTemplate', () => {
devTools: true,
includeSetup: false,
isProduction: true,
isStaging: false,
platform,
...actions,
};
@ -253,7 +250,6 @@ describe('createTemplate', () => {
devTools: true,
includeSetup: true,
isProduction: true,
isStaging: false,
platform,
...actions,
};

View file

@ -1,60 +0,0 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as fs from 'fs';
import * as path from 'path';
import { assert } from 'chai';
import { getAnimatedPngDataIfExists } from '../../util/getAnimatedPngDataIfExists';
describe('getAnimatedPngDataIfExists', () => {
const fixture = (filename: string): Promise<Buffer> => {
const fixturePath = path.join(
__dirname,
'..',
'..',
'..',
'fixtures',
filename
);
return fs.promises.readFile(fixturePath);
};
it('returns null for empty buffers', () => {
assert.isNull(getAnimatedPngDataIfExists(Buffer.alloc(0)));
});
it('returns null for non-PNG files', async () => {
await Promise.all(
[
'kitten-1-64-64.jpg',
'512x515-thumbs-up-lincoln.webp',
'giphy-GVNvOUpeYmI7e.gif',
'pixabay-Soap-Bubble-7141.mp4',
'lorem-ipsum.txt',
].map(async filename => {
assert.isNull(getAnimatedPngDataIfExists(await fixture(filename)));
})
);
});
it('returns null for non-animated PNG files', async () => {
assert.isNull(
getAnimatedPngDataIfExists(await fixture('20x200-yellow.png'))
);
});
it('returns data for animated PNG files', async () => {
assert.deepEqual(
getAnimatedPngDataIfExists(
await fixture('Animated_PNG_example_bouncing_beach_ball.png')
),
{ numPlays: Infinity }
);
assert.deepEqual(
getAnimatedPngDataIfExists(await fixture('apng_with_2_plays.png')),
{ numPlays: 2 }
);
});
});

View file

@ -10,7 +10,6 @@ export type MenuOptionsType = Readonly<{
devTools: boolean;
includeSetup: boolean;
isProduction: boolean;
isStaging: boolean;
platform: string;
}>;
@ -28,7 +27,6 @@ export type MenuActionsType = Readonly<{
showDebugLog: () => unknown;
showKeyboardShortcuts: () => unknown;
showSettings: () => unknown;
showStickerCreator: () => unknown;
showWindow: () => unknown;
}>;

View file

@ -1,85 +0,0 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
const ACTL_CHUNK_BYTES = new TextEncoder().encode('acTL');
const IDAT_CHUNK_BYTES = new TextEncoder().encode('IDAT');
const MAX_BYTES_TO_READ = 1024 * 1024;
type AnimatedPngData = {
numPlays: number;
};
/**
* This is a naïve implementation. It only performs two checks:
*
* 1. Do the bytes start with the [PNG signature][0]?
* 2. If so, does it contain the [`acTL` chunk][1] before the [`IDAT` chunk][2], in the
* first megabyte?
*
* Though we _could_ only check for the presence of the `acTL` chunk anywhere, we make
* sure it's before the `IDAT` chunk and within the first megabyte. This adds a small
* amount of validity checking and helps us avoid problems with large PNGs.
*
* It doesn't make sure the PNG is valid. It doesn't verify [the CRC code][3] of each PNG
* chunk; it doesn't verify any of the chunk's data; it doesn't verify that the chunks are
* in the right order; etc.
*
* [0]: https://www.w3.org/TR/PNG/#5PNG-file-signature
* [1]: https://wiki.mozilla.org/APNG_Specification#.60acTL.60:_The_Animation_Control_Chunk
* [2]: https://www.w3.org/TR/PNG/#11IDAT
* [3]: https://www.w3.org/TR/PNG/#5Chunk-layout
*/
export function getAnimatedPngDataIfExists(
bytes: Uint8Array
): null | AnimatedPngData {
if (!hasPngSignature(bytes)) {
return null;
}
let numPlays: void | number;
const dataView = new DataView(
bytes.buffer,
bytes.byteOffset,
bytes.byteLength
);
let i = PNG_SIGNATURE.length;
while (i < bytes.byteLength && i <= MAX_BYTES_TO_READ) {
const chunkTypeBytes = bytes.slice(i + 4, i + 8);
if (areBytesEqual(chunkTypeBytes, ACTL_CHUNK_BYTES)) {
// 4 bytes for the length; 4 bytes for the type; 4 bytes for the number of frames.
numPlays = dataView.getUint32(i + 12);
if (numPlays === 0) {
numPlays = Infinity;
}
return { numPlays };
}
if (areBytesEqual(chunkTypeBytes, IDAT_CHUNK_BYTES)) {
return null;
}
// Jump over the length (4 bytes), the type (4 bytes), the data, and the CRC checksum
// (4 bytes).
i += 12 + dataView.getUint32(i);
}
return null;
}
function hasPngSignature(bytes: Uint8Array): boolean {
return areBytesEqual(bytes.slice(0, 8), PNG_SIGNATURE);
}
function areBytesEqual(a: Uint8Array, b: Uint8Array): boolean {
if (a.byteLength !== b.byteLength) {
return false;
}
for (let i = 0; i < a.byteLength; i += 1) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}

View file

@ -1783,20 +1783,6 @@
"updated": "2021-09-16T20:26:31.296Z",
"reasonDetail": "Dev-only dependency."
},
{
"rule": "React-useRef",
"path": "sticker-creator/components/StickerFrame.js",
"line": " const timerRef = React.useRef();",
"reasonCategory": "falseMatch",
"updated": "2022-06-14T01:19:45.446Z"
},
{
"rule": "React-useRef",
"path": "sticker-creator/components/StickerFrame.tsx",
"line": " const timerRef = React.useRef<number>();",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T16:57:33.618Z"
},
{
"rule": "React-useRef",
"path": "ts/calling/useGetCallingFrameBuffer.ts",

View file

@ -62,7 +62,6 @@ const excludedFilesRegexp = RegExp(
'^js/curve/',
'^js/util_worker.js',
'^libtextsecure/test/test.js',
'^sticker-creator/dist/bundle.js',
'^test/test.js',
'^ts/workers/heicConverter.bundle.js',
'^ts/sql/mainWorker.bundle.js',
@ -87,7 +86,6 @@ const excludedFilesRegexp = RegExp(
'^node_modules/react/.+',
'^node_modules/react-contextmenu/.+',
'^node_modules/react-dom/.+',
'^node_modules/react-dropzone/.+',
'^node_modules/react-hot-loader/.+',
'^node_modules/react-icon-base/.+',
'^node_modules/react-input-autosize/.+',
@ -97,7 +95,6 @@ const excludedFilesRegexp = RegExp(
'^node_modules/react-router/.+',
'^node_modules/react-router-dom/.+',
'^node_modules/react-select/.+',
'^node_modules/react-sortable-hoc/.+',
'^node_modules/react-transition-group/.+',
'^node_modules/react-virtualized/.+',
'^node_modules/reactcss/.+',
@ -176,7 +173,6 @@ const excludedFilesRegexp = RegExp(
'^node_modules/express/.+',
'^node_modules/fast-glob/.+',
'^node_modules/file-entry-cache/.+',
'^node_modules/file-loader/.+',
'^node_modules/file-system-cache/.+', // Currently only used in storybook
'^node_modules/finalhandler/.+',
'^node_modules/flat-cache/.+',