From 9ac4fc36b6da4d69b8103037dcd934713d1b4245 Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Thu, 12 Feb 2026 22:23:43 -0300 Subject: [PATCH 01/13] chore(eslint): enable Prettier plugin and its recommended rules --- .eslintignore | 1 - .eslintrc.js | 12 ++++-- __mocks__/react-native-mmkv.js | 18 ++++----- .../helpers/getMentionRegexp.test.js | 2 +- .../UnreadBadge/getUnreadStyle.test.js | 2 +- app/sagas/createChannel.js | 2 +- app/sagas/createDiscussion.js | 2 +- app/sagas/deepLinking.js | 2 +- app/sagas/login.js | 10 ++--- app/sagas/rooms.js | 12 +++--- app/sagas/state.js | 2 +- package.json | 3 +- yarn.lock | 40 +++++++++++++++++-- 13 files changed, 72 insertions(+), 36 deletions(-) diff --git a/.eslintignore b/.eslintignore index edc3a77e7b9..ca60c6693b2 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,4 +4,3 @@ coverage e2e/docker android ios -.eslintrc.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index dba025b0233..bb03de15448 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -25,7 +25,13 @@ module.exports = { } }, parser: '@babel/eslint-parser', - extends: ['plugin:jest/recommended', '@rocket.chat/eslint-config', 'prettier', 'plugin:react-hooks/recommended'], + extends: [ + 'plugin:jest/recommended', + '@rocket.chat/eslint-config', + 'plugin:prettier/recommended', + 'prettier', + 'plugin:react-hooks/recommended' + ], parserOptions: { sourceType: 'module', ecmaVersion: 2017, @@ -155,8 +161,6 @@ module.exports = { 'valid-typeof': 2, 'linebreak-style': 0, 'prefer-template': 2, - quotes: [1, 'single'], - semi: [2, 'always'], 'prefer-const': 2, 'object-shorthand': 2, 'consistent-return': 0, @@ -166,7 +170,6 @@ module.exports = { 'require-await': 2, 'func-names': 0, 'react/static-property-placement': [0], - 'arrow-parens': ['warn', 'as-needed', { requireForBlockBody: true }], 'react/jsx-curly-newline': [0], 'react/state-in-constructor': [0], 'no-async-promise-executor': [0], @@ -186,6 +189,7 @@ module.exports = { 'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/eslint-recommended', '@rocket.chat/eslint-config', + 'plugin:prettier/recommended', 'prettier' ], parser: '@typescript-eslint/parser', diff --git a/__mocks__/react-native-mmkv.js b/__mocks__/react-native-mmkv.js index 3288748482c..44b12dcf0c9 100644 --- a/__mocks__/react-native-mmkv.js +++ b/__mocks__/react-native-mmkv.js @@ -84,7 +84,7 @@ export class MMKV { } notifyListeners(key) { - this.listeners.forEach((listener) => { + this.listeners.forEach(listener => { try { listener(key); } catch (error) { @@ -102,7 +102,7 @@ export function useMMKVString(key, mmkvInstance) { const [value, setValue] = useState(() => mmkvInstance.getString(key)); useEffect(() => { - const listener = mmkvInstance.addOnValueChangedListener((changedKey) => { + const listener = mmkvInstance.addOnValueChangedListener(changedKey => { if (changedKey === key || changedKey === undefined) { setValue(mmkvInstance.getString(key)); } @@ -110,7 +110,7 @@ export function useMMKVString(key, mmkvInstance) { return () => listener.remove(); }, [key, mmkvInstance]); - const setStoredValue = (newValue) => { + const setStoredValue = newValue => { if (newValue === undefined) { mmkvInstance.delete(key); } else { @@ -126,7 +126,7 @@ export function useMMKVNumber(key, mmkvInstance) { const [value, setValue] = useState(() => mmkvInstance.getNumber(key)); useEffect(() => { - const listener = mmkvInstance.addOnValueChangedListener((changedKey) => { + const listener = mmkvInstance.addOnValueChangedListener(changedKey => { if (changedKey === key || changedKey === undefined) { setValue(mmkvInstance.getNumber(key)); } @@ -134,7 +134,7 @@ export function useMMKVNumber(key, mmkvInstance) { return () => listener.remove(); }, [key, mmkvInstance]); - const setStoredValue = (newValue) => { + const setStoredValue = newValue => { if (newValue === undefined) { mmkvInstance.delete(key); } else { @@ -150,7 +150,7 @@ export function useMMKVBoolean(key, mmkvInstance) { const [value, setValue] = useState(() => mmkvInstance.getBoolean(key)); useEffect(() => { - const listener = mmkvInstance.addOnValueChangedListener((changedKey) => { + const listener = mmkvInstance.addOnValueChangedListener(changedKey => { if (changedKey === key || changedKey === undefined) { setValue(mmkvInstance.getBoolean(key)); } @@ -158,7 +158,7 @@ export function useMMKVBoolean(key, mmkvInstance) { return () => listener.remove(); }, [key, mmkvInstance]); - const setStoredValue = (newValue) => { + const setStoredValue = newValue => { if (newValue === undefined) { mmkvInstance.delete(key); } else { @@ -177,7 +177,7 @@ export function useMMKVObject(key, mmkvInstance) { }); useEffect(() => { - const listener = mmkvInstance.addOnValueChangedListener((changedKey) => { + const listener = mmkvInstance.addOnValueChangedListener(changedKey => { if (changedKey === key || changedKey === undefined) { const stored = mmkvInstance.getString(key); setValue(stored ? JSON.parse(stored) : undefined); @@ -186,7 +186,7 @@ export function useMMKVObject(key, mmkvInstance) { return () => listener.remove(); }, [key, mmkvInstance]); - const setStoredValue = (newValue) => { + const setStoredValue = newValue => { if (newValue === undefined) { mmkvInstance.delete(key); } else { diff --git a/app/containers/MessageComposer/helpers/getMentionRegexp.test.js b/app/containers/MessageComposer/helpers/getMentionRegexp.test.js index b04be1a6675..4faefe7d9ed 100644 --- a/app/containers/MessageComposer/helpers/getMentionRegexp.test.js +++ b/app/containers/MessageComposer/helpers/getMentionRegexp.test.js @@ -29,7 +29,7 @@ describe('getMentionRegexpUser', function () { }); test('removing query text on user suggestion autocomplete (special characters in query)', () => { - const message = 'Hey @\'=test123'; + const message = "Hey @'=test123"; expect(message.replace(regexp, '')).toBe('Hey @'); }); }); diff --git a/app/containers/UnreadBadge/getUnreadStyle.test.js b/app/containers/UnreadBadge/getUnreadStyle.test.js index 7e85c0e4ff6..4a99fd74986 100644 --- a/app/containers/UnreadBadge/getUnreadStyle.test.js +++ b/app/containers/UnreadBadge/getUnreadStyle.test.js @@ -2,7 +2,7 @@ import { themes } from '../../lib/constants/colors'; import { getUnreadStyle } from './getUnreadStyle'; -const testsForTheme = (theme) => { +const testsForTheme = theme => { const getUnreadStyleUtil = ({ ...props }) => getUnreadStyle({ theme, ...props }); test('render empty', () => { diff --git a/app/sagas/createChannel.js b/app/sagas/createChannel.js index caa54482011..2916653cfb4 100644 --- a/app/sagas/createChannel.js +++ b/app/sagas/createChannel.js @@ -61,7 +61,7 @@ const handleRequest = function* handleRequest({ data }) { const db = database.active; const subCollection = db.get('subscriptions'); yield db.write(async () => { - await subCollection.create((s) => { + await subCollection.create(s => { s._raw = sanitizedRaw({ id: sub.rid }, subCollection.schema); Object.assign(s, sub); }); diff --git a/app/sagas/createDiscussion.js b/app/sagas/createDiscussion.js index 0d43e8de4cb..526b3b29828 100644 --- a/app/sagas/createDiscussion.js +++ b/app/sagas/createDiscussion.js @@ -23,7 +23,7 @@ const handleRequest = function* handleRequest({ data }) { const db = database.active; const subCollection = db.get('subscriptions'); yield db.write(async () => { - await subCollection.create((s) => { + await subCollection.create(s => { s._raw = sanitizedRaw({ id: sub.rid }, subCollection.schema); Object.assign(s, sub); }); diff --git a/app/sagas/deepLinking.js b/app/sagas/deepLinking.js index 7afcadc7b92..d1d57dedf44 100644 --- a/app/sagas/deepLinking.js +++ b/app/sagas/deepLinking.js @@ -46,7 +46,7 @@ const waitForNavigation = () => { if (Navigation.navigationRef.current) { return Promise.resolve(); } - return new Promise((resolve) => { + return new Promise(resolve => { const listener = () => { emitter.off('navigationReady', listener); resolve(); diff --git a/app/sagas/login.js b/app/sagas/login.js index 16a4007402f..e88740ed6ff 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -58,7 +58,7 @@ const showSupportedVersionsWarning = function* showSupportedVersionsWarning(serv const serversDB = database.servers; yield serversDB.write(async () => { - await serverRecord.update((r) => { + await serverRecord.update(r => { r.supportedVersionsWarningAt = new Date(); }); }); @@ -105,7 +105,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnE } // this is updating on every login just to save `updated_at` // keeping this server as the most recent on autocomplete order - await serverHistoryRecord.update((s) => { + await serverHistoryRecord.update(s => { s.username = result.username; if (iconURL) { s.iconURL = iconURL; @@ -279,12 +279,12 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) { yield serversDB.write(async () => { try { const userRecord = await usersCollection.find(user.id); - await userRecord.update((record) => { + await userRecord.update(record => { record._raw = sanitizedRaw({ id: user.id, ...record._raw }, usersCollection.schema); Object.assign(record, u); }); } catch (e) { - await usersCollection.create((record) => { + await usersCollection.create(record => { record._raw = sanitizedRaw({ id: user.id }, usersCollection.schema); Object.assign(record, u); }); @@ -362,7 +362,7 @@ const handleSetUser = function* handleSetUser({ user }) { yield serversDB.write(async () => { try { const record = await userCollections.find(userId); - await record.update((userRecord) => { + await record.update(userRecord => { if ('avatarETag' in user) { userRecord.avatarETag = user.avatarETag; } diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index 39058a03228..174325121f7 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -18,7 +18,7 @@ const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) { const serverRecord = yield serversCollection.find(server); return serversDB.write(async () => { - await serverRecord.update((record) => { + await serverRecord.update(record => { record.roomsUpdatedAt = newRoomsUpdatedAt; }); }); @@ -75,12 +75,12 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) { const allRecords = [ ...subsToCreate.map(subscription => - subCollection.prepareCreate((s) => { + subCollection.prepareCreate(s => { s._raw = sanitizedRaw({ id: subscription.rid }, subCollection.schema); return Object.assign(s, subscription); }) ), - ...subsToUpdate.map((subscription) => { + ...subsToUpdate.map(subscription => { try { const newSub = subscriptions.find(s => s._id === subscription._id); if (!newSub) { @@ -99,7 +99,7 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) { return null; } }), - ...subsToDelete.map((subscription) => { + ...subsToDelete.map(subscription => { try { return subscription.prepareDestroyPermanently(); } catch (e) { @@ -108,13 +108,13 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) { } }), ...messagesToCreate.map(message => - messagesCollection.prepareCreate((m) => { + messagesCollection.prepareCreate(m => { m._raw = sanitizedRaw({ id: message._id }, messagesCollection.schema); m.subscription.id = message.rid; return Object.assign(m, message); }) ), - ...messagesToUpdate.map((message) => { + ...messagesToUpdate.map(message => { const newMessage = lastMessages.find(m => m._id === message.id); return message.prepareUpdate(() => { try { diff --git a/app/sagas/state.js b/app/sagas/state.js index 358549f2dd7..20272cfeb73 100644 --- a/app/sagas/state.js +++ b/app/sagas/state.js @@ -28,7 +28,7 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() { yield localAuthenticate(server); checkAndReopen(); // Check for pending notification when app comes to foreground (Android - notification tap while in background) - checkPendingNotification().catch((e) => { + checkPendingNotification().catch(e => { log('[state.js] Error checking pending notification:', e); }); return yield setUserPresenceOnline(); diff --git a/package.json b/package.json index c7553192103..412fe42ea4a 100644 --- a/package.json +++ b/package.json @@ -182,10 +182,11 @@ "babel-plugin-transform-remove-console": "^6.9.4", "babel-preset-expo": "~12.0.12", "eslint": "^8.57.0", - "eslint-config-prettier": "^9.1.0", + "eslint-config-prettier": "~10.1.8", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^27.9.0", "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-prettier": "~5.5.5", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^7.0.0", "eslint-plugin-react-native": "^4.1.0", diff --git a/yarn.lock b/yarn.lock index f802e7b09d0..ab05f4b451f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3882,6 +3882,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" + integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -7612,10 +7617,10 @@ eslint-config-prettier@^8.5.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-config-prettier@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== +eslint-config-prettier@~10.1.8: + version "10.1.8" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz#15734ce4af8c2778cc32f0b01b37b0b5cd1ecb97" + integrity sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w== eslint-import-context@^0.1.8: version "0.1.9" @@ -7722,6 +7727,14 @@ eslint-plugin-jsx-a11y@^6.8.0: object.entries "^1.1.7" object.fromentries "^2.0.7" +eslint-plugin-prettier@~5.5.5: + version "5.5.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz#9eae11593faa108859c26f9a9c367d619a0769c0" + integrity sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw== + dependencies: + prettier-linter-helpers "^1.0.1" + synckit "^0.11.12" + eslint-plugin-react-hooks@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" @@ -8183,6 +8196,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-fifo@^1.1.0, fast-fifo@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" @@ -11565,6 +11583,13 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier-linter-helpers@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz#6a31f88a4bad6c7adda253de12ba4edaea80ebcd" + integrity sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg== + dependencies: + fast-diff "^1.1.2" + prettier@2.8.8: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -13325,6 +13350,13 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synckit@^0.11.12: + version "0.11.12" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.12.tgz#abe74124264fbc00a48011b0d98bdc1cffb64a7b" + integrity sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ== + dependencies: + "@pkgr/core" "^0.2.9" + table-layout@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" From b654c8ca0f6ed511ee797d9bdb70921fcce29baf Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 17:03:38 -0300 Subject: [PATCH 02/13] chore(eslint): auto-detect React version --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index bb03de15448..9179d29966b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,6 +22,9 @@ module.exports = { // } // ] // } + }, + react: { + version: 'detect' } }, parser: '@babel/eslint-parser', From 79bf23fc602d3727667e5d104d251eccd00754b0 Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 17:34:37 -0300 Subject: [PATCH 03/13] chore(eslint): force right TypeScript parser --- .eslintrc.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9179d29966b..02d58f0838a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,4 @@ -module.exports = { +module.exports = /** @type {import('eslint').Linter.Config} */ { settings: { 'import/resolver': { node: { @@ -196,15 +196,6 @@ module.exports = { 'prettier' ], parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module', - ecmaVersion: 2018, - warnOnUnsupportedTypeScriptVersion: false, - ecmaFeatures: { - experimentalObjectRestSpread: true, - legacyDecorators: true - } - }, plugins: ['react', '@typescript-eslint'], rules: { '@typescript-eslint/no-var-requires': 'off', From 8772129e35e8cdd510f7577aabd690858144d26c Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 17:41:55 -0300 Subject: [PATCH 04/13] chore(eslint,typescript): reject unused parameters --- .eslintrc.js | 4 ++-- app/containers/AudioPlayer/Seek.tsx | 2 +- app/containers/List/ListRadio.tsx | 2 +- app/ee/omnichannel/lib/index.ts | 3 +-- app/ee/omnichannel/views/QueueListView.tsx | 2 +- app/lib/encryption/encryption.ts | 2 +- app/lib/encryption/helpers/base64-js/index.ts | 2 +- app/lib/encryption/room.ts | 2 +- app/lib/helpers/formatText.ts | 2 +- app/lib/hooks/useShortnameToUnicode/index.tsx | 2 +- app/lib/methods/search.ts | 2 +- app/views/SelectServerView.tsx | 2 +- tsconfig.json | 6 +++--- 13 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 02d58f0838a..0b033a81003 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -224,8 +224,8 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { '@typescript-eslint/no-unused-vars': [ 'error', { - argsIgnorePattern: '^_', - ignoreRestSiblings: true + args: 'all', + argsIgnorePattern: '^_' } ], '@typescript-eslint/consistent-type-imports': [ diff --git a/app/containers/AudioPlayer/Seek.tsx b/app/containers/AudioPlayer/Seek.tsx index eecd5d444e0..6b70602df0f 100644 --- a/app/containers/AudioPlayer/Seek.tsx +++ b/app/containers/AudioPlayer/Seek.tsx @@ -65,7 +65,7 @@ const Seek = ({ currentTime, duration, loaded = false, onChangeTime }: ISeek) => }; const onGestureEvent = useAnimatedGestureHandler({ - onStart: (event, ctx) => { + onStart: (_event, ctx) => { isPanning.value = true; ctx.offsetX = translateX.value; }, diff --git a/app/containers/List/ListRadio.tsx b/app/containers/List/ListRadio.tsx index 58e044bd378..5ddb959ae72 100644 --- a/app/containers/List/ListRadio.tsx +++ b/app/containers/List/ListRadio.tsx @@ -10,7 +10,7 @@ interface IListRadio extends IListItem { isSelected: boolean; } -const ListRadio = ({ value, isSelected, ...rest }: IListRadio) => { +const ListRadio = ({ value: _, isSelected, ...rest }: IListRadio) => { const { colors } = useTheme(); const iconName = isSelected ? 'radio-checked' : 'radio-unchecked'; diff --git a/app/ee/omnichannel/lib/index.ts b/app/ee/omnichannel/lib/index.ts index 3b81d091be4..b3cfc4a852b 100644 --- a/app/ee/omnichannel/lib/index.ts +++ b/app/ee/omnichannel/lib/index.ts @@ -53,5 +53,4 @@ class Omnichannel { }; } -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const omnichannel = new Omnichannel(); +new Omnichannel(); diff --git a/app/ee/omnichannel/views/QueueListView.tsx b/app/ee/omnichannel/views/QueueListView.tsx index ba2ed6aeb08..4da97ed00b8 100644 --- a/app/ee/omnichannel/views/QueueListView.tsx +++ b/app/ee/omnichannel/views/QueueListView.tsx @@ -67,7 +67,7 @@ const QueueListView = React.memo(() => { navigation.setOptions(options); }, [isMasterDetail, navigation]); - const getItemLayout = (data: ArrayLike | null | undefined, index: number) => { + const getItemLayout = (_data: ArrayLike | null | undefined, index: number) => { const rowHeight = 75 * fontScale; return { length: rowHeight, diff --git a/app/lib/encryption/encryption.ts b/app/lib/encryption/encryption.ts index 8a1e50c5762..eb09d56b68e 100644 --- a/app/lib/encryption/encryption.ts +++ b/app/lib/encryption/encryption.ts @@ -596,7 +596,7 @@ class Encryption { return roomE2E.encryptFile(rid, file); }; - decryptFile: TDecryptFile = async (messageId, path, encryption, originalChecksum) => { + decryptFile: TDecryptFile = async (_messageId, path, encryption, originalChecksum) => { const decryptedFile = await decryptAESCTR(path, encryption.key.k, encryption.iv); if (decryptedFile) { const checksum = await calculateFileChecksum(decryptedFile); diff --git a/app/lib/encryption/helpers/base64-js/index.ts b/app/lib/encryption/helpers/base64-js/index.ts index 7a77af0f268..343a8161150 100644 --- a/app/lib/encryption/helpers/base64-js/index.ts +++ b/app/lib/encryption/helpers/base64-js/index.ts @@ -44,7 +44,7 @@ export const byteLength = (b64: string): number => { return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen; }; -const _byteLength = (b64: string, validLen: number, placeHoldersLen: number) => +const _byteLength = (_b64: string, validLen: number, placeHoldersLen: number) => ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen; export const toByteArray = (b64: string): any[] | Uint8Array => { diff --git a/app/lib/encryption/room.ts b/app/lib/encryption/room.ts index 685ddb214eb..04058659758 100644 --- a/app/lib/encryption/room.ts +++ b/app/lib/encryption/room.ts @@ -500,7 +500,7 @@ export default class EncryptionRoom { return message; }; - encryptFile = async (rid: string, file: TSendFileMessageFileInfo): TEncryptFileResult => { + encryptFile = async (_rid: string, file: TSendFileMessageFileInfo): TEncryptFileResult => { const { path } = file; const vectorBuffer = b64ToBuffer(await randomBytes(16)); const keyBuffer = b64ToBuffer(await generateAESCTRKey()); diff --git a/app/lib/helpers/formatText.ts b/app/lib/helpers/formatText.ts index 2273134c85d..d1410002ab0 100644 --- a/app/lib/helpers/formatText.ts +++ b/app/lib/helpers/formatText.ts @@ -2,5 +2,5 @@ export const formatText = (text: string): string => text.replace( new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'), - (match, url, title) => `[${title}](${url})` + (_match, url, title) => `[${title}](${url})` ); diff --git a/app/lib/hooks/useShortnameToUnicode/index.tsx b/app/lib/hooks/useShortnameToUnicode/index.tsx index ebad540176d..c6118456c89 100644 --- a/app/lib/hooks/useShortnameToUnicode/index.tsx +++ b/app/lib/hooks/useShortnameToUnicode/index.tsx @@ -33,7 +33,7 @@ const useShortnameToUnicode = (isEmojiPicker?: boolean) => { const convertAsciiEmoji = useAppSelector(state => getUserSelector(state)?.settings?.preferences?.convertAsciiEmoji); const formatShortnameToUnicode = (str: string) => { str = str.replace(shortnamePattern, replaceShortNameWithUnicode); - str = str.replace(regAscii, (entire, m1, m2, m3) => { + str = str.replace(regAscii, (entire, _m1, m2, m3) => { if (!m3 || !(unescapeHTML(m3) in ascii)) { // if the ascii doesnt exist just return the entire match return entire; diff --git a/app/lib/methods/search.ts b/app/lib/methods/search.ts index d6f1df26750..0b04e886bab 100644 --- a/app/lib/methods/search.ts +++ b/app/lib/methods/search.ts @@ -138,7 +138,7 @@ export const search = async ({ text = '', filterUsers = true, filterRooms = true if (searchText && localSearchData.length < 7) { const { users, rooms } = (await Promise.race([ spotlight(searchText, usernames, { users: filterUsers, rooms: filterRooms, mentions: true }, rid), - new Promise((resolve, reject) => (debounce = reject)) + new Promise((_resolve, reject) => (debounce = reject)) ])) as { users: ISearch[]; rooms: ISearch[] }; if (filterUsers) { diff --git a/app/views/SelectServerView.tsx b/app/views/SelectServerView.tsx index 25cf0969f93..c77df86d021 100644 --- a/app/views/SelectServerView.tsx +++ b/app/views/SelectServerView.tsx @@ -15,7 +15,7 @@ import { type TServerModel } from '../definitions'; import { useAppSelector } from '../lib/hooks/useAppSelector'; import { selectServerRequest } from '../actions/server'; -const getItemLayout = (data: any, index: number) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index }); +const getItemLayout = (_data: any, index: number) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index }); const keyExtractor = (item: TServerModel) => item.id; const SelectServerView = () => { diff --git a/tsconfig.json b/tsconfig.json index edd328f5061..b8e5a9b4bdb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, + "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, // "lib": [], /* Specify library files to be included in the compilation. */ "allowJs": true /* Allow javascript files to be compiled. */, @@ -35,8 +35,8 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ From 1d0366c2fe8586dde9af58ff5177adee7aa41720 Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 18:29:10 -0300 Subject: [PATCH 05/13] test(eslint): fix some warnings --- app/lib/database/utils.test.ts | 28 +++++++---------------- app/lib/methods/serializeAsciiUrl.test.ts | 8 +++---- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/app/lib/database/utils.test.ts b/app/lib/database/utils.test.ts index 3c914112c13..93f215c77ef 100644 --- a/app/lib/database/utils.test.ts +++ b/app/lib/database/utils.test.ts @@ -3,8 +3,6 @@ import * as utils from './utils'; describe('sanitizeLikeStringTester', () => { // example chars that shouldn't return const disallowedChars = ',./;[]!@#$%^&*()_-=+~'; - const sanitizeLikeStringTester = (str: string) => - expect(utils.sanitizeLikeString(`${str}${disallowedChars}`)).toBe(`${str}${'_'.repeat(disallowedChars.length)}`); test('render empty', () => { expect(utils.sanitizeLikeString('')).toBe(''); @@ -12,24 +10,14 @@ describe('sanitizeLikeStringTester', () => { }); // Testing a couple of different alphabets - test('render test (latin)', () => { - sanitizeLikeStringTester('test123'); - }); - - test('render test (arabic)', () => { - sanitizeLikeStringTester('اختبار123'); - }); - - test('render test (russian)', () => { - sanitizeLikeStringTester('тест123'); - }); - - test('render test (chinese trad)', () => { - sanitizeLikeStringTester('測試123'); - }); - - test('render test (japanese)', () => { - sanitizeLikeStringTester('テスト123'); + test.each([ + ['latin', 'test123'], + ['arabic', 'اختبار123'], + ['russian', 'тест123'], + ['chineseTrad', '測試123'], + ['japanese', 'テスト123'] + ])('render test (%s)', (_, str) => { + expect(utils.sanitizeLikeString(`${str}${disallowedChars}`)).toBe(`${str}${'_'.repeat(disallowedChars.length)}`); }); }); diff --git a/app/lib/methods/serializeAsciiUrl.test.ts b/app/lib/methods/serializeAsciiUrl.test.ts index 0f58953c6cf..662a51c93cf 100644 --- a/app/lib/methods/serializeAsciiUrl.test.ts +++ b/app/lib/methods/serializeAsciiUrl.test.ts @@ -19,10 +19,10 @@ describe('Serialize ASCII url on ios', () => { describe('Serialize ASCII url on android', () => { jest.mock('react-native', () => ({ Platform: { OS: 'android' } })); // By default android converts ASCII addresses - // test('ASCII url', () => { - // const result = serializeAsciiUrl(ASCIIUrl); - // expect(result).toBe('filename.png'); - // }); + test('ASCII url', () => { + const result = serializeAsciiUrl(ASCIIUrl); + expect(result).toBe(ASCIIUrlSerialized); + }); test('Non ASCII url', () => { const result = serializeAsciiUrl(NonASCIIUrl); expect(result).toBe(NonASCIIUrl); From afb934717bc47a1d25b1ac1eb73fe124fdceae65 Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 20:16:17 -0300 Subject: [PATCH 06/13] chore(eslint): remove redundant rule configuration --- .eslintrc.js | 205 ++++-------------- .../RoomSettings/SwitchItemEncrypted.test.tsx | 8 +- scripts/build-icon-set.js | 2 +- 3 files changed, 47 insertions(+), 168 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0b033a81003..4c9d2b8a8c9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,4 @@ -module.exports = /** @type {import('eslint').Linter.Config} */ { +module.exports = { settings: { 'import/resolver': { node: { @@ -28,13 +28,7 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { } }, parser: '@babel/eslint-parser', - extends: [ - 'plugin:jest/recommended', - '@rocket.chat/eslint-config', - 'plugin:prettier/recommended', - 'prettier', - 'plugin:react-hooks/recommended' - ], + extends: ['@rocket.chat/eslint-config', 'plugin:react-hooks/recommended', 'plugin:prettier/recommended', 'prettier'], parserOptions: { sourceType: 'module', ecmaVersion: 2017, @@ -44,23 +38,15 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { legacyDecorators: true } }, - plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel', 'react-hooks', 'jest'], + plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel'], env: { - browser: true, - commonjs: true, es6: true, - node: true, - jquery: true, - mocha: true, - jest: true, - 'jest/globals': true + node: true }, rules: { - 'react-hooks/set-state-in-effect': 1, - 'react-hooks/immutability': 1, - 'react-hooks/refs': 1, - 'import/named': 'error', - 'import/no-unresolved': 'error', + 'react-hooks/set-state-in-effect': 'warn', + 'react-hooks/immutability': 'warn', + 'react-hooks/refs': 'warn', 'import/extensions': [ 'error', 'ignorePackages', @@ -71,119 +57,24 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { tsx: 'warning' } ], - 'react/jsx-filename-extension': [ - 1, - { - extensions: ['.js', '.jsx', '.ts', '.tsx'] - } - ], - 'react/require-default-props': [0], - 'ordered-imports': [0], - 'react/no-did-mount-set-state': 0, - 'react/no-multi-comp': [0], - 'react/jsx-indent-props': [2, 'tab'], - 'jsx-quotes': [2, 'prefer-single'], - 'jsx-a11y/href-no-hash': 0, - 'jsx-a11y/aria-role': 0, - 'import/prefer-default-export': 0, - 'import/no-cycle': 2, + 'import/named': 'error', + 'import/no-cycle': 'error', + 'import/no-unresolved': 'error', 'import/order': [ 'error', { 'newlines-between': 'ignore' } ], - camelcase: 0, - 'no-underscore-dangle': 0, - 'no-return-assign': 0, - 'no-param-reassign': 0, - 'no-tabs': 0, - 'no-multi-spaces': 2, - 'no-eval': 2, - 'no-extend-native': 2, - 'no-multi-str': 2, - 'no-use-before-define': 2, - 'no-const-assign': 2, - 'no-cond-assign': 2, - 'no-constant-condition': 2, - 'no-control-regex': 2, - 'no-debugger': 2, - 'no-delete-var': 2, - 'no-dupe-keys': 2, - 'no-dupe-args': 2, - 'no-dupe-class-members': 2, - 'no-duplicate-case': 2, - 'no-else-return': [0, { allowElseIf: true }], - 'no-empty': 2, - 'no-empty-character-class': 2, - 'no-ex-assign': 2, - 'no-extra-boolean-cast': 2, - 'no-extra-semi': 2, - 'no-fallthrough': 2, - 'no-func-assign': 2, - 'no-inner-declarations': [2, 'functions'], - 'no-invalid-regexp': 2, - 'no-irregular-whitespace': 2, - 'no-mixed-spaces-and-tabs': 1, - 'no-sparse-arrays': 2, - 'no-negated-in-lhs': 2, - 'no-obj-calls': 2, - 'no-octal': 2, - 'no-redeclare': 2, - 'no-regex-spaces': 2, - 'no-undef': 2, - 'no-unreachable': 2, - 'no-unused-expressions': 0, 'no-unused-vars': 'off', - 'max-len': 0, - 'react/jsx-uses-vars': 2, - 'no-void': 2, - 'no-var': 2, - 'one-var': [2, 'never'], - 'no-lonely-if': 2, - 'no-trailing-spaces': 2, - complexity: [1, 31], - 'space-in-parens': [2, 'never'], - 'space-before-blocks': [2, 'always'], - indent: 'off', - 'eol-last': [2, 'always'], - 'comma-dangle': [2, 'never'], - 'keyword-spacing': 2, - 'block-spacing': 2, - 'brace-style': [2, '1tbs', { allowSingleLine: true }], - 'computed-property-spacing': 2, - 'comma-spacing': 2, - 'comma-style': 2, - 'guard-for-in': 2, - 'wrap-iife': 2, - 'block-scoped-var': 2, - curly: [2, 'all'], - eqeqeq: [2, 'allow-null'], - 'new-cap': 'off', - 'use-isnan': 2, - 'valid-typeof': 2, - 'linebreak-style': 0, - 'prefer-template': 2, - 'prefer-const': 2, - 'object-shorthand': 2, - 'consistent-return': 0, - 'global-require': 'off', - 'react-native/no-unused-styles': 2, - 'react/jsx-one-expression-per-line': 0, - 'require-await': 2, - 'func-names': 0, - 'react/static-property-placement': [0], - 'react/jsx-curly-newline': [0], - 'react/state-in-constructor': [0], - 'no-async-promise-executor': [0], - 'max-classes-per-file': [0], - 'no-multiple-empty-lines': [0], - 'no-sequences': 'off', - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn' + 'react/jsx-uses-vars': 'error', + 'no-void': 'error', + 'new-cap': 'error', + 'react-native/no-unused-styles': 'error', + 'require-await': 'error' }, globals: { - __DEV__: true + __DEV__: 'readonly' }, overrides: [ { @@ -198,29 +89,21 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { parser: '@typescript-eslint/parser', plugins: ['react', '@typescript-eslint'], rules: { - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-empty-function': [0], - '@typescript-eslint/ban-types': [0], - 'func-call-spacing': 'off', - 'jsx-quotes': ['error', 'prefer-single'], - indent: 'off', - 'comma-dangle': [2, 'never'], - 'no-return-assign': 0, - 'no-dupe-class-members': 'off', - 'no-extra-parens': 'off', - 'no-spaced-func': 'off', - 'no-unused-vars': 'off', - 'no-useless-constructor': 'off', - 'no-use-before-define': 'off', - 'react/jsx-uses-react': 'error', - 'react/jsx-uses-vars': 'error', - 'react/jsx-no-undef': 'error', - 'react/jsx-fragments': ['error', 'syntax'], '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + disallowTypeAnnotations: true, + fixStyle: 'inline-type-imports' + } + ], '@typescript-eslint/indent': 'off', - '@typescript-eslint/no-extra-parens': 'off', '@typescript-eslint/no-dupe-class-members': 'error', + '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-extra-parens': 'off', '@typescript-eslint/no-unused-vars': [ 'error', { @@ -228,22 +111,23 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { argsIgnorePattern: '^_' } ], - '@typescript-eslint/consistent-type-imports': [ - 'error', - { - prefer: 'type-imports', - disallowTypeAnnotations: true, - fixStyle: 'inline-type-imports' - } - ], + '@typescript-eslint/no-var-requires': 'off', + 'no-return-assign': 'off', + 'no-dupe-class-members': 'off', + 'no-extra-parens': 'off', + 'no-spaced-func': 'off', + 'no-unused-vars': 'off', + 'no-useless-constructor': 'off', + 'no-use-before-define': 'off', + 'react/jsx-uses-react': 'error', + 'react/jsx-uses-vars': 'error', + 'react/jsx-no-undef': 'error', + 'react/jsx-fragments': ['error', 'syntax'], 'new-cap': 'off', - 'lines-between-class-members': 'off', - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - 'jest/no-conditional-expect': 'off' + 'lines-between-class-members': 'off' }, globals: { - JSX: true + JSX: 'readonly' }, settings: { 'import/resolver': { @@ -254,11 +138,8 @@ module.exports = /** @type {import('eslint').Linter.Config} */ { } }, { - files: ['e2e/**'], - rules: { - 'no-await-in-loop': 0, - 'jest/expect-expect': 'off' - } + files: ['jest.setup.js', '__mocks__/**/*.js', '**/*.test.{js,ts,tsx}'], + extends: ['plugin:jest/recommended'] } ] }; diff --git a/app/views/CreateChannelView/RoomSettings/SwitchItemEncrypted.test.tsx b/app/views/CreateChannelView/RoomSettings/SwitchItemEncrypted.test.tsx index 7eeefe93de2..215c3ac8da7 100644 --- a/app/views/CreateChannelView/RoomSettings/SwitchItemEncrypted.test.tsx +++ b/app/views/CreateChannelView/RoomSettings/SwitchItemEncrypted.test.tsx @@ -56,11 +56,9 @@ describe('SwitchItemEncrypted', () => { type={testEncrypted.type} /> ); - const component = screen.queryByTestId(testEncrypted.testSwitchID); - if (component) { - fireEvent(component, 'valueChange', { value: true }); - expect(onPressMock).toHaveReturnedWith({ value: !testEncrypted.encrypted }); - } + const component = screen.getByTestId(testEncrypted.testSwitchID); + fireEvent(component, 'valueChange', { value: true }); + expect(onPressMock).toHaveReturnedWith({ value: !testEncrypted.encrypted }); }); it('label when encrypted and isTeam are true and is a private team', () => { diff --git a/scripts/build-icon-set.js b/scripts/build-icon-set.js index 916e428644f..af7a3dd45b2 100644 --- a/scripts/build-icon-set.js +++ b/scripts/build-icon-set.js @@ -1,7 +1,7 @@ const fs = require('fs'); const customIcons = require('../app/containers/CustomIcon/selection.json'); -const sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {}); +const sortObject = o => Object.keys(o).sort().reduce((r, k) => { r[k] = o[k]; return r; }, {}); let icons = {}; From b6d14940d6189313e3e5834f8ff099f087c83796 Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 13 Feb 2026 21:18:12 -0300 Subject: [PATCH 07/13] chore(eslint): use recommended React rules as base --- .eslintrc.js | 24 ++++++++++++++-------- app/containers/ActionSheet/ActionSheet.tsx | 10 +++------ app/containers/Avatar/AvatarContainer.tsx | 6 +++--- app/containers/Avatar/AvatarWithEdit.tsx | 6 +++--- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4c9d2b8a8c9..3793de90445 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,22 +28,33 @@ module.exports = { } }, parser: '@babel/eslint-parser', - extends: ['@rocket.chat/eslint-config', 'plugin:react-hooks/recommended', 'plugin:prettier/recommended', 'prettier'], + extends: [ + '@rocket.chat/eslint-config', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:prettier/recommended', + 'prettier' + ], parserOptions: { sourceType: 'module', ecmaVersion: 2017, ecmaFeatures: { experimentalObjectRestSpread: true, - jsx: true, legacyDecorators: true } }, - plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel'], + plugins: ['jsx-a11y', 'import', 'react-native', '@babel'], env: { es6: true, node: true }, rules: { + 'react/display-name': 'off', + 'react/jsx-fragments': ['error', 'syntax'], + 'react/jsx-key': 'off', + 'react/no-direct-mutation-state': 'off', + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', 'react-hooks/set-state-in-effect': 'warn', 'react-hooks/immutability': 'warn', 'react-hooks/refs': 'warn', @@ -67,7 +78,6 @@ module.exports = { } ], 'no-unused-vars': 'off', - 'react/jsx-uses-vars': 'error', 'no-void': 'error', 'new-cap': 'error', 'react-native/no-unused-styles': 'error', @@ -87,7 +97,7 @@ module.exports = { 'prettier' ], parser: '@typescript-eslint/parser', - plugins: ['react', '@typescript-eslint'], + plugins: ['@typescript-eslint'], rules: { '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/ban-types': 'off', @@ -119,10 +129,6 @@ module.exports = { 'no-unused-vars': 'off', 'no-useless-constructor': 'off', 'no-use-before-define': 'off', - 'react/jsx-uses-react': 'error', - 'react/jsx-uses-vars': 'error', - 'react/jsx-no-undef': 'error', - 'react/jsx-fragments': ['error', 'syntax'], 'new-cap': 'off', 'lines-between-class-members': 'off' }, diff --git a/app/containers/ActionSheet/ActionSheet.tsx b/app/containers/ActionSheet/ActionSheet.tsx index 65f65d551dc..b05824f8590 100644 --- a/app/containers/ActionSheet/ActionSheet.tsx +++ b/app/containers/ActionSheet/ActionSheet.tsx @@ -168,13 +168,9 @@ const ActionSheet = React.memo( // We need this to allow horizontal swipe gesture inside the bottom sheet like in reaction picker enableContentPanningGesture={data?.enableContentPanningGesture ?? true} {...androidTablet}> - + + {data?.children} + )} diff --git a/app/containers/Avatar/AvatarContainer.tsx b/app/containers/Avatar/AvatarContainer.tsx index d9e610eda7b..4e54161efec 100644 --- a/app/containers/Avatar/AvatarContainer.tsx +++ b/app/containers/Avatar/AvatarContainer.tsx @@ -58,7 +58,6 @@ const AvatarContainer = ({ size={size} borderRadius={borderRadius} type={type} - children={children} userId={id} token={token} onPress={onPress} @@ -72,8 +71,9 @@ const AvatarContainer = ({ serverVersion={serverVersion} cdnPrefix={cdnPrefix} accessibilityLabel={accessibilityLabel} - accessible={accessible} - /> + accessible={accessible}> + {children} + ); }; diff --git a/app/containers/Avatar/AvatarWithEdit.tsx b/app/containers/Avatar/AvatarWithEdit.tsx index 49c96bd5f47..41767a01f9b 100644 --- a/app/containers/Avatar/AvatarWithEdit.tsx +++ b/app/containers/Avatar/AvatarWithEdit.tsx @@ -61,12 +61,12 @@ const AvatarWithEdit = ({ size={120} borderRadius={borderRadius} type={type} - children={children} onPress={onPress} getCustomEmoji={getCustomEmoji} isStatic={isStatic} - rid={rid} - /> + rid={rid}> + {children} + {handleEdit && serverVersion && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.6.0') ? (