Remove Sticker Creator in favor of Web App
This commit is contained in:
parent
78f0626e68
commit
f84b6a31dc
117 changed files with 67 additions and 5269 deletions
|
@ -1082,7 +1082,6 @@ export async function startApp(): Promise<void> {
|
|||
devTools: false,
|
||||
includeSetup: false,
|
||||
isProduction: true,
|
||||
isStaging: false,
|
||||
platform: 'unknown',
|
||||
};
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -126,7 +126,6 @@ export function getEmptyState(): UserStateType {
|
|||
devTools: false,
|
||||
includeSetup: false,
|
||||
isProduction: true,
|
||||
isStaging: false,
|
||||
platform: 'unknown',
|
||||
},
|
||||
osName,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
}>;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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/.+',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue