Initial move towards new ESLint config supporting TS
Co-authored-by: Sidney Keese <sidney@carbonfive.com>
This commit is contained in:
parent
c2aa8eb82b
commit
5b1536cc02
22 changed files with 3300 additions and 597 deletions
|
@ -27,3 +27,31 @@ test/blanket_mocha.js
|
||||||
# TypeScript generated files
|
# TypeScript generated files
|
||||||
ts/**/*.js
|
ts/**/*.js
|
||||||
|
|
||||||
|
**/*.d.ts
|
||||||
|
webpack.config.ts
|
||||||
|
|
||||||
|
# Temporarily ignored during TSLint transition
|
||||||
|
# JIRA: DESKTOP-304
|
||||||
|
ts/*.ts
|
||||||
|
ts/backbone/**
|
||||||
|
ts/build/**
|
||||||
|
ts/components/*.ts
|
||||||
|
ts/components/*.tsx
|
||||||
|
ts/components/conversation/**
|
||||||
|
ts/components/stickers/**
|
||||||
|
ts/notifications/**
|
||||||
|
ts/protobuf/**
|
||||||
|
ts/scripts/**
|
||||||
|
ts/services/**
|
||||||
|
ts/shims/**
|
||||||
|
ts/sql/**
|
||||||
|
ts/state/**
|
||||||
|
ts/storybook/**
|
||||||
|
ts/styleguide/**
|
||||||
|
ts/test/**
|
||||||
|
ts/textsecure/**
|
||||||
|
ts/types/**
|
||||||
|
ts/updater/**
|
||||||
|
ts/util/**
|
||||||
|
sticker-creator/**/*.ts
|
||||||
|
sticker-creator/**/*.tsx
|
||||||
|
|
47
.eslintrc.js
47
.eslintrc.js
|
@ -1,7 +1,11 @@
|
||||||
// For reference: https://github.com/airbnb/javascript
|
// For reference: https://github.com/airbnb/javascript
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
root: true,
|
||||||
settings: {
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
'import/core-modules': ['electron'],
|
'import/core-modules': ['electron'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -9,6 +13,35 @@ module.exports = {
|
||||||
|
|
||||||
plugins: ['mocha', 'more'],
|
plugins: ['mocha', 'more'],
|
||||||
|
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['*.ts', '*.tsx'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
project: 'tsconfig.json',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
ecmaVersion: 2018,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint'],
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'airbnb-typescript-prettier',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.stories.tsx'],
|
||||||
|
rules: {
|
||||||
|
'import/no-extraneous-dependencies': 'off',
|
||||||
|
'react/jsx-props-no-spreading': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
'comma-dangle': [
|
'comma-dangle': [
|
||||||
'error',
|
'error',
|
||||||
|
@ -37,7 +70,19 @@ module.exports = {
|
||||||
'no-console': 'error',
|
'no-console': 'error',
|
||||||
|
|
||||||
// consistently place operators at end of line except ternaries
|
// consistently place operators at end of line except ternaries
|
||||||
'operator-linebreak': 'error',
|
'operator-linebreak': [
|
||||||
|
'error',
|
||||||
|
'after',
|
||||||
|
{ overrides: { '?': 'ignore', ':': 'ignore' } },
|
||||||
|
],
|
||||||
|
|
||||||
|
// Temporarily turned off during transition from TSLint
|
||||||
|
// JIRA: DESKTOP-623
|
||||||
|
'import/order': 'off',
|
||||||
|
'no-else-return': 'off',
|
||||||
|
'no-async-promise-executor': 'off',
|
||||||
|
'prefer-object-spread': 'off',
|
||||||
|
strict: 'off',
|
||||||
|
|
||||||
quotes: [
|
quotes: [
|
||||||
'error',
|
'error',
|
||||||
|
|
|
@ -1910,6 +1910,42 @@
|
||||||
},
|
},
|
||||||
"description": "Shown as a tooltip over the emoji tone buttons."
|
"description": "Shown as a tooltip over the emoji tone buttons."
|
||||||
},
|
},
|
||||||
|
"EmojiPicker__button--recents": {
|
||||||
|
"message": "Recents",
|
||||||
|
"description": "Label for recents emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--emoji": {
|
||||||
|
"message": "Emoji",
|
||||||
|
"description": "Label for emoji emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--animal": {
|
||||||
|
"message": "Animal",
|
||||||
|
"description": "Label for animal emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--food": {
|
||||||
|
"message": "Food",
|
||||||
|
"description": "Label for food emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--activity": {
|
||||||
|
"message": "Activity",
|
||||||
|
"description": "Label for activity emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--travel": {
|
||||||
|
"message": "Travel",
|
||||||
|
"description": "Label for travel emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--object": {
|
||||||
|
"message": "Object",
|
||||||
|
"description": "Label for object emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--symbol": {
|
||||||
|
"message": "Symbol",
|
||||||
|
"description": "Label for symbol emoji picker button"
|
||||||
|
},
|
||||||
|
"EmojiPicker__button--flag": {
|
||||||
|
"message": "Flag",
|
||||||
|
"description": "Label for flag emoji picker button"
|
||||||
|
},
|
||||||
"confirmation-dialog--Cancel": {
|
"confirmation-dialog--Cancel": {
|
||||||
"message": "Cancel",
|
"message": "Cancel",
|
||||||
"description": "Appears on the cancel button in confirmation dialogs."
|
"description": "Appears on the cancel button in confirmation dialogs."
|
||||||
|
@ -2783,5 +2819,9 @@
|
||||||
"example": "10/23/2023, 7:10 PM"
|
"example": "10/23/2023, 7:10 PM"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"EmojiButton__label": {
|
||||||
|
"message": "Emoji",
|
||||||
|
"description": "Label for emoji button"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* global exports, require */
|
|
||||||
/* eslint-disable strict */
|
/* eslint-disable strict */
|
||||||
|
|
||||||
const { Menu, clipboard } = require('electron');
|
const { Menu, clipboard } = require('electron');
|
||||||
|
|
6
js/modules/i18n.d.ts
vendored
Normal file
6
js/modules/i18n.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { LocalizerType } from '../../ts/types/Util';
|
||||||
|
|
||||||
|
export const setup: (
|
||||||
|
language: string,
|
||||||
|
messages: Record<string, unknown>
|
||||||
|
) => LocalizerType;
|
|
@ -239,7 +239,7 @@ function assembleChunks(chunkDescriptors) {
|
||||||
return concatenateBytes(...chunks);
|
return concatenateBytes(...chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ASCII_PATTERN = new RegExp('[\\u0000-\\u007F]', 'g');
|
const ASCII_PATTERN = new RegExp('[\\u0020-\\u007F]', 'g');
|
||||||
|
|
||||||
function isLinkSneaky(link) {
|
function isLinkSneaky(link) {
|
||||||
// Any links which contain auth are considered sneaky
|
// Any links which contain auth are considered sneaky
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
/* global drawAttention: false */
|
/* global drawAttention: false */
|
||||||
/* global i18n: false */
|
/* global i18n: false */
|
||||||
/* global Signal: false */
|
|
||||||
/* global storage: false */
|
/* global storage: false */
|
||||||
/* global Whisper: false */
|
/* global Whisper: false */
|
||||||
/* global _: false */
|
/* global _: false */
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
_,
|
_,
|
||||||
ConversationController,
|
ConversationController,
|
||||||
MessageController,
|
MessageController,
|
||||||
window
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* eslint-disable more/no-then */
|
/* eslint-disable more/no-then */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global mocha, chai, assert */
|
/* global chai */
|
||||||
|
|
||||||
mocha.setup('bdd');
|
mocha.setup('bdd');
|
||||||
window.assert = chai.assert;
|
window.assert = chai.assert;
|
||||||
|
|
17
package.json
17
package.json
|
@ -195,6 +195,8 @@
|
||||||
"@types/webpack": "4.39.0",
|
"@types/webpack": "4.39.0",
|
||||||
"@types/webpack-dev-server": "3.1.7",
|
"@types/webpack-dev-server": "3.1.7",
|
||||||
"@types/websocket": "1.0.0",
|
"@types/websocket": "1.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "3.10.1",
|
||||||
|
"@typescript-eslint/parser": "3.10.1",
|
||||||
"arraybuffer-loader": "1.0.3",
|
"arraybuffer-loader": "1.0.3",
|
||||||
"asar": "0.14.0",
|
"asar": "0.14.0",
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
|
@ -209,12 +211,13 @@
|
||||||
"electron-builder": "22.3.6",
|
"electron-builder": "22.3.6",
|
||||||
"electron-mocha": "8.1.1",
|
"electron-mocha": "8.1.1",
|
||||||
"electron-notarize": "0.1.1",
|
"electron-notarize": "0.1.1",
|
||||||
"eslint": "4.18.2",
|
"eslint": "7.7.0",
|
||||||
"eslint-config-airbnb-base": "12.1.0",
|
"eslint-config-airbnb-typescript-prettier": "3.1.0",
|
||||||
"eslint-config-prettier": "2.9.0",
|
"eslint-config-prettier": "6.11.0",
|
||||||
"eslint-plugin-import": "2.8.0",
|
"eslint-plugin-import": "2.22.0",
|
||||||
"eslint-plugin-mocha": "4.12.1",
|
"eslint-plugin-mocha": "8.0.0",
|
||||||
"eslint-plugin-more": "0.3.1",
|
"eslint-plugin-more": "1.0.0",
|
||||||
|
"eslint-plugin-react": "7.20.6",
|
||||||
"file-loader": "4.2.0",
|
"file-loader": "4.2.0",
|
||||||
"grunt": "1.0.1",
|
"grunt": "1.0.1",
|
||||||
"grunt-cli": "1.2.0",
|
"grunt-cli": "1.2.0",
|
||||||
|
@ -242,7 +245,7 @@
|
||||||
"style-loader": "1.0.0",
|
"style-loader": "1.0.0",
|
||||||
"ts-loader": "4.1.0",
|
"ts-loader": "4.1.0",
|
||||||
"ts-node": "8.3.0",
|
"ts-node": "8.3.0",
|
||||||
"tslint": "5.13.0",
|
"tslint": "6",
|
||||||
"tslint-microsoft-contrib": "6.2.0",
|
"tslint-microsoft-contrib": "6.2.0",
|
||||||
"tslint-react": "3.6.0",
|
"tslint-react": "3.6.0",
|
||||||
"typed-scss-modules": "0.0.11",
|
"typed-scss-modules": "0.0.11",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global Signal, Whisper, assert, textsecure, _, libsignal */
|
/* global Signal, Whisper, textsecure, _, libsignal */
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Emoji, EmojiSizes, Props } from './Emoji';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import { setup as setupI18n } from '../../js/modules/i18n';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import enMessages from '../../_locales/en/messages.json';
|
|
||||||
import { storiesOf } from '@storybook/react';
|
import { storiesOf } from '@storybook/react';
|
||||||
import { boolean, select, text } from '@storybook/addon-knobs';
|
import { boolean, select, text } from '@storybook/addon-knobs';
|
||||||
|
import { Emoji, EmojiSizes, Props } from './Emoji';
|
||||||
|
|
||||||
const story = storiesOf('Components/Emoji/Emoji', module);
|
const story = storiesOf('Components/Emoji/Emoji', module);
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,13 @@ export const Emoji = React.memo(
|
||||||
}: Props,
|
}: Props,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const image = shortName
|
let image = '';
|
||||||
? getImagePath(shortName, skinTone)
|
if (shortName) {
|
||||||
: emoji
|
image = getImagePath(shortName, skinTone);
|
||||||
? emojiToImage(emoji)
|
} else if (emoji) {
|
||||||
: '';
|
image = emojiToImage(emoji) || '';
|
||||||
|
}
|
||||||
|
|
||||||
const backgroundStyle = inline
|
const backgroundStyle = inline
|
||||||
? { backgroundImage: `url('${image}')` }
|
? { backgroundImage: `url('${image}')` }
|
||||||
: {};
|
: {};
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import { setup as setupI18n } from '../../../js/modules/i18n';
|
|
||||||
// @ts-ignore
|
|
||||||
import enMessages from '../../../_locales/en/messages.json';
|
|
||||||
|
|
||||||
import { storiesOf } from '@storybook/react';
|
import { storiesOf } from '@storybook/react';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
|
|
||||||
|
import { setup as setupI18n } from '../../../js/modules/i18n';
|
||||||
|
import enMessages from '../../../_locales/en/messages.json';
|
||||||
|
|
||||||
import { EmojiButton } from './EmojiButton';
|
import { EmojiButton } from './EmojiButton';
|
||||||
|
|
||||||
const i18n = setupI18n('en', enMessages);
|
const i18n = setupI18n('en', enMessages);
|
||||||
|
|
|
@ -105,12 +105,14 @@ export const EmojiButton = React.memo(
|
||||||
<Reference>
|
<Reference>
|
||||||
{({ ref }) => (
|
{({ ref }) => (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={handleClickButton}
|
onClick={handleClickButton}
|
||||||
className={classNames({
|
className={classNames({
|
||||||
'module-emoji-button__button': true,
|
'module-emoji-button__button': true,
|
||||||
'module-emoji-button__button--active': open,
|
'module-emoji-button__button--active': open,
|
||||||
})}
|
})}
|
||||||
|
aria-label={i18n('EmojiButton__label')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Reference>
|
</Reference>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import { setup as setupI18n } from '../../../js/modules/i18n';
|
|
||||||
// @ts-ignore
|
|
||||||
import enMessages from '../../../_locales/en/messages.json';
|
|
||||||
|
|
||||||
import { storiesOf } from '@storybook/react';
|
import { storiesOf } from '@storybook/react';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
|
|
||||||
|
import { setup as setupI18n } from '../../../js/modules/i18n';
|
||||||
|
import enMessages from '../../../_locales/en/messages.json';
|
||||||
|
|
||||||
import { EmojiPicker } from './EmojiPicker';
|
import { EmojiPicker } from './EmojiPicker';
|
||||||
|
|
||||||
const i18n = setupI18n('en', enMessages);
|
const i18n = setupI18n('en', enMessages);
|
||||||
|
|
|
@ -73,10 +73,7 @@ export const EmojiPicker = React.memo(
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const focusRef = React.useRef<HTMLButtonElement>(null);
|
const focusRef = React.useRef<HTMLButtonElement>(null);
|
||||||
// Per design: memoize the initial recent emojis so the grid only updates after re-opening the picker.
|
const [firstRecent] = React.useState(recentEmojis);
|
||||||
const firstRecent = React.useMemo(() => {
|
|
||||||
return recentEmojis;
|
|
||||||
}, []);
|
|
||||||
const [selectedCategory, setSelectedCategory] = React.useState(
|
const [selectedCategory, setSelectedCategory] = React.useState(
|
||||||
categories[0]
|
categories[0]
|
||||||
);
|
);
|
||||||
|
@ -208,7 +205,7 @@ export const EmojiPicker = React.memo(
|
||||||
);
|
);
|
||||||
|
|
||||||
return [...chunk(firstRecent, COL_COUNT), ...chunks];
|
return [...chunk(firstRecent, COL_COUNT), ...chunks];
|
||||||
}, [dataByCategory, categories, firstRecent, searchText]);
|
}, [firstRecent, renderableCategories, searchText]);
|
||||||
|
|
||||||
const catRowEnds = React.useMemo(() => {
|
const catRowEnds = React.useMemo(() => {
|
||||||
const rowEnds: Array<number> = [
|
const rowEnds: Array<number> = [
|
||||||
|
@ -223,13 +220,13 @@ export const EmojiPicker = React.memo(
|
||||||
});
|
});
|
||||||
|
|
||||||
return rowEnds;
|
return rowEnds;
|
||||||
}, [categories, dataByCategory]);
|
}, [firstRecent.length, renderableCategories]);
|
||||||
|
|
||||||
const catToRowOffsets = React.useMemo(() => {
|
const catToRowOffsets = React.useMemo(() => {
|
||||||
const offsets = initial(catRowEnds).map(i => i + 1);
|
const offsets = initial(catRowEnds).map(i => i + 1);
|
||||||
|
|
||||||
return zipObject(categories, [0, ...offsets]);
|
return zipObject(categories, [0, ...offsets]);
|
||||||
}, [categories, catRowEnds]);
|
}, [catRowEnds]);
|
||||||
|
|
||||||
const catOffsetEntries = React.useMemo(
|
const catOffsetEntries = React.useMemo(
|
||||||
() => Object.entries(catToRowOffsets),
|
() => Object.entries(catToRowOffsets),
|
||||||
|
@ -259,6 +256,7 @@ export const EmojiPicker = React.memo(
|
||||||
style={cellStyle}
|
style={cellStyle}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
className="module-emoji-picker__button"
|
className="module-emoji-picker__button"
|
||||||
onClick={handlePickEmoji}
|
onClick={handlePickEmoji}
|
||||||
onKeyDown={handlePickEmoji}
|
onKeyDown={handlePickEmoji}
|
||||||
|
@ -270,7 +268,7 @@ export const EmojiPicker = React.memo(
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
},
|
},
|
||||||
[emojiGrid, selectedTone]
|
[emojiGrid, handlePickEmoji, selectedTone]
|
||||||
);
|
);
|
||||||
|
|
||||||
const getRowHeight = React.useCallback(
|
const getRowHeight = React.useCallback(
|
||||||
|
@ -297,13 +295,14 @@ export const EmojiPicker = React.memo(
|
||||||
|
|
||||||
setSelectedCategory(cat);
|
setSelectedCategory(cat);
|
||||||
}, 10),
|
}, 10),
|
||||||
[catOffsetEntries, categories]
|
[catOffsetEntries]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="module-emoji-picker" ref={ref} style={style}>
|
<div className="module-emoji-picker" ref={ref} style={style}>
|
||||||
<header className="module-emoji-picker__header">
|
<header className="module-emoji-picker__header">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
ref={focusRef}
|
ref={focusRef}
|
||||||
onClick={handleToggleSearch}
|
onClick={handleToggleSearch}
|
||||||
title={i18n('EmojiPicker--search-placeholder')}
|
title={i18n('EmojiPicker--search-placeholder')}
|
||||||
|
@ -314,6 +313,7 @@ export const EmojiPicker = React.memo(
|
||||||
? 'module-emoji-picker__button--icon--close'
|
? 'module-emoji-picker__button--icon--close'
|
||||||
: 'module-emoji-picker__button--icon--search'
|
: 'module-emoji-picker__button--icon--search'
|
||||||
)}
|
)}
|
||||||
|
aria-label={i18n('EmojiPicker--search-placeholder')}
|
||||||
/>
|
/>
|
||||||
{searchMode ? (
|
{searchMode ? (
|
||||||
<div className="module-emoji-picker__header__search-field">
|
<div className="module-emoji-picker__header__search-field">
|
||||||
|
@ -328,6 +328,7 @@ export const EmojiPicker = React.memo(
|
||||||
categories.map(cat =>
|
categories.map(cat =>
|
||||||
cat === 'recents' && firstRecent.length === 0 ? null : (
|
cat === 'recents' && firstRecent.length === 0 ? null : (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
key={cat}
|
key={cat}
|
||||||
data-category={cat}
|
data-category={cat}
|
||||||
title={cat}
|
title={cat}
|
||||||
|
@ -340,6 +341,7 @@ export const EmojiPicker = React.memo(
|
||||||
? 'module-emoji-picker__button--selected'
|
? 'module-emoji-picker__button--selected'
|
||||||
: null
|
: null
|
||||||
)}
|
)}
|
||||||
|
aria-label={i18n(`EmojiPicker__button--${cat}`)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -377,7 +379,7 @@ export const EmojiPicker = React.memo(
|
||||||
<Emoji
|
<Emoji
|
||||||
shortName="slightly_frowning_face"
|
shortName="slightly_frowning_face"
|
||||||
size={16}
|
size={16}
|
||||||
inline={true}
|
inline
|
||||||
style={{ marginLeft: '4px' }}
|
style={{ marginLeft: '4px' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -386,6 +388,7 @@ export const EmojiPicker = React.memo(
|
||||||
<footer className="module-emoji-picker__footer">
|
<footer className="module-emoji-picker__footer">
|
||||||
{[0, 1, 2, 3, 4, 5].map(tone => (
|
{[0, 1, 2, 3, 4, 5].map(tone => (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
key={tone}
|
key={tone}
|
||||||
data-tone={tone}
|
data-tone={tone}
|
||||||
onClick={handlePickTone}
|
onClick={handlePickTone}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @ts-ignore: untyped json
|
// Camelcase disabled due to emoji-datasource using snake_case
|
||||||
|
/* eslint-disable camelcase */
|
||||||
import untypedData from 'emoji-datasource';
|
import untypedData from 'emoji-datasource';
|
||||||
import emojiRegex from 'emoji-regex';
|
import emojiRegex from 'emoji-regex';
|
||||||
import {
|
import {
|
||||||
|
@ -17,8 +18,6 @@ import Fuse from 'fuse.js';
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
|
|
||||||
export type ValuesOf<T extends Array<any>> = T[number];
|
|
||||||
|
|
||||||
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
||||||
|
|
||||||
export type SkinToneKey = '1F3FB' | '1F3FC' | '1F3FD' | '1F3FE' | '1F3FF';
|
export type SkinToneKey = '1F3FB' | '1F3FC' | '1F3FD' | '1F3FE' | '1F3FF';
|
||||||
|
@ -82,7 +81,6 @@ const data = (untypedData as Array<EmojiData>)
|
||||||
: emoji
|
: emoji
|
||||||
);
|
);
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const ROOT_PATH = get(
|
const ROOT_PATH = get(
|
||||||
// tslint:disable-next-line no-typeof-undefined
|
// tslint:disable-next-line no-typeof-undefined
|
||||||
typeof window !== 'undefined' ? window : null,
|
typeof window !== 'undefined' ? window : null,
|
||||||
|
@ -97,7 +95,7 @@ const makeImagePath = (src: string) => {
|
||||||
const imageQueue = new PQueue({ concurrency: 10 });
|
const imageQueue = new PQueue({ concurrency: 10 });
|
||||||
const images = new Set();
|
const images = new Set();
|
||||||
|
|
||||||
export const preloadImages = async () => {
|
export const preloadImages = async (): Promise<void> => {
|
||||||
// Preload images
|
// Preload images
|
||||||
const preload = async (src: string) =>
|
const preload = async (src: string) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
|
@ -110,7 +108,7 @@ export const preloadImages = async () => {
|
||||||
setTimeout(reject, 5000);
|
setTimeout(reject, 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
// tslint:disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('Preloading emoji images');
|
console.log('Preloading emoji images');
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
||||||
|
@ -129,7 +127,7 @@ export const preloadImages = async () => {
|
||||||
await imageQueue.onEmpty();
|
await imageQueue.onEmpty();
|
||||||
|
|
||||||
const end = Date.now();
|
const end = Date.now();
|
||||||
// tslint:disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Done preloading emoji images in ${end - start}ms`);
|
console.log(`Done preloading emoji images in ${end - start}ms`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -222,7 +220,7 @@ const fuse = new Fuse(data, {
|
||||||
keys: ['name', 'short_name', 'short_names'],
|
keys: ['name', 'short_name', 'short_names'],
|
||||||
});
|
});
|
||||||
|
|
||||||
export function search(query: string, count: number = 0) {
|
export function search(query: string, count = 0): Array<EmojiData> {
|
||||||
const results = fuse.search(query.substr(0, 32));
|
const results = fuse.search(query.substr(0, 32));
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
|
@ -237,11 +235,11 @@ const shortNames = new Set([
|
||||||
...compact<string>(flatMap(data, 'short_names')),
|
...compact<string>(flatMap(data, 'short_names')),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function isShortName(name: string) {
|
export function isShortName(name: string): boolean {
|
||||||
return shortNames.has(name);
|
return shortNames.has(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unifiedToEmoji(unified: string) {
|
export function unifiedToEmoji(unified: string): string {
|
||||||
return unified
|
return unified
|
||||||
.split('-')
|
.split('-')
|
||||||
.map(c => String.fromCodePoint(parseInt(c, 16)))
|
.map(c => String.fromCodePoint(parseInt(c, 16)))
|
||||||
|
@ -251,7 +249,7 @@ export function unifiedToEmoji(unified: string) {
|
||||||
export function convertShortName(
|
export function convertShortName(
|
||||||
shortName: string,
|
shortName: string,
|
||||||
skinTone: number | SkinToneKey = 0
|
skinTone: number | SkinToneKey = 0
|
||||||
) {
|
): string {
|
||||||
const base = dataByShortName[shortName];
|
const base = dataByShortName[shortName];
|
||||||
|
|
||||||
if (!base) {
|
if (!base) {
|
||||||
|
@ -300,15 +298,17 @@ export function getSizeClass(str: string): SizeClassType {
|
||||||
|
|
||||||
if (emojiCount > 8) {
|
if (emojiCount > 8) {
|
||||||
return '';
|
return '';
|
||||||
} else if (emojiCount > 6) {
|
|
||||||
return 'small';
|
|
||||||
} else if (emojiCount > 4) {
|
|
||||||
return 'medium';
|
|
||||||
} else if (emojiCount > 2) {
|
|
||||||
return 'large';
|
|
||||||
} else {
|
|
||||||
return 'jumbo';
|
|
||||||
}
|
}
|
||||||
|
if (emojiCount > 6) {
|
||||||
|
return 'small';
|
||||||
|
}
|
||||||
|
if (emojiCount > 4) {
|
||||||
|
return 'medium';
|
||||||
|
}
|
||||||
|
if (emojiCount > 2) {
|
||||||
|
return 'large';
|
||||||
|
}
|
||||||
|
return 'jumbo';
|
||||||
}
|
}
|
||||||
|
|
||||||
data.forEach(emoji => {
|
data.forEach(emoji => {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -61,7 +61,7 @@
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
"import-sources-order": "any",
|
"import-sources-order": "any",
|
||||||
"named-imports-order": "case-insensitive"
|
"named-imports-order": "case-insensitive-legacy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -174,5 +174,8 @@
|
||||||
// We use || and && shortcutting because we're javascript programmers
|
// We use || and && shortcutting because we're javascript programmers
|
||||||
"strict-boolean-expressions": false
|
"strict-boolean-expressions": false
|
||||||
},
|
},
|
||||||
"rulesDirectory": ["node_modules/tslint-microsoft-contrib"]
|
"rulesDirectory": ["node_modules/tslint-microsoft-contrib"],
|
||||||
|
"linterOptions": {
|
||||||
|
"exclude": ["ts/components/emoji/**/*.ts"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
import { resolve } from 'path';
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
import { Configuration, EnvironmentPlugin } from 'webpack';
|
import { Configuration, EnvironmentPlugin } from 'webpack';
|
||||||
// tslint:disable-next-line no-require-imports
|
// tslint:disable-next-line no-require-imports
|
||||||
import HtmlWebpackPlugin = require('html-webpack-plugin');
|
import HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
import { resolve } from 'path';
|
|
||||||
|
|
||||||
const context = __dirname;
|
const context = __dirname;
|
||||||
const { NODE_ENV: mode = 'development' } = process.env;
|
const { NODE_ENV: mode = 'development' } = process.env;
|
||||||
|
@ -77,7 +78,6 @@ const stickerCreatorConfig: Configuration = {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
// @ts-ignore: this typing broke at some point
|
|
||||||
devServer: {
|
devServer: {
|
||||||
port: 6380,
|
port: 6380,
|
||||||
historyApiFallback: {
|
historyApiFallback: {
|
||||||
|
|
Loading…
Reference in a new issue