From 04db33a61e07e569db9d1cfa6137f259b8dfe08d Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Mon, 24 Jan 2022 17:12:36 -0300 Subject: [PATCH] Merge 4.24.0 into master (#3648) --- .eslintrc.js | 5 +- android/app/build.gradle | 2 +- .../networking/SSLPinningModule.java | 47 ++--- app/AppContainer.tsx | 2 +- .../{actionsTypes.js => actionsTypes.ts} | 4 +- app/actions/activeUsers.js | 8 - app/actions/activeUsers.ts | 15 ++ app/actions/selectedUsers.js | 28 --- app/actions/selectedUsers.ts | 43 +++++ app/constants/constantDisplayMode.js | 2 - app/constants/constantDisplayMode.ts | 9 + app/containers/ActionSheet/Button.ts | 3 +- app/containers/Avatar/Avatar.tsx | 5 +- app/containers/Avatar/index.tsx | 10 +- app/containers/Avatar/interfaces.ts | 38 ++-- app/containers/BackgroundContainer/index.tsx | 10 +- app/containers/HeaderButton/Common.tsx | 10 +- .../HeaderButton/HeaderButtonItem.tsx | 16 +- app/containers/List/ListContainer.tsx | 4 +- app/containers/List/ListHeader.tsx | 6 +- app/containers/List/ListIcon.tsx | 12 +- app/containers/List/ListInfo.tsx | 6 +- app/containers/List/ListItem.tsx | 41 ++--- app/containers/List/ListSection.tsx | 6 +- app/containers/List/ListSeparator.tsx | 8 +- app/containers/Loading.tsx | 6 +- app/containers/MessageActions/Header.tsx | 10 +- app/containers/MessageActions/index.tsx | 4 +- .../MessageBox/CommandsPreview/Item.tsx | 4 +- .../MessageBox/CommandsPreview/index.tsx | 4 +- app/containers/MessageBox/index.tsx | 29 ++- app/containers/Passcode/Base/Button.tsx | 20 +-- app/containers/RoomHeader/RoomHeader.tsx | 16 +- app/containers/RoomHeader/index.tsx | 7 +- app/containers/RoomTypeIcon.tsx | 20 ++- app/containers/SafeAreaView.tsx | 12 +- app/containers/SearchBox.tsx | 24 +-- .../{SearchHeader.js => SearchHeader.tsx} | 16 +- app/containers/StatusBar.tsx | 8 +- app/containers/TextInput.tsx | 2 +- app/containers/ThreadDetails.tsx | 33 ++-- app/containers/Toast.tsx | 6 +- app/containers/TwoFactor/index.tsx | 8 +- app/containers/markdown/index.tsx | 9 +- app/containers/message/Audio.tsx | 2 +- app/containers/message/Reactions.tsx | 2 +- app/containers/message/Reply.tsx | 28 +-- app/containers/message/Urls.tsx | 6 +- app/containers/message/User.tsx | 22 +-- app/containers/message/Video.tsx | 10 +- app/containers/message/index.tsx | 100 +++++------ app/containers/message/interfaces.ts | 7 +- app/containers/message/utils.ts | 16 +- app/definitions/IAttachment.ts | 15 ++ app/definitions/ICommand.ts | 6 + app/definitions/ICustomEmoji.ts | 10 ++ app/definitions/IFrequentlyUsedEmoji.ts | 10 ++ app/definitions/ILoggedUser.ts | 18 ++ app/definitions/IMention.ts | 6 + app/definitions/IMessage.ts | 96 +++++++++- app/definitions/INotification.ts | 13 ++ app/definitions/IPermission.ts | 9 + app/definitions/IReaction.ts | 5 + app/definitions/IRocketChatRecord.ts | 4 - app/definitions/IRole.ts | 8 + app/definitions/IRoom.ts | 44 ++--- app/definitions/IServedBy.ts | 5 + app/definitions/IServer.ts | 8 +- app/definitions/IServerHistory.ts | 10 ++ app/definitions/ISettings.ts | 12 ++ app/definitions/ISlashCommand.ts | 12 ++ app/definitions/ISubscription.ts | 91 ++++++++++ app/definitions/ITheme.ts | 8 + app/definitions/IThread.ts | 78 +++++++++ app/definitions/IThreadMessage.ts | 44 +++++ app/definitions/IUpload.ts | 16 ++ app/definitions/IUrl.ts | 6 + app/definitions/IUser.ts | 10 ++ app/definitions/index.ts | 19 ++ app/{ => definitions}/navigationTypes.ts | 23 ++- app/definitions/redux/index.ts | 31 ++++ app/dimensions.tsx | 7 +- app/externalModules.d.ts | 1 + app/i18n/locales/en.json | 2 + app/index.tsx | 11 +- app/lib/rocketchat.js | 14 +- ...{userPreferences.js => userPreferences.ts} | 15 +- app/notifications/push/index.js | 50 ------ app/notifications/push/index.ts | 58 ++++++ app/notifications/push/push.android.js | 32 ---- .../push/{push.ios.js => push.ios.ts} | 54 +++--- app/notifications/push/push.ts | 36 ++++ app/presentation/RoomItem/Actions.tsx | 6 +- app/presentation/RoomItem/IconOrAvatar.js | 6 +- app/presentation/RoomItem/RoomItem.tsx | 4 +- app/presentation/RoomItem/Wrapper.tsx | 6 +- app/presentation/ServerItem/index.tsx | 16 +- app/presentation/TextInput.tsx | 5 +- app/presentation/UnreadBadge/index.tsx | 20 +-- app/reducers/activeUsers.js | 15 -- app/reducers/activeUsers.test.ts | 16 ++ app/reducers/activeUsers.ts | 26 +++ app/reducers/mockedStore.ts | 7 + app/reducers/selectedUsers.test.ts | 36 ++++ .../{selectedUsers.js => selectedUsers.ts} | 19 +- app/reducers/sortPreferences.js | 6 +- app/sagas/room.js | 2 +- app/share.tsx | 10 +- .../MasterDetailStack/ModalContainer.tsx | 28 ++- app/stacks/MasterDetailStack/index.tsx | 16 +- app/stacks/MasterDetailStack/types.ts | 34 ++-- app/stacks/types.ts | 43 ++--- app/theme.tsx | 15 +- app/utils/{appGroup.js => appGroup.ts} | 2 +- app/utils/{avatar.js => avatar.ts} | 8 +- app/utils/base64-js/{index.js => index.ts} | 19 +- app/utils/debounce.js | 20 --- app/utils/debounce.ts | 22 +++ app/utils/{deviceInfo.js => deviceInfo.ts} | 2 +- app/utils/{events.js => events.ts} | 22 ++- app/utils/{fetch.js => fetch.ts} | 14 +- .../fileUpload/{index.ios.js => index.ios.ts} | 15 +- .../fileUpload/{index.android.js => index.ts} | 6 +- app/utils/fileUpload/interfaces.ts | 7 + app/utils/{goRoom.js => goRoom.ts} | 33 +++- app/utils/info.js | 25 --- app/utils/info.ts | 41 +++++ app/utils/{isReadOnly.js => isReadOnly.ts} | 11 +- .../{isValidEmail.js => isValidEmail.ts} | 2 +- ...{layoutAnimation.js => layoutAnimation.ts} | 0 ...thentication.js => localAuthentication.ts} | 45 +++-- app/utils/log/{events.js => events.ts} | 0 app/utils/log/{index.js => index.ts} | 24 +-- app/utils/{media.js => media.ts} | 13 +- .../{messageTypes.js => messageTypes.ts} | 8 + app/utils/{moment.js => moment.ts} | 4 +- .../{animations.js => animations.ts} | 14 +- .../{conditional.js => conditional.ts} | 6 +- app/utils/{openLink.js => openLink.ts} | 9 +- app/utils/{random.js => random.ts} | 2 +- app/utils/{review.js => review.ts} | 4 +- app/utils/room.js | 53 ------ app/utils/room.ts | 65 +++++++ app/utils/{server.js => server.ts} | 2 +- .../shortnameToUnicode/{ascii.js => ascii.ts} | 2 +- .../{emojis.js => emojis.ts} | 2 +- .../shortnameToUnicode/{index.js => index.ts} | 8 +- app/utils/{sslPinning.js => sslPinning.ts} | 22 ++- app/utils/{theme.js => theme.ts} | 16 +- app/utils/throttle.js | 26 --- app/utils/{touch.js => touch.tsx} | 27 +-- app/utils/{twoFactor.js => twoFactor.ts} | 9 +- app/utils/{url.js => url.ts} | 4 +- app/views/AddExistingChannelView.tsx | 14 +- app/views/AdminPanelView/index.tsx | 3 +- app/views/AttachmentView.tsx | 6 +- app/views/AutoTranslateView/index.tsx | 8 +- .../CreateDiscussionView/SelectChannel.tsx | 2 - .../CreateDiscussionView/SelectUsers.tsx | 5 +- app/views/CreateDiscussionView/interfaces.ts | 3 +- app/views/DefaultBrowserView.tsx | 4 +- app/views/DirectoryView/index.tsx | 6 +- ...splayPrefsView.js => DisplayPrefsView.tsx} | 56 +++--- app/views/E2EEncryptionSecurityView.tsx | 4 - app/views/InviteUsersView/index.tsx | 4 +- app/views/LanguageView/index.tsx | 2 +- app/views/LegalView.tsx | 4 +- app/views/MessagesView/index.tsx | 16 +- app/views/ModalBlockView.tsx | 19 +- app/views/NewServerView/ServerInput/Item.tsx | 6 +- app/views/NewServerView/ServerInput/index.tsx | 6 +- app/views/NewServerView/index.tsx | 20 +-- app/views/PickerView.tsx | 2 +- app/views/ProfileView/index.tsx | 1 - app/views/ProfileView/interfaces.ts | 4 +- app/views/RoomInfoView/Direct.js | 4 +- app/views/RoomInfoView/index.js | 27 ++- app/views/RoomMembersView/index.js | 1 - app/views/RoomsListView/index.js | 6 +- app/views/ScreenLockConfigView.tsx | 20 +-- app/views/SearchMessagesView/index.tsx | 12 +- app/views/SelectListView.tsx | 46 ++--- app/views/SelectServerView.tsx | 9 +- app/views/SelectedUsersView.tsx | 92 ++++------ app/views/SettingsView/index.tsx | 8 +- app/views/ShareListView/index.tsx | 15 +- app/views/ShareView/Header.tsx | 8 +- app/views/ShareView/index.tsx | 16 +- app/views/SidebarView/SidebarItem.tsx | 4 +- app/views/SidebarView/index.tsx | 36 ++-- app/views/StatusView.tsx | 10 +- app/views/ThemeView.tsx | 22 +-- .../{DropdownItem.js => DropdownItem.tsx} | 23 ++- ...wnItemFilter.js => DropdownItemFilter.tsx} | 16 +- ...wnItemHeader.js => DropdownItemHeader.tsx} | 19 +- .../Dropdown/{index.js => index.tsx} | 41 ++--- .../ThreadMessagesView/{Item.js => Item.tsx} | 48 +++-- app/views/ThreadMessagesView/filters.js | 5 - app/views/ThreadMessagesView/filters.ts | 5 + .../{index.js => index.tsx} | 165 ++++++++++++------ .../{styles.js => styles.ts} | 2 +- app/views/UserPreferencesView/index.tsx | 19 +- app/views/WorkspaceView/index.tsx | 4 +- ios/Podfile.lock | 8 +- ios/RocketChatRN.xcodeproj/project.pbxproj | 4 +- ios/RocketChatRN/Info.plist | 2 +- ios/ShareRocketChatRN/Info.plist | 2 +- package.json | 8 +- ...h => react-native-device-info+8.4.8.patch} | 2 +- storybook/stories/RoomItem.js | 22 +-- yarn.lock | 74 +++++++- 211 files changed, 2254 insertions(+), 1364 deletions(-) rename app/actions/{actionsTypes.js => actionsTypes.ts} (96%) delete mode 100644 app/actions/activeUsers.js create mode 100644 app/actions/activeUsers.ts delete mode 100644 app/actions/selectedUsers.js create mode 100644 app/actions/selectedUsers.ts delete mode 100644 app/constants/constantDisplayMode.js create mode 100644 app/constants/constantDisplayMode.ts rename app/containers/{SearchHeader.js => SearchHeader.tsx} (80%) create mode 100644 app/definitions/ICommand.ts create mode 100644 app/definitions/ICustomEmoji.ts create mode 100644 app/definitions/IFrequentlyUsedEmoji.ts create mode 100644 app/definitions/ILoggedUser.ts create mode 100644 app/definitions/IMention.ts create mode 100644 app/definitions/INotification.ts create mode 100644 app/definitions/IPermission.ts create mode 100644 app/definitions/IReaction.ts delete mode 100644 app/definitions/IRocketChatRecord.ts create mode 100644 app/definitions/IRole.ts create mode 100644 app/definitions/IServedBy.ts create mode 100644 app/definitions/IServerHistory.ts create mode 100644 app/definitions/ISettings.ts create mode 100644 app/definitions/ISlashCommand.ts create mode 100644 app/definitions/ISubscription.ts create mode 100644 app/definitions/ITheme.ts create mode 100644 app/definitions/IThread.ts create mode 100644 app/definitions/IThreadMessage.ts create mode 100644 app/definitions/IUpload.ts create mode 100644 app/definitions/IUrl.ts create mode 100644 app/definitions/IUser.ts create mode 100644 app/definitions/index.ts rename app/{ => definitions}/navigationTypes.ts (63%) create mode 100644 app/definitions/redux/index.ts rename app/lib/{userPreferences.js => userPreferences.ts} (75%) delete mode 100644 app/notifications/push/index.js create mode 100644 app/notifications/push/index.ts delete mode 100644 app/notifications/push/push.android.js rename app/notifications/push/{push.ios.js => push.ios.ts} (52%) create mode 100644 app/notifications/push/push.ts delete mode 100644 app/reducers/activeUsers.js create mode 100644 app/reducers/activeUsers.test.ts create mode 100644 app/reducers/activeUsers.ts create mode 100644 app/reducers/mockedStore.ts create mode 100644 app/reducers/selectedUsers.test.ts rename app/reducers/{selectedUsers.js => selectedUsers.ts} (55%) rename app/utils/{appGroup.js => appGroup.ts} (83%) rename app/utils/{avatar.js => avatar.ts} (72%) rename app/utils/base64-js/{index.js => index.ts} (87%) delete mode 100644 app/utils/debounce.js create mode 100644 app/utils/debounce.ts rename app/utils/{deviceInfo.js => deviceInfo.ts} (92%) rename app/utils/{events.js => events.ts} (53%) rename app/utils/{fetch.js => fetch.ts} (75%) rename app/utils/fileUpload/{index.ios.js => index.ios.ts} (65%) rename app/utils/fileUpload/{index.android.js => index.ts} (64%) create mode 100644 app/utils/fileUpload/interfaces.ts rename app/utils/{goRoom.js => goRoom.ts} (58%) delete mode 100644 app/utils/info.js create mode 100644 app/utils/info.ts rename app/utils/{isReadOnly.js => isReadOnly.ts} (59%) rename app/utils/{isValidEmail.js => isValidEmail.ts} (78%) rename app/utils/{layoutAnimation.js => layoutAnimation.ts} (100%) rename app/utils/{localAuthentication.js => localAuthentication.ts} (73%) rename app/utils/log/{events.js => events.ts} (100%) rename app/utils/log/{index.js => index.ts} (66%) rename app/utils/{media.js => media.ts} (65%) rename app/utils/{messageTypes.js => messageTypes.ts} (88%) rename app/utils/{moment.js => moment.ts} (57%) rename app/utils/navigation/{animations.js => animations.ts} (71%) rename app/utils/navigation/{conditional.js => conditional.ts} (87%) rename app/utils/{openLink.js => openLink.ts} (83%) rename app/utils/{random.js => random.ts} (80%) rename app/utils/{review.js => review.ts} (96%) delete mode 100644 app/utils/room.js create mode 100644 app/utils/room.ts rename app/utils/{server.js => server.ts} (84%) rename app/utils/shortnameToUnicode/{ascii.js => ascii.ts} (98%) rename app/utils/shortnameToUnicode/{emojis.js => emojis.ts} (99%) rename app/utils/shortnameToUnicode/{index.js => index.ts} (80%) rename app/utils/{sslPinning.js => sslPinning.ts} (75%) rename app/utils/{theme.js => theme.ts} (71%) delete mode 100644 app/utils/throttle.js rename app/utils/{touch.js => touch.tsx} (55%) rename app/utils/{twoFactor.js => twoFactor.ts} (68%) rename app/utils/{url.js => url.ts} (77%) rename app/views/{DisplayPrefsView.js => DisplayPrefsView.tsx} (76%) rename app/views/ThreadMessagesView/Dropdown/{DropdownItem.js => DropdownItem.tsx} (65%) rename app/views/ThreadMessagesView/Dropdown/{DropdownItemFilter.js => DropdownItemFilter.tsx} (51%) rename app/views/ThreadMessagesView/Dropdown/{DropdownItemHeader.js => DropdownItemHeader.tsx} (61%) rename app/views/ThreadMessagesView/Dropdown/{index.js => index.tsx} (67%) rename app/views/ThreadMessagesView/{Item.js => Item.tsx} (72%) delete mode 100644 app/views/ThreadMessagesView/filters.js create mode 100644 app/views/ThreadMessagesView/filters.ts rename app/views/ThreadMessagesView/{index.js => index.tsx} (74%) rename app/views/ThreadMessagesView/{styles.js => styles.ts} (93%) rename patches/{react-native-device-info+8.1.3.patch => react-native-device-info+8.4.8.patch} (98%) diff --git a/.eslintrc.js b/.eslintrc.js index 085f3a89d..952621fbf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,14 +17,15 @@ module.exports = { legacyDecorators: true } }, - plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel'], + plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel', 'jest'], env: { browser: true, commonjs: true, es6: true, node: true, jquery: true, - mocha: true + mocha: true, + 'jest/globals': true }, rules: { 'import/extensions': [ diff --git a/android/app/build.gradle b/android/app/build.gradle index 524eebd82..c95a2f79b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -144,7 +144,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode VERSIONCODE as Integer - versionName "4.23.0" + versionName "4.24.0" vectorDrawables.useSupportLibrary = true if (!isFoss) { manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] diff --git a/android/app/src/main/java/chat/rocket/reactnative/networking/SSLPinningModule.java b/android/app/src/main/java/chat/rocket/reactnative/networking/SSLPinningModule.java index 6a690a180..aad807859 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/networking/SSLPinningModule.java +++ b/android/app/src/main/java/chat/rocket/reactnative/networking/SSLPinningModule.java @@ -11,9 +11,12 @@ import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; import java.net.Socket; +import java.security.KeyStore; import java.security.Principal; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; + +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; import java.security.PrivateKey; import javax.net.ssl.SSLContext; @@ -21,11 +24,12 @@ import javax.net.ssl.X509TrustManager; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import okhttp3.OkHttpClient; -import java.lang.InterruptedException; import android.app.Activity; import javax.net.ssl.KeyManager; import android.security.KeyChain; import android.security.KeyChainAliasCallback; + +import java.util.Arrays; import java.util.concurrent.TimeUnit; import com.RNFetchBlob.RNFetchBlob; @@ -52,8 +56,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC public void apply(OkHttpClient.Builder builder) { if (alias != null) { SSLSocketFactory sslSocketFactory = getSSLFactory(alias); + X509TrustManager trustManager = getTrustManagerFactory(); if (sslSocketFactory != null) { - builder.sslSocketFactory(sslSocketFactory); + builder.sslSocketFactory(sslSocketFactory, trustManager); } } } @@ -68,8 +73,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC if (alias != null) { SSLSocketFactory sslSocketFactory = getSSLFactory(alias); + X509TrustManager trustManager = getTrustManagerFactory(); if (sslSocketFactory != null) { - builder.sslSocketFactory(sslSocketFactory); + builder.sslSocketFactory(sslSocketFactory, trustManager); } } @@ -162,25 +168,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC } }; - final TrustManager[] trustAllCerts = new TrustManager[] { - new X509TrustManager() { - @Override - public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override - public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return certChain; - } - } - }; - + final X509TrustManager trustManager = getTrustManagerFactory(); final SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(new KeyManager[]{keyManager}, trustAllCerts, new java.security.SecureRandom()); + sslContext.init(new KeyManager[]{keyManager}, new TrustManager[]{trustManager}, new java.security.SecureRandom()); SSLContext.setDefault(sslContext); final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); @@ -190,4 +180,19 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC return null; } } + + public static X509TrustManager getTrustManagerFactory() { + try { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); + } + final X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; + return trustManager; + } catch (Exception e) { + return null; + } + } } diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx index b73aaf8e3..441220fec 100644 --- a/app/AppContainer.tsx +++ b/app/AppContainer.tsx @@ -3,7 +3,7 @@ import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { connect } from 'react-redux'; -import { SetUsernameStackParamList, StackParamList } from './navigationTypes'; +import { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes'; import Navigation from './lib/Navigation'; import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation'; import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app'; diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.ts similarity index 96% rename from app/actions/actionsTypes.js rename to app/actions/actionsTypes.ts index 852ce83ea..ad2d1718d 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.ts @@ -2,8 +2,8 @@ const REQUEST = 'REQUEST'; const SUCCESS = 'SUCCESS'; const FAILURE = 'FAILURE'; const defaultTypes = [REQUEST, SUCCESS, FAILURE]; -function createRequestTypes(base, types = defaultTypes) { - const res = {}; +function createRequestTypes(base = {}, types = defaultTypes): Record { + const res: Record = {}; types.forEach(type => (res[type] = `${base}_${type}`)); return res; } diff --git a/app/actions/activeUsers.js b/app/actions/activeUsers.js deleted file mode 100644 index fc359602c..000000000 --- a/app/actions/activeUsers.js +++ /dev/null @@ -1,8 +0,0 @@ -import { SET_ACTIVE_USERS } from './actionsTypes'; - -export function setActiveUsers(activeUsers) { - return { - type: SET_ACTIVE_USERS, - activeUsers - }; -} diff --git a/app/actions/activeUsers.ts b/app/actions/activeUsers.ts new file mode 100644 index 000000000..737ae86b3 --- /dev/null +++ b/app/actions/activeUsers.ts @@ -0,0 +1,15 @@ +import { Action } from 'redux'; + +import { IActiveUsers } from '../reducers/activeUsers'; +import { SET_ACTIVE_USERS } from './actionsTypes'; + +export interface ISetActiveUsers extends Action { + activeUsers: IActiveUsers; +} + +export type TActionActiveUsers = ISetActiveUsers; + +export const setActiveUsers = (activeUsers: IActiveUsers): ISetActiveUsers => ({ + type: SET_ACTIVE_USERS, + activeUsers +}); diff --git a/app/actions/selectedUsers.js b/app/actions/selectedUsers.js deleted file mode 100644 index 65fbb0015..000000000 --- a/app/actions/selectedUsers.js +++ /dev/null @@ -1,28 +0,0 @@ -import * as types from './actionsTypes'; - -export function addUser(user) { - return { - type: types.SELECTED_USERS.ADD_USER, - user - }; -} - -export function removeUser(user) { - return { - type: types.SELECTED_USERS.REMOVE_USER, - user - }; -} - -export function reset() { - return { - type: types.SELECTED_USERS.RESET - }; -} - -export function setLoading(loading) { - return { - type: types.SELECTED_USERS.SET_LOADING, - loading - }; -} diff --git a/app/actions/selectedUsers.ts b/app/actions/selectedUsers.ts new file mode 100644 index 000000000..6924a5696 --- /dev/null +++ b/app/actions/selectedUsers.ts @@ -0,0 +1,43 @@ +import { Action } from 'redux'; + +import { ISelectedUser } from '../reducers/selectedUsers'; +import * as types from './actionsTypes'; + +type TUser = { + user: ISelectedUser; +}; + +type TAction = Action & TUser; + +interface ISetLoading extends Action { + loading: boolean; +} + +export type TActionSelectedUsers = TAction & ISetLoading; + +export function addUser(user: ISelectedUser): TAction { + return { + type: types.SELECTED_USERS.ADD_USER, + user + }; +} + +export function removeUser(user: ISelectedUser): TAction { + return { + type: types.SELECTED_USERS.REMOVE_USER, + user + }; +} + +export function reset(): Action { + return { + type: types.SELECTED_USERS.RESET + }; +} + +export function setLoading(loading: boolean): ISetLoading { + return { + type: types.SELECTED_USERS.SET_LOADING, + loading + }; +} diff --git a/app/constants/constantDisplayMode.js b/app/constants/constantDisplayMode.js deleted file mode 100644 index d7d7e1d53..000000000 --- a/app/constants/constantDisplayMode.js +++ /dev/null @@ -1,2 +0,0 @@ -export const DISPLAY_MODE_CONDENSED = 'condensed'; -export const DISPLAY_MODE_EXPANDED = 'expanded'; diff --git a/app/constants/constantDisplayMode.ts b/app/constants/constantDisplayMode.ts new file mode 100644 index 000000000..ecb6bd4b7 --- /dev/null +++ b/app/constants/constantDisplayMode.ts @@ -0,0 +1,9 @@ +export enum DisplayMode { + Condensed = 'condensed', + Expanded = 'expanded' +} + +export enum SortBy { + Alphabetical = 'alphabetical', + Activity = 'activity' +} diff --git a/app/containers/ActionSheet/Button.ts b/app/containers/ActionSheet/Button.ts index 5deb0f692..186cc6851 100644 --- a/app/containers/ActionSheet/Button.ts +++ b/app/containers/ActionSheet/Button.ts @@ -1,7 +1,8 @@ +import React from 'react'; import { TouchableOpacity } from 'react-native'; import { isAndroid } from '../../utils/deviceInfo'; import Touch from '../../utils/touch'; // Taken from https://github.com/rgommezz/react-native-scroll-bottom-sheet#touchables -export const Button = isAndroid ? Touch : TouchableOpacity; +export const Button: typeof React.Component = isAndroid ? Touch : TouchableOpacity; diff --git a/app/containers/Avatar/Avatar.tsx b/app/containers/Avatar/Avatar.tsx index 286bcc060..0ad2634f2 100644 --- a/app/containers/Avatar/Avatar.tsx +++ b/app/containers/Avatar/Avatar.tsx @@ -5,6 +5,7 @@ import Touchable from 'react-native-platform-touchable'; import { settings as RocketChatSettings } from '@rocket.chat/sdk'; import { avatarURL } from '../../utils/avatar'; +import { SubscriptionType } from '../../definitions/ISubscription'; import Emoji from '../markdown/Emoji'; import { IAvatar } from './interfaces'; @@ -27,8 +28,8 @@ const Avatar = React.memo( text, size = 25, borderRadius = 4, - type = 'd' - }: Partial) => { + type = SubscriptionType.DIRECT + }: IAvatar) => { if ((!text && !avatar && !emoji && !rid) || !server) { return null; } diff --git a/app/containers/Avatar/index.tsx b/app/containers/Avatar/index.tsx index 9c95db839..2ce066479 100644 --- a/app/containers/Avatar/index.tsx +++ b/app/containers/Avatar/index.tsx @@ -7,17 +7,17 @@ import { getUserSelector } from '../../selectors/login'; import Avatar from './Avatar'; import { IAvatar } from './interfaces'; -class AvatarContainer extends React.Component, any> { +class AvatarContainer extends React.Component { private mounted: boolean; - private subscription!: any; + private subscription: any; static defaultProps = { text: '', type: 'd' }; - constructor(props: Partial) { + constructor(props: IAvatar) { super(props); this.mounted = false; this.state = { avatarETag: '' }; @@ -55,7 +55,7 @@ class AvatarContainer extends React.Component, any> { try { if (this.isDirect) { const { text } = this.props; - const [user] = await usersCollection.query(Q.where('username', text!)).fetch(); + const [user] = await usersCollection.query(Q.where('username', text)).fetch(); record = user; } else { const { rid } = this.props; @@ -82,7 +82,7 @@ class AvatarContainer extends React.Component, any> { render() { const { avatarETag } = this.state; const { serverVersion } = this.props; - return ; + return ; } } diff --git a/app/containers/Avatar/interfaces.ts b/app/containers/Avatar/interfaces.ts index ed7fd3b9e..78152e522 100644 --- a/app/containers/Avatar/interfaces.ts +++ b/app/containers/Avatar/interfaces.ts @@ -1,23 +1,23 @@ export interface IAvatar { - server: string; - style: any; + server?: string; + style?: any; text: string; - avatar: string; - emoji: string; - size: number; - borderRadius: number; - type: string; - children: JSX.Element; - user: { - id: string; - token: string; + avatar?: string; + emoji?: string; + size?: number; + borderRadius?: number; + type?: string; + children?: JSX.Element; + user?: { + id?: string; + token?: string; }; - theme: string; - onPress(): void; - getCustomEmoji(): any; - avatarETag: string; - isStatic: boolean | string; - rid: string; - blockUnauthenticatedAccess: boolean; - serverVersion: string; + theme?: string; + onPress?: () => void; + getCustomEmoji?: () => any; + avatarETag?: string; + isStatic?: boolean | string; + rid?: string; + blockUnauthenticatedAccess?: boolean; + serverVersion?: string; } diff --git a/app/containers/BackgroundContainer/index.tsx b/app/containers/BackgroundContainer/index.tsx index fbe5d3077..fc26fe0ab 100644 --- a/app/containers/BackgroundContainer/index.tsx +++ b/app/containers/BackgroundContainer/index.tsx @@ -6,9 +6,9 @@ import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; interface IBackgroundContainer { - text: string; - theme: string; - loading: boolean; + text?: string; + theme?: string; + loading?: boolean; } const styles = StyleSheet.create({ @@ -35,8 +35,8 @@ const styles = StyleSheet.create({ const BackgroundContainer = ({ theme, text, loading }: IBackgroundContainer) => ( - {text ? {text} : null} - {loading ? : null} + {text ? {text} : null} + {loading ? : null} ); diff --git a/app/containers/HeaderButton/Common.tsx b/app/containers/HeaderButton/Common.tsx index b40543ddb..0877fb4c6 100644 --- a/app/containers/HeaderButton/Common.tsx +++ b/app/containers/HeaderButton/Common.tsx @@ -29,9 +29,9 @@ export const CloseModal = React.memo( export const CancelModal = React.memo(({ onPress, testID }: Partial) => ( {isIOS ? ( - + ) : ( - + )} )); @@ -39,19 +39,19 @@ export const CancelModal = React.memo(({ onPress, testID }: Partial) => ( - + )); export const Download = React.memo(({ onPress, testID, ...props }: Partial) => ( - + )); export const Preferences = React.memo(({ onPress, testID, ...props }: Partial) => ( - + )); diff --git a/app/containers/HeaderButton/HeaderButtonItem.tsx b/app/containers/HeaderButton/HeaderButtonItem.tsx index b350232d0..08f6b5a3a 100644 --- a/app/containers/HeaderButton/HeaderButtonItem.tsx +++ b/app/containers/HeaderButton/HeaderButtonItem.tsx @@ -8,12 +8,12 @@ import { themes } from '../../constants/colors'; import sharedStyles from '../../views/Styles'; interface IHeaderButtonItem { - title: string; - iconName: string; - onPress(): void; - testID: string; - theme: string; - badge(): void; + title?: string; + iconName?: string; + onPress: (arg: T) => void; + testID?: string; + theme?: string; + badge?(): void; } export const BUTTON_HIT_SLOP = { @@ -44,9 +44,9 @@ const Item = ({ title, iconName, onPress, testID, theme, badge }: IHeaderButtonI <> {iconName ? ( - + ) : ( - {title} + {title} )} {badge ? badge() : null} diff --git a/app/containers/List/ListContainer.tsx b/app/containers/List/ListContainer.tsx index 408310d9f..deb9c8a71 100644 --- a/app/containers/List/ListContainer.tsx +++ b/app/containers/List/ListContainer.tsx @@ -11,10 +11,10 @@ const styles = StyleSheet.create({ }); interface IListContainer { - children: JSX.Element; + children: React.ReactNode; + testID?: string; } const ListContainer = React.memo(({ children, ...props }: IListContainer) => ( - // @ts-ignore ( - + {translateTitle ? I18n.t(title) : title} diff --git a/app/containers/List/ListIcon.tsx b/app/containers/List/ListIcon.tsx index 7d569dce7..71e4fbdf2 100644 --- a/app/containers/List/ListIcon.tsx +++ b/app/containers/List/ListIcon.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { StyleSheet, View } from 'react-native'; +import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; import { themes } from '../../constants/colors'; import { CustomIcon } from '../../lib/Icons'; @@ -7,11 +7,11 @@ import { withTheme } from '../../theme'; import { ICON_SIZE } from './constants'; interface IListIcon { - theme: string; + theme?: string; name: string; - color: string; - style: object; - testID: string; + color?: string; + style?: StyleProp; + testID?: string; } const styles = StyleSheet.create({ @@ -23,7 +23,7 @@ const styles = StyleSheet.create({ const ListIcon = React.memo(({ theme, name, color, style, testID }: IListIcon) => ( - + )); diff --git a/app/containers/List/ListInfo.tsx b/app/containers/List/ListInfo.tsx index bc4f02e33..2bfe68e32 100644 --- a/app/containers/List/ListInfo.tsx +++ b/app/containers/List/ListInfo.tsx @@ -20,13 +20,13 @@ const styles = StyleSheet.create({ interface IListHeader { info: string; - theme: string; - translateInfo: boolean; + theme?: string; + translateInfo?: boolean; } const ListInfo = React.memo(({ info, theme, translateInfo = true }: IListHeader) => ( - {translateInfo ? I18n.t(info) : info} + {translateInfo ? I18n.t(info) : info} )); diff --git a/app/containers/List/ListItem.tsx b/app/containers/List/ListItem.tsx index a05eaf9ad..87abfd2dd 100644 --- a/app/containers/List/ListItem.tsx +++ b/app/containers/List/ListItem.tsx @@ -56,11 +56,11 @@ const styles = StyleSheet.create({ interface IListItemContent { title?: string; subtitle?: string; - left?: Function; - right?: Function; + left?: () => JSX.Element | null; + right?: () => JSX.Element | null; disabled?: boolean; testID?: string; - theme: string; + theme?: string; color?: string; translateTitle?: boolean; translateSubtitle?: boolean; @@ -89,15 +89,15 @@ const Content = React.memo( {left ? {left()} : null} - + {translateTitle ? I18n.t(title) : title} {alert ? ( - + ) : null} {subtitle ? ( - + {translateSubtitle ? I18n.t(subtitle) : subtitle} ) : null} @@ -112,38 +112,39 @@ const Content = React.memo( ) ); -interface IListItemButton { +interface IListButtonPress { + onPress?: Function; +} + +interface IListItemButton extends IListButtonPress { title?: string; - onPress: Function; disabled?: boolean; - theme: string; - backgroundColor: string; + theme?: string; + backgroundColor?: string; underlayColor?: string; } -const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => ( +const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => ( onPress(props.title)} - style={{ backgroundColor: backgroundColor || themes[props.theme].backgroundColor }} + onPress={() => onPress!(props.title)} + style={{ backgroundColor: backgroundColor || themes[props.theme!].backgroundColor }} underlayColor={underlayColor} enabled={!props.disabled} - theme={props.theme}> + theme={props.theme!}> )); -interface IListItem { - onPress: Function; - theme: string; - backgroundColor: string; +interface IListItem extends IListItemContent, IListButtonPress { + backgroundColor?: string; } -const ListItem = React.memo(({ ...props }: IListItem) => { +const ListItem = React.memo(({ ...props }: IListItem) => { if (props.onPress) { return