Merge 4.15.0 into master (#2984)
* [FIX] MessagesView title not working (#2294)
* Set title in header of room actions view items
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Remove unneeded spaces
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Set header title on constructor
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Remove unused navigation options
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [TESTS] Stabilise Room Actions test (#2333)
* Stabilise Room Actions test
* Fix Create Room test
* Be more tolerant of slow starting apps in CI
* Be more tolerant of slow running apps in CI
* Switch visibility checks ti stabilise Room Create test in CI
* Move slow simulator readiness waiting to initial navigateToX methods rather than repeatedly in tests without description of purpose
* [CHORE] Update icon names (#2318)
* [CHORE] Move Detox to Github Actions (#2340)
* Initial workflow for iOS detox tests
* Increase timeout
* Parallelise tests and optimise when to build
* Refine GH Actions logic
* Improve Detox App caching
* Upload failed test artifacts
* Rate limiting aware data setup
* Remove detox tests from Circle CI
* Revert "Rate limiting aware data setup"
This reverts commit d115604270f719de775018b9b06e89f2bfdc2dc7.
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Push notification data privacy (#2213)
* [WIP] Notification Service
* [WIP] Android push notification privacy
* [WIP] Retry request when it fails (iOS)
* [WIP] Override notification bundle
* [CHORE] Remove unnecessary import
* [WIP] Check notification Type (iOS)
* [WIP] Change to notification endpoint
* eof
* fix unwrap conditional value
* turn run request synchronous
* fix bundle info
* eof
* remove extra tab
* undo unnecessary change
* remove not working code for a while
* fix notification title
* change endpoint and received/sent data
* message-id-only working properly on android
* notification privacy working on ios
* invalidate circleCI yarn cache
* Fix provisioning profiles
* fix notification service version
* fix unwrap nil
* compatibility older servers android
* show received notification when cant fetch content from server
* undo some android changes
* prevent group & reply fallback notifications
* dont show more than one fallback notification by server
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Apply new mention colors (#2351)
* New mention colors
* Increase letterSpacing for mentions
* Refactor
* UnreadBadge
* Add migration
* [FIX] Missing icons (#2353)
* [FIX] Long press gestures not working properly on Android (#2354)
* [FIX] In-app notification showing while in a Jitsi call (#2345)
* Hide in app notification when focused on JitsiMeetView
* Hide notifications from different rooms
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Only run Flipper in debug via MainApplication is debug (#2347)
* Only run Flipper in debug via MainApplication is debug
* ReactNativeFlipper package rename + gradle bump
* [CHORE] Update Flipper to 0.51.0 (#2356)
* Only run Flipper in debug via MainApplication is debug
* ReactNativeFlipper package rename + gradle bump
* Update Flipper to latest 0.51 for Android
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Log events from RoomsList, SideDrawer and Profile (#2190)
* Create method to track user event to isolate the logic to improve future refactoring
* Track Onboarding view
* Track NewServer view
* Refactor track method due to firebase already send the current screen
* Track default login and all the oAuth options
* Track default sign up in RegisterView
* Change trackUserEvent signature and update all the files
* Track the remaining login services
* track add server, change server and search
* Track SidebarView and refactor to use react-navigation
* Track profile events and handle exceptions
* Track create channel flux
* Track send message to user via NewMessageView
* Track create direct message flux
* Handle failure of create channel and group in the saga
* Track create discussion flux
* Track navigate to directory and its actions
* Track read, favorite and hide a channel, handling its errors
* Track all channels sorting and grouping
* Resolve requests to improve the importing logs and events
* Remove unused events file
* Leave a bugsnag breadcrumb when logging an event
* Move all logEvent to the top of code block and log remaining fail events
* Move all the non-logic-dependent logEvent to the top of code block
* Improve the logging of sidebar events
* Improve events from onboarding and newserver
* Improve events from login and register view, and log enter with apple
* Improve NewMessageView events
* Improve CreateChannel events
* Improve CreateDiscussion and SelectedUsers create group events
* Improve RoomsList events and log trivial events
* Improve ProfileView events
* Remove single line function body for the sidebarNavigate
* Navigate to Status and AdminPanel View using the defined sidebarNavigate method
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Add missing keys to push get payload (#2358)
* [IMPROVEMENT] Add deep link to Jitsi calls (#2223)
* [WIP] Jitsi Deep Links
* [WIP] Add app links
* save uniqueID servers database
* add serverInfoKey of uniqueID
* search server by call url
* open jitsi deeplink poc
* improve jitsi url
* fix
* improve comment
* add missing android scheme
* handle host not found
* Allow app links to be matched on parseDeepLinking
* Fix push notification of a call
* Minor fix
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App hanging on splash screen when deep link params are wrong (#2359)
* Add rule when there's no host on the deep link params
* Add fallbackNavigation()
* Fix insecure hosts
* [FIX] More missing icons (#2360)
* [NEW] Log events from Room, Settings and Edit status (#2206)
* Create method to track user event to isolate the logic to improve future refactoring
* Track Onboarding view
* Track NewServer view
* Refactor track method due to firebase already send the current screen
* Track default login and all the oAuth options
* Track default sign up in RegisterView
* Change trackUserEvent signature and update all the files
* Track the remaining login services
* track add server, change server and search
* Track SidebarView and refactor to use react-navigation
* Track profile events and handle exceptions
* Track create channel flux
* Track send message to user via NewMessageView
* Track create direct message flux
* Handle failure of create channel and group in the saga
* Track create discussion flux
* Track navigate to directory and its actions
* Track read, favorite and hide a channel, handling its errors
* Track all channels sorting and grouping
* Resolve requests to improve the importing logs and events
* Remove unused events file
* Remove unused events file
* log proposed Room events
* Log proposed Message actions events
* Log EditStatus proposed events
* Log Settings proposed events
* Leave a bugsnag breadcrumb when logging an event
* Move all logEvent to the top of code block and log remaining fail events
* Move all the non-logic-dependent logEvent to the top of code block
* Move all non-logic and non-data dependent logEvent to the top of code block
* Improve the logging of sidebar events
* Improve events from onboarding and newserver
* Improve events from login and register view, and log enter with apple
* Improve NewMessageView events
* Improve CreateChannel events
* Improve CreateDiscussion and SelectedUsers create group events
* Improve RoomsList events and log trivial events
* Improve ProfileView events
* Remove single line function body for the sidebarNavigate
* Improve SettingsView events
* Log more events from ScreenLockConfigView
* Navigate to Status and AdminPanel View using the defined sidebarNavigate method
* Improve StatusView events
* Improve RoomView events
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Vertically centralize RoomItem when `Store_Last_Message` is disabled (#2363)
* Split RoomItem into container and component
* Refactor RoomItem
* Fix wrong status
* Tests
* Wrapper
* [NEW] Omnichannel inquiry queue (#2352)
* [WIP] Omnichannel queue
* Request inquiry when login
* Show take inquiry queued room
* Queue List as a Screen
* Poc using unread badge
* Prevent navigation to empty list
* Remove chat from queue when taked
* Fix header status on omnichannel preview room
* Fix room actions view to preview queued chat
* Use isOmnichannelPreview and dont show actions when is preview
* Filter queue chats taken by other people
* Fix room info to omnichannel preview room
* Handle show Queue
* Reset inquiry store when change server
* Improve queue logic
* Disable swipe on RoomItem when is a Queue Item
* Add unreadBadge style
* Move unread badge to presentation folder
* Cleanup inquiry reducers
* Move take saga to rocketchat function
* Remove comments
* Add relevant comments
* Subscribe to public stream if is livechat manager or doesnt have departments
* Add pt-br and improve queue empty message
* Fix take when dont have view-livechat-manager permission
* Add missing events
* Create selector for inquiry queue
* Minor fixes
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Wrap logEvent in a try/catch (#2361)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Minor i18n issues (#2335)
* Add new translations to ptBr
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix update language in headers
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Use parsed EJSON info on load notification (#2370)
* [NEW] Log remaining events (#2368)
* Change NAVIGATE_TO for GO_TO to reduce event size
* Log RA JitsiMeet events and join / terminate
* Log more RoomView events
* Log slash commands and handle fail
* Log RoomActions events
* Change from GO_TO to just GO
* Log RoomInfoEdit events
* Log InviteUsers and InviteUsersEdit events
* Log AutoTranslate events
* Log NotificationPreferences events
* Log remaining routes from RoomActions
* Log RoomAction toggle block user
* Fix command event
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] WorkspaceView not looking for the correct image path (#2376)
Co-authored-by: Gabriel Henriques <gabriel.henriques@rocket.chat>
* [FIX] Android targeting wrong SDK version (#2375)
* [FIX] Mentions crashing without username (#2374)
* [FIX] Missing delete icon on MessageErrorActions (#2373)
* [FIX] Quote not working on Group DM (#2372)
* [DOCS] Add Whitelabel (#2379)
* Update readme (#2381)
* Update README.md (#2378)
* Update README.md
* Update README.md
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [DOCS] Refactor Readme (#2382)
* Refactoring
* Detail docs
* Contributing
* Update CONTRIBUTING.md
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* Merge beta into master (#2388)
* Sync develop on master (#275)
* Create LICENSE
* Sync master (#721)
* Merge 1.13.0 into Master (#936)
* fix last messages (#239)
* fix last messages
* Room actions (#231)
* Layout
* Empty starred list
* Favorite room
* Pinned messages
* fix last messages
* fix date on pinned messages
* fix package
* [NEW] OAuth (#241)
* Layout
* tmp
* test iscordova
* Webview redirecting
* Open and Close login actions
* Login services saved on redux
* OAuth Github
* Server regex fix
* OAuth modal style
* - Twitter login
- Remove services from redux
- Open login saga fix
* - Facebook login
- Fixed user agent
- Reactions fix
- Message url unique key fix
* Google login
* Email keyboard removed from messagebox
* - Login buttons refactored
- RoomList header
* Layout improvements
* Meteor login redirect_uri changed
* fix
* Random credentialToken state
* [NEW] Room actions: Mentioned messages and Room Members (#242)
* Mentioned messages
* Starred and pinned actions debounce
* Room members
* Open room on member touch
* [WIP] Improves (#245)
* hotfix for ios
* hotfix for ios
* Update config.yml
* Workaround for RN 0.54 on iOS (#246)
* Update iOS to RN 0.54 (#248)
* Update iOS to RN 0.54
* [WIP] Audio message functionality (#247)
* [NEW] Add module react-native-audio
* [WIP] Audio message basic UI
* [NEW] Record audio message
* Use cordova repository to get certificates
* Icon 1024
* [NEW] Room actions: block user, snippet messages, room files and leave room (#250)
* - Block user
- Load room members async
- fixed reactive change of room's read only flag
* Snippet messages
* - Room files
- Dismiss Video component on back button press
- Improvements on Image component
* Improvement on Video component
* Leave room
* Missing message types
* lint
* Reactotron working (#249)
* [NEW] Room info and Room info edit (#254)
* - Block user
- Load room members async
- fixed reactive change of room's read only flag
* Snippet messages
* - Room files
- Dismiss Video component on back button press
- Improvements on Image component
* Improvement on Video component
* Leave room
* Missing message types
* lint
* - Room info (read only)
- Missing message types
* Room info scroll
* - Tap on room header opens room info
- Layout tweaks
* - Room info edit
- iOS Toast fixed
* - Style not implemented actions as disabled
* Edit room permission
* - Save all room settings in a single call
- Implemented roomType and readOnly
* - Allow reacting when room is read only
* Message type added: room_changed_privacy
* Erase room
* Created TextInput and SwitchContainer components for reuse and readability
* - hasPermission method
* - Archive/Unarchive room
- Set Join Code
* Twitter keyboard type on iOS
* Archived room
* reactWhenReadOnly permission on message
* Active users refactored
* User roles
* - Subscribe to roles (in order to get role description info: e.g. 'core-team' to 'Rocket.Chat Team')
- Save roles to realm (for offline access)
- Save roles to redux (and get data from realm on app init)
* Lint
* code style
* password show/hide feature
* fix show/hide password
* password show/hide
* Crashlytics (#258)
* Fabric iOS
* Fabric configured on iOS and Android
* login tracked
* more logs
* fix reaction
* CI fix
* Bug fixes (#261)
* Layout fixes
* RoomsListView's SafeAreaView
* Unhandled promise rejection fix
* Prevent navigation from opening scenes twice
* Create channel fixes
* Create LICENSE
* Beta (#265)
* Fabric iOS
* Fabric configured on iOS and Android
* - react-native-fabric configured
- login tracked
* README updated
* Run scripts from README updated
* README scripts
* get rooms and messages by rest
* user status
* more improves
* more improves
* send pong on timeout
* fix some methods
* more tests
* rest messages
* Room actions (#266)
* Toggle notifications
* Search messages
* Invite users
* Mute/Unmute users in room
* rocket.cat messages
* Room topic layout fixed
* Starred messages loading onEndReached
* Room actions onEndReached
* Unnecessary login request
* Login loading
* Login services fixed
* User presence layout
* ïmproves on room actions view
* Removed unnecessary data from SelectedUsersView
* load few messages on open room, search message improve
* fix loading messages forever
* Removed state from search
* Custom message time format
* secureTextEntry layout
* Reduce android app size
* Roles subscription fix
* Public routes navigation
* fix reconnect
* - New login/register, login, register
* proguard
* Login flux
* App init/restore
* Android layout fixes
* Multiple meteor connection requests fixed
* Nested attachments
* Nested attachments
* fix check status
* New login layout (#269)
* Public routes navigation
* New login/register, login, register
* Multiple meteor connection requests fixed
* Nested attachments
* Button component
* TextInput android layout fixed
* Register fixed
* Thinner close modal button
* Requests /me after login only one time
* Static images moved
* fix reconnect
* fix ddp
* fix custom emoji
* New message layout (#273)
* Grouping messages
* Message layout
* Users typing animation
* Image attachment layout
* Fabric and image fix (#284)
* Fixed images not showing
* Keyboard libs updated
* Fabric fix and location removed (#286)
* Proguard disabled
* message with list + links fixed (#288)
* Better image cache component (#292)
* react-native-img-cache removed
* Improve list render
* Support <http://link/Text> inside markdown
* Deep linking (#291)
* deep linking
* Basic deep link working
* Deep link routing
* Multiple servers working
* Send user to the room
* Avatar initials and room type icon (#298)
* Deep linking fix and more (#294)
* Fix - Any https link was deep linking to RocketChat
* Keyboard dismiss after add new server
* Room info bug fix
* Opacity animation
* Navigation when adding server fixed
* Throttle for unnecessary render on receiving several messages
* Search inputs without autocorrect and autocapitalize
* Search messages fixed
* Messagebox unnecessary render and spotlight fixed
* react-native-keyboard-input updated
* Lint
* Tests updated
* Update all dependencies (#299)
* Update react-navigation to the latest version 🚀 (#293)
* fix(package): update react-navigation to version 2.0.0
* Code updated to support breaking changes of react-navigation
* Detox tests E2E (#283)
* RoomsListView re-render (#304)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
- [x] Removed unnecessary re-renders on RoomsListView
* [NEW] Broadcast channels (#301)
* Broadcast channels
* e2e tests
* New markdown (#306)
Our current markdown is causing a lot of issues on Android devices, since it wraps everything inside a Text component.
On Android, Text doesn't support View as a child.
This PR adds react-native-markdown-renderer, that uses View as wrapper and may be better.
* Fixed audio recording issues (#310)
* Fix for "java.lang.IllegalArgumentException: unexpected url" (#313)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
User was able to add an invalid instance of Rocket.Chat by pressing submit button instead of "Connect" button.
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* I18n (#312)
* Unread and date separator layout improved (#319)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
- [x] Unread and date separator layout
- [x] "Start of conversation"/"Loading messages" label
![screen shot 2018-05-30 at 18 10 43](https://user-images.githubusercontent.com/804994/40747867-0424964a-6435-11e8-9293-31cc43c110ab.png)
![screen shot 2018-05-30 at 18 09 05](https://user-images.githubusercontent.com/804994/40747868-04484784-6435-11e8-8c31-92e0776276f0.png)
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [FIX] iOS Universal links (#318)
* [NEW] Drawer (#322)
* [FIX] invalid user muted value
* Ddp fixes (#324)
* [NEW] User Profile (#323)
* Drawer layout
* Drawer changes
* Profile
* Profile avatar
* Set language
* Tests
* Custom fields
* Readme updated
* fix invalid user muted value
* Fix for "Cannot add a child that doesn't have a YogaNode to a parent without a measure function! (Trying to add a 'RCTVirtualText' to a 'RCTView')"
* Settings/Permissions improvements (#325)
* Changed the way we read RocketChat settings since setting.type won't be returned from server anymore
* Permissions
* Unnecessary action sheet render
* Update gradle and targetSdkVersion (#328)
* Changed the way we read RocketChat settings since setting.type won't be returned from server anymore
* Permissions
* Unnecessary action sheet render
* Update gradle
* Switched testServer to use blob
* RoomsListHeader search fixed
* Runs loadMessagesForRoom only if room has at least 20 rows
* - Logout if user's token expired
- Removed update avatar logic
- Profile dialog border on android
* - Animations disabled
- CircleCI set
* Tests updated
* "eventType argument is required" fix
* Switch push notification lib (#346)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #342
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Allow x-instance-id and X-Instance-ID header (#354)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #137
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
Some server configurations may send x-instance-id header with different case.
* Image upload improvements (#368)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
- [x] Crop image
- [x] Type image description (like web)
- [x] Show upload progress
- [x] "Try again" in case of error
- [x] Cancel upload while in progress
- [x] [Android] Zoom on photos
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![image](https://user-images.githubusercontent.com/804994/42526934-a12da304-844d-11e8-8668-f3d69369726a.png)
![image](https://user-images.githubusercontent.com/804994/42527829-297945fe-8450-11e8-9f0e-9e668dd33043.png)
* [NEW] Room Loading(#372)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [FIX] Empty room name for livechat (#375)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #320
Closes #209
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [NEW] Reply preview (#374)
* Updated to React Native 0.56
* Reply Preview
* [FIX] Close websocket (#379)
* Fixed a bug when closing websocket
* removeListener fixed
* [I18N] Russian translation (#381)
[I18N] Russian translation file
* [NEW] Icon (#383)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![image](https://user-images.githubusercontent.com/804994/43228416-d8af49d6-9037-11e8-8830-a1803932c7fd.png)
* [FIX] Android 8 notifications (#382)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #380
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Added CocoaPods to manage react-native-image-crop-picker (#373)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
react-native-image-crop-picker raised an error when uploading to TestFlight.
The lib highly recommends CocoaPods for production builds.
* Added single-server to readme (#390)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #386
Closes #295
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Improve RoomsList render time (#384)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
- [x] Added FlatList.getItemLayout() to improve list render time
- [x] Some texts were breaking lines at sidebar
- [x] Removed onPress from links at RoomsListView
- [x] Added eslint rule to prevent unused styles
- [x] Fixed auto focus bug at CreateChannel and NewServer
- [x] Fix change server bug
- [x] Fixed a bug when resuming in ListServer
- [x] I18n fixed
- [x] Fixed a bug on actionsheet ref not being created
- [x] Reply wasn't showing on Android
- [x] Use Notification.Builder.setColor/getColor only after Android SDK 23
- [x] Listen to app state only when inside app
- [x] Switched register push token position in order to improve login performance
- [x] When deep link changes server, it doesn't refresh rooms list
- [x] Added SafeAreaView in all views to improve iPhone X experience
- [x] Subpath regex #388
* [NEW] Empty room background (#412)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #398
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-09-2018 11-35-32](https://user-images.githubusercontent.com/804994/43906080-cbfadf92-9bc8-11e8-9ac9-44f43d3af023.gif)
![aug-09-2018 11-35-16](https://user-images.githubusercontent.com/804994/43906082-cc19411c-9bc8-11e8-9892-c65c86951a91.gif)
![image](https://user-images.githubusercontent.com/804994/43911366-ad830cd0-9bd5-11e8-8913-6a7e87a2206c.png)
* Add roadmap (#406)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #45
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [NEW] Onboarding (#407)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #392
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-07-2018 17-03-50](https://user-images.githubusercontent.com/804994/43799447-f62074dc-9a63-11e8-8aac-bf2c4c5a8a2b.gif)
![aug-07-2018 17-03-35](https://user-images.githubusercontent.com/804994/43799446-f5f84a70-9a63-11e8-8947-265113ae9bf4.gif)
![aug-07-2018 17-03-13](https://user-images.githubusercontent.com/804994/43799445-f5d70ee6-9a63-11e8-94a9-f49c7d69fbba.gif)
* [NEW] Updated Logo on Splash screen (#409)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #399
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-07-2018 17-39-44](https://user-images.githubusercontent.com/804994/43801415-739a0cca-9a69-11e8-8bec-d65f751e6a28.gif)
![aug-07-2018 17-31-12](https://user-images.githubusercontent.com/804994/43801416-73d19bd6-9a69-11e8-90ac-bbc7ddeed938.gif)
* [FIX] Only single attachment rendered (#417)
* [NEW] Rooms list layout (#413)
* RoomsListView layout
* Rooms list layout
* Sort component
* Header icons
* Default header colors
* Add server dropdown
* Close sort dropdown if server dropdown will open
* UserItem
* Room type icon
* Search working
* Tests updated
* Android layout
* Using realm queries instead of array iterates
* Animation duration
* Fixed render bug
* [NEW] Create channel layout (#420)
* RoomsListView layout
* Rooms list layout
* Sort component
* Header icons
* Default header colors
* Add server dropdown
* Close sort dropdown if server dropdown will open
* UserItem
* Room type icon
* Search working
* Tests updated
* Android layout
* Using realm queries instead of array iterates
* Animation duration
* Fixed render bug
* - NewMessageView
- backButtonTitle always empty
- SearchBox created
* New create channel layout
* Search refactored
* loginSuccess dismiss modal
* Tests working
* [FIX] Open unsupported videos on browser (#422)
* 1.1
* Sort/group rooms local only (#425)
* Update android api from ci
* Sort local only
* [FIX] Missing current server (#427)
* server.current removed
* Increased area of touch on header
* Hide search when sort dropdown is tapped
* default server icon url
* 1.1.1
* [NEW] Experimental Icon (#430)
* [NEW] Message layout (#426)
* message container/component
* Separator component
* Reply
* Url
* tests updated
* Minor changes
* Audio component
* Broadcast button
* Minor touches
* Reply preview
* Edited
* Minor bug fixes
* - Update roadmap
- Bump version to 1.2
* Onboarding styles fix
* [FIX] Drawer navigation won't refresh chats (#432)
* Avoid errors on Audio/Image/Video (#443)
* Bump version to 1.2.1 (#444)
* Stop supporting Android 4.4 and lower (#447)
* Several fixes for 1.2.1 (#448)
* Fix user.roles
* Better onLongPress handle on messages
* Indicator position
* Fix role undefined in system messages
* Add baseUrl in case of file attachments
* Join room fixed
* RoomView params
* Broadcast fixes
* Add server layout changes
* Use native images
* Subscribe to not joined channels
* Fix alerts without i18n
* Tests updated
* Bump version to 1.2.2 (#449)
* [NEW] Use community JSC for Android (#450)
* [NEW] Use community JSC for Android
* Quick fix on unread chats
* [NEW] Show app version (#454)
* [NEW] Portuguese translation (#452)
* [NEW] Portuguese translation
* Remove servers from sidebar
* Update dependencies (#431)
* Update dependencies
* Lint and test
* Added react-native fork
* rn 57
* Lint and tests updated
* Update xcode on circleci
* Use legacy build system
* Update tests
* Use inline requires (#459)
* Update dependencies
* Lint and test
* Added react-native fork
* rn 57
* Lint and tests updated
* Update xcode on circleci
* Use legacy build system
* Update tests
* Inline requires
* Fix eslint and remove temp gradle
* Unnecessary renders
* Update isNotch and Readme
* Tests updated
* Bump version to 1.3.0 (#461)
* Better touch handling on rooms list (#462)
* Use react-native-gesture-handler at RoomItem
* Fixed info message author
* Edit message render improvement
* Fix ws to http replace
* Bump version to 1.3.1 (#463)
* Composer layout tweaked (#464)
* Composer layout tweaked
* Fix localization error
* Bump version to 1.3.2
* [FIX] Handle deleted messages (#466)
* [FIX] Handle deleted messages
* Fix rest error
* Fix some connection issues
* [FIX] Search rooms (#468)
* Bump version to 1.3.3 (#469)
* Connecting to DDP badge (#471)
* Display custom fields on user info (#476)
* Render custom fields on user info
* renderCustomFields fix
* Display custom fields in user info
* Fix lint error
* [FIX] DDP badge wasn't hiding on fast connections (#477)
* Use Rocket.Chat JS SDK (#481)
* JS SDK
* API working
* Multiple servers
* Bump version to 1.4.0 (#482)
* [FIX] 2FA and LDAP (#488)
* [FIX] Unread rooms group order (#487)
* Use grouping setting on temp messages (#486)
* [FIX] Delete room error (#485)
* Rename to Rocket.Chat Experimental (#483)
* Update dependencies (#484)
* Bump version to 1.4.0 (#482)
* test
* one more test
* Fix build
* Regression: Wait for unmount to delete database after logout (#489)
* Bump version to 1.4.1 (#490)
* Regression: Crash on Android search (#492)
* Bump version to 1.4.2 (#493)
* Update Rocket.Chat.js.SDK (#494)
* Bump version to v1.4.3 (#495)
* [FIX] OAuth (#496)
* Smaller header icons inside the room (#499)
* [FIX] Logout (#497)
* [FIX] Logout
* Removed realm instances on rooms list
* Bump version to 1.4.4 (#498)
* Update navigation library (#501)
* v2
* Working on Android 0.57.3
* Drawer working
* Removing v1 navigator
* - Splash screen
- Icons changed
* Deeplink
* Remove EventEmitter from CreateChannelView
* Android search
* Android notifications
* OAuth
* Fix search props
* Lint and tests fixed
* Fix android build
* Improvements on iPhone X* usage
* Fix detox
* Fix android build
* Room.f added to RoomView.shouldComponentUpdate
* Animations on RoomsListView and RoomView
* Fix topbar buttons on Android
* Bump version to 1.5.0 (#503)
* Check $FABRIC_KEY availability in CircleCI (#506)
* Check $FABRIC_KEY in CircleCI
* Remove config scripts
* Check $FABRIC_KEY availability in CircleCI for iOS (#507)
* [I18n] Add Simplified Chinese(zh-CN) locale (#505)
* [FIX] iOS pop gesture not working properly (#509)
* Check if lastMessage has an attachment and show "User sent an attachment" at RoomsList (#510)
* [FIX] Messages not being loaded properly (#513)
* Fetch avatar initials from server (#512)
* Fix iOS pop gesture and open sidemenu gesture (#511)
* Bump version to 1.5.1 (#516)
* [NEW] Room header layout (#521)
* Clear iOS notification on resume/open (#520)
* [FIX] Flashing avatars on Android after #512 (#519)
* [FIX] App connects to previous server instead of the recent added (#518)
* [FIX] Room view header crashes when destructuring reducer (#523)
* [FIX] Dismiss keyboard on room close (#530)
* [FIX] Composer composer's send icon slowness (#528)
* [WIP] New Authentication layout (#536)
New Authentication layout
* Regression: Resend messages with error (#532)
* DDP Connection badge animation changed (#533)
* [FIX] Upload buttons on Android (#541)
* Bump version to 1.6.0 (#543)
* I18n: Add missing translation of simplified Chinese (#539)
* Update dependencies (#544)
* AndroidManifest changes
* Regression: Deep linking stopped working after react-native-navigation update (#549)
* [FIX] Android stuck on splash screen after hardware back button is pressed (#550)
* [FIX] Android stuck on splash screen after hardware button is pressed
* Fix empty user at asyncstorage
* Remove unused subscribe
* [FIX] x-instance-id header prop is case insensitive (#551)
* Bump version to 1.6.1 (#553)
* [FIX] x-instance-id header prop is case insensitive
* Use Rest API calls (#558)
* Chats: Don't show group header if none of the filters is selected (#560)
* [CHORE] Update Xcode image version on CircleCI (#561)
* Bump version to 1.7.0 (#562)
* [FIX] Load messages on notification tap (#564)
* Use Rest API pt 2 (#568)
* Room files
* Pinned messages
* Starred messages
* Mentioned messages
* Search messages
* Bug fixes
* Profile
* Livechat
* Block/unblock user
* Erase room
* Archive room
* Remove unused method
* Bug fix
* [CHORE] Add hold step on CircleCI before TestFlight (#572)
* [FIX] GET /info to check if it's a valid server instead of x-instance-id (#573)
* Bump version to 1.7.1 (#574)
* Unnecessary re-renders removed (#570)
* shouldComponentUpdate
* Rooms list shouldcomponentupdate
* RoomView shouldComponentUpdate
* Messagebox and Message shouldComponentUpdate
* EmojiPicker shouldComponentUpdate
* RoomActions shouldComponentUpdate
* Room info shouldComponentUpdate
* Update RNN
* Use only one Flatlist if none group filter is selected
* Update fix
* shouldComponentUpdate
* Bug fixes
* ListView changes
* Bug fix
* render list bug fix
* Changes on public channels
* - RoomView saga leak removed
- Join room e2e tests added
* Rest versions
* Method call versions
* Min RocketChat version alert
* Update dependencies (#587)
* [FIX] Better message actions (#567)
* [FIX] Back button press on message actions (#592)
* Bump version to 1.8.0 (#595)
* [FIX] LDAP login (#596)
* Create class to manage navigation (#594)
* Add Navigation class
* Place Drawer.js logic inside of Navigation
* Load less views at startup
* [FIX] v1.8.0 (#599)
* Downgrade react-native-fast-image
* Update iOS permission usage descriptions
* [FIX] Delete upload item
* Update JS SDK version (#602)
* Add Icons class (#611)
Creates Icons class to manage when to load icons from native side or react-native-vector-icons.
It also fixes `react-native run-android` #517
* Updating room indicator (#609)
Shows "Updating..." when requesting rooms from Rest API.
* [FIX] Load avatar on servers that prevent unauthenticated avatar access (#604)
App would show an empty space on servers that require authentication on avatar access
* [FIX] 2FA login in a server with LDAP enabled (#612)
* [FIX] Start loop searching for rooms updates only when connection goes down and SDK has userId (#613)
* Allow to create empty channel (#615)
* [FIX] Reply title should break text (#616)
* Bump version to 1.9.0 (#617)
* [FIX] SDK issues (#621)
* Remove listeners from room
* Properly close connections on change server
* Minor layout change on connecting badge
* [CHORE] Add TestFlight invite and update Readme (#623)
* [FIX] npm -> yarn dependencies migration (#622)
* I18n: Add French (#629)
* [FIX] Remove rooms listener (#630)
* [CHORE] Update issue template (#638)
* I18n: Add German (#641)
* Bump version to 1.10.0 (#644)
* [FIX] Prevent mass is typing dispatchs (#651)
* [FIX] Handle database errors properly (#650)
* [FIX] Change actions labels (#654)
* [FIX] Room members filter (#655)
* [FIX] uploadProgress is not a function (#656)
* [FIX] Slow messagebox (#658)
* Remove drawer (#653)
* Remove drawer (layout needs to be changed in future releases, though)
* Don't navigate outside on logout if there's other logged server
* Update react-native-navigation
* Message button (#660)
* Remove touchable opacity when scrolling messages
* Tap on disable messages closes keyboard
* Unify vibration
* Vibrate only on Android
* [FIX] Fetch rooms date (#662)
* [FIX] Select emoji error (#666)
* Update Realm to 2.24 (#667)
* Update React Native to 0.58.6 (#668)
* [FIX] Fix some language issues in German language (#664)
* New icons (#643)
* New Icons
* Remove unused assets
* Change send icon
* Layout tweaks
* Refactor Status
* Styles changed
* User layout fix
* Separator layout changes
* Sidebar status layout fix
* Fix Message.onLongPress issue
* Fix code markdown
Closes https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/625
* Status lint
* Fix tests
* Navigation debounce
* RoomActions icons
* Space between components
* Group text
* Update tests
* [CHORE] Remove .debug suffix on Android (#681)
* [FIX] Fix null native Messagebox component object (#680)
* Fix null native Messagebox component object
* [iOS] Fix header alignment
* Remove unused files
* Switch to react-navigation (#687)
* Update readme (#714)
* Bump to 1.10.1 (#731)
* [FIX] Deep linking between multiple logged servers (#730)
* Fix handle invisible status (#692)
* I18n: Add Portuguese (Portugal) (#722)
* [FIX] Show ActivityIndicator in RoomMembersView (#686)
* Bump version to 1.11.0 (#761)
* Migrate from GCM to FCM (#760)
* [NEW] Scrollable room name feature (#756)
* [NEW] Scroll down floating button (#735)
* [CHORE] Added Storybook documentation (#757)
* Use FlatList in RoomView (#762)
* [FIX] iOS requiring location permission (#768)
* Room item layout (#771)
* [NEW] Draft message per room (#772)
* [FIX] Add Realm.safeAddListener (#785)
* [CHORE] Remove tvOS target (#779)
* [NEW] Discussions (#696)
* Bump version to 1.12.0 (#804)
* [NEW] Threads (#798)
* RoomsListView improvements (#819)
* [FIX] Giphy not showing (#810)
* [FIX] Apply emojify on empty texts (#824)
* Lock drawer when stack is not on root screen (#825)
* Room item layout (#835)
* [FIX] Threads (#838)
Closes #826
Closes #827
Closes #828
Closes #829
Closes #830
Closes #831
Closes #832
Closes #833
* [FIX] Smaller thread title (#846)
* [FIX] Smaller thread title
* Remove markdown notation from thread title
* On message press debounce
* Align vertical thread title
* [Regression] Search stopped working on Android after LastMessage refactor (#851)
* Load legal pages from web (#849)
* Update fetch permissions api (#850)
* Update custom emojis endpoint (#852)
* Update emoji endpoint
* Use React.memo on Markdown
* Support RC versions lower than 0.75.0
* Realm migration
* Fetch roles from rest api (#853)
* Fetch roles from rest api
* Fix RoomInfoView role get
* Remove roles from redux
* Bump version to 1.13 (#857)
* Active users improvements (#855)
* Remove connection badge (#862)
* Connecting indicator on RoomsListView header
* Connecting indicator on RoomView header
* Remove ConnectionBadge
* Show updating on RoomView load messages
* Update dependencies (#863)
* Minor updates
* Update jsc-android
* Update react-native-modal
* Minor updates
* Update react-native-fast-image
* Minor dev updates
* Few major updates
* Update react-native-keyboard-aware-scroll-view
* Update pods
* Update android-support
* Update tests
* Remove duplicated getRoleDescription function (#866)
* [FIX] Load local URL image (#871)
* [FIX] Toggle/follow thread icon (#867)
* Tweaks on sequential threads messages layout (#858)
* Tweaks on sequential threads messages
* Update tests
* Fix quote
* Prevent from deleting thread start message when positioned inside the thread
* Remove thread listener from RightButtons
* Fix error on thread start parse
* Stop parsing threads on render
* Check replied thread only if necessary
* Fix messages don't displaying
* Fix threads e2e
* RoomsListView.updateState slice
* Stop fetching hidden messages on threads
* Set initialNumToRender to 5
* [FIX] Check if room is mounted before setting state (#864)
* Tweaks on sequential threads messages
* Update tests
* Fix quote
* Prevent from deleting thread start message when positioned inside the thread
* Remove thread listener from RightButtons
* Fix error on thread start parse
* Stop parsing threads on render
* Check replied thread only if necessary
* Fix messages don't displaying
* Fix threads e2e
* RoomsListView.updateState slice
* Stop fetching hidden messages on threads
* Check if RoomView is mounted before rendering
* Refactor navigation events on RoomsListView
* Fix lint
* Fix listener
* [FIX] Typing not getting cleared after popping a room (#873)
* [CHORE] Remove e2e tests from CI (#875)
* [FIX] Remove listeners on RoomView header unmount (#874)
* [RELEASE] Merge beta into master (#1055)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [RELEASE] Merge beta into master (#1082)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [FIX] Swipe animations (#1044)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Fix favorite button
* [FIX] Auto-translate messages as they arrive (#1049)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* [FIX] Auto-translate messages as they arrive
* [i18n] Add missing de translations (#1040)
* [CHORE] Switch to react-native-localize (#1043)
* Bump version to 1.17.0 (#1057)
* Load views as needed (#1056)
* [IMPROVEMENT] Change "resend" icon position (#1048)
* [NEW] Video support (#801)
* [NEW] File upload (#882)
* [NEW] Share extension (#942)
* [FIX] Share extension CI build (#1060)
* Change bundleID
* Provisioning
* get provisioning profile
* [IMPROVEMENT] Reusable toast (#1065)
* [FIX] Moment locales (#1066)
* [FIX] Share Extension issues (#1064)
* [FIX] Empty white list enables all media types upload (#1077)
* Merge branch 'master' into develop (#1079)
* [FIX] Empty white list enables all media types upload (#1080)
* Create utils to media (canUpload)
* Fix variable name
* [CHORE] Update README (#1081)
* [RELEASE] Merge beta into master (#1088)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [FIX] Swipe animations (#1044)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Fix favorite button
* [FIX] Auto-translate messages as they arrive (#1049)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* [FIX] Auto-translate messages as they arrive
* [i18n] Add missing de translations (#1040)
* [CHORE] Switch to react-native-localize (#1043)
* Bump version to 1.17.0 (#1057)
* Load views as needed (#1056)
* [IMPROVEMENT] Change "resend" icon position (#1048)
* [NEW] Video support (#801)
* [NEW] File upload (#882)
* [NEW] Share extension (#942)
* [FIX] Share extension CI build (#1060)
* Change bundleID
* Provisioning
* get provisioning profile
* [IMPROVEMENT] Reusable toast (#1065)
* [FIX] Moment locales (#1066)
* [FIX] Share Extension issues (#1064)
* [FIX] Empty white list enables all media types upload (#1077)
* Merge branch 'master' into develop (#1079)
* [FIX] Empty white list enables all media types upload (#1080)
* Create utils to media (canUpload)
* Fix variable name
* [CHORE] Update README (#1081)
* [FIX] Media share type (#1086)
* [RELEASE] Merge beta into master (#1142)
* [RELEASE] Merge beta into master (#1174)
* [RELEASE] Merge beta into master (#1282)
* Merge beta into master (#1461)
* Merge beta into master (#1637)
* Merge beta into master (#1759)
* Merge beta into master (#1897)
* [FIX] Close SortDropdown on sort select (#1230)
* [FIX] Cancel upload and check failed upload (#1232)
* [FIX] Slash commands not cleaning is typing and not using state (#1233)
* [FIX] Dispatch roomsRequest on app foreground event even if not connected (#1234)
* [CHORE] Update react-native-jitsi-meet (#1235)
* [FIX] Regex on run slash command (#1223)
* Update React Native to 0.61.1 (#1236)
* Update React Native to 0.61.1
* Update patch to SSL Pinning
* Revert storybook
* [CHORE] Update react-native-safe-area-view (#1219)
* [FIX] Try/catch JSON.parse XHR response (#1238)
* [FIX] Change messagebox icon immediate on change text (#1241)
* [FIX] Update last open on message stream received (#1240)
* [FIX] Remove animation from RoomsListView.willFocus (#1239)
* [FIX] Delete message on thread (#1214)
* [REGRESSION] Markdown text (#1242)
* [FIX] Jest (#1243)
* [FIX] Avatar shown when useRealName is activated (#1162)
* Fix avatar when use real name
* Wrong indentation
* [DOCS] Add SECURITY.md (#1244)
* [CHORE] Update react-native-reanimated to 1.3.0 (#1246)
* [FIX] Run credentials migration only once (#1245)
* [CHORE] Update react-native-jitsi-meet to 2.0.1 (#1249)
* [FIX] Messagebox onChangeText issues (#1252)
* Stop ongoing debounces on messagebox unmount
* Immediately change send icon, but keep debouncing others
* Make CustomEmoji stateless function
* Fix mentions keyExtractor
* [FIX] Room subscription issues (#1255)
* [FIX] Reaction press (#1258)
* [FIX] Channel avatars not showing after application unloads (#1264)
* Revert react-native-safe-area-view (#1265)
* [FIX] Remove console on production mode (#1268)
* [FIX] Messages preview issues (#1257)
* [FIX] Select user from native credentials (#1266)
* [FIX] Some issues on preview message (#1271)
* [FIX] Audio player track and thumb not rendering on Android (#1273)
* [FIX] Record audio message throws exception when FileSystem.getInfoAsync is called (#1272)
* [FIX] China shouldn't use CallKit (#1274)
* [FIX] Watermelon batches (#1277)
* Bump version to 1.20.1 (#1285)
* [CHORE] Remove memoize-one (#1284)
* [FIX] End Jitsi call on unmount (#1291)
* [FIX] Allow self-signed certificates (#1310)
* [FIX] Set User-Agent (#1318)
* Set User-Agent Fetch & Websocket & XHR
* Set User-Agent
* Custom User Agent on fetch/websocket
* Fix names
* Use DeviceInfo
* fix server with subpath (#1322)
* [FIX] Server with https:\\ instead of https:// (#1320)
* [FIX] Server dropdown not closing after changing stack (#1299)
* [FIX] Invalid server version (#1319)
* [IMPROVEMENT] Respect "Hide counter" preference (#1306)
* [FIX] Pass isFocused as a function to Messagebox (#1309)
* [CHORE] Remove icons folder (#1290)
* [CHORE] Refactor RoomItem touchable (#1331)
* [FIX] Unnecessary rerender on RoomItem when status is undefined (#1336)
* [UPDATE DEPS] react-navigation and react-navigation-stack (#1337)
* [FIX] Avatars not loading on share extension when Accounts_AvatarBlockUnauthenticatedAccess is enabled (#1339)
* Bump version to 1.20.2 (#1340)
* [FIX] Remove some unnecessary re-renders on Messagebox (#1341)
* [REGRESSION] Use LayoutAnimation instead of Transition API (#1338)
* [FIX] Remove setState from notifications view causing watermelon object to be updated outside an action (#1342)
* [IMPROVEMENT] Save last message as message when subscription is updated (#1344)
* [UPDATE DEPS] Update RN to 0.61.3 (#1345)
* [DOCS] Update Readme (#1346)
* [CHORE] Remove react-native-scrollable-tab-view fork (#1352)
* [FIX] URL preview (#1360)
* [REGRESSION] Decrease list view memory size (#1361)
* [FIX] Paste (#1350)
* [CHORE] Update gems (#1365)
* Bump version to 1.20.3 (#1366)
* [FIX] Use Ruby 2.4 on TestFlight upload (#1368)
* [FIX] Parse Urls (#1371)
* [FIX] Parse image URL only if it's not empty (#1372)
* [FIX] Load messages issues (#1373)
* Bump version to 1.21.0 (#1376)
* [FIX] Crowd login (#1381)
* [FIX] Clicking user avatar in thread previews crashes app (#1363)
* [IMPROVEMENT] Error messages on connect (#1379)
* [FIX] ProfileView input navigation error when custom fields aren't set (#1383)
* [FIX] Batch server deletion on logout (#1382)
* Bump app to 1.22.0 (#1387)
* [FIX] Server Version (#1392)
* Update patch and minor deps (#1386)
* [FIX] Crash when open thread (#1395)
* Bump version to 1.23.0 (#1394)
* [I18N] Update ru.js (#1384)
* [FIX] CAS building wrong URL (#1362)
* [FIX] Delete messages (#1399)
* [FIX] In-app notification showing wrong content on channels (#1400)
* Bump version to 1.24.0 (#1404)
* [FIX] Prevent server with whitespace (#1402)
* [IMPROVEMENT] Keyboard and content type on login (#1403)
* [FIX] Messages stop loading (#1410)
* [NEW] Tablet support (#1300)
* [IMPROVEMENT] Authentication via deep linking (#1418)
* [IMPROVEMENT] Markdown performance when identifying emoji only content (#1422)
* [FIX] BackHandler remove random failing on development (#1423)
* Bump version to 1.25.0 (#1424)
* [CHORE] Update CI Xcode Image (#1430)
* [FIX] Rooms grouping not working properly (#1435)
* [FIX] Take a video (#1437)
* [NEW] Themes (#1298)
* [FIX] Share extension doesn't reconnect to previous selected server on Android (#1429)
* [FIX] Init local settings on notification tap (#1438)
* Bump version to 1.26.0 (#1450)
* [FIX] Emoji parser not working on Hermes (#1445)
* [NEW] Enable Hermes (#1446)
* [FIX] Automatic theme repeating (#1457)
* [CHORE] Sync Experimental and Official app versions (#1458)
* [DOCS] Update readme (#1459)
* [FIX] Messages being sent but showing as temp status (#1469)
* [FIX] Missing messages after reconnect (#1470)
* [FIX] Few fixes on themes (#1477)
* [I18N] Missing German translations (#1465)
* Missing German translation
* adding a missing space behind colon
* added a missing space after colon
* and another attempt to finally fix this – got confused by all the branches
* some smaller fixes for the translation
* better wording
* fixed another typo
* [FIX] Crash while displaying the attached image with http on file name (#1401)
* [IMPROVEMENT] Tap app and server version to copy to clipboard (#1425)
* [NEW] Reply notification (#1448)
* [FIX] Incorrect background color login on iPad (#1480)
* [FIX] Prevent multiple tap on send (Share Extension) (#1481)
* [NEW] Image Viewer (#1479)
* [DOCS] Update Readme (#1485)
* [FIX] Jitsi with Hermes Enabled (#1523)
* [FIX] Draft messages not working with themed Messagebox (#1525)
* [FIX] Go to direct message from members list (#1519)
* [FIX] Make SAML wait for idp token instead of creating it on client (#1527)
* [FIX] Server Test Push Notification (#1508)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Update to new server response (#1509)
* [FIX] Insert messages with blank users (#1529)
* Bump version to 4.2.1 (#1530)
* [FIX] Error when normalizing empty messages (#1532)
* [REGRESSION] CAS (#1570)
* Bump version to 4.2.2 (#1571)
* [FIX] Add username block condition to prevent error (#1585)
* Bump version to 4.2.3
* Bump version to 4.2.4
* Bump version to 4.3.0 (#1630)
* [FIX] Channels doesn't load (#1586)
* [FIX] Channels doesn't load
* [FIX] Update roomsUpdatedAt when subscriptions.length is 0
* [FIX] Remove unnecessary changes
* [FIX] Improve the code
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Make SAML to work on Rocket.Chat < 2.3.0 (#1629)
* [NEW] Invite links (#1534)
* [FIX] Set the http-agent to the form that Rocket.Chat requires for logging (#1482)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] "Following thread" and "Unfollowed Thread" is hardcoded and not translated (#1625)
* [FIX] Disable reset button if form didn't changed (#1569)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Header title of RoomInfoView (#1553)
* [I18N] Gallery Permissions DE (#1542)
* [FIX] Not allow to send messages to archived room (#1623)
* [FIX] Profile fields automatically reset (#1502)
* [FIX] Show attachment on ThreadMessagesView (#1493)
* [NEW] Wordpress auth (#1633)
* [CHORE] Add Start Packager script (#1639)
* [CHORE] Update RN to 0.61.5 (#1638)
* [CHORE] Update RN to 0.61.5
* [CHORE] Update react-native patch
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* Bump version to 4.3.1 (#1641)
* [FIX] Change force logout rule (#1640)
* Bump version to 4.4.0 (#1643)
* [IMPROVEMENT] Use MessagingStyle on Android Notification (#1575)
* [NEW] Request review (#1627)
* [NEW] Pull to refresh RoomView (#1657)
* [FIX] Unsubscribe from room (#1655)
* [FIX] Server with subdirs (#1646)
* [NEW] Clear cache (#1660)
* [IMPROVEMENT] Memoize and batch subscriptions updates (#1642)
* [FIX] Disallow empty sharing (#1664)
* [REGRESSION] Use HTTPS links for sharing and markets protocol for review (#1663)
* [FIX] In some cases, share extension doesn't load images (#1649)
* [i18n] DE translations for new invite function and some minor fixes (#1631)
* [FIX] Remove duplicate jetify step (#1628)
minor: also remove 'cd' calls
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [REGRESSION] Read messages (#1666)
* [i18n] German translations missing (#1670)
* [FIX] Notifications crash on older Android Versions (#1672)
* [i18n] Added Dutch translation (#1676)
* [NEW] Omnichannel Beta (#1674)
* [NEW] Confirm logout/clear cache (#1688)
* [I18N] Add es-ES language (#1495)
* [NEW] UiKit Beta (#1497)
* [IMPROVEMENT] Use reselect (#1696)
* [FIX] Notification in Android API level less than 24 (#1692)
* [IMPROVEMENT] Send tmid on slash commands and media (#1698)
* [FIX] Unhandled action on UIKit (#1703)
* [NEW] Pull to refresh RoomsList (#1701)
* [IMPROVEMENT] Reset app when language is changed (#1702)
* [FIX] Small fixes on UIKit (#1709)
* [FIX] Spotlight (#1719)
* [CHORE] Update react-native-image-crop-picker (#1712)
* [FIX] Messages Overlapping (Android) and MessageBox Scroll (iOS) (#1720)
* [REGRESSION] Remove @ and # from mention (#1721)
* [NEW] Direct message from user info (#1516)
* [FIX] Delete slash commands (#1723)
* [IMPROVEMENT] Hold URL to copy (#1684)
* [FIX] Different sourcemaps generation for Hermes (#1724)
* [FIX] Different sourcemaps generation for Hermes
* Upload sourcemaps after build
* [REVERT] Show emoji keyboard on Android (#1738)
* [FIX] Stop logging react-native-image-crop-picker (#1745)
* [FIX] Prevent toast ref error (#1744)
* [FIX] Prevent reaction map error (#1743)
* [FIX] Add missing calls to user info (#1741)
* [FIX] Catch room unsubscribe error (#1739)
* [i18n] Missing German keys (#1735)
* [FIX] Missing i18n on MessagesView title (#1733)
* [FIX] UIKit Modal: Weird behavior on Android Tablet (#1742)
* [i18n] Missing key on German (#1747)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Add Italian (#1736)
…
* [CHORE] Improve ISSUE_TEMPLATE.md (#2390)
* Bump version to 4.11.0 (#2392)
* [i18n] Update fr.js (#2380)
* Update fr.js
* Update fr.js
* Update fr.js
* Update fr.js
* Update fr.js
* Update fr.js
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Add to internal lane instead of alpha (#2400)
* [CHORE] Remove Google Services files from repo (#2405)
* Android
* iOS
* [FIX] Fix broken StatusView on tablet (#2407)
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* [FIX] REST for method calls not raising errors (#2408)
* [FIX] REST for Method calls not raising erorrs
* Remove unnecessary lint disable
* [NEW] Encrypt user credentials and preferences (#2247)
* install react-native-mmkv-storage
* wip ios migration
* change all js rn-user-defaults -> react-native-mmkv-storage
* remove all rn-user-defaults native references (iOS)
* android migration from rn-user-defaults to react-native-mmkv-storage
* ios app group accessible mmkv
* handle get errors
* remove access of credentials from legacy native apps
* remove data of user defaults
* remove no longer necessary import
* js mmkv encryption
* run migration only once
* reply from notification android
* fix app group key access at native level ios
* encrypt user credentials using a specific key
* ios encrypt with random key
* use a random key at the first encryption
* encrypt migrated data on js land
* remove unused function
* reply notifications ios should be working
* use fix instanceID
* android ejson retrieve encrypted data
* remove encryption migrated data for a while
* encryption working between app and share extension
* fix patch react-native-notifications
* ssl pinning working using mmkv encrypted data
* improve react-native-notifications
* run encrypt migration data only once
* fix build
* fix patches magic string
* fix mmkv id
* mmkv -> userPreferences
* fix instance id on android migration
* cast our oldest sharedPreferences string into an object
* revert log remove
* create currentServer Rocket.Chat key
* wrap mmkv api class
* change the get logic
* move userPreferences to lib
* move encrypt migrated data to userPreferences class
* check if the new object is new before insert
* invalidate ci yarn cache
* fix sort migration from android shared preferences
* fix splashscreen forever
* invalidate yarn cache
* invalidate yarn cache
* fix patch
* Minor change
* fix android notifications looking for wrong mmkv instance
* Fix some issues on iOS mmkv native access
* Remove unnecessary code
* Fix notification reply and ssl pinning
* WIP NotificationService use MMKV credentials
* Add KeychainGroup
* Notification idOnly get credentials from mmkv
* Some fixes
* Invalidate yarn cache
* Pods
* Use MMKVAppExtension on NotificationService
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Use font icons on login services (#2412)
* Replace font
* Use CustomIcon
* Remove native assets
* [FIX] SharedPreferences data migration (#2413)
* [IMPROVEMENT] Move directory to header (#2414)
* [FIX] Android crashing on receive a notification (#2415)
* [NEW] User notification preferences (#2403)
* Button to preferences view
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Create screen to preferences and listItem to notifications
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Refactoring NotificationPreferencesView
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* List notification preferences
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Adding translations to labels
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* SetUserPreferences api call
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Saving new user preference in API
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix lint
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Add in-app notification test
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix in app mentions preference
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Improve object in testInAppNotification
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Removing improper options for NotificationpreferencesView
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Adding API version
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Use redux in UserNotificationPrefView
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Remove in app test
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Use components from another view
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Removing verification for testing in-app notifications
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Move to ProfileView
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Verify Enterprise status on Omnichannel (#2399)
* Add enterpriseModules on Redux
* Fetch enterprise modules and put on redux
* hasLicense
* Clear modules
* Hide omnichannel rooms
* Minor refactor
* Hide omnichannel toggle
* Check license on user status
* Apply on search
* lint
* Look for 'livechat-enterprise'
* One module is enough to enable the features
* Unhide omnichannel rooms
* Sort tweaks
* Move omnichannel toggle to RoomsListView
* Remove omnichannel toggle from SettingsView
* Fix toggle
* Ask to enable omnichannel
* Lint
* Fix issues found on review
* [FIX] Change some icons (#2419)
* [FIX] User Preferences (#2418)
* [FIX] User Preferences
* PreferencesView -> UserPreferencesView
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Customize Sign in with Apple button (#2420)
* [Snyk] Security upgrade lodash from 4.17.19 to 4.17.20 (#2416)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-LODASH-590103
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Add to F-Droid (#2171)
* create play and foss build
* update package.json to generate each build
* check1
* requested changes
* initial commit
* Update config.yml
* minor changes
* remove bugsnag from foss build
* remove bugsnag tasks from foss job
* fix stuck screen
* fixes
* update
* fix lint
* finalise 🚀
* requested changes
* share app for fdroid
* update
* use negation for builds
* requested change
* update share app
* fix issues due to latest sync
* add extra line
* fix lint
* update
* update
* fix bugsnag issue
* Update config.yml
* Fix store url
* Foss release instead of debug
* Add hold for foss
* Fix build
* requested changes
* update name and icons
* update
* fix
* Revert "Bump version to 4.11.0 (#2392)"
This reverts commit ea287980d9
.
* finalise
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Commit pods after #2171 (#2424)
* [IMPROVEMENT] Add subscription and room events on the same batch queue (#2423)
* [IMPROVEMENT] Add subscription and room events on the same batch queue
* Send both params
* Unused var
* [IMPROVEMENT] Show "Chats in Progress" group (#2425)
* [NEW] Logout from other logged in locations (#2386)
* Logout from other logged in locations
* Add UI feedback for the request result
* Refactor request to use the proper REST API
* Change backgroundColor
* I18n
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App can't reopening a room in some cases (#2429)
* [FIX] Logout from custom oauth (#2377)
* New field in table of users
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Saving when the user logged in with email and password
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Saving login method info
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Ask for the user to clear cookies
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix lint
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Removing loginMethod from redux and add I18n
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Using async/await instead of then/catch
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix lint
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Pods
* Added dismissText on showConfirmationAlert
* Fix iOS
* Rename function
* I18n tweaks
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Wrong date and time shown in file section (#2409)
* Adding missing prop to item object
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Resolving the missing date in the files section in a more elegant way
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Using ts attribute always inside of an item object
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Verify useRealName setting on files screen (#2427)
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Apply theme on Directory description (#2428)
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Wrong merge resolution after #2171 (#2431)
* [FIX] Upload to internal looking for the wrong path after #2171 (#2432)
* [FIX] Detox tests (#2433)
* Spotlight issues
* Fix room tests
* Fix roomactions tests
* [FIX] Crashlytics reportError not working after #2171 (#2436)
* [FIX] Logout from custom oauth when using password (#2435)
* [FIX] Logout from custom oauth when using password
* Remove an useless const
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Move toggle and inquiry to Enterprise Edition license (#2426)
* [IMPROVEMENT] Move toggle and inquiry to Enterprise
* Move inquiry stream to ee
* Emit inquiry subscribe
* imports to ee last
* Add readme to ee
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [CHORE] App Group path as a iOS constant (#2439)
* [FIX] Chrome debugging
* Remove rn-fetch-blob
* [CHORE] Use Rocket.Chat JS SDK's official repo (#2440)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Disable HTTP for production on Android (#2357)
* Only enable HTTP and user CAs on debug builds and
* Allow User CAs in prod
* Add config on debug
* Add lint
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] E2E Encryption (#2394)
* Add E2EKey to Subscription Model
* Install react-native-simple-crypto
* Install bytebuffer
* Add translations
* CreateChannel Encrypted toggle
* Request E2E_Enabled setting
* Add some E2E API methods
* POC E2E Encryption
* Garbage remove
* Remove keys cleaner
* Android cast JWK -> PKCS1
* Initialize E2E when Login Success
* Add some translations
* Add e2e property to Message model
* Send Encrypted messages
* (iOS) PKCS1 -> JWK & e2e.setUserPublicAndPrivateKeys
* (Android) PKCS1 -> JWK & e2e.setUserPublicAndPrivateKeys
* Create an encrypted channel
* Fix app crashing on RoomsList
* Create room key
* Set Room E2E Key (Android)
* Edit room encrypted
* Show encrypted icon on messages
* logEvents
* Decrypt pending subscriptions & messages
* Handle user cancel e2e password entry
* E2ESavePasswordView
* Update Snapshot
* Add encrypted props to message on Send
* Thread messages encryption
* E2E -> Encryption
* Share Extension: Share encrypted text
* (POC) Search messages on Encrypted room
* Provide room key to new users
* Request roomKey on stream-notify-room-users
* Add e2eKeyId to Room Model
* (WIP) E2E Encryption Screens
* Remove encryption subscription file
* Move E2E_Enable to Server Model
* Encryption List Banner
* Move Encryption init to Sagas
* Show banner only when enabled
* Use RocketChat/react-native-simple-crypto
* Search on WM only when is an Encrypted channel
* (WIP) Encryption Banner
* Encryption banner
* Patch -> Fork
* Improve send encrypted message
* Update simple-crypto
* Not decrypt already decrypted messages
* Add comments
* Change eslint disable to inline
* Improve code
* Remove comment
* Some fixes
* (WIP) Encryption Screens
* Improve sub find
* Resend an encrypted message
* Fix comment
* Code improvements
* Hide e2e buttons on features if it is not enabled
* InApp notifications of a encrypted room
* Encryption stop logic
* Edit encrypted message
* DB batch on decryptPending
* Encryption ready client
* Comments
* Handle getRoomInstance errors
* Multiple messages decrypt
* Remove unnecessary try/catch
* Fix decrypt all messages history
* Just add a questionmark
* Fix some subscriptions missing decrypt
* Disable request key logic
* Fix unicode emojis
* Fix e2ekey request
* roomId -> subscription
* Decrypt subscription after merge
* E2ERoom -> EncryptionRoom
* Fix infinite loading
* Handle import key errors
* Handle request key errors
* Move e2eRequestRoomKey to Rocket.Chat
* WIP handshake when key should be requested
* Add search messages explanation
* Remove some TODO and update comments
* Improvements
* Dont show message hash to user
* Handle key request & prevent multiple calls
* Request E2EKey on decryptSubscription that doesn't exists on database yet
* Insert decrypted subscription
* Fix crash after login
* Decrypt sub when receive the key
* Decrypt pending messages of a room
* Encrypted as a switch
* Buffer to Base64 URI Safe
* Add a relevant comment
* Prevent import key without a privateKey
* Prevent create a new instance when client is not ready
* Update simple-crypto & remove replace trick
* More comments
* Remove useless comment
* Remove useless try/catch
* I18n all E2E screens
* E2ESavePassword -> E2ESaveYourPassword
* Prevent multiple views on message when is not encrypted
* Fix encryption toggle not working sometimes
* follow some suggestions
* dont rotate icons
* remove unnecessary condition
* remove unreachable event
* create channel comment
* disable no-bitwise rule for entire file
* loadKeys -> persistKeys
* getMasterKey -> generateMasterKey
* explicit difference between E2EKey & e2eKeyId
* roomId -> rid
* group columns
* Remove server selector
* missing log events
* remove comment
* use stored public key
* update simple-crypto & remove base64-js patch
* add some logs
* remove unreachable condition
* log errors
* handle errors on provide key directly on subscription
* Downgrade RocketChat/react-native-simple-crypto
* improve get room instance
* migration of older apps
* check encrypted status before send a message
* wait client ready
* use our own base64-js
* add more jest tests
* explain return
* remove unncessary stop
* thrown error to caller
* remove superfluous checks
* use Encryption property
* change ready state logic
* ready -> establishing
* encryption.room -> encryptionRoom
* EncryptionRoom -> Room
* add documentation
* wait establishing before provide a room key
* remove superfluous condition
* improve error handling logic
* fallback e2ekey set
* remove no longer necessary check
* remove e.g.
* improve getRoomInstance
* import from index
* use batch
* fix a comment
* decrypt tmsg
* dont show hash when message is encrypted
* Fix detox
* Apply suggestions from code review
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Update run-ios and run-android scripts (#2450)
* [IMPROVEMENT] Show errors on server enter (#2449)
* Catching errors
* [IMPROVEMENT] Show errors on server enter
* "Not rc server" instead of "invalid or insecure url" msg
* [NEW] Show server history (#2421)
* Add dropdown
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Adding new table to serverSchema
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Saving if not exists
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* list of visited servers finished
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Fix lint
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* Rename ServerLinks to ServersHistory
* Refactor
* Save username
* Sort servers desc
* ServerInput
* Item
* Refactor
* Layout tweaks
* Layout
* query by text
* Small refactor
* Redirecting to login
* Save username for oauth
* Fix keyboard persist
* Add tests
* Unnecessary yield
* Stop rendering FlatList logic when there's no servers on history
* Dismiss keyboard and autocomplete when tapped outside server TextInput
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Toggle analytics events (#2422)
* Create flow to toggle analytics events on memory
* Persist toggle analytics events
* Update crash report to contemplate analytics events
* Minor tweaks
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Local database searches using non-latin characters (#2462)
* [FIX] Local database searches using non-latin characters
* Add tests
* [FIX] Read receipt crashing in some cases (#2464)
* [IMPROVEMENT] Add "Allow_Save_Media_to_Gallery" setting (#2459)
* [IMPROVEMENT] Add "Allow_Save_Media_to_Gallery" setting
* Default true for old servers
* [FIX] Jitsi breaking changes (#2468)
* [FIX] Jitsi breaking changes
* Update yarn cache
* Update WatermelonDB to 0.19.0 (#2469)
* [FIX] Jitsi breaking changes
* Update yarn cache
* Update watermelon to 0.19
* [FIX] SanitizeLikeString util crashes for empty strings (#2471)
* [i18n] Add Traditional Chinese (zh_TW) (#2465)
* I18n: Add Traditional Chinese language file(zh_TW)
* Minor fixes
* I18n: Add missing translation and fix some weird words
* fix escape char
* Fix minor issues
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18n] Improve Simplified Chinese (zh_CN) (#2466)
* I18n: Improve Simplified Chinese(zh_CN) language file
* I18n: Add missing translation
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Simplify i18n files (#2472)
* [FIX] Remove assets from share extension on iOS (#2473)
* [CHORE] Change database location to Experimental Apps (#2483)
* change database location of experimental apps
* fix migration from older versions
* [FIX] WatermelonDB caching Date as String (#2484)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] E2E Encryption push (Android) (#2481)
* poc push encryption android
* eof
* format code
* react-native-simple-crypto update
* prevent find sub twice
* remove storage and use ejson storage
* invalidate yarn cache
* Bump crypto and fix db path
* Fix google-services path
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Language set by web client (#2488)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Improve Chinese translation (zh-TW, zh-CN) (#2486)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Add missing italian strings (#2487)
fix some existing ones too
* [NEW] E2E Encryption push (iOS) (#2463)
* link pods to notification service
* push encryption poc
* decrypt room key poc
* read user key from mmkv and cast into a pkcs
* push decrypt poc (iOS)
* expose needed watermelon methods
* watermelon -> database
* indent & simple-crypto update
* string extensions
* storage
* toBase64 -> toData
* remove a forced unwrap
* remove unused import
* database driver
* improvement
* folder structure & watermelon bridge
* more improvement stuff
* watermelon -> database
* reuse database instance
* improvement
* database fix: bypass watermelon cache
* some code improvements
* encryption instances
* start api stuff
* network layer
* improve notification service
* improve folder structure
* watermelon patch
* retry fetch logic
* rocketchat class
* fix try to decrypt without a roomKey
* fallback to original content that is translated
* some fixes to rocketchat logic
* merge develop
* remove unnecessary extension
* [CHORE] Improve reply notification code (iOS)
* undo sign changes
* remove mocked value
* import direct from library
* send message request
* reply notification with encrypted message working properly
* revert apple sign
* fix api onerror
* trick to display sender name on group notifications
* revert data.host change
* fix some multithread issues
* use sendername sent by server
* small improvement
* Bump crypto lib
* Update ios/NotificationService/NotificationService.swift
* add experimental string
* remove trailing slash
* remove trailing slash on reply
* fix decrypt messages
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [REGRESSION] HTTP Basic Auth (#2490)
* [FIX] Logout when install fresh Official and Experimental iOS app (#2493)
* [FIX] Show images in iOS 14 (#2494)
* [DOCS] Add Reactotron (#2498)
* Update about the inspection tool for our app.
Information about the Reactotron tool was missing in the contribution file.
* Update CONTRIBUTING.md
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [REGRESSION] SSL Pinning stopped working after #2449 (#2510)
* [CHORE] Reset yarn cache (#2512)
* [FIX] Fastlane iOS (#2513)
* [IMPROVEMENT] Add F-Droid modules as AdditionalModules (#2530)
* [IMPROVEMENT] Add F-Droid modules as AdditionalModules
* Fix missing import
* [CHORE] Use App Store Connect API Key (#2549)
* [CHORE] Use App Store Connect API Key
* Update bundle
* rollback keychain
* Remove keychain
* Keychain is actually needed
* Update gitignore
* [FIX] Failing iOS build on fork PR (#2558)
* Fix fastlane build for a fork PR
* Change the iOS fastlane command to build_fork
* [FIX] Avatar cache invalidation (#2311)
* [WIP] Avatar cache invalidation
* [WIP] Avatar container
* [IMPROVEMENT] Avatar container
* [CHORE] Improve code
* Allow static image on Avatar
* Fix avatar changing while change username (#1583)
Co-authored-by: Prateek93a <prateek93a@gmail.com>
* Add default props to properly update on Sidebar and ProfileView
* Fix subscribing on the wrong moment
* Storyshots update
* RoomItem using Avatar Component
* use iife to unsubscribe from user
* Use component on avatar container
* RoomItem as a React.Component
* Move servers models to servers folder
* Avatar -> AvatarContainer
* Users indexed fields
* Initialize author and check if u is present
* Not was found -> User not found (turn comments more relevant)
* RoomItemInner -> Wrapper
* Revert Avatar Touchable logic
* Revert responsability of LeftButton on Tablet Mode
* Prevent setState on constructor
* Run avatarURL only when its not static
* Add streams RC Version
* Move entire add user logic to result.success
* Reorder init on RoomItem
* onPress as a class function
* Fix roomItem using same username
* Add avatar Stories
* Fix pick an image from gallery on ProfileView
* get avatar etag on select users of create discussion
* invalidate ci cache
* Fix migration
* Fix sidebar avatar not updating
Co-authored-by: Prateek93a <prateek93a@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Channel avatars (#2504)
* [WIP] Avatar cache invalidation
* [WIP] Avatar container
* [IMPROVEMENT] Avatar container
* [CHORE] Improve code
* Allow static image on Avatar
* Fix avatar changing while change username (#1583)
Co-authored-by: Prateek93a <prateek93a@gmail.com>
* Add default props to properly update on Sidebar and ProfileView
* Fix subscribing on the wrong moment
* Storyshots update
* RoomItem using Avatar Component
* use iife to unsubscribe from user
* Use component on avatar container
* RoomItem as a React.Component
* Move servers models to servers folder
* Avatar -> AvatarContainer
* Users indexed fields
* Initialize author and check if u is present
* Not was found -> User not found (turn comments more relevant)
* RoomItemInner -> Wrapper
* Revert Avatar Touchable logic
* Revert responsability of LeftButton on Tablet Mode
* Prevent setState on constructor
* Run avatarURL only when its not static
* Add streams RC Version
* Move entire add user logic to result.success
* Reorder init on RoomItem
* onPress as a class function
* Fix roomItem using same username
* Add avatar Stories
* Fix pick an image from gallery on ProfileView
* Format Avatar URL to use RoomId.
Co-authored-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* edit room avatar
* invalidate cache of room images
* reinit avatar if something change
* read avatar cache on search
* room avatar changed system message
* add avatar by rid test
* update snapshot
* etag cache on select channel
* reset room avatar
* increase caching to have a better image quality
* fix lgtm warn
* invalidate ci cache
* get avatar etag on select users of create discussion
* invalidate ci cache
* Fix migration
* Fix sidebar avatar not updating
* Remove outdated comment
* Tests
Co-authored-by: Prateek93a <prateek93a@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
Co-authored-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com>
* [IMPROVEMENT] List Component (#2506)
* List.Item
* section
* Start removing theme as prop
* Remove StatusBar theme prop
* SafeAreaView theme prop
* Minor fixes
* List.Container
* Add translateTitle and translateSubtitle props
* Storybook
* Show action indicator
* Header
* Info
* Theme stories
* FlatList
* DisplayName
* Fix settings
* FlatList tweaks
* ThemeView
* Screen Lock Config
* DefaultBrowserView
* PickerView and User Prefs
* Notification Prefs
* StatusView
* Auto Translate
* InviteUsersEdit
* Visitor
* Minor fixes
* Remove Separator
* Remove iteminfo
* Font scale
* Legal
* Jitsi and e2e
* Block
* search, star, etc
* auto translate and notifications
* RoomInfo
* Refactor RoomActions
* lint
* Remove DisclosureIndicator
* padding horizontal 12
* Detox
* Tests
* Address review comments
* Fix vertical scroll
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [FIX] App always sends auth for Avatar requests (#2517)
* [FIX] Sending auth for Avatar requests when not necessary
* fix storybook
* Fix ShareListView not updating avatars
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] iOS uploads always cropping as squares (#2516)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Mentions layout without background (#2559)
* [IMPROVEMENT] Mentions layout without background
* Fix RoomItem
* Fix tests
* [IMPROVEMENT] Support badge number on header buttons (#2566)
* Beginning header buttons refactor
* Add HeaderButtons
* item with title
* Refactor
* Remove lib
* Refactor
* Update snapshot
* Refactor
* Update tests
* Lint
* [NEW] Threads (#2567)
* [IMPROVEMENT] Mentions layout without background
* Fix RoomItem
* Fix tests
* Smaller messagebox
* Messagebox colors tweak
* Beginning header buttons refactor
* Add HeaderButtons
* item with title
* Refactor
* Remove lib
* Refactor
* Update snapshot
* Send to channel on messagebox
* Add tshow
* Add showMessageInMainThread to login.user reducer
* Filter threads on main channel based on user setting
* Send tshow
* Add tunread
* Move unread colors logic away from UnreadBadge component so it can be used on other components
* Export UnreadBadge on index
* Add empty test
* Refactor
* Update tests
* Lint
* Thread unread user and group on RoomItem
* Thread badge working
* Started ThreadMessagesView.Item
* Fix separator
* Reactivity working
* Lint
* custom emojis aren't necessary
* Basic filter layout
* Filtering layout
* Refactor
* apply filter
* DropdownItemHeader
* default all
* few fixes
* No data found
* Fixes list performance issues
* Use locale on date formats
* Fixed minor styles
* Thread badge
* Refactor getBadgeColor
* Fix send to channel background color
* starting search threads
* Fix lint and tests
* Bump to 4.12.0 just for testing :)
* Search input layout
* query
* starting threads header
* fix unnecessary tlm on tmid messages
* Fix thread header
* lint
* Fix thread header on ShareView
* Add e2e tests
* Fix subscriptions sort
* Update stories and minor fixes
* Fix button sizes on Messagebox
* Remove comment
* Unnecessary conditional
* Add showMessageInMainThread to user collection
* Fix thread header
* Fix thread messages not working on tablet
* Reset Messagebox.tshow after sending a message
* Allow to send to channel when replying to a thread from main channel
* Unnecessary theme prop
* Address comments
* Remove re-render
* Fix scroll indicator bug
* Fix style
* Minor i18n fix
* Fix dropdown height
* I18n ptbr
* I18n
* [IMPROVEMENT] Android push notification as a heads-up notification (#2507)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Add `Change Encryption Password` and `Reset E2E Key` (#2542)
* init
* Basic tests passing
* Add SecurityPrivacyView
* List.Item
* section
* Start removing theme as prop
* Remove StatusBar theme prop
* SafeAreaView theme prop
* Minor fixes
* List.Container
* Add translateTitle and translateSubtitle props
* Storybook
* Show action indicator
* Header
* Info
* Theme stories
* FlatList
* DisplayName
* Fix settings
* FlatList tweaks
* ThemeView
* Screen Lock Config
* DefaultBrowserView
* PickerView and User Prefs
* Notification Prefs
* StatusView
* Auto Translate
* InviteUsersEdit
* Visitor
* Minor fixes
* Remove Separator
* Remove iteminfo
* Font scale
* Legal
* Jitsi and e2e
* Block
* search, star, etc
* auto translate and notifications
* RoomInfo
* Refactor RoomActions
* lint
* Remove DisclosureIndicator
* padding horizontal 12
* Detox
* Tests
* SecurityPrivacy
* E2E encryption sec view
* stash
* Reset own key
* Reset key
* Change password
* Hide content
* Small refactor
* Fix tests
* Tests passing
* Change test order
* add pt-br
* Address review comments
* tests
* Missing i18n ptbr
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [IMPROVEMENT] Branding update (#2580)
* iOS native icons
* Android native icons
* Foss native icons
* Experimental icon iOS
* Experimental
* Notification icon
* Splash screen
* Splash screen iOS
* Blue notification text
* Fix iOS Launch Screen Icon
* Experimental and foss
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Update Xcode to 12.1.0 (#2592)
* [CHORE] Update Xcode to 12.1.0
* Remove alpha from Xcode App Store Icon
* [IMPROVEMENT] Auto search when text changes in directory textfield (#2547)
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Rooms header overlapping right icons (#2503)
takes into account long names on small screen which led to overlapping title and right buttons on the header bar
* [IMPROVEMENT] Jitsi lean (#2534)
* 2.10.2
* update jitsi sdk
* use our own react-native-jitsi-meet
* use own android jitsi sdk
* remove jsc reference
* use self-builded ios sdk
* update react-native-jitsi-meet
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] German word fix (#2598)
Report in German means "The Report" not "to report". Therefor "Melden" ist better suited here.
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Improve Chinese translation (#2570)
* [FIX] App crashing when notification is received/replied (Android) (#2602)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Update react native CLI to support white labeling with XCode 12 (#2560)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Add missing German strings (#2571)
* adding missing German strings
* resolving conflict
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [REGRESSION] Avatars doesn't show up on older servers (< 3.6.0) (#2603)
* [REGRESSION] Avatars doesn't show up on older servers (< 3.6.0)
* fix: snapshots tests failing
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Missing locales in moment helper (#2562)
* [i18n] Add missing Russian strings (#2555)
* Added waiting for network string translate
* [i18n] Add missing russian strings
* Some E2E strings
* [i18n] Add missing russian strings
* Some grammatical changes and translate optimizations
* Add english strings
* Final translate
Co-authored-by: Карлан Антон Андреевич <KarlanAA@global.bcs>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] 'Send to channel' when replying as a quote (#2606)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Android notification on Dark Theme using Official main color (#2604)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Storybook not able to import Avatar (#2607)
* [FIX] Storybook not able to import Avatar
* Fix lint
* Mock Date.now
* Fix RU translation
* isLegacy -> serverVersion
* Remove change avatar from room info edit for servers below 3.6
* Mock for storyshots only
* lint
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [BUG] App isn't showing message for PDF/file uploads (#2584)
* Fixed the issue #2531
In app/containers/message/Reply.js added a View Contaier around the
Attachment Touchable and Added a Markdown attribute with msg set to
description of attachment to display the message if any.
* Added the condition to check if File Description Exists
Added an if statement to check if file description exists and if yes
then add a markdown with value msg equal to the description.
Also tested using 'yarn test -u' to add/update the tests.
* Made the requested Changes
Removed the condition to check for attachment description.
Added the `markdown` inside the touchable and wrapped `attachmentContainer` and the `markdown` inside a `<>` component
* Added file not showing message issue code in this branch
* Fixed the mistake in return
* fix
* Add tests
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Header title positioning not changing according to the number of icons (#2608)
* [DOCS] Update Android Supported versions (#2611)
* [i18n] Improve Russian translation (#2609)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] User notification preferences throwing an error when select default Email option (#2615)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] MomentJS crashing on Spanish language (#2616)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] AllowBackup manifest attribute causing unexpected behaviour on login (#2617)
* [FIX] Search messages crashing when show a thread message (#2618)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] F-Droid build for store (#2557)
* [FIX] F-Droid build for store
* Trying to make Override custom push notifications on play build only
* Use play sourceSets
* Change version code
* Fix react-native-config-reader
* [FIX] F-Droid build for store
* Trying to make Override custom push notifications on play build only
* Use play sourceSets
* Change version code
* Fix react-native-config-reader
* Remove react-native-device-info Google dependencies / Use LIBRE_BUILD of react-native-jitsi-meet
* Invalidate CI Cache
* Set specific jitsi-meet-sdk
* Specify 2.10.0-libre
* jitsi-meet using an url based on play build
* update react-native-jitsi-meet
* react-native-device-info foss
* undo some unnecessary changes
* Fix notifications
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* Merge beta into master (#2621)
* Sync develop on master (#275)
* Create LICENSE
* Sync master (#721)
* Merge 1.13.0 into Master (#936)
* fix last messages (#239)
* fix last messages
* Room actions (#231)
* Layout
* Empty starred list
* Favorite room
* Pinned messages
* fix last messages
* fix date on pinned messages
* fix package
* [NEW] OAuth (#241)
* Layout
* tmp
* test iscordova
* Webview redirecting
* Open and Close login actions
* Login services saved on redux
* OAuth Github
* Server regex fix
* OAuth modal style
* - Twitter login
- Remove services from redux
- Open login saga fix
* - Facebook login
- Fixed user agent
- Reactions fix
- Message url unique key fix
* Google login
* Email keyboard removed from messagebox
* - Login buttons refactored
- RoomList header
* Layout improvements
* Meteor login redirect_uri changed
* fix
* Random credentialToken state
* [NEW] Room actions: Mentioned messages and Room Members (#242)
* Mentioned messages
* Starred and pinned actions debounce
* Room members
* Open room on member touch
* [WIP] Improves (#245)
* hotfix for ios
* hotfix for ios
* Update config.yml
* Workaround for RN 0.54 on iOS (#246)
* Update iOS to RN 0.54 (#248)
* Update iOS to RN 0.54
* [WIP] Audio message functionality (#247)
* [NEW] Add module react-native-audio
* [WIP] Audio message basic UI
* [NEW] Record audio message
* Use cordova repository to get certificates
* Icon 1024
* [NEW] Room actions: block user, snippet messages, room files and leave room (#250)
* - Block user
- Load room members async
- fixed reactive change of room's read only flag
* Snippet messages
* - Room files
- Dismiss Video component on back button press
- Improvements on Image component
* Improvement on Video component
* Leave room
* Missing message types
* lint
* Reactotron working (#249)
* [NEW] Room info and Room info edit (#254)
* - Block user
- Load room members async
- fixed reactive change of room's read only flag
* Snippet messages
* - Room files
- Dismiss Video component on back button press
- Improvements on Image component
* Improvement on Video component
* Leave room
* Missing message types
* lint
* - Room info (read only)
- Missing message types
* Room info scroll
* - Tap on room header opens room info
- Layout tweaks
* - Room info edit
- iOS Toast fixed
* - Style not implemented actions as disabled
* Edit room permission
* - Save all room settings in a single call
- Implemented roomType and readOnly
* - Allow reacting when room is read only
* Message type added: room_changed_privacy
* Erase room
* Created TextInput and SwitchContainer components for reuse and readability
* - hasPermission method
* - Archive/Unarchive room
- Set Join Code
* Twitter keyboard type on iOS
* Archived room
* reactWhenReadOnly permission on message
* Active users refactored
* User roles
* - Subscribe to roles (in order to get role description info: e.g. 'core-team' to 'Rocket.Chat Team')
- Save roles to realm (for offline access)
- Save roles to redux (and get data from realm on app init)
* Lint
* code style
* password show/hide feature
* fix show/hide password
* password show/hide
* Crashlytics (#258)
* Fabric iOS
* Fabric configured on iOS and Android
* login tracked
* more logs
* fix reaction
* CI fix
* Bug fixes (#261)
* Layout fixes
* RoomsListView's SafeAreaView
* Unhandled promise rejection fix
* Prevent navigation from opening scenes twice
* Create channel fixes
* Create LICENSE
* Beta (#265)
* Fabric iOS
* Fabric configured on iOS and Android
* - react-native-fabric configured
- login tracked
* README updated
* Run scripts from README updated
* README scripts
* get rooms and messages by rest
* user status
* more improves
* more improves
* send pong on timeout
* fix some methods
* more tests
* rest messages
* Room actions (#266)
* Toggle notifications
* Search messages
* Invite users
* Mute/Unmute users in room
* rocket.cat messages
* Room topic layout fixed
* Starred messages loading onEndReached
* Room actions onEndReached
* Unnecessary login request
* Login loading
* Login services fixed
* User presence layout
* ïmproves on room actions view
* Removed unnecessary data from SelectedUsersView
* load few messages on open room, search message improve
* fix loading messages forever
* Removed state from search
* Custom message time format
* secureTextEntry layout
* Reduce android app size
* Roles subscription fix
* Public routes navigation
* fix reconnect
* - New login/register, login, register
* proguard
* Login flux
* App init/restore
* Android layout fixes
* Multiple meteor connection requests fixed
* Nested attachments
* Nested attachments
* fix check status
* New login layout (#269)
* Public routes navigation
* New login/register, login, register
* Multiple meteor connection requests fixed
* Nested attachments
* Button component
* TextInput android layout fixed
* Register fixed
* Thinner close modal button
* Requests /me after login only one time
* Static images moved
* fix reconnect
* fix ddp
* fix custom emoji
* New message layout (#273)
* Grouping messages
* Message layout
* Users typing animation
* Image attachment layout
* Fabric and image fix (#284)
* Fixed images not showing
* Keyboard libs updated
* Fabric fix and location removed (#286)
* Proguard disabled
* message with list + links fixed (#288)
* Better image cache component (#292)
* react-native-img-cache removed
* Improve list render
* Support <http://link/Text> inside markdown
* Deep linking (#291)
* deep linking
* Basic deep link working
* Deep link routing
* Multiple servers working
* Send user to the room
* Avatar initials and room type icon (#298)
* Deep linking fix and more (#294)
* Fix - Any https link was deep linking to RocketChat
* Keyboard dismiss after add new server
* Room info bug fix
* Opacity animation
* Navigation when adding server fixed
* Throttle for unnecessary render on receiving several messages
* Search inputs without autocorrect and autocapitalize
* Search messages fixed
* Messagebox unnecessary render and spotlight fixed
* react-native-keyboard-input updated
* Lint
* Tests updated
* Update all dependencies (#299)
* Update react-navigation to the latest version 🚀 (#293)
* fix(package): update react-navigation to version 2.0.0
* Code updated to support breaking changes of react-navigation
* Detox tests E2E (#283)
* RoomsListView re-render (#304)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
- [x] Removed unnecessary re-renders on RoomsListView
* [NEW] Broadcast channels (#301)
* Broadcast channels
* e2e tests
* New markdown (#306)
Our current markdown is causing a lot of issues on Android devices, since it wraps everything inside a Text component.
On Android, Text doesn't support View as a child.
This PR adds react-native-markdown-renderer, that uses View as wrapper and may be better.
* Fixed audio recording issues (#310)
* Fix for "java.lang.IllegalArgumentException: unexpected url" (#313)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
User was able to add an invalid instance of Rocket.Chat by pressing submit button instead of "Connect" button.
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* I18n (#312)
* Unread and date separator layout improved (#319)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
- [x] Unread and date separator layout
- [x] "Start of conversation"/"Loading messages" label
![screen shot 2018-05-30 at 18 10 43](https://user-images.githubusercontent.com/804994/40747867-0424964a-6435-11e8-9293-31cc43c110ab.png)
![screen shot 2018-05-30 at 18 09 05](https://user-images.githubusercontent.com/804994/40747868-04484784-6435-11e8-8c31-92e0776276f0.png)
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [FIX] iOS Universal links (#318)
* [NEW] Drawer (#322)
* [FIX] invalid user muted value
* Ddp fixes (#324)
* [NEW] User Profile (#323)
* Drawer layout
* Drawer changes
* Profile
* Profile avatar
* Set language
* Tests
* Custom fields
* Readme updated
* fix invalid user muted value
* Fix for "Cannot add a child that doesn't have a YogaNode to a parent without a measure function! (Trying to add a 'RCTVirtualText' to a 'RCTView')"
* Settings/Permissions improvements (#325)
* Changed the way we read RocketChat settings since setting.type won't be returned from server anymore
* Permissions
* Unnecessary action sheet render
* Update gradle and targetSdkVersion (#328)
* Changed the way we read RocketChat settings since setting.type won't be returned from server anymore
* Permissions
* Unnecessary action sheet render
* Update gradle
* Switched testServer to use blob
* RoomsListHeader search fixed
* Runs loadMessagesForRoom only if room has at least 20 rows
* - Logout if user's token expired
- Removed update avatar logic
- Profile dialog border on android
* - Animations disabled
- CircleCI set
* Tests updated
* "eventType argument is required" fix
* Switch push notification lib (#346)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #342
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Allow x-instance-id and X-Instance-ID header (#354)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #137
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
Some server configurations may send x-instance-id header with different case.
* Image upload improvements (#368)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
- [x] Crop image
- [x] Type image description (like web)
- [x] Show upload progress
- [x] "Try again" in case of error
- [x] Cancel upload while in progress
- [x] [Android] Zoom on photos
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![image](https://user-images.githubusercontent.com/804994/42526934-a12da304-844d-11e8-8668-f3d69369726a.png)
![image](https://user-images.githubusercontent.com/804994/42527829-297945fe-8450-11e8-9f0e-9e668dd33043.png)
* [NEW] Room Loading(#372)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [FIX] Empty room name for livechat (#375)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #320
Closes #209
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [NEW] Reply preview (#374)
* Updated to React Native 0.56
* Reply Preview
* [FIX] Close websocket (#379)
* Fixed a bug when closing websocket
* removeListener fixed
* [I18N] Russian translation (#381)
[I18N] Russian translation file
* [NEW] Icon (#383)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![image](https://user-images.githubusercontent.com/804994/43228416-d8af49d6-9037-11e8-8830-a1803932c7fd.png)
* [FIX] Android 8 notifications (#382)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #380
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Added CocoaPods to manage react-native-image-crop-picker (#373)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
react-native-image-crop-picker raised an error when uploading to TestFlight.
The lib highly recommends CocoaPods for production builds.
* Added single-server to readme (#390)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #386
Closes #295
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* Improve RoomsList render time (#384)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
- [x] Added FlatList.getItemLayout() to improve list render time
- [x] Some texts were breaking lines at sidebar
- [x] Removed onPress from links at RoomsListView
- [x] Added eslint rule to prevent unused styles
- [x] Fixed auto focus bug at CreateChannel and NewServer
- [x] Fix change server bug
- [x] Fixed a bug when resuming in ListServer
- [x] I18n fixed
- [x] Fixed a bug on actionsheet ref not being created
- [x] Reply wasn't showing on Android
- [x] Use Notification.Builder.setColor/getColor only after Android SDK 23
- [x] Listen to app state only when inside app
- [x] Switched register push token position in order to improve login performance
- [x] When deep link changes server, it doesn't refresh rooms list
- [x] Added SafeAreaView in all views to improve iPhone X experience
- [x] Subpath regex #388
* [NEW] Empty room background (#412)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #398
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-09-2018 11-35-32](https://user-images.githubusercontent.com/804994/43906080-cbfadf92-9bc8-11e8-9ac9-44f43d3af023.gif)
![aug-09-2018 11-35-16](https://user-images.githubusercontent.com/804994/43906082-cc19411c-9bc8-11e8-9892-c65c86951a91.gif)
![image](https://user-images.githubusercontent.com/804994/43911366-ad830cd0-9bd5-11e8-8913-6a7e87a2206c.png)
* Add roadmap (#406)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #45
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
* [NEW] Onboarding (#407)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #392
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-07-2018 17-03-50](https://user-images.githubusercontent.com/804994/43799447-f62074dc-9a63-11e8-8aac-bf2c4c5a8a2b.gif)
![aug-07-2018 17-03-35](https://user-images.githubusercontent.com/804994/43799446-f5f84a70-9a63-11e8-8947-265113ae9bf4.gif)
![aug-07-2018 17-03-13](https://user-images.githubusercontent.com/804994/43799445-f5d70ee6-9a63-11e8-94a9-f49c7d69fbba.gif)
* [NEW] Updated Logo on Splash screen (#409)
<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative
<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->
Closes #399
<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
![aug-07-2018 17-39-44](https://user-images.githubusercontent.com/804994/43801415-739a0cca-9a69-11e8-8bec-d65f751e6a28.gif)
![aug-07-2018 17-31-12](https://user-images.githubusercontent.com/804994/43801416-73d19bd6-9a69-11e8-90ac-bbc7ddeed938.gif)
* [FIX] Only single attachment rendered (#417)
* [NEW] Rooms list layout (#413)
* RoomsListView layout
* Rooms list layout
* Sort component
* Header icons
* Default header colors
* Add server dropdown
* Close sort dropdown if server dropdown will open
* UserItem
* Room type icon
* Search working
* Tests updated
* Android layout
* Using realm queries instead of array iterates
* Animation duration
* Fixed render bug
* [NEW] Create channel layout (#420)
* RoomsListView layout
* Rooms list layout
* Sort component
* Header icons
* Default header colors
* Add server dropdown
* Close sort dropdown if server dropdown will open
* UserItem
* Room type icon
* Search working
* Tests updated
* Android layout
* Using realm queries instead of array iterates
* Animation duration
* Fixed render bug
* - NewMessageView
- backButtonTitle always empty
- SearchBox created
* New create channel layout
* Search refactored
* loginSuccess dismiss modal
* Tests working
* [FIX] Open unsupported videos on browser (#422)
* 1.1
* Sort/group rooms local only (#425)
* Update android api from ci
* Sort local only
* [FIX] Missing current server (#427)
* server.current removed
* Increased area of touch on header
* Hide search when sort dropdown is tapped
* default server icon url
* 1.1.1
* [NEW] Experimental Icon (#430)
* [NEW] Message layout (#426)
* message container/component
* Separator component
* Reply
* Url
* tests updated
* Minor changes
* Audio component
* Broadcast button
* Minor touches
* Reply preview
* Edited
* Minor bug fixes
* - Update roadmap
- Bump version to 1.2
* Onboarding styles fix
* [FIX] Drawer navigation won't refresh chats (#432)
* Avoid errors on Audio/Image/Video (#443)
* Bump version to 1.2.1 (#444)
* Stop supporting Android 4.4 and lower (#447)
* Several fixes for 1.2.1 (#448)
* Fix user.roles
* Better onLongPress handle on messages
* Indicator position
* Fix role undefined in system messages
* Add baseUrl in case of file attachments
* Join room fixed
* RoomView params
* Broadcast fixes
* Add server layout changes
* Use native images
* Subscribe to not joined channels
* Fix alerts without i18n
* Tests updated
* Bump version to 1.2.2 (#449)
* [NEW] Use community JSC for Android (#450)
* [NEW] Use community JSC for Android
* Quick fix on unread chats
* [NEW] Show app version (#454)
* [NEW] Portuguese translation (#452)
* [NEW] Portuguese translation
* Remove servers from sidebar
* Update dependencies (#431)
* Update dependencies
* Lint and test
* Added react-native fork
* rn 57
* Lint and tests updated
* Update xcode on circleci
* Use legacy build system
* Update tests
* Use inline requires (#459)
* Update dependencies
* Lint and test
* Added react-native fork
* rn 57
* Lint and tests updated
* Update xcode on circleci
* Use legacy build system
* Update tests
* Inline requires
* Fix eslint and remove temp gradle
* Unnecessary renders
* Update isNotch and Readme
* Tests updated
* Bump version to 1.3.0 (#461)
* Better touch handling on rooms list (#462)
* Use react-native-gesture-handler at RoomItem
* Fixed info message author
* Edit message render improvement
* Fix ws to http replace
* Bump version to 1.3.1 (#463)
* Composer layout tweaked (#464)
* Composer layout tweaked
* Fix localization error
* Bump version to 1.3.2
* [FIX] Handle deleted messages (#466)
* [FIX] Handle deleted messages
* Fix rest error
* Fix some connection issues
* [FIX] Search rooms (#468)
* Bump version to 1.3.3 (#469)
* Connecting to DDP badge (#471)
* Display custom fields on user info (#476)
* Render custom fields on user info
* renderCustomFields fix
* Display custom fields in user info
* Fix lint error
* [FIX] DDP badge wasn't hiding on fast connections (#477)
* Use Rocket.Chat JS SDK (#481)
* JS SDK
* API working
* Multiple servers
* Bump version to 1.4.0 (#482)
* [FIX] 2FA and LDAP (#488)
* [FIX] Unread rooms group order (#487)
* Use grouping setting on temp messages (#486)
* [FIX] Delete room error (#485)
* Rename to Rocket.Chat Experimental (#483)
* Update dependencies (#484)
* Bump version to 1.4.0 (#482)
* test
* one more test
* Fix build
* Regression: Wait for unmount to delete database after logout (#489)
* Bump version to 1.4.1 (#490)
* Regression: Crash on Android search (#492)
* Bump version to 1.4.2 (#493)
* Update Rocket.Chat.js.SDK (#494)
* Bump version to v1.4.3 (#495)
* [FIX] OAuth (#496)
* Smaller header icons inside the room (#499)
* [FIX] Logout (#497)
* [FIX] Logout
* Removed realm instances on rooms list
* Bump version to 1.4.4 (#498)
* Update navigation library (#501)
* v2
* Working on Android 0.57.3
* Drawer working
* Removing v1 navigator
* - Splash screen
- Icons changed
* Deeplink
* Remove EventEmitter from CreateChannelView
* Android search
* Android notifications
* OAuth
* Fix search props
* Lint and tests fixed
* Fix android build
* Improvements on iPhone X* usage
* Fix detox
* Fix android build
* Room.f added to RoomView.shouldComponentUpdate
* Animations on RoomsListView and RoomView
* Fix topbar buttons on Android
* Bump version to 1.5.0 (#503)
* Check $FABRIC_KEY availability in CircleCI (#506)
* Check $FABRIC_KEY in CircleCI
* Remove config scripts
* Check $FABRIC_KEY availability in CircleCI for iOS (#507)
* [I18n] Add Simplified Chinese(zh-CN) locale (#505)
* [FIX] iOS pop gesture not working properly (#509)
* Check if lastMessage has an attachment and show "User sent an attachment" at RoomsList (#510)
* [FIX] Messages not being loaded properly (#513)
* Fetch avatar initials from server (#512)
* Fix iOS pop gesture and open sidemenu gesture (#511)
* Bump version to 1.5.1 (#516)
* [NEW] Room header layout (#521)
* Clear iOS notification on resume/open (#520)
* [FIX] Flashing avatars on Android after #512 (#519)
* [FIX] App connects to previous server instead of the recent added (#518)
* [FIX] Room view header crashes when destructuring reducer (#523)
* [FIX] Dismiss keyboard on room close (#530)
* [FIX] Composer composer's send icon slowness (#528)
* [WIP] New Authentication layout (#536)
New Authentication layout
* Regression: Resend messages with error (#532)
* DDP Connection badge animation changed (#533)
* [FIX] Upload buttons on Android (#541)
* Bump version to 1.6.0 (#543)
* I18n: Add missing translation of simplified Chinese (#539)
* Update dependencies (#544)
* AndroidManifest changes
* Regression: Deep linking stopped working after react-native-navigation update (#549)
* [FIX] Android stuck on splash screen after hardware back button is pressed (#550)
* [FIX] Android stuck on splash screen after hardware button is pressed
* Fix empty user at asyncstorage
* Remove unused subscribe
* [FIX] x-instance-id header prop is case insensitive (#551)
* Bump version to 1.6.1 (#553)
* [FIX] x-instance-id header prop is case insensitive
* Use Rest API calls (#558)
* Chats: Don't show group header if none of the filters is selected (#560)
* [CHORE] Update Xcode image version on CircleCI (#561)
* Bump version to 1.7.0 (#562)
* [FIX] Load messages on notification tap (#564)
* Use Rest API pt 2 (#568)
* Room files
* Pinned messages
* Starred messages
* Mentioned messages
* Search messages
* Bug fixes
* Profile
* Livechat
* Block/unblock user
* Erase room
* Archive room
* Remove unused method
* Bug fix
* [CHORE] Add hold step on CircleCI before TestFlight (#572)
* [FIX] GET /info to check if it's a valid server instead of x-instance-id (#573)
* Bump version to 1.7.1 (#574)
* Unnecessary re-renders removed (#570)
* shouldComponentUpdate
* Rooms list shouldcomponentupdate
* RoomView shouldComponentUpdate
* Messagebox and Message shouldComponentUpdate
* EmojiPicker shouldComponentUpdate
* RoomActions shouldComponentUpdate
* Room info shouldComponentUpdate
* Update RNN
* Use only one Flatlist if none group filter is selected
* Update fix
* shouldComponentUpdate
* Bug fixes
* ListView changes
* Bug fix
* render list bug fix
* Changes on public channels
* - RoomView saga leak removed
- Join room e2e tests added
* Rest versions
* Method call versions
* Min RocketChat version alert
* Update dependencies (#587)
* [FIX] Better message actions (#567)
* [FIX] Back button press on message actions (#592)
* Bump version to 1.8.0 (#595)
* [FIX] LDAP login (#596)
* Create class to manage navigation (#594)
* Add Navigation class
* Place Drawer.js logic inside of Navigation
* Load less views at startup
* [FIX] v1.8.0 (#599)
* Downgrade react-native-fast-image
* Update iOS permission usage descriptions
* [FIX] Delete upload item
* Update JS SDK version (#602)
* Add Icons class (#611)
Creates Icons class to manage when to load icons from native side or react-native-vector-icons.
It also fixes `react-native run-android` #517
* Updating room indicator (#609)
Shows "Updating..." when requesting rooms from Rest API.
* [FIX] Load avatar on servers that prevent unauthenticated avatar access (#604)
App would show an empty space on servers that require authentication on avatar access
* [FIX] 2FA login in a server with LDAP enabled (#612)
* [FIX] Start loop searching for rooms updates only when connection goes down and SDK has userId (#613)
* Allow to create empty channel (#615)
* [FIX] Reply title should break text (#616)
* Bump version to 1.9.0 (#617)
* [FIX] SDK issues (#621)
* Remove listeners from room
* Properly close connections on change server
* Minor layout change on connecting badge
* [CHORE] Add TestFlight invite and update Readme (#623)
* [FIX] npm -> yarn dependencies migration (#622)
* I18n: Add French (#629)
* [FIX] Remove rooms listener (#630)
* [CHORE] Update issue template (#638)
* I18n: Add German (#641)
* Bump version to 1.10.0 (#644)
* [FIX] Prevent mass is typing dispatchs (#651)
* [FIX] Handle database errors properly (#650)
* [FIX] Change actions labels (#654)
* [FIX] Room members filter (#655)
* [FIX] uploadProgress is not a function (#656)
* [FIX] Slow messagebox (#658)
* Remove drawer (#653)
* Remove drawer (layout needs to be changed in future releases, though)
* Don't navigate outside on logout if there's other logged server
* Update react-native-navigation
* Message button (#660)
* Remove touchable opacity when scrolling messages
* Tap on disable messages closes keyboard
* Unify vibration
* Vibrate only on Android
* [FIX] Fetch rooms date (#662)
* [FIX] Select emoji error (#666)
* Update Realm to 2.24 (#667)
* Update React Native to 0.58.6 (#668)
* [FIX] Fix some language issues in German language (#664)
* New icons (#643)
* New Icons
* Remove unused assets
* Change send icon
* Layout tweaks
* Refactor Status
* Styles changed
* User layout fix
* Separator layout changes
* Sidebar status layout fix
* Fix Message.onLongPress issue
* Fix code markdown
Closes https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/625
* Status lint
* Fix tests
* Navigation debounce
* RoomActions icons
* Space between components
* Group text
* Update tests
* [CHORE] Remove .debug suffix on Android (#681)
* [FIX] Fix null native Messagebox component object (#680)
* Fix null native Messagebox component object
* [iOS] Fix header alignment
* Remove unused files
* Switch to react-navigation (#687)
* Update readme (#714)
* Bump to 1.10.1 (#731)
* [FIX] Deep linking between multiple logged servers (#730)
* Fix handle invisible status (#692)
* I18n: Add Portuguese (Portugal) (#722)
* [FIX] Show ActivityIndicator in RoomMembersView (#686)
* Bump version to 1.11.0 (#761)
* Migrate from GCM to FCM (#760)
* [NEW] Scrollable room name feature (#756)
* [NEW] Scroll down floating button (#735)
* [CHORE] Added Storybook documentation (#757)
* Use FlatList in RoomView (#762)
* [FIX] iOS requiring location permission (#768)
* Room item layout (#771)
* [NEW] Draft message per room (#772)
* [FIX] Add Realm.safeAddListener (#785)
* [CHORE] Remove tvOS target (#779)
* [NEW] Discussions (#696)
* Bump version to 1.12.0 (#804)
* [NEW] Threads (#798)
* RoomsListView improvements (#819)
* [FIX] Giphy not showing (#810)
* [FIX] Apply emojify on empty texts (#824)
* Lock drawer when stack is not on root screen (#825)
* Room item layout (#835)
* [FIX] Threads (#838)
Closes #826
Closes #827
Closes #828
Closes #829
Closes #830
Closes #831
Closes #832
Closes #833
* [FIX] Smaller thread title (#846)
* [FIX] Smaller thread title
* Remove markdown notation from thread title
* On message press debounce
* Align vertical thread title
* [Regression] Search stopped working on Android after LastMessage refactor (#851)
* Load legal pages from web (#849)
* Update fetch permissions api (#850)
* Update custom emojis endpoint (#852)
* Update emoji endpoint
* Use React.memo on Markdown
* Support RC versions lower than 0.75.0
* Realm migration
* Fetch roles from rest api (#853)
* Fetch roles from rest api
* Fix RoomInfoView role get
* Remove roles from redux
* Bump version to 1.13 (#857)
* Active users improvements (#855)
* Remove connection badge (#862)
* Connecting indicator on RoomsListView header
* Connecting indicator on RoomView header
* Remove ConnectionBadge
* Show updating on RoomView load messages
* Update dependencies (#863)
* Minor updates
* Update jsc-android
* Update react-native-modal
* Minor updates
* Update react-native-fast-image
* Minor dev updates
* Few major updates
* Update react-native-keyboard-aware-scroll-view
* Update pods
* Update android-support
* Update tests
* Remove duplicated getRoleDescription function (#866)
* [FIX] Load local URL image (#871)
* [FIX] Toggle/follow thread icon (#867)
* Tweaks on sequential threads messages layout (#858)
* Tweaks on sequential threads messages
* Update tests
* Fix quote
* Prevent from deleting thread start message when positioned inside the thread
* Remove thread listener from RightButtons
* Fix error on thread start parse
* Stop parsing threads on render
* Check replied thread only if necessary
* Fix messages don't displaying
* Fix threads e2e
* RoomsListView.updateState slice
* Stop fetching hidden messages on threads
* Set initialNumToRender to 5
* [FIX] Check if room is mounted before setting state (#864)
* Tweaks on sequential threads messages
* Update tests
* Fix quote
* Prevent from deleting thread start message when positioned inside the thread
* Remove thread listener from RightButtons
* Fix error on thread start parse
* Stop parsing threads on render
* Check replied thread only if necessary
* Fix messages don't displaying
* Fix threads e2e
* RoomsListView.updateState slice
* Stop fetching hidden messages on threads
* Check if RoomView is mounted before rendering
* Refactor navigation events on RoomsListView
* Fix lint
* Fix listener
* [FIX] Typing not getting cleared after popping a room (#873)
* [CHORE] Remove e2e tests from CI (#875)
* [FIX] Remove listeners on RoomView header unmount (#874)
* [RELEASE] Merge beta into master (#1055)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [RELEASE] Merge beta into master (#1082)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [FIX] Swipe animations (#1044)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Fix favorite button
* [FIX] Auto-translate messages as they arrive (#1049)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* [FIX] Auto-translate messages as they arrive
* [i18n] Add missing de translations (#1040)
* [CHORE] Switch to react-native-localize (#1043)
* Bump version to 1.17.0 (#1057)
* Load views as needed (#1056)
* [IMPROVEMENT] Change "resend" icon position (#1048)
* [NEW] Video support (#801)
* [NEW] File upload (#882)
* [NEW] Share extension (#942)
* [FIX] Share extension CI build (#1060)
* Change bundleID
* Provisioning
* get provisioning profile
* [IMPROVEMENT] Reusable toast (#1065)
* [FIX] Moment locales (#1066)
* [FIX] Share Extension issues (#1064)
* [FIX] Empty white list enables all media types upload (#1077)
* Merge branch 'master' into develop (#1079)
* [FIX] Empty white list enables all media types upload (#1080)
* Create utils to media (canUpload)
* Fix variable name
* [CHORE] Update README (#1081)
* [RELEASE] Merge beta into master (#1088)
* Bump version to 1.16.0 (#1014)
* [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table
* ✨ Introduce user table
* 🔥 Remove unused table
* ➕ Add userdefaults to storage data
* 💚 Fix android build
* ✨ Get credentials from iOS native client
* 🔥 Remove unused code
* ⏪ Revert sign xcode
* 🐛 Fix first login-logout
* 🎨 Use constants to UserDefaults Keys
* 🐛 Fix clear server-user-info on logout
* 🐛 Fix filter null value
* 🚑 Remove user object in logout
* ✨ Fix get servers from native-client
* 🚑 Fix error on change server
* [FIX] Don't run UserDefaults credentials on Android (#1015)
* 🐛 Fix native credentials (android)
* Fix migration loop
* [IMPROVEMENT] Hide frequently used emoji tab when empty (#792)
* [IMPROVEMENT] Bigger emoji in emoji only messages (#793)
* issue #725: bigger emoji in emoji only message
* issue-725/add storybook for Message/Emoji
* issue-725: update storybook/Message jest snapshot
* comment storybook import
* allow spaces and line breaks in emoji only message
* merge develop
* revert unnecessary spacing
* [FIX] Empty message if contains only a link (#787)
* Fix empty message if contains only a link
* 🐛 Fix empty space
* [IMPROVEMENT] Refactor empty space regex on quote (#1017)
* 🎨 Improve regex to empty space on quote
* 🎨 Improve on regex to empty space on quote
* [NEW] Custom fields on signup (#1013)
* added custom feilds on registration
* added flag as leftIcon and removed lable
* added try and catch
* typo
* [CHORE] Renew provisioning profiles (#1020)
* [NEW] Auto-translate (#1012)
* Update realm
* View original and translate working
* Read AutoTranslate_Enabled setting
* RocketChat.canAutoTranslate()
* AutoTranslateView
* Save language
* Auto-translate switch
* Translate message
* [IMPROVEMENT] Use haptics rather than vibration (#1016)
* Install expo-haptics
* Use expo-haptics rather than RN's Vibration module
* [IMPROVEMENT] Use Rest API for file upload (#1005)
* removed rn-fetch-blob and use native XMLHttpRequest instead
* removed unnessary changes
* fix android bug
* fix android bug
* added tmid support
* fix bug
* fixed isssue with cacel model
* fix problems with audio
* done requested changes
* fix bug with android
* [CHORE] [CI] [TESTS] update detox to make ci pass (#1026)
* feat: update detox to 12.11.3 to make CI pass
* ci: comment all jobs but leave e2e-test job
* commit to rerun IC e2e-test job
* ci: uncomment all CI jobs
* [NEW] Room swipe actions: mark as read/unread, hide, fav (#976)
* added unread and fav feature
* changed the layout
* fix jest
* done requested changes
* added requested changes
* [FIX] Android build (#1027)
* [FIX] Android build
* CircleCI error
* [FIX] iOS share credentials build (#1028)
* [FIX] iOS share credentials build
* Use `hasMigration` as a string
* [CI] Restore cache on CI (#1029)
* feat: add fastlane save\restore cache config; comment not needed jobs;
* install fastlane using 'bundle install'
* install fastlane using 'sudo bundle install'
* uncomment ios build commands
* run set up google services in ios folder
* add working_directory: ios to ios-build steps
* remove 'cd ios' from Fastlane build step
* add save\restore cache for npm modules
* group save_cache steps
* cache fastlane in ios-testflight job
* uncomment previously commented jobs\steps
* fix: add missing colon
* use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
* add names for save\restore steps
* ci: add `default` step with `working_directory: ~/repo` to ios-build job
* return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}`
* fix: add missing curly braces
* save\restore cache in e2e-test job; remove {{arch}} from cache names
* add names to restore_cache steps in android-build job
* add names to save_cache steps in android-build job
* add names to all save\restore steps; change checksum package.json to yarn.lock
* change `npm` to `NPM` in steps naming
* remove {{ checksum circle ci }} from android-build job and fix naming of steps
* [FIX] Rooms swipes (#1034)
* Regression: on press style feedback
* Action button styles
* Fix animations
* Styles changed
* Update subscription without having to wait for socket
* Calculate width on RoomsListView instead
* [FIX] Decrease bigger emoji size to 30 (#1031)
* [FIX] Append server URL on avatar if necessary (#1038)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Bump version to 1.16.1 (#1045)
* [FIX] Set UserDefaults AppGroup on notification tap (#1047)
* [FIX] Auto-translate messages as they arrive
* Fix favorite button
* [FIX] Swipe animations (#1044)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* Fix favorite button
* [FIX] Auto-translate messages as they arrive (#1049)
* Comment removeClippedSubviews
* Comment width animation
* Remove redux from RoomItem
* Fix wrong re-render comparison
* Remove listener
* Raise minDeltaX
* memo actions
* Spring with native driver
* Refactor functions
* Fix props issues
* Remove RoomItem.height
* Long swipe
* Refactor animations
* this.rowTranslation -> this.transX
* Moved state to this
* [FIX] Auto-translate messages as they arrive
* [i18n] Add missing de translations (#1040)
* [CHORE] Switch to react-native-localize (#1043)
* Bump version to 1.17.0 (#1057)
* Load views as needed (#1056)
* [IMPROVEMENT] Change "resend" icon position (#1048)
* [NEW] Video support (#801)
* [NEW] File upload (#882)
* [NEW] Share extension (#942)
* [FIX] Share extension CI build (#1060)
* Change bundleID
* Provisioning
* get provisioning profile
* [IMPROVEMENT] Reusable toast (#1065)
* [FIX] Moment locales (#1066)
* [FIX] Share Extension issues (#1064)
* [FIX] Empty white list enables all media types upload (#1077)
* Merge branch 'master' into develop (#1079)
* [FIX] Empty white list enables all media types upload (#1080)
* Create utils to media (canUpload)
* Fix variable name
* [CHORE] Update README (#1081)
* [FIX] Media share type (#1086)
* [RELEASE] Merge beta into master (#1142)
* [RELEASE] Merge beta into master (#1174)
* [RELEASE] Merge beta into master (#1282)
* Merge beta into master (#1461)
* Merge beta into master (#1637)
* Merge beta into master (#1759)
* Merge beta into master (#1897)
* [FIX] Close SortDropdown on sort select (#1230)
* [FIX] Cancel upload and check failed upload (#1232)
* [FIX] Slash commands not cleaning is typing and not using state (#1233)
* [FIX] Dispatch roomsRequest on app foreground event even if not connected (#1234)
* [CHORE] Update react-native-jitsi-meet (#1235)
* [FIX] Regex on run slash command (#1223)
* Update React Native to 0.61.1 (#1236)
* Update React Native to 0.61.1
* Update patch to SSL Pinning
* Revert storybook
* [CHORE] Update react-native-safe-area-view (#1219)
* [FIX] Try/catch JSON.parse XHR response (#1238)
* [FIX] Change messagebox icon immediate on change text (#1241)
* [FIX] Update last open on message stream received (#1240)
* [FIX] Remove animation from RoomsListView.willFocus (#1239)
* [FIX] Delete message on thread (#1214)
* [REGRESSION] Markdown text (#1242)
* [FIX] Jest (#1243)
* [FIX] Avatar shown when useRealName is activated (#1162)
* Fix avatar when use real name
* Wrong indentation
* [DOCS] Add SECURITY.md (#1244)
* [CHORE] Update react-native-reanimated to 1.3.0 (#1246)
* [FIX] Run credentials migration only once (#1245)
* [CHORE] Update react-native-jitsi-meet to 2.0.1 (#1249)
* [FIX] Messagebox onChangeText issues (#1252)
* Stop ongoing debounces on messagebox unmount
* Immediately change send icon, but keep debouncing others
* Make CustomEmoji stateless function
* Fix mentions keyExtractor
* [FIX] Room subscription issues (#1255)
* [FIX] Reaction press (#1258)
* [FIX] Channel avatars not showing after application unloads (#1264)
* Revert react-native-safe-area-view (#1265)
* [FIX] Remove console on production mode (#1268)
* [FIX] Messages preview issues (#1257)
* [FIX] Select user from native credentials (#1266)
* [FIX] Some issues on preview message (#1271)
* [FIX] Audio player track and thumb not rendering on Android (#1273)
* [FIX] Record audio message throws exception when FileSystem.getInfoAsync is called (#1272)
* [FIX] China shouldn't use CallKit (#1274)
* [FIX] Watermelon batches (#1277)
* Bump version to 1.20.1 (#1285)
* [CHORE] Remove memoize-one (#1284)
* [FIX] End Jitsi call on unmount (#1291)
* [FIX] Allow self-signed certificates (#1310)
* [FIX] Set User-Agent (#1318)
* Set User-Agent Fetch & Websocket & XHR
* Set User-Agent
* Custom User Agent on fetch/websocket
* Fix names
* Use DeviceInfo
* fix server with subpath (#1322)
* [FIX] Server with https:\\ instead of https:// (#1320)
* [FIX] Server dropdown not closing after changing stack (#1299)
* [FIX] Invalid server version (#1319)
* [IMPROVEMENT] Respect "Hide counter" preference (#1306)
* [FIX] Pass isFocused as a function to Messagebox (#1309)
* [CHORE] Remove icons folder (#1290)
* [CHORE] Refactor RoomItem touchable (#1331)
* [FIX] Unnecessary rerender on RoomItem when status is undefined (#1336)
* [UPDATE DEPS] react-navigation and react-navigation-stack (#1337)
* [FIX] Avatars not loading on share extension when Accounts_AvatarBlockUnauthenticatedAccess is enabled (#1339)
* Bump version to 1.20.2 (#1340)
* [FIX] Remove some unnecessary re-renders on Messagebox (#1341)
* [REGRESSION] Use LayoutAnimation instead of Transition API (#1338)
* [FIX] Remove setState from notifications view causing watermelon object to be updated outside an action (#1342)
* [IMPROVEMENT] Save last message as message when subscription is updated (#1344)
* [UPDATE DEPS] Update RN to 0.61.3 (#1345)
* [DOCS] Update Readme (#1346)
* [CHORE] Remove react-native-scrollable-tab-view fork (#1352)
* [FIX] URL preview (#1360)
* [REGRESSION] Decrease list view memory size (#1361)
* [FIX] Paste (#1350)
* [CHORE] Update gems (#1365)
* Bump version to 1.20.3 (#1366)
* [FIX] Use Ruby 2.4 on TestFlight upload (#1368)
* [FIX] Parse Urls (#1371)
* [FIX] Parse image URL only if it's not empty (#1372)
* [FIX] Load messages issues (#1373)
* Bump version to 1.21.0 (#1376)
* [FIX] Crowd login (#1381)
* [FIX] Clicking user avatar in thread previews crashes app (#1363)
* [IMPROVEMENT] Error messages on connect (#1379)
* [FIX] ProfileView input navigation error when custom fields aren't set (#1383)
* [FIX] Batch server deletion on logout (#1382)
* Bump app to 1.22.0 (#1387)
* [FIX] Server Version (#1392)
* Update patch and minor deps (#1386)
* [FIX] Crash when open thread (#1395)
* Bump version to 1.23.0 (#1394)
* [I18N] Update ru.js (#1384)
* [FIX] CAS building wrong URL (#1362)
* [FIX] Delete messages (#1399)
* [FIX] In-app notification showing wrong content on channels (#1400)
* Bump version to 1.24.0 (#1404)
* [FIX] Prevent server with whitespace (#1402)
* [IMPROVEMENT] Keyboard and content type on login (#1403)
* [FIX] Messages stop loading (#1410)
* [NEW] Tablet support (#1300)
* [IMPROVEMENT] Authentication via deep linking (#1418)
* [IMPROVEMENT] Markdown performance when identifying emoji only content (#1422)
* [FIX] BackHandler remove random failing on development (#1423)
* Bump version to 1.25.0 (#1424)
* [CHORE] Update CI Xcode Image (#1430)
* [FIX] Rooms grouping not working properly (#1435)
* [FIX] Take a video (#1437)
* [NEW] Themes (#1298)
* [FIX] Share extension doesn't reconnect to previous selected server on Android (#1429)
* [FIX] Init local settings on notification tap (#1438)
* Bump version to 1.26.0 (#1450)
* [FIX] Emoji parser not working on Hermes (#1445)
* [NEW] Enable Hermes (#1446)
* [FIX] Automatic theme repeating (#1457)
* [CHORE] Sync Experimental and Official app versions (#1458)
* [DOCS] Update readme (#1459)
* [FIX] Messages being sent but showing as temp status (#1469)
* [FIX] Missing messages after reconnect (#1470)
* [FIX] Few fixes on themes (#1477)
* [I18N] Missing German translations (#1465)
* Missing German translation
* adding a missing space behind colon
* added a missing space after colon
* and another attempt to finally fix this – got confused by all the branches
* some smaller fixes for the translation
* better wording
* fixed another typo
* [FIX] Crash while displaying the attached image with http on file name (#1401)
* [IMPROVEMENT] Tap app and server version to copy to clipboard (#1425)
* [NEW] Reply notification (#1448)
* [FIX] Incorrect background color login on iPad (#1480)
* [FIX] Prevent multiple tap on send (Share Extension) (#1481)
* [NEW] Image Viewer (#1479)
* [DOCS] Update Readme (#1485)
* [FIX] Jitsi with Hermes Enabled (#1523)
* [FIX] Draft messages not working with themed Messagebox (#1525)
* [FIX] Go to direct message from members list (#1519)
* [FIX] Make SAML wait for idp token instead of creating it on client (#1527)
* [FIX] Server Test Push Notification (#1508)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Update to new server response (#1509)
* [FIX] Insert messages with blank users (#1529)
* Bump version to 4.2.1 (#1530)
* [FIX] Error when normalizing empty messages (#1532)
* [REGRESSION] CAS (#1570)
* Bump version to 4.2.2 (#1571)
* [FIX] Add username block condition to prevent error (#1585)
* Bump version to 4.2.3
* Bump version to 4.2.4
* Bump version to 4.3.0 (#1630)
* [FIX] Channels doesn't load (#1586)
* [FIX] Channels doesn't load
* [FIX] Update roomsUpdatedAt when subscriptions.length is 0
* [FIX] Remove unnecessary changes
* [FIX] Improve the code
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Make SAML to work on Rocket.Chat < 2.3.0 (#1629)
* [NEW] Invite links (#1534)
* [FIX] Set the http-agent to the form that Rocket.Chat requires for logging (#1482)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] "Following thread" and "Unfollowed Thread" is hardcoded and not translated (#1625)
* [FIX] Disable reset button if form didn't changed (#1569)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Header title of RoomInfoView (#1553)
* [I18N] Gallery Permissions DE (#1542)
* [FIX] Not allow to send messages to archived room (#1623)
* [FIX] Profile fields automatically reset (#1502)
* [FIX] Show attachment on ThreadMessagesView (#1493)
* [NEW] Wordpress auth (#1633)
* [CHORE] Add Start Packager script (#1639)
* [CHORE] Update RN to 0.61.5 (#1638)
* [CHORE] Update RN to 0.61.5
* [CHORE] Update react-native patch
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* Bump version to 4.3.1 (#1641)
* [FIX] Change force logout rule (#1640)
* Bump version to 4.4.0 (#1643)
* [IMPROVEMENT] Use MessagingStyle on Android Notification (#1575)
* [NEW] Request review (#1627)
* [NEW] Pull to refresh RoomView (#1657)
* [FIX] Unsubscribe from room (#1655)
* [FIX] Server with subdirs (#1646)
* [NEW] Clear cache (#1660)
* [IMPROVEMENT] Memoize and batch subscriptions updates (#1642)
* [FIX] Disallow empty sharing (#1664)
* [REGRESSION] Use HTTPS links for sharing and markets protocol for review (#1663)
* [FIX] In some cases, share extension doesn't load images (#1649)
* [i18n] DE translations for new invite function and some minor fixes (#1631)
* [FIX] Remove duplicate jetify step (#1628)
minor: also remove 'cd' calls
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [REGRESSION] Read messages (#1666)
* [i18n] German translations missing (#1670)
* [FIX] Notifications crash on older Android Versions (#1672)
* [i18n] Added Dutch translation (#1676)
* [NEW] Omnichannel Beta (#1674)
* [NEW] Confirm logout/clear cache (#1688)
* [I18N] Add es-ES language (#1495)
* [NEW] UiKit Beta (#1497)
* [IMPROVEMENT] Use reselect (#1696)
* [FIX] Notification in Android API level less than 24 (#1692)
* [IMPROVEMENT] Send tmid on slash commands and media (#1698)
* [FIX] Unhandled action on UIKit (#1703)
* [NEW] Pull to refresh RoomsList (#1701)
* [IMPROVEMENT] Reset app when language is changed (#1702)
* [FIX] Small fixes on UIKit (#1709)
* [FIX] Spotlight (#1719)
* [CHORE] Update react-native-image-crop-picker (#1712)
* [FIX] Messages Overlapping (Android) and MessageBox Scroll (iOS) (#1720)
* [REGRESSION] Remove @ and # from mention (#1721)
* [NEW] Direct message from user info (#1516)
* [FIX] Delete slash commands (#1723)
* [IMPROVEMENT] Hold URL to copy (#1684)
* [FIX] Different sourcemaps generation for Hermes (#1724)
* [FIX] Different sourcemaps generation for Hermes
* Upload sourcemaps after build
* [REVERT] Show emoji keyboard on Android (#1738)
* [FIX] Stop logging react-native-image-crop-picker (#1745)
* [FIX] Prevent toast ref error (#1744)
* [FIX] Prevent reaction map error (#1743)
* [FIX] Add missing calls to user info (#1741)
* [FIX] Catch room unsubscribe error (#1739)
* [i18n] Missing German keys (#1735)
* [FIX] Missing i18n on MessagesView title (#1733)
* [FIX] UIKit Modal: Weird behavior on Android Tablet (#1742)
* [i18n] Missing key on German (#1747)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Add Italian (#1736)
…
* [FIX] Notification stream throwing an error when there isn't a message on payload (#2637)
* [FIX] Threads not being updated and other related issues (#2636)
* Fix parent title on thread header breaking lines
* Fix https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/2519
* Fix thread badge not being updated
* [FIX] Minor room header issues (#2630)
* Add hitSlop to RoomView header
* Use 1 icon padding for threads header
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [FIX] Whitelabel unable to find package name (#2626)
* Fixes #2625
* Fixes #2614
* Apply resValue on defaultConfig and undo unnecessary changes
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Add missing German strings (#2619)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Model columns misplaced (#2640)
* [FIX] Connect a null server (#2639)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Jitsi users unable to unmute (#2623)
* [FIX] Jitsi users being muted always
* fix: bundle is invalid
* Update jitsi meet sdk with ui improvements
* Update JitsiMeetSDK ios
* Centralize toolbox android
* Fix images on Jitsi
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* Bump version to 4.12.1 (#2641)
* [FIX] Share extension and save image not working on Android 10 (#2651)
* Bump version to 4.13.0 (#2657)
* [FIX] Update Loading logo (#2658)
* [NEW] Support client certificates for SSL (two-way authentication) (Android) (#2624)
* wip: Android SSL Pinning
* Use own SSLPinningModule
* wip: Use Rocket.Chat own react-native
* wip: Fresco Images using custom OkHttpClient
* wip: react-native-webview onReceivedClientCertRequest
* feat: Save Images of a SSL Pinning protected server
* chore: SSLPinning package as a interface to iOS & Android implementations
* chore: update glide
* feat: load images under a client ssl certificate protected server
* chore: remove patch
* feat: Audio & Video under a SSL Client protected server
* fix: Unpin certificate when change server
* feat: Fast Image as a patch
* chore: update fast-image
* Fix merge
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Channel actions (#2644)
* room roles
* handle owner
* endpoints
* Leader and Moderator
* Remove user from room
* stash ignore
* Add subscription.ignored column
* ignore user
* Fix icons
* I18n
* Minor i18n fixes
* Direct Message and open action sheet after a normal tap
* Fix icon
* stash isIgnored
* isManualUnignored message
* Fix update
* Ignored
* Mute, moderator, leader, owner, remove from room
* ignore
* Tests
* pt-BR
* Update pods
* Apply requested changes
* Add RC version on requests
* [NEW] Support RTL (#2656)
* wip: RTL (iOS)
* wip: RTL (Android)
* wip: reload bundle when change between RTL languages
* fix: Stack Animation on Android
* fix: update snapshot
* fix: Swipe Room Actions in RTL mode
* fix: snapshots
* Move isRTL to i18n
* Fix styling
* Update tests
* Update pods
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Initial users' status is not fetched (#2664)
* [FIX] Messages overlapping and emoji keyboard not opening (#2670)
* Replace keyboard libs for react-native-ui-lib
* Apply Jitsi branch
* Require keyboard on bundle
* Update ui-lib
* chore: update deps
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [CHORE] Force normalized params for 2FA (#2683)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Thread message flickering while thread parent isn't found (#2676)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Light theme not working on Android with Dark Theme set (#2675)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App not prompting join code for password protected channels (#2514)
* Adding joinCode parameter
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
Co-authored-by: Fernando Aguilar <fernando.aguilar@hotmail.com.br>
* Insert join code input
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
* Add joinCode field on db
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
* Add label i18 pt-br and en-us
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
* Add insert join code text
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
* Fix atribute name
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
* Add join text
Signed-off-by: Vitor.Leal <vitor_leal2201@hotmail.com>
Co-authored-by: Daniel Maike <danmke@hotmail.com>
Co-authored-by: Fernando Aguilar <fernando.aguilar@hotmail.com.br>
* Fix attributes joinCode, joinCodeRequired and pass attribute param in navigation
Signed-off-by: Daniel Maike <danmke@hotmail.com>
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
* Fixing attribute joinCodeRequired pass to goRoom
Signed-off-by: Daniel Maike <danmke@hotmail.com>
* Changed textinput style
Signed-off-by: Daniel Maike <danmke@hotmail.com>
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
* Delete not necessary attribute
Signed-off-by: Daniel Maike <danmke@hotmail.com>
* Fixing input style
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
* Undo unncessary changes
* use a join code modal
* tests: e2e tests to join protected channel
* fix: undo unnecessary change
* tests: cancel join code
* Remove some tests
* Minor fixes
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
Co-authored-by: Fernando Aguilar <fernando.aguilar@hotmail.com.br>
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
Co-authored-by: youssef-md <emaildeyoussefmuhamad@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18n] Add Arabic (#2537)
* Arabic language setup
* Added arabic translation
* Arabic translation Proofreading
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18N] Add missing zh_TW and zh_CN strings (#2680)
* feat(i18n): add some missing strings and improve some translation
* fix: add missing server version
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Add username on status messages (#2553)
* 1689 - missing user name for status messages
* 1689 - missing user name for status messages. Fixed broken e2e test "should pin message".
* Minor tweak
* Remove center style
* Small refactor on User
* Remove toLowerCase
* Update tests
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Filenames are incorrect in non-latin alphabets on upload (#2671)
* fix: filename on react-native-image-crop-picker
* fix: use rn-fetch-blob to upload files
* fix: FileUpload as a service
* fix: cancel upload on iOS
* fix: file upload from share extension
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Ease white labelling for Android (#2685)
* improve white labelling for Android
* Move application ID to gradle properties
* Fix CI
* Point foss sufix to main app
* Use npx on android-whitelabel script
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Chats order (#2688)
* Persist highest value on subscription.roomUpdatedAt
* Update tests
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [REGRESSION] Re-enable Jitsi Chat (#2687)
* Fix main jitsi
* Fix iOS
* Clear build.gradle cache
* Don't restore gradle
* cache is back
* Use master
* Point to react-native-jitsi-meet#master
* [CHORE] Build official apps on CI (#2701)
* Duplicated target and changed Bridging Header
* Display name
* Unnecessary dumb swift file removed
* Buildable name
* Reorder Info.plist
* Rename Official target's bundle id
* Ignore .mobileprovision
* Fix provisioning of official app
* Starting signing
* stash fastfile
* starting official ci iOS
* Uncomment Fastfile keychain
* Fix CI config
* allowProvisioningUpdates
* Changing AppIcon and Splash Screen
* Remove unnecessary folder inside of Images.xcassets
* Reorder notificationservice and shareextension plists
* Fix signing
* Manual signing style for official
* Split official signing
* Update project provisioning
* Use ENV as profile
* Output match
* Keys
* TestFlight refactor
* Setting up android
* android-official-play-build job
* Start removing unnecessary fastlane tasks on Android
* Trying to refactor Android jobs
* android-env
* Remove foss build for now
* Fork
* Fix if conditions
* Fix push
* ios-build command
* Rename Android builds
* Upload dSYMs
* Refactoring workflow
* Reorder upload-to-testflight
* upload-to-google-play-beta command
* Fix ci
* Fix android fork build
* Fix keystore
* Fix options on fastlane android
* Fix keystore
* Check isOfficial on iOS
* Check isOfficial on db
* Remove unused imports
* Database names on Android
* Tag fix
* Minor fixes
* Set IS_OFFICIAL on CI
* Fix detox
* follow review suggestions
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
* [i18n] Update fr (#2697)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [i18n] Update fr (#2705)
Typo
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Empty space on Messagebox (#2704)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Yarn android scripts (#2716)
* [CHORE] Rename Experimental iOS lane (#2717)
* Move build_fork to the end
* Rename release to build_experimental
* [IMPROVEMENT] Use class variable instead of state for List's animated (#2718)
* [FIX] Bottom sheet being hidden sometimes (#2722)
* [IMPROVEMENT] Match background and text mention colors (#2723)
* [FIX] App freezing if Markdown preview contains sequential empty spaces (#2726)
* Remove sequential empty spaces from Markdown preview
* Use Markdown preview on RepliedThread
* [FIX] Official app without sharedUserId (#2734)
* [CHORE] Update React Native to 0.63.4 (#2737)
* Bump version to 4.13.1 (#2739)
* [REGRESSION] Multiple uploads not working on iOS (#2738)
* Update React Native to 0.63.4
* Fix multiple uploads not working on iOS
* [FIX] Unable to save attachment on iOS (#2743)
* Fix rn-fetch-blob's document dir without forward slash
* Update camera roll
* [FIX] Generate Jitsi access token when making a call (#2694)
fixes: #2693
# Please enter the commit message for your changes. Lines starting
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Jitsi notification delay (#2668)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Channels list not following the same sorting logic from web client (#2763)
* [FIX] Pods lost on Official target (#2764)
* [FIX] RoomItem using deprecated animated event signature (#2771)
* [FIX] Server autocomplete text breaking line (#2774)
* [FIX] ServerDropdown flashing bigger server icon (#2775)
* [FIX] ServerDropdown flashing bigger server icon
* Remove unused logo and update image path where needed
* Minor tweak
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Rooms list not being updated on some cases (#2765)
* Request subscriptions on RoomsListView.constructor
* Removes opened rooms from last message persisting
* Change server reducer
* Prevent undefined ids causing query error
* [FIX] Share Extension hitting memory limit on iOS (#2788)
* [FIX] Disallow swipe to dismiss on share extension
* Limit query to 20 and clean up props
* Remove rn-extension-share branch pointer
* Test new branch
* Remove branch
* [IMPROVEMENT] Threads layout tweaks (#2686)
* improvement: Thread Details
* fix: re-render Thread Messages Item
* fix: update snapshots
* improve: thread details component
* fix: cast replies length
* improvement: format date of threads
* improvement: thread details styles
* fix: wrap text
* tests: update snapshot
* improvement: use same date format for all dates
* Icon size 24
* Remove date
* Remove prop drill
* Badge position
* Badge container tweak
* Fix inline style
* Move ThreadDetails to containers
* Update stories
* Fix lint
* Remove wrong prop
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Remove some migrations (#2792)
* Remove force rooms refresh
* Remove MMKV migration
* Bump version to 4.14.0 (#2797)
* [FIX] Messagebox tracking lost on pop gesture navigation (#2799)
* Use setTimeout instead of InteractionManager
* Update tracking lib
* [FIX] Back button closing activity when on root stack screen (#2804)
* Make hardware back button to behave as home button on root screens
* Remove unnecessary code
* Remove handleBackPress from OnboardingView
* Fix lint
* [i18n] Add missing German strings (#2715)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [NEW] Encrypted Discussions (#2813)
* I18n key fix
* Add encrypted switch
* Remove unused i18n keys
* Add enabled to encryption reducer
* Show encrypted option on CreateDiscussionView only when e2e encryption is properly set
* Add localSearch and use it on search
* Use encrypted from parent channel
* Fix method calls as rest api with 2fa enabled
* Fix logout after reset keys
* Use encryption reducer instead of lib directly to check render
* Check for room type logic to display encryption option on create discussion
* Check toggle-room-e2e-encryption permission on RoomActionsView
* Check for encryption status instead of setting on server
* Fix
* Disable switch instead of hide it
* Fix spotlight for DMs
* Fix server test
* [FIX] Messagebox missing style for text color (#2786)
* Changing auxilaryTintColor
* Changed Placeholder color to BodyText color
* added color prop
* eslint changes
* used array for styles
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18N] Update arabic (#2696)
* Update ar.js
* Update ar.js
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Workspace input without i18n (#2689)
* [FIX] Translation of strings in Login page
* Strings are added for translation.
fixes: #2620
* Add pt-BR
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Spotlight returning duplicated entries (#2805)
* Update rocketchat.js
* Updated search function
* Minor improvements
* Remove atIndex
* Add remove logic to remove duplicate data from response
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Refactor ServerItem (#2778)
* Updated ServerDropdown and ServerItem
* Added ServerItem stories
* Update ServerDropdown.js
* Updated ServerItem stories
* Updated ServerItem stories and ServerItem component
* Updated SelectServerView, ServerItem and ServerItem stories
* Updated ServerItem stories
* Updated ServerItem stories
* Update tests
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [DOCS] Updated Quick Start docs link in e2e/readme (#2802)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18N] Add Turkish (#2793)
* Turkish language support added
* Update tr.js
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Lint on #2793 (#2818)
* [I18N] Add missing german strings (#2689) (#2820)
* [I18N] Add missing italian strings (#2817)
* [FIX] Server version becoming null on server change (#2821)
* [FIX] Wrong styling on E2E encryption banner (#2767)
* [FIX] Wrong styling on E2E encryption banner
* [FIX] Wrong styling on E2E encryption banner
* [FIX] Wrong styling on E2E encryption banner
* [FIX] Wrong styling on E2E encryption banner (#2767)
* Updated SortDropdown, ListHeader, ListItem and added stories for List.Item
* Updated SortDropdown
* Removed unused component
* Updated List.Item and stories
* Reverted unnecessary changes and updated ListItem stories
* Fix minor indentation
* Stop breaking Touch's default underlay color
* Fix indentation
* Remove falsy comparison from render
* Fix left icon
* Use List.Item on OmnichannelStatus
* Add missing separator
* Lint
* Fix sort dropdown
* Remove unnecessary styles
* Fix detox
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App Store using Experimental's app id (#2826)
* [FIX] Wrong username on push notifications (#2825)
* [FIX] Share extension memory issues on iOS (#2845)
* Remove unnecessary class prop
* Stop rendering servers when there's only one
* Map and alloc only necessary columns from query
* Fetch servers count instead of all servers records
* Fetch only needed servers
* Separators
* Remove renderContent
* Minor fix
* Refactor query
* Smaller avatars in memory
* Fix getItemLayout
* Add topic
* Load less pods
* tests
* Import only used functions from lodash
* Fix pods
* Import only used functions from semver
* Fix media sharing
* Update pods
* Disables preview and thumb on iOS
* Update expo-video-thumbnail
* Unnecessary change
* [FIX] Logout from other locations not prompting confirmation option (#2854)
* Fixed logout toast bug for the iOS
* Removing callToAction and replacing with confirmationText
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* Bump version to 4.14.1 (#2859)
* [IMPROVEMENT] Check for focused rooms on in-app notifications (#2857)
* Update InAppNotification and room reducer
* Update InAppNotification
This reverts commit 60330a1e04cfe8d2e5aa311f367083d831682c49.
* Stop subscribing to threads
* Remove ref
* Fix prop-types
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Real name being ignored in SearchMessagesView (#2838)
Co-authored-by: Gerzon Z <gerzonc@icloud.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Remove unnecessary share reducer calls (#2861)
* Remove unnecesary share reducer calls
* Update Avatar
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Breadcrumbs exceeding characters limit (#2862)
* [FIX] breadcrumbs exceeding
* fix.breadcrumbs-exceeding-change-events
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App compressing videos on iOS (#2915)
* Update index.js
* Update index.js
* [FIX] Real name setting ignored on reply preview (#2908)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Reply component sending unused prop to Description (#2900)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] BackdropOpacity based on themes (#2863)
* Added backdropOpacity based on theme
* Updated ActionSheet, ReactionsModal, ReactionPicker and Sidebar
* Updated MultiSelect
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Webview not falling back to default auth challenge when no cert is provided (#2918)
* [FIX] Android - fallback to default auth challenge handling when no cert is provided
* If a certificate auth challenge is requested on Android the webview will hang if no certificate is loaded.
To prevent this, fallback to default Android behavior and cancel the challenge with request.cancel()
* No client certificate case defaults to super implementation
* Update react-native-webview
* Downgrade to previous dependency version
Co-authored-by: Diego Mello <diegolmello@gmail.com>
Co-authored-by: Gerzon Z <gerzonc@icloud.com>
Co-authored-by: Jan Garaj <jan.garaj@gmail.com>
* [FIX] Support Jitsi_URL_Room_Hash (#2905)
* [FIX] Temp attachment files not being flushed after saved to gallery (#2871)
* Update AttachmentView.js
* Update AttachmentView.js
* Update AttachmentView.js
* Update AttachmentView.js
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Update iOS profiles for Experimental app (#2933)
* [IMPROVE] Deleted thread reply redirects to thread (#2840)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Thread showing typing indicator from main room (#2869)
* [FIX] Remove typing indicator from thread's header
* remove unnecessary props and change usersTyping condition
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] DM rooms show typing status from last group room (#2878)
* [FIX] DM rooms show typing status from last group room
* Undo changes
* Check if current typing is from focused room before dispatching to redux
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Can't copy or edit media's description (#2885)
* [FIX] Image descriptions issues
* shorten the condition string
* fix selectedMessage state
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] RightButtonsContainer re-render check not returning default value (#2899)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Remove InteractionManager blocks (#2906)
* [FIX] Remove InteractionManager blocks
* Minor fix
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] App not sending second argument for EventEmitter.removeListener on some places (#2909)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Temp message ignoring real name (#2919)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] System message of e2e encryption is missing (#2888)
* [FIX] System message of e2e encryption missing
* add new encryption string
* add to stories
* Add pt-BR
* Move stories
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Add permissions to Redux (#2914)
* [FIX] Add permissions to Redux store
* add only permissions being used in the app
* add clear permissions reducer
* call RocketChat.hasPermission from reducer
* add server version comparison on getPermissions
* refactor hasPermission function
* refactor hasPermission function
* remove uncomment code
* use Q.experimentalSortBy()
* add coerce function
* Change Rocketchat.hasPermission
* Apply on isReadOnly
* Apply to RoomInfoEditView
* Apply to RoomInfoView and RoomInfoEditView
* canAutoTranslate
* Unnecessary clear permissions
* Revert getUpdatedSince
* Naming fix
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Add hold step for ios and android build experimental (#2943)
* [CHORE] Add hold step for ios-build-experimental and android-build-experimental
* Android hold step
* add ios hold step
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [IMPROVEMENT] Remove lodash.isEqual (#2893)
* Added dequal and react-fast-compare as substitutes to lodash.isEqual
* Update ReplyPreview.js
* Remove react-fast-compare
* Removed deep-equal and upgrade babel-eslint dev dependency
* Fix avatar
* Fix Messagebox
* Fix CreateDiscussionView
* ModalBlockView
* NewMessageView
* ProfileView
* RoomInfoEditView
* ServerDropdown
* Return local search as object instead of observable
* SelectedUsersView
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [I18N] Add missing Russian strings (#2946)
* [i18n] Add missing Russian strings
* Couple fixes
* Fix Direct_message
Translate Direct_message as already has been translated
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [CHORE] Use shortcut syntax for get collections (#2932)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Use List.Separator in all places (#2931)
* [FIX] Use List.Separator in all places
* add List.Separator
* change List.Separator
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Limit new message list query size to 50 (#2947)
* Limit query to 50
* Remove observable
* [FIX] Support chats order for older versions of the server (#2934)
* Update mergeSubscriptionsRooms.js
* Update mergeSubscriptionsRooms.js
* Update mergeSubscriptionsRooms.js
* Minor refactor
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Reactions modal's backdrop color too light (#2949)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* Bump version to 4.15.0 (#2950)
* [FIX] Share extension not working correctly on Official app (#2963)
* [FIX] Cannot read property 'some' of undefined on hasPermission (#2966)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
* [FIX] Deep linking and other connectivity issues (#2894)
* Navigate from push notification only if necessary
* Use JS SDK branch
* Stop reconnecting if it's already connected
* Fix RoomsListView forever loading after tapping push notification of another server
* Execute fewer operations on app/index
* Remove roomsRequest call from onForeground
* Apply check and reopen
* Stop opening in-app notification when the app is on backgorund
* Connecting tweaks
* Fix deep linking not working if the app is on background
* Force reset yarn cache
* Upgrade JS SDK
* Remove listener on unmount
* Fix resume on Android after back button is pressed
* Fix local authentication resume
* Fix back button android
* Change JS SDK branch
* [FIX] Messagebox's placeholder color is too bright (#2968)
Co-authored-by: Ezequiel de Oliveira <ezequiel1de1oliveira@gmail.com>
Co-authored-by: Dan Caseley <dan@caseley.me.uk>
Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
Co-authored-by: Youssef Muhamad <emaildeyoussefmuhamad@gmail.com>
Co-authored-by: Graham Smith <graham@wiseman-designs.com>
Co-authored-by: Gabriel Henriques <gabriel.henriques@rocket.chat>
Co-authored-by: Júlia Grala <30629556+juliagrala@users.noreply.github.com>
Co-authored-by: Guilherme Gazzo <guilhermegazzo@gmail.com>
Co-authored-by: Prateek Jain <44807945+Prateek93a@users.noreply.github.com>
Co-authored-by: Lucas Siqueira <lucassiqzro@gmail.com>
Co-authored-by: Calebe Rios <calebersmendes@gmail.com>
Co-authored-by: Pitstopper <18574776+Pitstopper@users.noreply.github.com>
Co-authored-by: phriedrich <info@phriedrich.de>
Co-authored-by: Guilherme Siqueira <guilhersiqueira@gmail.com>
Co-authored-by: Prateek Jain <prateek93a@gmail.com>
Co-authored-by: devyaniChoubey <52153085+devyaniChoubey@users.noreply.github.com>
Co-authored-by: Bernard Seow <ssbing99@gmail.com>
Co-authored-by: Hiroki Ishiura <ishiura@ja2.so-net.ne.jp>
Co-authored-by: Exordian <jakob.englisch@gmail.com>
Co-authored-by: Daanchaam <daanhendriks97@gmail.com>
Co-authored-by: Iván Álvarez <ialvarezpereira@gmail.com>
Co-authored-by: Sarthak Pranesh <41206172+sarthakpranesh@users.noreply.github.com>
Co-authored-by: Michele Pellegrini <pellettiero@users.noreply.github.com>
Co-authored-by: Tanmoy Bhowmik <tanmoy.openroot@gmail.com>
Co-authored-by: Hibikine Kage <14365761+hibikine@users.noreply.github.com>
Co-authored-by: Neil Agarwal <neil@neilagarwal.me>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Govind Dixit <GOVINDDIXIT93@GMAIL.COM>
Co-authored-by: Zhaubassarova Aruzhan <49000079+azhaubassar@users.noreply.github.com>
Co-authored-by: Aroo <azhaubassar@gmail.com>
Co-authored-by: Sarthak Pranesh <sarthak.pranesh2018@vitstudent.ac.in>
Co-authored-by: Siddharth Padhi <padhisiddharth31@gmail.com>
Co-authored-by: Bruno Dantas <oliveiradantas96@gmail.com>
Co-authored-by: devyaniChoubey <devyanichoubey16@gmail.com>
Co-authored-by: Heng Sok <sokheng@idatahub.com>
Co-authored-by: Snyk bot <snyk-bot@snyk.io>
Co-authored-by: nixxou <45721836+nixxou@users.noreply.github.com>
Co-authored-by: David-Tsui <st880221@gmail.com>
Co-authored-by: Vincenzo Esposito <aenon.esposito@gmail.com>
Co-authored-by: Rishabh Gupta <38923768+imrishabh18@users.noreply.github.com>
Co-authored-by: Hendy Irawan <hendy@hendyirawan.com>
Co-authored-by: Alexandru Naiman <alex.naiman.4@gmail.com>
Co-authored-by: Dani <assgex@gmail.com>
Co-authored-by: Luis <ljcp28ljcp@gmail.com>
Co-authored-by: zaphod534 <32894570+zaphod534@users.noreply.github.com>
Co-authored-by: ankar84 <ankar84@gmail.com>
Co-authored-by: Карлан Антон Андреевич <KarlanAA@global.bcs>
Co-authored-by: Saket Mahajan <saketmahajan99@gmail.com>
Co-authored-by: Rohit Verma <44283521+refactor-droidyy@users.noreply.github.com>
Co-authored-by: Marco Jakobs <mj@jacotec.de>
Co-authored-by: Daniel Maike <danmke@hotmail.com>
Co-authored-by: Vitor Leal <vitor_leal2201@hotmail.com>
Co-authored-by: Fernando Aguilar <fernando.aguilar@hotmail.com.br>
Co-authored-by: Abdullah Alhamoud <10301923+abalhamoud@users.noreply.github.com>
Co-authored-by: Dave Koo <dkoo761@gmail.com>
Co-authored-by: Fazil Boudjelal <fazildiablou@hotmail.fr>
Co-authored-by: Lucas Dousse <Cormoran96@users.noreply.github.com>
Co-authored-by: Sumukha Hegde <SUMUKHA214@GMAIL.COM>
Co-authored-by: Gerzon Z <gerzonzcanario@gmail.com>
Co-authored-by: Gerzon Z <gerzonc@icloud.com>
Co-authored-by: yash-rajpal <58601732+yash-rajpal@users.noreply.github.com>
Co-authored-by: Hakan YILMAZ <mukerrem.yilmaz@hotmail.com>
Co-authored-by: Arkadyuti Bandyopadhyay <bandyopadhyayarkadyuti@gmail.com>
Co-authored-by: Anant Bhasin <38764067+aKn1ghtOut@users.noreply.github.com>
Co-authored-by: Gung Wah <41157464+kresnaputra@users.noreply.github.com>
Co-authored-by: Billy Newman <newmanw10@gmail.com>
Co-authored-by: Jan Garaj <jan.garaj@gmail.com>
This commit is contained in:
parent
197b78e8f0
commit
f5b013f4e7
|
@ -237,9 +237,13 @@ commands:
|
|||
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY_OFFICIAL" ./RocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./RocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./ShareRocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./NotificationService/Info.plist
|
||||
else
|
||||
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./RocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./ShareRocketChatRN/Info.plist
|
||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
|
||||
fi
|
||||
|
||||
if [[ $APP_STORE_CONNECT_API_KEY ]]; then
|
||||
|
@ -416,9 +420,13 @@ workflows:
|
|||
- lint-testunit
|
||||
|
||||
# iOS Experimental
|
||||
- ios-hold-build-experimental:
|
||||
type: approval
|
||||
requires:
|
||||
- lint-testunit
|
||||
- ios-build-experimental:
|
||||
requires:
|
||||
- lint-testunit
|
||||
- ios-hold-build-experimental
|
||||
- ios-hold-testflight-experimental:
|
||||
type: approval
|
||||
requires:
|
||||
|
@ -444,9 +452,13 @@ workflows:
|
|||
- ios-hold-testflight-official
|
||||
|
||||
# Android Experimental
|
||||
- android-hold-build-experimental:
|
||||
type: approval
|
||||
requires:
|
||||
- lint-testunit
|
||||
- android-build-experimental:
|
||||
requires:
|
||||
- lint-testunit
|
||||
- android-hold-build-experimental
|
||||
- android-hold-google-play-beta-experimental:
|
||||
type: approval
|
||||
requires:
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parser": "@babel/eslint-parser",
|
||||
"extends": "airbnb",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
|
@ -21,7 +21,8 @@ module.exports = {
|
|||
"react",
|
||||
"jsx-a11y",
|
||||
"import",
|
||||
"react-native"
|
||||
"react-native",
|
||||
"@babel"
|
||||
],
|
||||
"env": {
|
||||
"browser": true,
|
||||
|
@ -148,7 +149,8 @@ module.exports = {
|
|||
"react/jsx-curly-newline": [0],
|
||||
"react/state-in-constructor": [0],
|
||||
"no-async-promise-executor": [0],
|
||||
"max-classes-per-file": [0]
|
||||
"max-classes-per-file": [0],
|
||||
"no-multiple-empty-lines": [0]
|
||||
},
|
||||
"globals": {
|
||||
"__DEV__": true
|
||||
|
|
|
@ -44404,6 +44404,309 @@ exports[`Storyshots Message list message 1`] = `
|
|||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"fontSize": 20,
|
||||
"fontWeight": "300",
|
||||
"marginLeft": 10,
|
||||
"marginVertical": 30,
|
||||
},
|
||||
Object {
|
||||
"color": "#0d0e12",
|
||||
},
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
"marginTop": 30,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
Toggle e2e encryption
|
||||
</Text>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flexDirection": "column",
|
||||
"paddingHorizontal": 14,
|
||||
"paddingVertical": 4,
|
||||
"width": "100%",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"borderRadius": 2,
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
},
|
||||
Object {
|
||||
"marginLeft": 16,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"overflow": "hidden",
|
||||
},
|
||||
Object {
|
||||
"borderRadius": 2,
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<FastImageView
|
||||
resizeMode="cover"
|
||||
source={
|
||||
Object {
|
||||
"headers": undefined,
|
||||
"priority": "high",
|
||||
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=20",
|
||||
}
|
||||
}
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"marginLeft": 46,
|
||||
},
|
||||
Object {
|
||||
"marginLeft": 10,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
accessibilityLabel="This room's encryption has been disabled by diego.mello"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "transparent",
|
||||
"fontFamily": "System",
|
||||
"fontSize": 16,
|
||||
"fontStyle": "italic",
|
||||
"fontWeight": "400",
|
||||
"textAlign": "left",
|
||||
},
|
||||
Object {
|
||||
"color": "#9ca2a8",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
This room's encryption has been disabled by diego.mello
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flexDirection": "column",
|
||||
"paddingHorizontal": 14,
|
||||
"paddingVertical": 4,
|
||||
"width": "100%",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"borderRadius": 2,
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
},
|
||||
Object {
|
||||
"marginLeft": 16,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"overflow": "hidden",
|
||||
},
|
||||
Object {
|
||||
"borderRadius": 2,
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<FastImageView
|
||||
resizeMode="cover"
|
||||
source={
|
||||
Object {
|
||||
"headers": undefined,
|
||||
"priority": "high",
|
||||
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=20",
|
||||
}
|
||||
}
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"marginLeft": 46,
|
||||
},
|
||||
Object {
|
||||
"marginLeft": 10,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
accessibilityLabel="This room's encryption has been enabled by diego.mello"
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "transparent",
|
||||
"fontFamily": "System",
|
||||
"fontSize": 16,
|
||||
"fontStyle": "italic",
|
||||
"fontWeight": "400",
|
||||
"textAlign": "left",
|
||||
},
|
||||
Object {
|
||||
"color": "#9ca2a8",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
This room's encryption has been enabled by diego.mello
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Array [
|
||||
|
|
|
@ -144,7 +144,7 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode VERSIONCODE as Integer
|
||||
versionName "4.14.1"
|
||||
versionName "4.15.0"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
if (!isFoss) {
|
||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
|
|
|
@ -70,3 +70,5 @@ export const SETTINGS = createRequestTypes('SETTINGS', ['CLEAR', 'ADD']);
|
|||
export const APP_STATE = createRequestTypes('APP_STATE', ['FOREGROUND', 'BACKGROUND']);
|
||||
export const ENTERPRISE_MODULES = createRequestTypes('ENTERPRISE_MODULES', ['CLEAR', 'SET']);
|
||||
export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DECODE_KEY', 'SET', 'SET_BANNER']);
|
||||
|
||||
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET']);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import * as types from './actionsTypes';
|
||||
|
||||
export function setPermissions(permissions) {
|
||||
return {
|
||||
type: types.PERMISSIONS.SET,
|
||||
permissions
|
||||
};
|
||||
}
|
|
@ -63,6 +63,7 @@ export const themes = {
|
|||
passcodeDotFull: '#6C727A',
|
||||
previewBackground: '#1F2329',
|
||||
previewTintColor: '#ffffff',
|
||||
backdropOpacity: 0.3,
|
||||
...mentions
|
||||
},
|
||||
dark: {
|
||||
|
@ -109,6 +110,7 @@ export const themes = {
|
|||
passcodeDotFull: '#6C727A',
|
||||
previewBackground: '#030b1b',
|
||||
previewTintColor: '#ffffff',
|
||||
backdropOpacity: 0.9,
|
||||
...mentions
|
||||
},
|
||||
black: {
|
||||
|
@ -155,6 +157,7 @@ export const themes = {
|
|||
passcodeDotFull: '#6C727A',
|
||||
previewBackground: '#000000',
|
||||
previewTintColor: '#ffffff',
|
||||
backdropOpacity: 0.9,
|
||||
...mentions
|
||||
}
|
||||
};
|
||||
|
|
|
@ -101,6 +101,9 @@ export default {
|
|||
Jitsi_Enabled_TokenAuth: {
|
||||
type: 'valueAsBoolean'
|
||||
},
|
||||
Jitsi_URL_Room_Hash: {
|
||||
type: 'valueAsBoolean'
|
||||
},
|
||||
Jitsi_URL_Room_Prefix: {
|
||||
type: 'valueAsString'
|
||||
},
|
||||
|
|
|
@ -147,7 +147,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
|
|||
const animatedPosition = React.useRef(new Value(0));
|
||||
const opacity = interpolate(animatedPosition.current, {
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, 0.7],
|
||||
outputRange: [0, themes[theme].backdropOpacity],
|
||||
extrapolate: Extrapolate.CLAMP
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import isEqual from 'react-fast-compare';
|
||||
|
||||
import database from '../../lib/database';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
|
@ -34,7 +33,8 @@ class AvatarContainer extends React.Component {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!isEqual(prevProps, this.props)) {
|
||||
const { text, type } = this.props;
|
||||
if (prevProps.text !== text || prevProps.type !== type) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ class AvatarContainer extends React.Component {
|
|||
|
||||
init = async() => {
|
||||
const db = database.active;
|
||||
const usersCollection = db.collections.get('users');
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const usersCollection = db.get('users');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
|
||||
let record;
|
||||
try {
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
|||
import { View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import { connect } from 'react-redux';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
|
@ -67,7 +67,7 @@ class EmojiPicker extends Component {
|
|||
if (nextState.width !== width) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.frequentlyUsed, frequentlyUsed)) {
|
||||
if (!dequal(nextState.frequentlyUsed, frequentlyUsed)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -95,7 +95,7 @@ class EmojiPicker extends Component {
|
|||
// eslint-disable-next-line react/sort-comp
|
||||
_addFrequentlyUsed = protectedFunction(async(emoji) => {
|
||||
const db = database.active;
|
||||
const freqEmojiCollection = db.collections.get('frequently_used_emojis');
|
||||
const freqEmojiCollection = db.get('frequently_used_emojis');
|
||||
let freqEmojiRecord;
|
||||
try {
|
||||
freqEmojiRecord = await freqEmojiCollection.find(emoji.content);
|
||||
|
@ -120,7 +120,7 @@ class EmojiPicker extends Component {
|
|||
|
||||
updateFrequentlyUsed = async() => {
|
||||
const db = database.active;
|
||||
const frequentlyUsedRecords = await db.collections.get('frequently_used_emojis').query().fetch();
|
||||
const frequentlyUsedRecords = await db.get('frequently_used_emojis').query().fetch();
|
||||
let frequentlyUsed = orderBy(frequentlyUsedRecords, ['count'], ['desc']);
|
||||
frequentlyUsed = frequentlyUsed.map((item) => {
|
||||
if (item.isCustom) {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import React, { memo, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NotifierRoot, Notifier, Easing } from 'react-native-notifier';
|
||||
import { connect } from 'react-redux';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import NotifierComponent from './NotifierComponent';
|
||||
import EventEmitter from '../../utils/events';
|
||||
|
@ -8,13 +11,17 @@ import { getActiveRoute } from '../../utils/navigation';
|
|||
|
||||
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
||||
|
||||
const InAppNotification = memo(() => {
|
||||
const InAppNotification = memo(({ rooms, appState }) => {
|
||||
const show = (notification) => {
|
||||
if (appState !== 'foreground') {
|
||||
return;
|
||||
}
|
||||
|
||||
const { payload } = notification;
|
||||
const state = Navigation.navigationRef.current?.getRootState();
|
||||
const route = getActiveRoute(state);
|
||||
if (payload.rid) {
|
||||
if ((route?.name === 'RoomView' && route.params?.rid === payload.rid) || route?.name === 'JitsiMeetView') {
|
||||
if (rooms.includes(payload.rid) || route?.name === 'JitsiMeetView') {
|
||||
return;
|
||||
}
|
||||
Notifier.showNotification({
|
||||
|
@ -28,13 +35,23 @@ const InAppNotification = memo(() => {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
||||
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
||||
return () => {
|
||||
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER);
|
||||
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
||||
};
|
||||
}, []);
|
||||
}, [rooms]);
|
||||
|
||||
return <NotifierRoot />;
|
||||
}, (prevProps, nextProps) => dequal(prevProps.rooms, nextProps.rooms));
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
rooms: state.room.rooms,
|
||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||
});
|
||||
|
||||
export default InAppNotification;
|
||||
InAppNotification.propTypes = {
|
||||
rooms: PropTypes.array,
|
||||
appState: PropTypes.string
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(InAppNotification);
|
||||
|
|
|
@ -96,7 +96,7 @@ const Header = React.memo(({
|
|||
const setEmojis = async() => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const freqEmojiCollection = db.collections.get('frequently_used_emojis');
|
||||
const freqEmojiCollection = db.get('frequently_used_emojis');
|
||||
let freqEmojis = await freqEmojiCollection.query().fetch();
|
||||
|
||||
const isLandscape = width > height;
|
||||
|
|
|
@ -34,20 +34,24 @@ const MessageActions = React.memo(forwardRef(({
|
|||
Message_AllowPinning,
|
||||
Message_AllowStarring,
|
||||
Message_Read_Receipt_Store_Users,
|
||||
isMasterDetail
|
||||
isMasterDetail,
|
||||
editMessagePermission,
|
||||
deleteMessagePermission,
|
||||
forceDeleteMessagePermission,
|
||||
pinMessagePermission
|
||||
}, ref) => {
|
||||
let permissions = {};
|
||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||
|
||||
const getPermissions = async() => {
|
||||
try {
|
||||
const permission = ['edit-message', 'delete-message', 'force-delete-message', 'pin-message'];
|
||||
const permission = [editMessagePermission, deleteMessagePermission, forceDeleteMessagePermission, pinMessagePermission];
|
||||
const result = await RocketChat.hasPermission(permission, room.rid);
|
||||
permissions = {
|
||||
hasEditPermission: result[permission[0]],
|
||||
hasDeletePermission: result[permission[1]],
|
||||
hasForceDeletePermission: result[permission[2]],
|
||||
hasPinPermission: result[permission[3]]
|
||||
hasEditPermission: result[0],
|
||||
hasDeletePermission: result[1],
|
||||
hasForceDeletePermission: result[2],
|
||||
hasPinPermission: result[3]
|
||||
};
|
||||
} catch {
|
||||
// Do nothing
|
||||
|
@ -141,7 +145,7 @@ const MessageActions = React.memo(forwardRef(({
|
|||
const db = database.active;
|
||||
const result = await RocketChat.markAsUnread({ messageId });
|
||||
if (result.success) {
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
const subRecord = await subCollection.find(rid);
|
||||
await db.action(async() => {
|
||||
try {
|
||||
|
@ -171,7 +175,7 @@ const MessageActions = React.memo(forwardRef(({
|
|||
|
||||
const handleCopy = async(message) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_COPY);
|
||||
await Clipboard.setString(message.msg);
|
||||
await Clipboard.setString(message?.attachments?.[0]?.description || message.msg);
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') });
|
||||
};
|
||||
|
||||
|
@ -440,7 +444,11 @@ MessageActions.propTypes = {
|
|||
Message_AllowPinning: PropTypes.bool,
|
||||
Message_AllowStarring: PropTypes.bool,
|
||||
Message_Read_Receipt_Store_Users: PropTypes.bool,
|
||||
server: PropTypes.string
|
||||
server: PropTypes.string,
|
||||
editMessagePermission: PropTypes.array,
|
||||
deleteMessagePermission: PropTypes.array,
|
||||
forceDeleteMessagePermission: PropTypes.array,
|
||||
pinMessagePermission: PropTypes.array
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
|
@ -452,7 +460,11 @@ const mapStateToProps = state => ({
|
|||
Message_AllowPinning: state.settings.Message_AllowPinning,
|
||||
Message_AllowStarring: state.settings.Message_AllowStarring,
|
||||
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users,
|
||||
isMasterDetail: state.app.isMasterDetail
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
editMessagePermission: state.permissions['edit-message'],
|
||||
deleteMessagePermission: state.permissions['delete-message'],
|
||||
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
||||
pinMessagePermission: state.permissions['pin-message']
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null, null, { forwardRef: true })(MessageActions);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import Item from './Item';
|
||||
import styles from '../styles';
|
||||
|
@ -31,7 +31,7 @@ const CommandsPreview = React.memo(({ theme, commandPreview, showCommandPreview
|
|||
if (prevProps.showCommandPreview !== nextProps.showCommandPreview) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.commandPreview, nextProps.commandPreview)) {
|
||||
if (!dequal(prevProps.commandPreview, nextProps.commandPreview)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import styles from '../styles';
|
||||
import MentionItem from './MentionItem';
|
||||
|
@ -30,7 +30,7 @@ const Mentions = React.memo(({ mentions, trackingType, theme }) => {
|
|||
if (prevProps.trackingType !== nextProps.trackingType) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.mentions, nextProps.mentions)) {
|
||||
if (!dequal(prevProps.mentions, nextProps.mentions)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,6 @@ import { View, Text, StyleSheet } from 'react-native';
|
|||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { connect } from 'react-redux';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import Markdown from '../markdown';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
|
@ -43,7 +42,7 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
|
||||
const ReplyPreview = React.memo(({
|
||||
message, Message_TimeFormat, baseUrl, username, replying, getCustomEmoji, close, theme
|
||||
message, Message_TimeFormat, baseUrl, username, replying, getCustomEmoji, close, theme, useRealName
|
||||
}) => {
|
||||
if (!replying) {
|
||||
return null;
|
||||
|
@ -59,7 +58,7 @@ const ReplyPreview = React.memo(({
|
|||
>
|
||||
<View style={[styles.messageContainer, { backgroundColor: themes[theme].chatComponentBackground }]}>
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.username, { color: themes[theme].tintColor }]}>{message.u?.username}</Text>
|
||||
<Text style={[styles.username, { color: themes[theme].tintColor }]}>{useRealName ? message.u?.name : message.u?.username}</Text>
|
||||
<Text style={[styles.time, { color: themes[theme].auxiliaryText }]}>{time}</Text>
|
||||
</View>
|
||||
<Markdown
|
||||
|
@ -75,7 +74,7 @@ const ReplyPreview = React.memo(({
|
|||
<CustomIcon name='close' color={themes[theme].auxiliaryText} size={20} style={styles.close} onPress={close} />
|
||||
</View>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.replying === nextProps.replying && prevProps.theme === nextProps.theme && isEqual(prevProps.message, nextProps.message));
|
||||
}, (prevProps, nextProps) => prevProps.replying === nextProps.replying && prevProps.theme === nextProps.theme && prevProps.message.id === nextProps.message.id);
|
||||
|
||||
ReplyPreview.propTypes = {
|
||||
replying: PropTypes.bool,
|
||||
|
@ -85,12 +84,14 @@ ReplyPreview.propTypes = {
|
|||
baseUrl: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
getCustomEmoji: PropTypes.func,
|
||||
theme: PropTypes.string
|
||||
theme: PropTypes.string,
|
||||
useRealName: PropTypes.bool
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||
baseUrl: state.server.server
|
||||
baseUrl: state.server.server,
|
||||
useRealName: state.settings.UI_Use_Real_Name
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ReplyPreview);
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import { connect } from 'react-redux';
|
||||
import { KeyboardAccessoryView } from 'react-native-ui-lib/keyboard';
|
||||
import ImagePicker from 'react-native-image-crop-picker';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import DocumentPicker from 'react-native-document-picker';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
|
||||
|
@ -63,6 +63,7 @@ const imagePickerConfig = {
|
|||
|
||||
const libraryPickerConfig = {
|
||||
multiple: true,
|
||||
compressVideoPreset: 'Passthrough',
|
||||
mediaType: 'any'
|
||||
};
|
||||
|
||||
|
@ -189,8 +190,8 @@ class MessageBox extends Component {
|
|||
} = this.props;
|
||||
let msg;
|
||||
try {
|
||||
const threadsCollection = db.collections.get('threads');
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const threadsCollection = db.get('threads');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
try {
|
||||
this.room = await subsCollection.find(rid);
|
||||
} catch (error) {
|
||||
|
@ -270,7 +271,7 @@ class MessageBox extends Component {
|
|||
} = this.state;
|
||||
|
||||
const {
|
||||
roomType, replying, editing, isFocused, message, theme, children
|
||||
roomType, replying, editing, isFocused, message, theme
|
||||
} = this.props;
|
||||
if (nextProps.theme !== theme) {
|
||||
return true;
|
||||
|
@ -299,16 +300,13 @@ class MessageBox extends Component {
|
|||
if (nextState.tshow !== tshow) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.mentions, mentions)) {
|
||||
if (!dequal(nextState.mentions, mentions)) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.commandPreview, commandPreview)) {
|
||||
if (!dequal(nextState.commandPreview, commandPreview)) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.message, message)) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.children, children)) {
|
||||
if (!dequal(nextProps.message?.id, message?.id)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -366,7 +364,7 @@ class MessageBox extends Component {
|
|||
const slashCommand = text.match(/^\/([a-z0-9._-]+) (.+)/im);
|
||||
if (slashCommand) {
|
||||
const [, name, params] = slashCommand;
|
||||
const commandsCollection = db.collections.get('slash_commands');
|
||||
const commandsCollection = db.get('slash_commands');
|
||||
try {
|
||||
const command = await commandsCollection.find(name);
|
||||
if (command.providesPreview) {
|
||||
|
@ -507,7 +505,7 @@ class MessageBox extends Component {
|
|||
getEmojis = debounce(async(keyword) => {
|
||||
const db = database.active;
|
||||
if (keyword) {
|
||||
const customEmojisCollection = db.collections.get('custom_emojis');
|
||||
const customEmojisCollection = db.get('custom_emojis');
|
||||
const likeString = sanitizeLikeString(keyword);
|
||||
let customEmojis = await customEmojisCollection.query(
|
||||
Q.where('name', Q.like(`${ likeString }%`))
|
||||
|
@ -521,7 +519,7 @@ class MessageBox extends Component {
|
|||
|
||||
getSlashCommands = debounce(async(keyword) => {
|
||||
const db = database.active;
|
||||
const commandsCollection = db.collections.get('slash_commands');
|
||||
const commandsCollection = db.get('slash_commands');
|
||||
const likeString = sanitizeLikeString(keyword);
|
||||
const commands = await commandsCollection.query(
|
||||
Q.where('id', Q.like(`${ likeString }%`))
|
||||
|
@ -753,7 +751,7 @@ class MessageBox extends Component {
|
|||
// Slash command
|
||||
if (message[0] === MENTIONS_TRACKING_TYPE_COMMANDS) {
|
||||
const db = database.active;
|
||||
const commandsCollection = db.collections.get('slash_commands');
|
||||
const commandsCollection = db.get('slash_commands');
|
||||
const command = message.replace(/ .*/, '').slice(1);
|
||||
const likeString = sanitizeLikeString(command);
|
||||
const slashCommand = await commandsCollection.query(
|
||||
|
@ -941,7 +939,7 @@ class MessageBox extends Component {
|
|||
keyboardType='twitter'
|
||||
blurOnSubmit={false}
|
||||
placeholder={I18n.t('New_Message')}
|
||||
placeholderTextColor={themes[theme].auxiliaryTintColor}
|
||||
placeholderTextColor={themes[theme].auxiliaryText}
|
||||
onChangeText={this.onChangeText}
|
||||
onSelectionChange={this.onSelectionChange}
|
||||
underlineColorAndroid='transparent'
|
||||
|
|
|
@ -19,8 +19,8 @@ const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
|||
try {
|
||||
const db = database.active;
|
||||
const deleteBatch = [];
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadCollection = db.collections.get('threads');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadCollection = db.get('threads');
|
||||
|
||||
// Delete the object (it can be Message or ThreadMessage instance)
|
||||
deleteBatch.push(message.prepareDestroyPermanently());
|
||||
|
|
|
@ -28,7 +28,7 @@ class Toast extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
EventEmitter.addEventListener(LISTENER, this.showToast);
|
||||
this.listener = EventEmitter.addEventListener(LISTENER, this.showToast);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
|
@ -40,7 +40,7 @@ class Toast extends React.Component {
|
|||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
EventEmitter.removeListener(LISTENER);
|
||||
EventEmitter.removeListener(LISTENER, this.listener);
|
||||
}
|
||||
|
||||
getToastRef = toast => this.toast = toast;
|
||||
|
|
|
@ -58,9 +58,9 @@ const TwoFactor = React.memo(({ theme, isMasterDetail }) => {
|
|||
const showTwoFactor = args => setData(args);
|
||||
|
||||
useEffect(() => {
|
||||
EventEmitter.addEventListener(TWO_FACTOR, showTwoFactor);
|
||||
const listener = EventEmitter.addEventListener(TWO_FACTOR, showTwoFactor);
|
||||
|
||||
return () => EventEmitter.removeListener(TWO_FACTOR);
|
||||
return () => EventEmitter.removeListener(TWO_FACTOR, listener);
|
||||
}, []);
|
||||
|
||||
const onCancel = () => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
View, Text, TouchableWithoutFeedback, Modal, KeyboardAvoidingView, Animated, Easing
|
||||
View, Text, TouchableWithoutFeedback, Modal, KeyboardAvoidingView, Animated, Easing, StyleSheet
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
@ -172,7 +172,7 @@ export const MultiSelect = React.memo(({
|
|||
>
|
||||
<TouchableWithoutFeedback onPress={onHide}>
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.backdrop, { backgroundColor: themes[theme].backdropColor }]} />
|
||||
<View style={{ ...StyleSheet.absoluteFill, opacity: themes[theme].backdropOpacity, backgroundColor: themes[theme].backdropColor }} />
|
||||
<KeyboardAvoidingView style={styles.keyboardView} behavior={behavior}>
|
||||
<Animated.View style={[styles.animatedContent, { transform: [{ translateY }] }]}>
|
||||
{showContent ? renderContent() : null}
|
||||
|
|
|
@ -8,10 +8,6 @@ export default StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'flex-end'
|
||||
},
|
||||
backdrop: {
|
||||
...StyleSheet.absoluteFill,
|
||||
opacity: 0.3
|
||||
},
|
||||
modal: {
|
||||
height: 300,
|
||||
width: '100%',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { dequal } from 'dequal';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Image from './Image';
|
||||
|
@ -28,7 +28,7 @@ const Attachments = React.memo(({
|
|||
// eslint-disable-next-line react/no-array-index-key
|
||||
return <Reply key={index} index={index} attachment={file} timeFormat={timeFormat} getCustomEmoji={getCustomEmoji} theme={theme} />;
|
||||
});
|
||||
}, (prevProps, nextProps) => isEqual(prevProps.attachments, nextProps.attachments) && prevProps.theme === nextProps.theme);
|
||||
}, (prevProps, nextProps) => dequal(prevProps.attachments, nextProps.attachments) && prevProps.theme === nextProps.theme);
|
||||
|
||||
Attachments.propTypes = {
|
||||
attachments: PropTypes.array,
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import { Audio } from 'expo-av';
|
||||
import Slider from '@react-native-community/slider';
|
||||
import moment from 'moment';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
|
||||
|
||||
import Touchable from './Touchable';
|
||||
|
@ -150,7 +150,7 @@ class MessageAudio extends React.Component {
|
|||
if (nextState.paused !== paused) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.file, file)) {
|
||||
if (!dequal(nextProps.file, file)) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.loading !== loading) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useContext } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import I18n from '../../i18n';
|
||||
import styles from './styles';
|
||||
|
@ -108,10 +108,10 @@ const Content = React.memo((props) => {
|
|||
if (prevProps.isIgnored !== nextProps.isIgnored) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.mentions, nextProps.mentions)) {
|
||||
if (!dequal(prevProps.mentions, nextProps.mentions)) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.channels, nextProps.channels)) {
|
||||
if (!dequal(prevProps.channels, nextProps.channels)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { useContext } from 'react';
|
|||
import { View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import FastImage from '@rocket.chat/react-native-fast-image';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import { createImageProgress } from 'react-native-image-progress';
|
||||
import * as Progress from 'react-native-progress';
|
||||
|
||||
|
@ -66,7 +66,7 @@ const ImageContainer = React.memo(({
|
|||
<MessageImage img={img} theme={theme} />
|
||||
</Button>
|
||||
);
|
||||
}, (prevProps, nextProps) => equal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme);
|
||||
}, (prevProps, nextProps) => dequal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme);
|
||||
|
||||
ImageContainer.propTypes = {
|
||||
file: PropTypes.object,
|
||||
|
|
|
@ -119,7 +119,7 @@ const MessageTouchable = React.memo((props) => {
|
|||
<Touchable
|
||||
onLongPress={onLongPress}
|
||||
onPress={onPress}
|
||||
disabled={props.isInfo || props.archived || props.isTemp}
|
||||
disabled={(props.isInfo && !props.isThreadReply) || props.archived || props.isTemp}
|
||||
>
|
||||
<View>
|
||||
<Message {...props} />
|
||||
|
@ -132,6 +132,7 @@ MessageTouchable.displayName = 'MessageTouchable';
|
|||
MessageTouchable.propTypes = {
|
||||
hasError: PropTypes.bool,
|
||||
isInfo: PropTypes.bool,
|
||||
isThreadReply: PropTypes.bool,
|
||||
isTemp: PropTypes.bool,
|
||||
archived: PropTypes.bool
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { useContext } from 'react';
|
|||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import isEqual from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import Touchable from './Touchable';
|
||||
import Markdown from '../markdown';
|
||||
|
@ -125,7 +125,7 @@ const Fields = React.memo(({ attachment, theme }) => {
|
|||
))}
|
||||
</View>
|
||||
);
|
||||
}, (prevProps, nextProps) => isEqual(prevProps.attachment.fields, nextProps.attachment.fields) && prevProps.theme === nextProps.theme);
|
||||
}, (prevProps, nextProps) => dequal(prevProps.attachment.fields, nextProps.attachment.fields) && prevProps.theme === nextProps.theme);
|
||||
|
||||
const Reply = React.memo(({
|
||||
attachment, timeFormat, index, getCustomEmoji, theme
|
||||
|
@ -172,7 +172,6 @@ const Reply = React.memo(({
|
|||
/>
|
||||
<Description
|
||||
attachment={attachment}
|
||||
timeFormat={timeFormat}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
theme={theme}
|
||||
/>
|
||||
|
@ -188,7 +187,7 @@ const Reply = React.memo(({
|
|||
/>
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment) && prevProps.theme === nextProps.theme);
|
||||
}, (prevProps, nextProps) => dequal(prevProps.attachment, nextProps.attachment) && prevProps.theme === nextProps.theme);
|
||||
|
||||
Reply.propTypes = {
|
||||
attachment: PropTypes.object,
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import FastImage from '@rocket.chat/react-native-fast-image';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import Touchable from './Touchable';
|
||||
import openLink from '../../utils/openLink';
|
||||
|
@ -112,7 +112,7 @@ const Url = React.memo(({ url, index, theme }) => {
|
|||
</>
|
||||
</Touchable>
|
||||
);
|
||||
}, (oldProps, newProps) => isEqual(oldProps.url, newProps.url) && oldProps.theme === newProps.theme);
|
||||
}, (oldProps, newProps) => dequal(oldProps.url, newProps.url) && oldProps.theme === newProps.theme);
|
||||
|
||||
const Urls = React.memo(({ urls, theme }) => {
|
||||
if (!urls || urls.length === 0) {
|
||||
|
@ -122,7 +122,7 @@ const Urls = React.memo(({ urls, theme }) => {
|
|||
return urls.map((url, index) => (
|
||||
<Url url={url} key={url.url} index={index} theme={theme} />
|
||||
));
|
||||
}, (oldProps, newProps) => isEqual(oldProps.urls, newProps.urls) && oldProps.theme === newProps.theme);
|
||||
}, (oldProps, newProps) => dequal(oldProps.urls, newProps.urls) && oldProps.theme === newProps.theme);
|
||||
|
||||
UrlImage.propTypes = {
|
||||
image: PropTypes.string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import isEqual from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import Touchable from './Touchable';
|
||||
import Markdown from '../markdown';
|
||||
|
@ -57,7 +57,7 @@ const Video = React.memo(({
|
|||
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => isEqual(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme);
|
||||
}, (prevProps, nextProps) => dequal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme);
|
||||
|
||||
Video.propTypes = {
|
||||
file: PropTypes.object,
|
||||
|
|
|
@ -37,7 +37,9 @@ export const SYSTEM_MESSAGES = [
|
|||
'room_changed_privacy',
|
||||
'room_changed_avatar',
|
||||
'message_snippeted',
|
||||
'thread-created'
|
||||
'thread-created',
|
||||
'room_e2e_enabled',
|
||||
'room_e2e_disabled'
|
||||
];
|
||||
|
||||
export const SYSTEM_MESSAGE_TYPES = {
|
||||
|
@ -100,6 +102,10 @@ export const getInfoMessage = ({
|
|||
return I18n.t('Room_changed_avatar', { userBy: username });
|
||||
} else if (type === 'message_snippeted') {
|
||||
return I18n.t('Created_snippet');
|
||||
} else if (type === 'room_e2e_disabled') {
|
||||
return I18n.t('This_room_encryption_has_been_disabled_by__username_', { username });
|
||||
} else if (type === 'room_e2e_enabled') {
|
||||
return I18n.t('This_room_encryption_has_been_enabled_by__username_', { username });
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { FlatList } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import isEqual from 'react-fast-compare';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import I18n from '../../../i18n';
|
||||
import RoomItem, { ROW_HEIGHT } from '../../../presentation/RoomItem';
|
||||
|
@ -56,7 +56,7 @@ class QueueListView extends React.Component {
|
|||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { queued } = this.props;
|
||||
if (!isEqual(nextProps.queued, queued)) {
|
||||
if (!dequal(nextProps.queued, queued)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -704,5 +704,7 @@ export default {
|
|||
Direct_message: 'Direct message',
|
||||
Message_Ignored: 'Message ignored. Tap to display it.',
|
||||
Enter_workspace_URL: 'Enter workspace URL',
|
||||
Workspace_URL_Example: 'Ex. your-company.rocket.chat'
|
||||
Workspace_URL_Example: 'Ex. your-company.rocket.chat',
|
||||
This_room_encryption_has_been_enabled_by__username_: 'This room\'s encryption has been enabled by {{username}}',
|
||||
This_room_encryption_has_been_disabled_by__username_: 'This room\'s encryption has been disabled by {{username}}'
|
||||
};
|
||||
|
|
|
@ -651,5 +651,7 @@ export default {
|
|||
Direct_message: 'Mensagem direta',
|
||||
Message_Ignored: 'Mensagem ignorada. Toque para mostrar.',
|
||||
Enter_workspace_URL: 'Digite a URL da sua workspace',
|
||||
Workspace_URL_Example: 'Ex. sua-empresa.rocket.chat'
|
||||
Workspace_URL_Example: 'Ex. sua-empresa.rocket.chat',
|
||||
This_room_encryption_has_been_enabled_by__username_: 'A criptografia para essa sala foi habilitada por {{username}}',
|
||||
This_room_encryption_has_been_disabled_by__username_: 'A criptografia para essa sala foi desabilitada por {{username}}'
|
||||
};
|
||||
|
|
|
@ -678,5 +678,31 @@ export default {
|
|||
No_threads: 'Тредов нет',
|
||||
No_threads_following: 'Нет тредов, за которыми вы следите',
|
||||
No_threads_unread: 'Непрочитанных тредов нет',
|
||||
Messagebox_Send_to_channel: 'Отправить в чат'
|
||||
Messagebox_Send_to_channel: 'Отправить в чат',
|
||||
Set_as_leader: 'Назначить лидером',
|
||||
Set_as_moderator: 'Назначить модератором',
|
||||
Set_as_owner: 'Назначить владельцем',
|
||||
Remove_as_leader: 'Удалить из лидеров',
|
||||
Remove_as_moderator: 'Удалить из модераторов',
|
||||
Remove_as_owner: 'Удалить из владельцев',
|
||||
Remove_from_room: 'Удалить из чата',
|
||||
Ignore: 'Игнориновать',
|
||||
Unignore: 'Прекратить игнорировать',
|
||||
User_has_been_ignored: 'Пользователь теперь игнорируется',
|
||||
User_has_been_unignored: 'Пользователь больше не игнорируется',
|
||||
User_has_been_removed_from_s: 'Пользователь удален из {{s}}',
|
||||
User__username__is_now_a_leader_of__room_name_: 'Пользователь {{username}} больше не лидер в чате {{room_name}}',
|
||||
User__username__is_now_a_moderator_of__room_name_: 'Пользователь {{username}} больше не модератор в чате {{room_name}}',
|
||||
User__username__is_now_a_owner_of__room_name_: 'Пользователь {{username}} больше не владелец в чате {{room_name}}',
|
||||
User__username__removed_from__room_name__leaders: 'Пользователь {{username}} удален из {{room_name}} лидеров',
|
||||
User__username__removed_from__room_name__moderators: 'Пользователь {{username}} удален из {{room_name}} модераторов',
|
||||
User__username__removed_from__room_name__owners: 'Пользователь {{username}} удален из {{room_name}} владельцев',
|
||||
The_user_will_be_removed_from_s: 'Пользователь будет удален из {{s}}',
|
||||
Yes_remove_user: 'Да, удалить пользователя!',
|
||||
Direct_message: 'Личное сообщение',
|
||||
Message_Ignored: 'Сообщение игнорируется. Тапните по нему, чтобы отобразить его.',
|
||||
Enter_workspace_URL: 'Введите URL вашего рабочего пространства',
|
||||
Workspace_URL_Example: 'Например, your-company.rocket.chat',
|
||||
This_room_encryption_has_been_enabled_by__username_: 'Шифрование для этого чата включено {{username}}',
|
||||
This_room_encryption_has_been_disabled_by__username_: 'Шифрование для этого чата выключено {{username}}'
|
||||
};
|
||||
|
|
21
app/index.js
21
app/index.js
|
@ -112,16 +112,25 @@ export default class Root extends React.Component {
|
|||
|
||||
init = async() => {
|
||||
UserPreferences.getMapAsync(THEME_PREFERENCES_KEY).then(this.setTheme);
|
||||
const [notification, deepLinking] = await Promise.all([initializePushNotifications(), Linking.getInitialURL()]);
|
||||
const parsedDeepLinkingURL = parseDeepLinking(deepLinking);
|
||||
store.dispatch(appInitLocalSettings());
|
||||
|
||||
// Open app from push notification
|
||||
const notification = await initializePushNotifications();
|
||||
if (notification) {
|
||||
onNotification(notification);
|
||||
} else if (parsedDeepLinkingURL) {
|
||||
store.dispatch(deepLinkingOpen(parsedDeepLinkingURL));
|
||||
} else {
|
||||
store.dispatch(appInit());
|
||||
return;
|
||||
}
|
||||
|
||||
// Open app from deep linking
|
||||
const deepLinking = await Linking.getInitialURL();
|
||||
const parsedDeepLinkingURL = parseDeepLinking(deepLinking);
|
||||
if (parsedDeepLinkingURL) {
|
||||
store.dispatch(deepLinkingOpen(parsedDeepLinkingURL));
|
||||
return;
|
||||
}
|
||||
|
||||
// Open app from app icon
|
||||
store.dispatch(appInit());
|
||||
}
|
||||
|
||||
getMasterDetail = (width) => {
|
||||
|
|
|
@ -229,9 +229,9 @@ class Encryption {
|
|||
decryptPendingMessages = async(roomId) => {
|
||||
const db = database.active;
|
||||
|
||||
const messagesCollection = db.collections.get('messages');
|
||||
const threadsCollection = db.collections.get('threads');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const messagesCollection = db.get('messages');
|
||||
const threadsCollection = db.get('threads');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
|
||||
// e2e status is null or 'pending' and message type is 'e2e'
|
||||
const whereClause = [
|
||||
|
@ -286,7 +286,7 @@ class Encryption {
|
|||
// after initialize the encryption client
|
||||
decryptPendingSubscriptions = async() => {
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
try {
|
||||
// Find all rooms that can have a lastMessage encrypted
|
||||
// If we select only encrypted rooms we can miss some room that changed their encrypted status
|
||||
|
@ -347,7 +347,7 @@ class Encryption {
|
|||
|
||||
const { rid } = subscription;
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
|
||||
let subRecord;
|
||||
try {
|
||||
|
@ -400,7 +400,7 @@ class Encryption {
|
|||
encryptMessage = async(message) => {
|
||||
const { rid } = message;
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
|
||||
try {
|
||||
// Find the subscription
|
||||
|
|
|
@ -49,7 +49,7 @@ export default class EncryptionRoom {
|
|||
}
|
||||
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
try {
|
||||
// Find the subscription
|
||||
const subscription = await subCollection.find(this.roomId);
|
||||
|
|
|
@ -2,7 +2,7 @@ import reduxStore from '../createStore';
|
|||
import Navigation from '../Navigation';
|
||||
import { logEvent, events } from '../../utils/log';
|
||||
|
||||
async function jitsiURL({ rid }) {
|
||||
async function jitsiURL({ room }) {
|
||||
const { settings } = reduxStore.getState();
|
||||
const { Jitsi_Enabled } = settings;
|
||||
|
||||
|
@ -11,31 +11,37 @@ async function jitsiURL({ rid }) {
|
|||
}
|
||||
|
||||
const {
|
||||
Jitsi_Domain, Jitsi_URL_Room_Prefix, Jitsi_SSL, Jitsi_Enabled_TokenAuth, uniqueID
|
||||
Jitsi_Domain, Jitsi_URL_Room_Prefix, Jitsi_SSL, Jitsi_Enabled_TokenAuth, uniqueID, Jitsi_URL_Room_Hash
|
||||
} = settings;
|
||||
|
||||
const domain = `${ Jitsi_Domain }/`;
|
||||
const prefix = Jitsi_URL_Room_Prefix;
|
||||
const uniqueIdentifier = uniqueID || 'undefined';
|
||||
const protocol = Jitsi_SSL ? 'https://' : 'http://';
|
||||
|
||||
let queryString = '';
|
||||
if (Jitsi_Enabled_TokenAuth) {
|
||||
try {
|
||||
const accessToken = await this.methodCallWrapper('jitsi:generateAccessToken', rid);
|
||||
const accessToken = await this.methodCallWrapper('jitsi:generateAccessToken', room?.rid);
|
||||
queryString = `?jwt=${ accessToken }`;
|
||||
} catch {
|
||||
logEvent(events.RA_JITSI_F);
|
||||
}
|
||||
}
|
||||
|
||||
return `${ protocol }${ domain }${ prefix }${ uniqueIdentifier }${ rid }${ queryString }`;
|
||||
let rname;
|
||||
if (Jitsi_URL_Room_Hash) {
|
||||
rname = uniqueID + room?.rid;
|
||||
} else {
|
||||
rname = encodeURIComponent(room.t === 'd' ? room?.usernames?.join?.(' x ') : room?.name);
|
||||
}
|
||||
|
||||
return `${ protocol }${ domain }${ prefix }${ rname }${ queryString }`;
|
||||
}
|
||||
|
||||
async function callJitsi(rid, onlyAudio = false) {
|
||||
async function callJitsi(room, onlyAudio = false) {
|
||||
logEvent(onlyAudio ? events.RA_JITSI_AUDIO : events.RA_JITSI_VIDEO);
|
||||
const url = await jitsiURL.call(this, { rid });
|
||||
Navigation.navigate('JitsiMeetView', { url, onlyAudio, rid });
|
||||
const url = await jitsiURL.call(this, { room });
|
||||
Navigation.navigate('JitsiMeetView', { url, onlyAudio, rid: room?.rid });
|
||||
}
|
||||
|
||||
export default callJitsi;
|
||||
|
|
|
@ -57,7 +57,7 @@ async function open({ type, rid, name }) {
|
|||
export default async function canOpenRoom({ rid, path, isCall }) {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
|
||||
if (isCall && !rid) {
|
||||
// Extract rid from a Jitsi URL
|
||||
|
@ -75,7 +75,8 @@ export default async function canOpenRoom({ rid, path, isCall }) {
|
|||
name: room.name,
|
||||
fname: room.fname,
|
||||
prid: room.prid,
|
||||
uids: room.uids
|
||||
uids: room.uids,
|
||||
usernames: room.usernames
|
||||
};
|
||||
} catch (e) {
|
||||
// Do nothing
|
||||
|
|
|
@ -13,7 +13,7 @@ export async function setEnterpriseModules() {
|
|||
try {
|
||||
const { server: serverId } = reduxStore.getState().server;
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
let server;
|
||||
try {
|
||||
server = await serversCollection.find(serverId);
|
||||
|
@ -39,7 +39,7 @@ export function getEnterpriseModules() {
|
|||
const enterpriseModules = await this.methodCallWrapper('license:getModules');
|
||||
if (enterpriseModules) {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
const server = await serversCollection.find(serverId);
|
||||
await serversDB.action(async() => {
|
||||
await server.update((s) => {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import lt from 'semver/functions/lt';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
|
@ -21,7 +20,7 @@ const updateEmojis = async({ update = [], remove = [], allRecords }) => {
|
|||
return;
|
||||
}
|
||||
const db = database.active;
|
||||
const emojisCollection = db.collections.get('custom_emojis');
|
||||
const emojisCollection = db.get('custom_emojis');
|
||||
let emojisToCreate = [];
|
||||
let emojisToUpdate = [];
|
||||
let emojisToDelete = [];
|
||||
|
@ -63,7 +62,7 @@ const updateEmojis = async({ update = [], remove = [], allRecords }) => {
|
|||
|
||||
export async function setCustomEmojis() {
|
||||
const db = database.active;
|
||||
const emojisCollection = db.collections.get('custom_emojis');
|
||||
const emojisCollection = db.get('custom_emojis');
|
||||
const allEmojis = await emojisCollection.query().fetch();
|
||||
const parsed = allEmojis.reduce((ret, item) => {
|
||||
ret[item.name] = {
|
||||
|
@ -86,7 +85,7 @@ export function getCustomEmojis() {
|
|||
try {
|
||||
const serverVersion = reduxStore.getState().server.version;
|
||||
const db = database.active;
|
||||
const emojisCollection = db.collections.get('custom_emojis');
|
||||
const emojisCollection = db.get('custom_emojis');
|
||||
const allRecords = await emojisCollection.query().fetch();
|
||||
const updatedSince = await getUpdatedSince(allRecords);
|
||||
|
||||
|
@ -95,18 +94,16 @@ export function getCustomEmojis() {
|
|||
// RC 0.61.0
|
||||
const result = await this.sdk.get('emoji-custom');
|
||||
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
let { emojis } = result;
|
||||
emojis = emojis.filter(emoji => !updatedSince || emoji._updatedAt > updatedSince);
|
||||
const changedEmojis = await updateEmojis({ update: emojis, allRecords });
|
||||
let { emojis } = result;
|
||||
emojis = emojis.filter(emoji => !updatedSince || emoji._updatedAt > updatedSince);
|
||||
const changedEmojis = await updateEmojis({ update: emojis, allRecords });
|
||||
|
||||
// `setCustomEmojis` is fired on selectServer
|
||||
// We run it again only if emojis were changed
|
||||
if (changedEmojis) {
|
||||
setCustomEmojis();
|
||||
}
|
||||
return resolve();
|
||||
});
|
||||
// `setCustomEmojis` is fired on selectServer
|
||||
// We run it again only if emojis were changed
|
||||
if (changedEmojis) {
|
||||
setCustomEmojis();
|
||||
}
|
||||
return resolve();
|
||||
} else {
|
||||
const params = {};
|
||||
if (updatedSince) {
|
||||
|
@ -120,17 +117,15 @@ export function getCustomEmojis() {
|
|||
return resolve();
|
||||
}
|
||||
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
const { emojis } = result;
|
||||
const { update, remove } = emojis;
|
||||
const changedEmojis = await updateEmojis({ update, remove, allRecords });
|
||||
const { emojis } = result;
|
||||
const { update, remove } = emojis;
|
||||
const changedEmojis = await updateEmojis({ update, remove, allRecords });
|
||||
|
||||
// `setCustomEmojis` is fired on selectServer
|
||||
// We run it again only if emojis were changed
|
||||
if (changedEmojis) {
|
||||
setCustomEmojis();
|
||||
}
|
||||
});
|
||||
// `setCustomEmojis` is fired on selectServer
|
||||
// We run it again only if emojis were changed
|
||||
if (changedEmojis) {
|
||||
setCustomEmojis();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
|
|
@ -1,12 +1,55 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import lt from 'semver/functions/lt';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import coerce from 'semver/functions/coerce';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
|
||||
import database from '../database';
|
||||
import log from '../../utils/log';
|
||||
import reduxStore from '../createStore';
|
||||
import protectedFunction from './helpers/protectedFunction';
|
||||
import { setPermissions as setPermissionsAction } from '../../actions/permissions';
|
||||
|
||||
const PERMISSIONS = [
|
||||
'add-user-to-any-c-room',
|
||||
'add-user-to-any-p-room',
|
||||
'add-user-to-joined-room',
|
||||
'archive-room',
|
||||
'auto-translate',
|
||||
'create-invite-links',
|
||||
'delete-c',
|
||||
'delete-message',
|
||||
'delete-p',
|
||||
'edit-message',
|
||||
'edit-room',
|
||||
'force-delete-message',
|
||||
'mute-user',
|
||||
'pin-message',
|
||||
'post-readonly',
|
||||
'remove-user',
|
||||
'set-leader',
|
||||
'set-moderator',
|
||||
'set-owner',
|
||||
'set-react-when-readonly',
|
||||
'set-readonly',
|
||||
'toggle-room-e2e-encryption',
|
||||
'transfer-livechat-guest',
|
||||
'unarchive-room',
|
||||
'view-broadcast-member-list',
|
||||
'view-privileged-setting',
|
||||
'view-room-administration',
|
||||
'view-statistics',
|
||||
'view-user-administration'
|
||||
];
|
||||
|
||||
export async function setPermissions() {
|
||||
const db = database.active;
|
||||
const permissionsCollection = db.collections.get('permissions');
|
||||
const allPermissions = await permissionsCollection.query(Q.where('id', Q.oneOf(PERMISSIONS))).fetch();
|
||||
const parsed = allPermissions.reduce((acc, item) => ({ ...acc, [item.id]: item.roles }), {});
|
||||
|
||||
reduxStore.dispatch(setPermissionsAction(parsed));
|
||||
}
|
||||
|
||||
const getUpdatedSince = (allRecords) => {
|
||||
try {
|
||||
|
@ -26,7 +69,7 @@ const updatePermissions = async({ update = [], remove = [], allRecords }) => {
|
|||
return;
|
||||
}
|
||||
const db = database.active;
|
||||
const permissionsCollection = db.collections.get('permissions');
|
||||
const permissionsCollection = db.get('permissions');
|
||||
|
||||
// filter permissions
|
||||
let permissionsToCreate = [];
|
||||
|
@ -65,33 +108,35 @@ const updatePermissions = async({ update = [], remove = [], allRecords }) => {
|
|||
await db.action(async() => {
|
||||
await db.batch(...batch);
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
|
||||
export default function() {
|
||||
export function getPermissions() {
|
||||
return new Promise(async(resolve) => {
|
||||
try {
|
||||
const serverVersion = reduxStore.getState().server.version;
|
||||
const db = database.active;
|
||||
const permissionsCollection = db.collections.get('permissions');
|
||||
const permissionsCollection = db.get('permissions');
|
||||
const allRecords = await permissionsCollection.query().fetch();
|
||||
|
||||
// if server version is lower than 0.73.0, fetches from old api
|
||||
if (serverVersion && lt(serverVersion, '0.73.0')) {
|
||||
if (serverVersion && lt(coerce(serverVersion), '0.73.0')) {
|
||||
// RC 0.66.0
|
||||
const result = await this.sdk.get('permissions.list');
|
||||
if (!result.success) {
|
||||
return resolve();
|
||||
}
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
await updatePermissions({ update: result.permissions, allRecords });
|
||||
return resolve();
|
||||
});
|
||||
const changePermissions = await updatePermissions({ update: result.permissions, allRecords });
|
||||
if (changePermissions) {
|
||||
setPermissions();
|
||||
}
|
||||
return resolve();
|
||||
} else {
|
||||
const params = {};
|
||||
const updatedSince = await getUpdatedSince(allRecords);
|
||||
const updatedSince = getUpdatedSince(allRecords);
|
||||
if (updatedSince) {
|
||||
params.updatedSince = updatedSince;
|
||||
}
|
||||
|
@ -102,10 +147,11 @@ export default function() {
|
|||
return resolve();
|
||||
}
|
||||
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
await updatePermissions({ update: result.update, remove: result.delete, allRecords });
|
||||
return resolve();
|
||||
});
|
||||
const changePermissions = await updatePermissions({ update: result.update, remove: result.delete, allRecords });
|
||||
if (changePermissions) {
|
||||
setPermissions();
|
||||
}
|
||||
return resolve();
|
||||
}
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
|
||||
import database from '../database';
|
||||
|
@ -19,43 +18,41 @@ export default function() {
|
|||
const { roles } = result;
|
||||
|
||||
if (roles && roles.length) {
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
await db.action(async() => {
|
||||
const rolesCollections = db.collections.get('roles');
|
||||
const allRolesRecords = await rolesCollections.query().fetch();
|
||||
await db.action(async() => {
|
||||
const rolesCollections = db.get('roles');
|
||||
const allRolesRecords = await rolesCollections.query().fetch();
|
||||
|
||||
// filter roles
|
||||
let rolesToCreate = roles.filter(i1 => !allRolesRecords.find(i2 => i1._id === i2.id));
|
||||
let rolesToUpdate = allRolesRecords.filter(i1 => roles.find(i2 => i1.id === i2._id));
|
||||
// filter roles
|
||||
let rolesToCreate = roles.filter(i1 => !allRolesRecords.find(i2 => i1._id === i2.id));
|
||||
let rolesToUpdate = allRolesRecords.filter(i1 => roles.find(i2 => i1.id === i2._id));
|
||||
|
||||
// Create
|
||||
rolesToCreate = rolesToCreate.map(role => rolesCollections.prepareCreate(protectedFunction((r) => {
|
||||
r._raw = sanitizedRaw({ id: role._id }, rolesCollections.schema);
|
||||
Object.assign(r, role);
|
||||
})));
|
||||
// Create
|
||||
rolesToCreate = rolesToCreate.map(role => rolesCollections.prepareCreate(protectedFunction((r) => {
|
||||
r._raw = sanitizedRaw({ id: role._id }, rolesCollections.schema);
|
||||
Object.assign(r, role);
|
||||
})));
|
||||
|
||||
// Update
|
||||
rolesToUpdate = rolesToUpdate.map((role) => {
|
||||
const newRole = roles.find(r => r._id === role.id);
|
||||
return role.prepareUpdate(protectedFunction((r) => {
|
||||
Object.assign(r, newRole);
|
||||
}));
|
||||
});
|
||||
|
||||
const allRecords = [
|
||||
...rolesToCreate,
|
||||
...rolesToUpdate
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
// Update
|
||||
rolesToUpdate = rolesToUpdate.map((role) => {
|
||||
const newRole = roles.find(r => r._id === role.id);
|
||||
return role.prepareUpdate(protectedFunction((r) => {
|
||||
Object.assign(r, newRole);
|
||||
}));
|
||||
});
|
||||
return resolve();
|
||||
|
||||
const allRecords = [
|
||||
...rolesToCreate,
|
||||
...rolesToUpdate
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
});
|
||||
return resolve();
|
||||
}
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
|
|
@ -44,7 +44,7 @@ const loginSettings = [
|
|||
const serverInfoUpdate = async(serverInfo, iconSetting) => {
|
||||
const serversDB = database.servers;
|
||||
const serverId = reduxStore.getState().server.server;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
const server = await serversCollection.find(serverId);
|
||||
|
||||
let info = serverInfo.reduce((allSettings, setting) => {
|
||||
|
@ -118,7 +118,7 @@ export async function getLoginSettings({ server }) {
|
|||
|
||||
export async function setSettings() {
|
||||
const db = database.active;
|
||||
const settingsCollection = db.collections.get('settings');
|
||||
const settingsCollection = db.get('settings');
|
||||
const settingsRecords = await settingsCollection.query().fetch();
|
||||
const parsed = Object.values(settingsRecords).map(item => ({
|
||||
_id: item.id,
|
||||
|
@ -157,7 +157,7 @@ export default async function() {
|
|||
}
|
||||
|
||||
await db.action(async() => {
|
||||
const settingsCollection = db.collections.get('settings');
|
||||
const settingsCollection = db.get('settings');
|
||||
const allSettingsRecords = await settingsCollection
|
||||
.query(Q.where('id', Q.oneOf(filteredSettingsIds)))
|
||||
.fetch();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
|
||||
import database from '../database';
|
||||
|
@ -20,47 +19,45 @@ export default function() {
|
|||
const { commands } = result;
|
||||
|
||||
if (commands && commands.length) {
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
await db.action(async() => {
|
||||
const slashCommandsCollection = db.collections.get('slash_commands');
|
||||
const allSlashCommandsRecords = await slashCommandsCollection.query().fetch();
|
||||
await db.action(async() => {
|
||||
const slashCommandsCollection = db.get('slash_commands');
|
||||
const allSlashCommandsRecords = await slashCommandsCollection.query().fetch();
|
||||
|
||||
// filter slash commands
|
||||
let slashCommandsToCreate = commands.filter(i1 => !allSlashCommandsRecords.find(i2 => i1.command === i2.id));
|
||||
let slashCommandsToUpdate = allSlashCommandsRecords.filter(i1 => commands.find(i2 => i1.id === i2.command));
|
||||
let slashCommandsToDelete = allSlashCommandsRecords
|
||||
.filter(i1 => !slashCommandsToCreate.find(i2 => i2.command === i1.id) && !slashCommandsToUpdate.find(i2 => i2.id === i1.id));
|
||||
// filter slash commands
|
||||
let slashCommandsToCreate = commands.filter(i1 => !allSlashCommandsRecords.find(i2 => i1.command === i2.id));
|
||||
let slashCommandsToUpdate = allSlashCommandsRecords.filter(i1 => commands.find(i2 => i1.id === i2.command));
|
||||
let slashCommandsToDelete = allSlashCommandsRecords
|
||||
.filter(i1 => !slashCommandsToCreate.find(i2 => i2.command === i1.id) && !slashCommandsToUpdate.find(i2 => i2.id === i1.id));
|
||||
|
||||
// Create
|
||||
slashCommandsToCreate = slashCommandsToCreate.map(command => slashCommandsCollection.prepareCreate(protectedFunction((s) => {
|
||||
s._raw = sanitizedRaw({ id: command.command }, slashCommandsCollection.schema);
|
||||
Object.assign(s, command);
|
||||
})));
|
||||
// Create
|
||||
slashCommandsToCreate = slashCommandsToCreate.map(command => slashCommandsCollection.prepareCreate(protectedFunction((s) => {
|
||||
s._raw = sanitizedRaw({ id: command.command }, slashCommandsCollection.schema);
|
||||
Object.assign(s, command);
|
||||
})));
|
||||
|
||||
// Update
|
||||
slashCommandsToUpdate = slashCommandsToUpdate.map((command) => {
|
||||
const newCommand = commands.find(s => s.command === command.id);
|
||||
return command.prepareUpdate(protectedFunction((s) => {
|
||||
Object.assign(s, newCommand);
|
||||
}));
|
||||
});
|
||||
|
||||
// Delete
|
||||
slashCommandsToDelete = slashCommandsToDelete.map(command => command.prepareDestroyPermanently());
|
||||
|
||||
const allRecords = [
|
||||
...slashCommandsToCreate,
|
||||
...slashCommandsToUpdate,
|
||||
...slashCommandsToDelete
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
// Update
|
||||
slashCommandsToUpdate = slashCommandsToUpdate.map((command) => {
|
||||
const newCommand = commands.find(s => s.command === command.id);
|
||||
return command.prepareUpdate(protectedFunction((s) => {
|
||||
Object.assign(s, newCommand);
|
||||
}));
|
||||
});
|
||||
|
||||
// Delete
|
||||
slashCommandsToDelete = slashCommandsToDelete.map(command => command.prepareDestroyPermanently());
|
||||
|
||||
const allRecords = [
|
||||
...slashCommandsToCreate,
|
||||
...slashCommandsToUpdate,
|
||||
...slashCommandsToDelete
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -72,7 +72,7 @@ export default async function getUsersPresence() {
|
|||
ids = [];
|
||||
|
||||
const db = database.active;
|
||||
const userCollection = db.collections.get('users');
|
||||
const userCollection = db.get('users');
|
||||
users.forEach(async(user) => {
|
||||
try {
|
||||
const userRecord = await userCollection.find(user._id);
|
||||
|
|
|
@ -5,7 +5,7 @@ import database from '../../database';
|
|||
export default async(subscriptions = [], rooms = []) => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
|
||||
const roomIds = rooms.filter(r => !subscriptions.find(s => s.rid === r._id)).map(r => r._id);
|
||||
let existingSubs = await subCollection.query(Q.where('rid', Q.oneOf(roomIds))).fetch();
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import EJSON from 'ejson';
|
||||
import { lt, coerce } from 'semver';
|
||||
|
||||
import normalizeMessage from './normalizeMessage';
|
||||
import findSubscriptionsRooms from './findSubscriptionsRooms';
|
||||
import { Encryption } from '../../encryption';
|
||||
import reduxStore from '../../createStore';
|
||||
// TODO: delete and update
|
||||
|
||||
export const merge = (subscription, room) => {
|
||||
const serverVersion = reduxStore.getState().server.version;
|
||||
subscription = EJSON.fromJSONValue(subscription);
|
||||
room = EJSON.fromJSONValue(room);
|
||||
|
||||
|
@ -25,9 +28,15 @@ export const merge = (subscription, room) => {
|
|||
subscription.usernames = room.usernames;
|
||||
subscription.uids = room.uids;
|
||||
}
|
||||
// https://github.com/RocketChat/Rocket.Chat/blob/develop/app/ui-sidenav/client/roomList.js#L180
|
||||
const lastRoomUpdate = room.lm || subscription.ts || subscription._updatedAt;
|
||||
subscription.roomUpdatedAt = subscription.lr ? Math.max(new Date(subscription.lr), new Date(lastRoomUpdate)) : lastRoomUpdate;
|
||||
if (serverVersion && lt(coerce(serverVersion), '3.7.0')) {
|
||||
const updatedAt = room?._updatedAt ? new Date(room._updatedAt) : null;
|
||||
const lastMessageTs = subscription?.lastMessage?.ts ? new Date(subscription.lastMessage.ts) : null;
|
||||
subscription.roomUpdatedAt = Math.max(updatedAt, lastMessageTs);
|
||||
} else {
|
||||
// https://github.com/RocketChat/Rocket.Chat/blob/develop/app/ui-sidenav/client/roomList.js#L180
|
||||
const lastRoomUpdate = room.lm || subscription.ts || subscription._updatedAt;
|
||||
subscription.roomUpdatedAt = subscription.lr ? Math.max(new Date(subscription.lr), new Date(lastRoomUpdate)) : lastRoomUpdate;
|
||||
}
|
||||
subscription.ro = room.ro;
|
||||
subscription.broadcast = room.broadcast;
|
||||
subscription.encrypted = room.encrypted;
|
||||
|
|
|
@ -5,7 +5,7 @@ import updateMessages from './updateMessages';
|
|||
const getLastUpdate = async(rid) => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
const sub = await subsCollection.find(rid);
|
||||
return sub.lastOpen.toISOString();
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
|
||||
|
@ -30,44 +29,42 @@ export default function loadThreadMessages({ tmid, rid, offset = 0 }) {
|
|||
let data = await load.call(this, { tmid, offset });
|
||||
|
||||
if (data && data.length) {
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
try {
|
||||
data = data.map(m => buildMessage(m));
|
||||
data = await Encryption.decryptMessages(data);
|
||||
const db = database.active;
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const allThreadMessagesRecords = await threadMessagesCollection.query(Q.where('rid', tmid)).fetch();
|
||||
let threadMessagesToCreate = data.filter(i1 => !allThreadMessagesRecords.find(i2 => i1._id === i2.id));
|
||||
let threadMessagesToUpdate = allThreadMessagesRecords.filter(i1 => data.find(i2 => i1.id === i2._id));
|
||||
try {
|
||||
data = data.map(m => buildMessage(m));
|
||||
data = await Encryption.decryptMessages(data);
|
||||
const db = database.active;
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
const allThreadMessagesRecords = await threadMessagesCollection.query(Q.where('rid', tmid)).fetch();
|
||||
let threadMessagesToCreate = data.filter(i1 => !allThreadMessagesRecords.find(i2 => i1._id === i2.id));
|
||||
let threadMessagesToUpdate = allThreadMessagesRecords.filter(i1 => data.find(i2 => i1.id === i2._id));
|
||||
|
||||
threadMessagesToCreate = threadMessagesToCreate.map(threadMessage => threadMessagesCollection.prepareCreate(protectedFunction((tm) => {
|
||||
tm._raw = sanitizedRaw({ id: threadMessage._id }, threadMessagesCollection.schema);
|
||||
Object.assign(tm, threadMessage);
|
||||
tm.subscription.id = rid;
|
||||
threadMessagesToCreate = threadMessagesToCreate.map(threadMessage => threadMessagesCollection.prepareCreate(protectedFunction((tm) => {
|
||||
tm._raw = sanitizedRaw({ id: threadMessage._id }, threadMessagesCollection.schema);
|
||||
Object.assign(tm, threadMessage);
|
||||
tm.subscription.id = rid;
|
||||
tm.rid = threadMessage.tmid;
|
||||
delete threadMessage.tmid;
|
||||
})));
|
||||
|
||||
threadMessagesToUpdate = threadMessagesToUpdate.map((threadMessage) => {
|
||||
const newThreadMessage = data.find(t => t._id === threadMessage.id);
|
||||
return threadMessage.prepareUpdate(protectedFunction((tm) => {
|
||||
Object.assign(tm, newThreadMessage);
|
||||
tm.rid = threadMessage.tmid;
|
||||
delete threadMessage.tmid;
|
||||
})));
|
||||
}));
|
||||
});
|
||||
|
||||
threadMessagesToUpdate = threadMessagesToUpdate.map((threadMessage) => {
|
||||
const newThreadMessage = data.find(t => t._id === threadMessage.id);
|
||||
return threadMessage.prepareUpdate(protectedFunction((tm) => {
|
||||
Object.assign(tm, newThreadMessage);
|
||||
tm.rid = threadMessage.tmid;
|
||||
delete threadMessage.tmid;
|
||||
}));
|
||||
});
|
||||
|
||||
await db.action(async() => {
|
||||
await db.batch(
|
||||
...threadMessagesToCreate,
|
||||
...threadMessagesToUpdate
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return resolve(data);
|
||||
});
|
||||
await db.action(async() => {
|
||||
await db.batch(
|
||||
...threadMessagesToCreate,
|
||||
...threadMessagesToUpdate
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return resolve(data);
|
||||
} else {
|
||||
return resolve([]);
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ async function removeServerData({ server }) {
|
|||
const serversDB = database.servers;
|
||||
const userId = await UserPreferences.getStringAsync(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
|
||||
const usersCollection = serversDB.collections.get('users');
|
||||
const usersCollection = serversDB.get('users');
|
||||
if (userId) {
|
||||
const userRecord = await usersCollection.find(userId);
|
||||
batch.push(userRecord.prepareDestroyPermanently());
|
||||
}
|
||||
const serverCollection = serversDB.collections.get('servers');
|
||||
const serverCollection = serversDB.get('servers');
|
||||
const serverRecord = await serverCollection.find(server);
|
||||
batch.push(serverRecord.prepareDestroyPermanently());
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import log from '../../utils/log';
|
|||
export default async function readMessages(rid, ls, updateLastOpen = false) {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subscription = await db.collections.get('subscriptions').find(rid);
|
||||
const subscription = await db.get('subscriptions').find(rid);
|
||||
|
||||
// RC 0.61.0
|
||||
await this.sdk.post('subscriptions.read', { rid });
|
||||
|
|
|
@ -40,7 +40,7 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
|
|||
fileInfo.rid = rid;
|
||||
|
||||
const db = database.active;
|
||||
const uploadsCollection = db.collections.get('uploads');
|
||||
const uploadsCollection = db.get('uploads');
|
||||
let uploadRecord;
|
||||
try {
|
||||
uploadRecord = await uploadsCollection.find(fileInfo.path);
|
||||
|
|
|
@ -9,8 +9,8 @@ import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../encryption/constants';
|
|||
|
||||
const changeMessageStatus = async(id, tmid, status, message) => {
|
||||
const db = database.active;
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
const successBatch = [];
|
||||
const messageRecord = await msgCollection.find(id);
|
||||
successBatch.push(
|
||||
|
@ -89,10 +89,10 @@ export async function resendMessage(message, tmid) {
|
|||
export default async function(rid, msg, tmid, user, tshow) {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadCollection = db.collections.get('threads');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadCollection = db.get('threads');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
const messageId = random(17);
|
||||
const batch = [];
|
||||
|
||||
|
@ -151,7 +151,8 @@ export default async function(rid, msg, tmid, user, tshow) {
|
|||
tm.status = messagesStatus.TEMP;
|
||||
tm.u = {
|
||||
_id: user.id || '1',
|
||||
username: user.username
|
||||
username: user.username,
|
||||
name: user.name
|
||||
};
|
||||
tm.t = message.t;
|
||||
if (message.t === E2E_MESSAGE_TYPE) {
|
||||
|
@ -175,7 +176,8 @@ export default async function(rid, msg, tmid, user, tshow) {
|
|||
m.status = messagesStatus.TEMP;
|
||||
m.u = {
|
||||
_id: user.id || '1',
|
||||
username: user.username
|
||||
username: user.username,
|
||||
name: user.name
|
||||
};
|
||||
if (tmid && tMessageRecord) {
|
||||
m.tmid = tmid;
|
||||
|
|
|
@ -90,6 +90,10 @@ export default class RoomSubscription {
|
|||
if (ev === 'typing') {
|
||||
const { user } = reduxStore.getState().login;
|
||||
const { UI_Use_Real_Name } = reduxStore.getState().settings;
|
||||
const { rooms } = reduxStore.getState().room;
|
||||
if (rooms[0] !== _rid) {
|
||||
return;
|
||||
}
|
||||
const [name, typing] = ddpMessage.fields.args;
|
||||
const key = UI_Use_Real_Name ? 'name' : 'username';
|
||||
if (name !== user[key]) {
|
||||
|
@ -105,9 +109,9 @@ export default class RoomSubscription {
|
|||
try {
|
||||
const { _id } = ddpMessage.fields.args[0];
|
||||
const db = database.active;
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadsCollection = db.collections.get('threads');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadsCollection = db.get('threads');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
let deleteMessage;
|
||||
let deleteThread;
|
||||
let deleteThreadMessage;
|
||||
|
@ -159,9 +163,9 @@ export default class RoomSubscription {
|
|||
}
|
||||
|
||||
const db = database.active;
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadsCollection = db.collections.get('threads');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadsCollection = db.get('threads');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
|
||||
// Decrypt the message if necessary
|
||||
message = await Encryption.decryptMessage(message);
|
||||
|
|
|
@ -32,8 +32,8 @@ const WINDOW_TIME = 500;
|
|||
const createOrUpdateSubscription = async(subscription, room) => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const roomsCollection = db.collections.get('rooms');
|
||||
const subCollection = db.get('subscriptions');
|
||||
const roomsCollection = db.get('rooms');
|
||||
|
||||
if (!subscription) {
|
||||
try {
|
||||
|
@ -185,7 +185,7 @@ const createOrUpdateSubscription = async(subscription, room) => {
|
|||
const { rooms } = store.getState().room;
|
||||
if (tmp.lastMessage && !rooms.includes(tmp.rid)) {
|
||||
const lastMessage = buildMessage(tmp.lastMessage);
|
||||
const messagesCollection = db.collections.get('messages');
|
||||
const messagesCollection = db.get('messages');
|
||||
let messageRecord;
|
||||
try {
|
||||
messageRecord = await messagesCollection.find(lastMessage._id);
|
||||
|
@ -281,7 +281,7 @@ export default function subscribeRooms() {
|
|||
if (/subscriptions/.test(ev)) {
|
||||
if (type === 'removed') {
|
||||
try {
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
const sub = await subCollection.find(data.rid);
|
||||
const messages = await sub.messages.fetch();
|
||||
const threads = await sub.threads.fetch();
|
||||
|
@ -335,7 +335,7 @@ export default function subscribeRooms() {
|
|||
}
|
||||
};
|
||||
try {
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const msgCollection = db.get('messages');
|
||||
await db.action(async() => {
|
||||
await msgCollection.create(protectedFunction((m) => {
|
||||
m._raw = sanitizedRaw({ id: message._id }, msgCollection.schema);
|
||||
|
@ -407,7 +407,7 @@ export default function subscribeRooms() {
|
|||
};
|
||||
|
||||
connectedListener = this.sdk.onStreamData('connected', handleConnection);
|
||||
disconnectedListener = this.sdk.onStreamData('close', handleConnection);
|
||||
// disconnectedListener = this.sdk.onStreamData('close', handleConnection);
|
||||
streamListener = this.sdk.onStreamData('stream-notify-user', handleStreamMessageReceived);
|
||||
|
||||
try {
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function updateMessages({ rid, update = [], remove = [] }) {
|
|||
return db.action(async() => {
|
||||
// Decrypt these messages
|
||||
update = await Encryption.decryptMessages(update);
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
let sub;
|
||||
try {
|
||||
sub = await subCollection.find(rid);
|
||||
|
@ -26,9 +26,9 @@ export default function updateMessages({ rid, update = [], remove = [] }) {
|
|||
}
|
||||
|
||||
const messagesIds = [...update.map(m => m._id), ...remove.map(m => m._id)];
|
||||
const msgCollection = db.collections.get('messages');
|
||||
const threadCollection = db.collections.get('threads');
|
||||
const threadMessagesCollection = db.collections.get('thread_messages');
|
||||
const msgCollection = db.get('messages');
|
||||
const threadCollection = db.get('threads');
|
||||
const threadMessagesCollection = db.get('thread_messages');
|
||||
const allMessagesRecords = await msgCollection
|
||||
.query(Q.where('rid', rid), Q.where('id', Q.oneOf(messagesIds)))
|
||||
.fetch();
|
||||
|
|
|
@ -32,7 +32,7 @@ import readMessages from './methods/readMessages';
|
|||
import getSettings, { getLoginSettings, setSettings } from './methods/getSettings';
|
||||
|
||||
import getRooms from './methods/getRooms';
|
||||
import getPermissions from './methods/getPermissions';
|
||||
import { setPermissions, getPermissions } from './methods/getPermissions';
|
||||
import { getCustomEmojis, setCustomEmojis } from './methods/getCustomEmojis';
|
||||
import {
|
||||
getEnterpriseModules, setEnterpriseModules, hasLicense, isOmnichannelModuleAvailable
|
||||
|
@ -70,7 +70,6 @@ const CERTIFICATE_KEY = 'RC_CERTIFICATE_KEY';
|
|||
export const THEME_PREFERENCES_KEY = 'RC_THEME_PREFERENCES_KEY';
|
||||
export const CRASH_REPORT_KEY = 'RC_CRASH_REPORT_KEY';
|
||||
export const ANALYTICS_EVENTS_KEY = 'RC_ANALYTICS_EVENTS_KEY';
|
||||
const returnAnArray = obj => obj || [];
|
||||
const MIN_ROCKETCHAT_VERSION = '0.70.0';
|
||||
|
||||
const STATUSES = ['offline', 'online', 'away', 'busy'];
|
||||
|
@ -178,9 +177,16 @@ const RocketChat = {
|
|||
}
|
||||
this.controller = new AbortController();
|
||||
},
|
||||
checkAndReopen() {
|
||||
return this?.sdk?.checkAndReopen();
|
||||
},
|
||||
connect({ server, user, logoutOnError = false }) {
|
||||
return new Promise((resolve) => {
|
||||
if (!this.sdk || this.sdk.client.host !== server) {
|
||||
if (this?.sdk?.client?.host === server) {
|
||||
return resolve();
|
||||
} else {
|
||||
this.sdk?.disconnect?.();
|
||||
this.sdk = null;
|
||||
database.setActiveDB(server);
|
||||
}
|
||||
reduxStore.dispatch(connectRequest());
|
||||
|
@ -209,11 +215,6 @@ const RocketChat = {
|
|||
|
||||
EventEmitter.emit('INQUIRY_UNSUBSCRIBE');
|
||||
|
||||
if (this.sdk) {
|
||||
this.sdk.disconnect();
|
||||
this.sdk = null;
|
||||
}
|
||||
|
||||
if (this.code) {
|
||||
this.code = null;
|
||||
}
|
||||
|
@ -241,6 +242,10 @@ const RocketChat = {
|
|||
|
||||
sdkConnect();
|
||||
|
||||
this.connectedListener = this.sdk.onStreamData('connecting', () => {
|
||||
reduxStore.dispatch(connectRequest());
|
||||
});
|
||||
|
||||
this.connectedListener = this.sdk.onStreamData('connected', () => {
|
||||
reduxStore.dispatch(connectSuccess());
|
||||
});
|
||||
|
@ -276,7 +281,7 @@ const RocketChat = {
|
|||
} else if (/updateAvatar/.test(eventName)) {
|
||||
const { username, etag } = ddpMessage.fields.args[0];
|
||||
const db = database.active;
|
||||
const userCollection = db.collections.get('users');
|
||||
const userCollection = db.get('users');
|
||||
try {
|
||||
const [userRecord] = await userCollection.query(Q.where('username', Q.eq(username))).fetch();
|
||||
await db.action(async() => {
|
||||
|
@ -290,7 +295,7 @@ const RocketChat = {
|
|||
} else if (/Users:NameChanged/.test(eventName)) {
|
||||
const userNameChanged = ddpMessage.fields.args[0];
|
||||
const db = database.active;
|
||||
const userCollection = db.collections.get('users');
|
||||
const userCollection = db.get('users');
|
||||
try {
|
||||
const userRecord = await userCollection.find(userNameChanged._id);
|
||||
await db.action(async() => {
|
||||
|
@ -334,7 +339,7 @@ const RocketChat = {
|
|||
// set Server
|
||||
const currentServer = { server };
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
try {
|
||||
const serverRecord = await serversCollection.find(server);
|
||||
currentServer.version = serverRecord.version;
|
||||
|
@ -349,7 +354,7 @@ const RocketChat = {
|
|||
// set Settings
|
||||
const settings = ['Accounts_AvatarBlockUnauthenticatedAccess'];
|
||||
const db = database.active;
|
||||
const settingsCollection = db.collections.get('settings');
|
||||
const settingsCollection = db.get('settings');
|
||||
const settingsRecords = await settingsCollection.query(Q.where('id', Q.oneOf(settings))).fetch();
|
||||
const parsed = Object.values(settingsRecords).map(item => ({
|
||||
_id: item.id,
|
||||
|
@ -363,7 +368,7 @@ const RocketChat = {
|
|||
|
||||
// set User info
|
||||
const userId = await UserPreferences.getStringAsync(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
const userCollections = serversDB.collections.get('users');
|
||||
const userCollections = serversDB.get('users');
|
||||
let user = null;
|
||||
if (userId) {
|
||||
const userRecord = await userCollections.find(userId);
|
||||
|
@ -545,7 +550,7 @@ const RocketChat = {
|
|||
try {
|
||||
const serversDB = database.servers;
|
||||
await serversDB.action(async() => {
|
||||
const serverCollection = serversDB.collections.get('servers');
|
||||
const serverCollection = serversDB.get('servers');
|
||||
const serverRecord = await serverCollection.find(server);
|
||||
await serverRecord.update((s) => {
|
||||
s.roomsUpdatedAt = null;
|
||||
|
@ -605,7 +610,7 @@ const RocketChat = {
|
|||
}
|
||||
const db = database.active;
|
||||
const likeString = sanitizeLikeString(searchText);
|
||||
let data = await db.collections.get('subscriptions').query(
|
||||
let data = await db.get('subscriptions').query(
|
||||
Q.or(
|
||||
Q.where('name', Q.like(`%${ likeString }%`)),
|
||||
Q.where('fname', Q.like(`%${ likeString }%`))
|
||||
|
@ -621,19 +626,15 @@ const RocketChat = {
|
|||
|
||||
data = data.slice(0, 7);
|
||||
|
||||
data = data.map((sub) => {
|
||||
if (sub.t !== 'd') {
|
||||
return {
|
||||
rid: sub.rid,
|
||||
name: sub.name,
|
||||
fname: sub.fname,
|
||||
avatarETag: sub.avatarETag,
|
||||
t: sub.t,
|
||||
encrypted: sub.encrypted
|
||||
};
|
||||
}
|
||||
return sub;
|
||||
});
|
||||
data = data.map(sub => ({
|
||||
rid: sub.rid,
|
||||
name: sub.name,
|
||||
fname: sub.fname,
|
||||
avatarETag: sub.avatarETag,
|
||||
t: sub.t,
|
||||
encrypted: sub.encrypted,
|
||||
lastMessage: sub.lastMessage
|
||||
}));
|
||||
|
||||
return data;
|
||||
},
|
||||
|
@ -740,6 +741,7 @@ const RocketChat = {
|
|||
getLoginSettings,
|
||||
setSettings,
|
||||
getPermissions,
|
||||
setPermissions,
|
||||
getCustomEmojis,
|
||||
setCustomEmojis,
|
||||
getEnterpriseModules,
|
||||
|
@ -796,7 +798,7 @@ const RocketChat = {
|
|||
async getRoom(rid) {
|
||||
try {
|
||||
const db = database.active;
|
||||
const room = await db.collections.get('subscriptions').find(rid);
|
||||
const room = await db.get('subscriptions').find(rid);
|
||||
return Promise.resolve(room);
|
||||
} catch (error) {
|
||||
return Promise.reject(new Error('Room not found'));
|
||||
|
@ -1172,10 +1174,13 @@ const RocketChat = {
|
|||
// RC 0.65.0
|
||||
return this.sdk.get(`${ this.roomTypeToApiType(type) }.roles`, { roomId });
|
||||
},
|
||||
/**
|
||||
* Permissions: array of permissions' roles from redux. Example: [['owner', 'admin'], ['leader']]
|
||||
* Returns an array of boolean for each permission from permissions arg
|
||||
*/
|
||||
async hasPermission(permissions, rid) {
|
||||
const db = database.active;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const permissionsCollection = db.collections.get('permissions');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
let roomRoles = [];
|
||||
try {
|
||||
// get the room from database
|
||||
|
@ -1184,31 +1189,16 @@ const RocketChat = {
|
|||
roomRoles = room.roles || [];
|
||||
} catch (error) {
|
||||
console.log('hasPermission -> Room not found');
|
||||
return permissions.reduce((result, permission) => {
|
||||
result[permission] = false;
|
||||
return result;
|
||||
}, {});
|
||||
return permissions.map(() => false);
|
||||
}
|
||||
// get permissions from database
|
||||
|
||||
try {
|
||||
const permissionsFiltered = await permissionsCollection.query(Q.where('id', Q.oneOf(permissions))).fetch();
|
||||
const shareUser = reduxStore.getState().share.user;
|
||||
const loginUser = reduxStore.getState().login.user;
|
||||
// get user roles on the server from redux
|
||||
const userRoles = (shareUser?.roles || loginUser?.roles) || [];
|
||||
// merge both roles
|
||||
const mergedRoles = [...new Set([...roomRoles, ...userRoles])];
|
||||
|
||||
// return permissions in object format
|
||||
// e.g. { 'edit-room': true, 'set-readonly': false }
|
||||
return permissions.reduce((result, permission) => {
|
||||
result[permission] = false;
|
||||
const permissionFound = permissionsFiltered.find(p => p.id === permission);
|
||||
if (permissionFound) {
|
||||
result[permission] = returnAnArray(permissionFound.roles).some(r => mergedRoles.includes(r));
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
return permissions.map(permission => permission?.some(r => mergedRoles.includes(r) ?? false));
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
|
@ -1438,17 +1428,15 @@ const RocketChat = {
|
|||
query, count, offset, sort
|
||||
});
|
||||
},
|
||||
async canAutoTranslate() {
|
||||
const db = database.active;
|
||||
canAutoTranslate() {
|
||||
try {
|
||||
const AutoTranslate_Enabled = reduxStore.getState().settings && reduxStore.getState().settings.AutoTranslate_Enabled;
|
||||
const { AutoTranslate_Enabled } = reduxStore.getState().settings;
|
||||
if (!AutoTranslate_Enabled) {
|
||||
return false;
|
||||
}
|
||||
const permissionsCollection = db.collections.get('permissions');
|
||||
const autoTranslatePermission = await permissionsCollection.find('auto-translate');
|
||||
const userRoles = (reduxStore.getState().login.user && reduxStore.getState().login.user.roles) || [];
|
||||
return autoTranslatePermission.roles.some(role => userRoles.includes(role));
|
||||
const autoTranslatePermission = reduxStore.getState().permissions['auto-translate'];
|
||||
const userRoles = (reduxStore.getState().login?.user?.roles) ?? [];
|
||||
return autoTranslatePermission?.some(role => userRoles.includes(role));
|
||||
} catch (e) {
|
||||
log(e);
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import I18n from '../../i18n';
|
||||
import styles from './styles';
|
||||
|
@ -45,7 +45,7 @@ const formatMsg = ({
|
|||
return `${ prefix }${ lastMessage.msg }`;
|
||||
};
|
||||
|
||||
const arePropsEqual = (oldProps, newProps) => isEqual(oldProps, newProps);
|
||||
const arePropsEqual = (oldProps, newProps) => dequal(oldProps, newProps);
|
||||
|
||||
const LastMessage = React.memo(({
|
||||
lastMessage, type, showLastMessage, username, alert, useRealName, theme
|
||||
|
|
|
@ -18,6 +18,7 @@ import inviteLinks from './inviteLinks';
|
|||
import createDiscussion from './createDiscussion';
|
||||
import enterpriseModules from './enterpriseModules';
|
||||
import encryption from './encryption';
|
||||
import permissions from './permissions';
|
||||
|
||||
import inquiry from '../ee/omnichannel/reducers/inquiry';
|
||||
|
||||
|
@ -41,5 +42,6 @@ export default combineReducers({
|
|||
createDiscussion,
|
||||
inquiry,
|
||||
enterpriseModules,
|
||||
encryption
|
||||
encryption,
|
||||
permissions
|
||||
});
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import { PERMISSIONS } from '../actions/actionsTypes';
|
||||
|
||||
const initialState = {
|
||||
permissions: {}
|
||||
};
|
||||
|
||||
export default function permissions(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case PERMISSIONS.SET:
|
||||
return action.permissions;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ const handleRequest = function* handleRequest({ data }) {
|
|||
broadcast,
|
||||
encrypted
|
||||
} = data;
|
||||
logEvent(events.CREATE_CHANNEL_CREATE, {
|
||||
logEvent(events.CR_CREATE, {
|
||||
type: type ? 'private' : 'public',
|
||||
readOnly,
|
||||
broadcast,
|
||||
|
@ -53,7 +53,7 @@ const handleRequest = function* handleRequest({ data }) {
|
|||
|
||||
try {
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
yield db.action(async() => {
|
||||
await subCollection.create((s) => {
|
||||
s._raw = sanitizedRaw({ id: sub.rid }, subCollection.schema);
|
||||
|
@ -66,7 +66,7 @@ const handleRequest = function* handleRequest({ data }) {
|
|||
|
||||
yield put(createChannelSuccess(sub));
|
||||
} catch (err) {
|
||||
logEvent(events[data.group ? 'SELECTED_USERS_CREATE_GROUP_F' : 'CREATE_CHANNEL_CREATE_F']);
|
||||
logEvent(events[data.group ? 'SELECTED_USERS_CREATE_GROUP_F' : 'CR_CREATE_F']);
|
||||
yield put(createChannelFailure(err));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ const create = function* create(data) {
|
|||
};
|
||||
|
||||
const handleRequest = function* handleRequest({ data }) {
|
||||
logEvent(events.CREATE_DISCUSSION_CREATE);
|
||||
logEvent(events.CD_CREATE);
|
||||
try {
|
||||
const auth = yield select(state => state.login.isAuthenticated);
|
||||
if (!auth) {
|
||||
|
@ -27,7 +27,7 @@ const handleRequest = function* handleRequest({ data }) {
|
|||
|
||||
try {
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
yield db.action(async() => {
|
||||
await subCollection.create((s) => {
|
||||
s._raw = sanitizedRaw({ id: sub.rid }, subCollection.schema);
|
||||
|
@ -39,11 +39,11 @@ const handleRequest = function* handleRequest({ data }) {
|
|||
}
|
||||
yield put(createDiscussionSuccess(sub));
|
||||
} else {
|
||||
logEvent(events.CREATE_DISCUSSION_CREATE_F);
|
||||
logEvent(events.CD_CREATE_F);
|
||||
yield put(createDiscussionFailure(result));
|
||||
}
|
||||
} catch (err) {
|
||||
logEvent(events.CREATE_DISCUSSION_CREATE_F);
|
||||
logEvent(events.CD_CREATE_F);
|
||||
yield put(createDiscussionFailure(err));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -31,6 +31,14 @@ const handleInviteLink = function* handleInviteLink({ params, requireLogin = fal
|
|||
}
|
||||
};
|
||||
|
||||
const popToRoot = function popToRoot({ isMasterDetail }) {
|
||||
if (isMasterDetail) {
|
||||
Navigation.navigate('DrawerNavigator');
|
||||
} else {
|
||||
Navigation.navigate('RoomsListView');
|
||||
}
|
||||
};
|
||||
|
||||
const navigate = function* navigate({ params }) {
|
||||
yield put(appStart({ root: ROOT_INSIDE }));
|
||||
if (params.path) {
|
||||
|
@ -38,22 +46,31 @@ const navigate = function* navigate({ params }) {
|
|||
if (type !== 'invite') {
|
||||
const room = yield RocketChat.canOpenRoom(params);
|
||||
if (room) {
|
||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||
if (isMasterDetail) {
|
||||
Navigation.navigate('DrawerNavigator');
|
||||
} else {
|
||||
Navigation.navigate('RoomsListView');
|
||||
}
|
||||
const item = {
|
||||
name,
|
||||
t: roomTypes[type],
|
||||
roomUserId: RocketChat.getUidDirectMessage(room),
|
||||
...room
|
||||
};
|
||||
yield goRoom({ item, isMasterDetail });
|
||||
|
||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||
const focusedRooms = yield select(state => state.room.rooms);
|
||||
|
||||
if (focusedRooms.includes(room.rid)) {
|
||||
// if there's one room on the list or last room is the one
|
||||
if (focusedRooms.length === 1 || focusedRooms[0] === room.rid) {
|
||||
yield goRoom({ item, isMasterDetail });
|
||||
} else {
|
||||
popToRoot({ isMasterDetail });
|
||||
yield goRoom({ item, isMasterDetail });
|
||||
}
|
||||
} else {
|
||||
popToRoot({ isMasterDetail });
|
||||
yield goRoom({ item, isMasterDetail });
|
||||
}
|
||||
|
||||
if (params.isCall) {
|
||||
RocketChat.callJitsi(item.rid);
|
||||
RocketChat.callJitsi(item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -72,7 +89,7 @@ const fallbackNavigation = function* fallbackNavigation() {
|
|||
|
||||
const handleOpen = function* handleOpen({ params }) {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
|
||||
let { host } = params;
|
||||
if (params.isCall && !host) {
|
||||
|
@ -121,10 +138,10 @@ const handleOpen = function* handleOpen({ params }) {
|
|||
} else {
|
||||
// search if deep link's server already exists
|
||||
try {
|
||||
const servers = yield serversCollection.find(host);
|
||||
if (servers && user) {
|
||||
const hostServerRecord = yield serversCollection.find(host);
|
||||
if (hostServerRecord && user) {
|
||||
yield localAuthenticate(host);
|
||||
yield put(selectServerRequest(host));
|
||||
yield put(selectServerRequest(host, hostServerRecord.version, true, true));
|
||||
yield take(types.LOGIN.SUCCESS);
|
||||
yield navigate({ params });
|
||||
return;
|
||||
|
|
|
@ -30,7 +30,7 @@ const handleEncryptionInit = function* handleEncryptionInit() {
|
|||
|
||||
// Fetch server info to check E2E enable
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
let serverInfo;
|
||||
try {
|
||||
serverInfo = yield serversCollection.find(server);
|
||||
|
|
|
@ -38,7 +38,7 @@ const restore = function* restore() {
|
|||
yield put(appStart({ root: ROOT_OUTSIDE }));
|
||||
} else {
|
||||
const serversDB = database.servers;
|
||||
const serverCollections = serversDB.collections.get('servers');
|
||||
const serverCollections = serversDB.get('servers');
|
||||
|
||||
let serverObj;
|
||||
try {
|
||||
|
|
|
@ -57,7 +57,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnE
|
|||
|
||||
// Saves username on server history
|
||||
const serversDB = database.servers;
|
||||
const serversHistoryCollection = serversDB.collections.get('servers_history');
|
||||
const serversHistoryCollection = serversDB.get('servers_history');
|
||||
yield serversDB.action(async() => {
|
||||
try {
|
||||
const serversHistory = await serversHistoryCollection.query(Q.where('url', server)).fetch();
|
||||
|
@ -145,7 +145,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
|||
moment.locale(toMomentLocale(user.language));
|
||||
|
||||
const serversDB = database.servers;
|
||||
const usersCollection = serversDB.collections.get('users');
|
||||
const usersCollection = serversDB.get('users');
|
||||
const u = {
|
||||
token: user.token,
|
||||
username: user.username,
|
||||
|
@ -222,7 +222,7 @@ const handleLogout = function* handleLogout({ forcedByServer }) {
|
|||
} else {
|
||||
const serversDB = database.servers;
|
||||
// all servers
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
const servers = yield serversCollection.query().fetch();
|
||||
|
||||
// see if there're other logged in servers and selects first one
|
||||
|
|
|
@ -12,7 +12,7 @@ const handleReplyBroadcast = function* handleReplyBroadcast({ message }) {
|
|||
try {
|
||||
const db = database.active;
|
||||
const { username } = message.u;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch();
|
||||
|
||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||
|
|
|
@ -15,7 +15,7 @@ import protectedFunction from '../lib/methods/helpers/protectedFunction';
|
|||
|
||||
const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
try {
|
||||
const serverRecord = yield serversCollection.find(server);
|
||||
|
||||
|
@ -39,7 +39,7 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
|
|||
if (params.allData) {
|
||||
yield put(roomsRefresh());
|
||||
} else {
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
try {
|
||||
const serverRecord = yield serversCollection.find(server);
|
||||
({ roomsUpdatedAt } = serverRecord);
|
||||
|
@ -51,8 +51,8 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
|
|||
const { subscriptions } = yield mergeSubscriptionsRooms(subscriptionsResult, roomsResult);
|
||||
|
||||
const db = database.active;
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const messagesCollection = db.collections.get('messages');
|
||||
const subCollection = db.get('subscriptions');
|
||||
const messagesCollection = db.get('messages');
|
||||
|
||||
const subsIds = subscriptions.map(sub => sub.rid).concat(roomsResult.remove.map(room => room._id));
|
||||
if (subsIds.length) {
|
||||
|
|
|
@ -46,7 +46,7 @@ const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
|
|||
}
|
||||
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
yield serversDB.action(async() => {
|
||||
try {
|
||||
const serverRecord = await serversCollection.find(server);
|
||||
|
@ -78,7 +78,7 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
|
|||
const serversDB = database.servers;
|
||||
yield UserPreferences.setStringAsync(RocketChat.CURRENT_SERVER, server);
|
||||
const userId = yield UserPreferences.getStringAsync(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
const userCollections = serversDB.collections.get('users');
|
||||
const userCollections = serversDB.get('users');
|
||||
let user = null;
|
||||
if (userId) {
|
||||
try {
|
||||
|
@ -124,6 +124,7 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
|
|||
// and block the selectServerSuccess raising multiples errors
|
||||
RocketChat.setSettings();
|
||||
RocketChat.setCustomEmojis();
|
||||
RocketChat.setPermissions();
|
||||
RocketChat.setEnterpriseModules();
|
||||
|
||||
let serverInfo;
|
||||
|
@ -151,7 +152,7 @@ const handleServerRequest = function* handleServerRequest({ server, username, fr
|
|||
|
||||
const serverInfo = yield getServerInfo({ server });
|
||||
const serversDB = database.servers;
|
||||
const serversHistoryCollection = serversDB.collections.get('servers_history');
|
||||
const serversHistoryCollection = serversDB.get('servers_history');
|
||||
|
||||
if (serverInfo) {
|
||||
yield RocketChat.getLoginServices(server);
|
||||
|
|
|
@ -12,13 +12,14 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() {
|
|||
if (appRoot === ROOT_OUTSIDE) {
|
||||
return;
|
||||
}
|
||||
const auth = yield select(state => state.login.isAuthenticated);
|
||||
if (!auth) {
|
||||
const login = yield select(state => state.login);
|
||||
const server = yield select(state => state.server);
|
||||
if (!login.isAuthenticated || login.isFetching || server.connecting || server.loading || server.changingServer) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const server = yield select(state => state.server.server);
|
||||
yield localAuthenticate(server);
|
||||
yield localAuthenticate(server.server);
|
||||
RocketChat.checkAndReopen();
|
||||
setBadgeCount();
|
||||
return yield RocketChat.setUserPresenceOnline();
|
||||
} catch (e) {
|
||||
|
@ -31,14 +32,6 @@ const appHasComeBackToBackground = function* appHasComeBackToBackground() {
|
|||
if (appRoot === ROOT_OUTSIDE) {
|
||||
return;
|
||||
}
|
||||
const auth = yield select(state => state.login.isAuthenticated);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const localAuthenticated = yield select(state => state.login.isLocalAuthenticated);
|
||||
if (!localAuthenticated) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const server = yield select(state => state.server.server);
|
||||
yield saveLastLocalAuthenticationSession(server);
|
||||
|
|
|
@ -31,6 +31,7 @@ import PickerView from '../views/PickerView';
|
|||
import ThreadMessagesView from '../views/ThreadMessagesView';
|
||||
import MarkdownTableView from '../views/MarkdownTableView';
|
||||
import ReadReceiptsView from '../views/ReadReceiptView';
|
||||
import { themes } from '../constants/colors';
|
||||
|
||||
// Profile Stack
|
||||
import ProfileView from '../views/ProfileView';
|
||||
|
@ -280,19 +281,24 @@ const AdminPanelStackNavigator = () => {
|
|||
|
||||
// DrawerNavigator
|
||||
const Drawer = createDrawerNavigator();
|
||||
const DrawerNavigator = () => (
|
||||
<Drawer.Navigator
|
||||
drawerContent={({ navigation, state }) => <Sidebar navigation={navigation} state={state} />}
|
||||
drawerPosition={I18nManager.isRTL ? 'right' : 'left'}
|
||||
screenOptions={{ swipeEnabled: false }}
|
||||
drawerType='back'
|
||||
>
|
||||
<Drawer.Screen name='ChatsStackNavigator' component={ChatsStackNavigator} />
|
||||
<Drawer.Screen name='ProfileStackNavigator' component={ProfileStackNavigator} />
|
||||
<Drawer.Screen name='SettingsStackNavigator' component={SettingsStackNavigator} />
|
||||
<Drawer.Screen name='AdminPanelStackNavigator' component={AdminPanelStackNavigator} />
|
||||
</Drawer.Navigator>
|
||||
);
|
||||
const DrawerNavigator = () => {
|
||||
const { theme } = React.useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<Drawer.Navigator
|
||||
drawerContent={({ navigation, state }) => <Sidebar navigation={navigation} state={state} />}
|
||||
drawerPosition={I18nManager.isRTL ? 'right' : 'left'}
|
||||
screenOptions={{ swipeEnabled: false }}
|
||||
drawerType='back'
|
||||
overlayColor={`rgba(0,0,0,${ themes[theme].backdropOpacity })`}
|
||||
>
|
||||
<Drawer.Screen name='ChatsStackNavigator' component={ChatsStackNavigator} />
|
||||
<Drawer.Screen name='ProfileStackNavigator' component={ProfileStackNavigator} />
|
||||
<Drawer.Screen name='SettingsStackNavigator' component={SettingsStackNavigator} />
|
||||
<Drawer.Screen name='AdminPanelStackNavigator' component={AdminPanelStackNavigator} />
|
||||
</Drawer.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
// NewMessageStackNavigator
|
||||
const NewMessageStack = createStackNavigator();
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import RocketChat from '../lib/rocketchat';
|
||||
import reduxStore from '../lib/createStore';
|
||||
|
||||
const canPost = async({ rid }) => {
|
||||
try {
|
||||
const permission = await RocketChat.hasPermission(['post-readonly'], rid);
|
||||
return permission && permission['post-readonly'];
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
return false;
|
||||
const canPostReadOnly = async({ rid }) => {
|
||||
// TODO: this is not reactive. If this permission changes, the component won't be updated
|
||||
const postReadOnlyPermission = reduxStore.getState().permissions['post-readonly'];
|
||||
const permission = await RocketChat.hasPermission([postReadOnlyPermission], rid);
|
||||
return permission[0];
|
||||
};
|
||||
|
||||
const isMuted = (room, user) => room && room.muted && room.muted.find && !!room.muted.find(m => m === user.username);
|
||||
|
@ -20,7 +18,7 @@ export const isReadOnly = async(room, user) => {
|
|||
return true;
|
||||
}
|
||||
if (room?.ro) {
|
||||
const allowPost = await canPost(room);
|
||||
const allowPost = await canPostReadOnly(room);
|
||||
if (allowPost) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import { setLocalAuthenticated } from '../actions/login';
|
|||
|
||||
export const saveLastLocalAuthenticationSession = async(server, serverRecord) => {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
await serversDB.action(async() => {
|
||||
try {
|
||||
if (!serverRecord) {
|
||||
|
@ -91,7 +91,7 @@ export const checkHasPasscode = async({ force = true, serverRecord }) => {
|
|||
|
||||
export const localAuthenticate = async(server) => {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.collections.get('servers');
|
||||
const serversCollection = serversDB.get('servers');
|
||||
|
||||
let serverRecord;
|
||||
try {
|
||||
|
@ -102,9 +102,6 @@ export const localAuthenticate = async(server) => {
|
|||
|
||||
// if screen lock is enabled
|
||||
if (serverRecord?.autoLock) {
|
||||
// set isLocalAuthenticated to false
|
||||
store.dispatch(setLocalAuthenticated(false));
|
||||
|
||||
// Make sure splash screen has been hidden
|
||||
RNBootSplash.hide();
|
||||
|
||||
|
@ -118,6 +115,9 @@ export const localAuthenticate = async(server) => {
|
|||
|
||||
// if last authenticated session is older than configured auto lock time, authentication is required
|
||||
if (diffToLastSession >= serverRecord?.autoLockTime) {
|
||||
// set isLocalAuthenticated to false
|
||||
store.dispatch(setLocalAuthenticated(false));
|
||||
|
||||
let hasBiometry = false;
|
||||
|
||||
// if biometry is enabled on the app
|
||||
|
|
|
@ -5,9 +5,8 @@ export default {
|
|||
ONBOARD_CREATE_NEW_WORKSPACE_F: 'onboard_create_new_workspace_f',
|
||||
|
||||
// NEW SERVER VIEW
|
||||
NEWSERVER_CONNECT_TO_WORKSPACE: 'newserver_connect_to_workspace',
|
||||
NEWSERVER_CONNECT_TO_WORKSPACE_F: 'newserver_connect_to_workspace_f',
|
||||
NEWSERVER_JOIN_OPEN_WORKSPACE: 'newserver_join_open_workspace',
|
||||
NS_CONNECT_TO_WORKSPACE: 'ns_connect_to_workspace',
|
||||
NS_JOIN_OPEN_WORKSPACE: 'ns_join_open_workspace',
|
||||
|
||||
// LOGIN VIEW
|
||||
LOGIN_DEFAULT_LOGIN: 'login_default_login',
|
||||
|
@ -99,20 +98,20 @@ export default {
|
|||
SELECTED_USERS_CREATE_GROUP_F: 'selected_users_create_group_f',
|
||||
|
||||
// CREATE CHANNEL VIEW
|
||||
CREATE_CHANNEL_CREATE: 'create_channel_create',
|
||||
CREATE_CHANNEL_CREATE_F: 'create_channel_create_f',
|
||||
CREATE_CHANNEL_TOGGLE_TYPE: 'create_channel_toggle_type',
|
||||
CREATE_CHANNEL_TOGGLE_READ_ONLY: 'create_channel_toggle_read_only',
|
||||
CREATE_CHANNEL_TOGGLE_BROADCAST: 'create_channel_toggle_broadcast',
|
||||
CREATE_CHANNEL_TOGGLE_ENCRYPTED: 'create_channel_toggle_encrypted',
|
||||
CREATE_CHANNEL_REMOVE_USER: 'create_channel_remove_user',
|
||||
CR_CREATE: 'cr_create',
|
||||
CR_CREATE_F: 'cr_create_f',
|
||||
CR_TOGGLE_TYPE: 'cr_toggle_type',
|
||||
CR_TOGGLE_READ_ONLY: 'cr_toggle_read_only',
|
||||
CR_TOGGLE_BROADCAST: 'cr_toggle_broadcast',
|
||||
CR_TOGGLE_ENCRYPTED: 'cr_toggle_encrypted',
|
||||
CR_REMOVE_USER: 'cr_remove_user',
|
||||
|
||||
// CREATE DISCUSSION VIEW
|
||||
CREATE_DISCUSSION_CREATE: 'create_discussion_create',
|
||||
CREATE_DISCUSSION_CREATE_F: 'create_discussion_create_f',
|
||||
CREATE_DISCUSSION_SELECT_CHANNEL: 'create_discussion_select_channel',
|
||||
CREATE_DISCUSSION_SELECT_USERS: 'create_discussion_select_users',
|
||||
CREATE_DISCUSSION_TOGGLE_ENCRY: 'create_discussion_toggle_encry',
|
||||
CD_CREATE: 'cd_create',
|
||||
CD_CREATE_F: 'cd_create_f',
|
||||
CD_SELECT_CHANNEL: 'cd_select_channel',
|
||||
CD_SELECT_USERS: 'cd_select_users',
|
||||
CD_TOGGLE_ENCRY: 'cd_toggle_encry',
|
||||
|
||||
// PROFILE VIEW
|
||||
PROFILE_PICK_AVATAR: 'profile_pick_avatar',
|
||||
|
@ -122,8 +121,9 @@ export default {
|
|||
PROFILE_SAVE_AVATAR_F: 'profile_save_avatar_f',
|
||||
PROFILE_SAVE_CHANGES: 'profile_save_changes',
|
||||
PROFILE_SAVE_CHANGES_F: 'profile_save_changes_f',
|
||||
PROFILE_LOGOUT_OTHER_LOCATIONS: 'profile_logout_other_locations',
|
||||
PROFILE_LOGOUT_OTHER_LOCATIONS_F: 'profile_logout_other_locations_f',
|
||||
// PROFILE LOGOUT
|
||||
PL_OTHER_LOCATIONS: 'pl_other_locations',
|
||||
PL_OTHER_LOCATIONS_F: 'pl_other_locations_f',
|
||||
|
||||
// SETTINGS VIEW
|
||||
SE_CONTACT_US: 'se_contact_us',
|
||||
|
@ -297,8 +297,6 @@ export default {
|
|||
NP_AUDIONOTIFICATIONS_F: 'np_audio_notifications_f',
|
||||
NP_AUDIONOTIFICATIONVALUE: 'np_audio_notification_value',
|
||||
NP_AUDIONOTIFICATIONVALUE_F: 'np_audio_notification_value_f',
|
||||
NP_DESKTOPNOTIFICATIONDURATION: 'np_desktopnotificationduration',
|
||||
NP_DESKTOPNOTIFICATIONDURATION_F: 'np_desktopnotificationduration_f',
|
||||
NP_EMAILNOTIFICATIONS: 'np_email_notifications',
|
||||
NP_EMAILNOTIFICATIONS_F: 'np_email_notifications_f',
|
||||
|
||||
|
|
|
@ -121,8 +121,9 @@ class AttachmentView extends React.Component {
|
|||
const extension = image_url ? `.${ mime.extension(image_type) || 'jpg' }` : `.${ mime.extension(video_type) || 'mp4' }`;
|
||||
const documentDir = `${ RNFetchBlob.fs.dirs.DocumentDir }/`;
|
||||
const path = `${ documentDir + SHA256(url) + extension }`;
|
||||
const file = await RNFetchBlob.config({ path }).fetch('GET', mediaAttachment).then(res => res.path());
|
||||
await CameraRoll.save(file, { album: 'Rocket.Chat' });
|
||||
const file = await RNFetchBlob.config({ path }).fetch('GET', mediaAttachment);
|
||||
await CameraRoll.save(path, { album: 'Rocket.Chat' });
|
||||
await file.flush();
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('saved_to_gallery') });
|
||||
} catch (e) {
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t(image_url ? 'error-save-image' : 'error-save-video') });
|
||||
|
|
|
@ -63,12 +63,12 @@ const ChangePasscodeView = React.memo(({ theme }) => {
|
|||
if (!isTablet) {
|
||||
Orientation.lockToPortrait();
|
||||
}
|
||||
EventEmitter.addEventListener(CHANGE_PASSCODE_EMITTER, showChangePasscode);
|
||||
const listener = EventEmitter.addEventListener(CHANGE_PASSCODE_EMITTER, showChangePasscode);
|
||||
return (() => {
|
||||
if (!isTablet) {
|
||||
Orientation.unlockAllOrientations();
|
||||
}
|
||||
EventEmitter.removeListener(CHANGE_PASSCODE_EMITTER);
|
||||
EventEmitter.removeListener(CHANGE_PASSCODE_EMITTER, listener);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ import PropTypes from 'prop-types';
|
|||
import {
|
||||
View, Text, Switch, ScrollView, StyleSheet, FlatList
|
||||
} from 'react-native';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import * as List from '../containers/List';
|
||||
|
||||
import TextInput from '../presentation/TextInput';
|
||||
import Loading from '../containers/Loading';
|
||||
|
@ -31,12 +32,6 @@ const styles = StyleSheet.create({
|
|||
list: {
|
||||
width: '100%'
|
||||
},
|
||||
separator: {
|
||||
marginLeft: 60
|
||||
},
|
||||
formSeparator: {
|
||||
marginLeft: 15
|
||||
},
|
||||
input: {
|
||||
height: 54,
|
||||
paddingHorizontal: 18,
|
||||
|
@ -133,7 +128,7 @@ class CreateChannelView extends React.Component {
|
|||
if (nextProps.encryptionEnabled !== encryptionEnabled) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.users, users)) {
|
||||
if (!dequal(nextProps.users, users)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -177,7 +172,7 @@ class CreateChannelView extends React.Component {
|
|||
}
|
||||
|
||||
removeUser = (user) => {
|
||||
logEvent(events.CREATE_CHANNEL_REMOVE_USER);
|
||||
logEvent(events.CR_REMOVE_USER);
|
||||
const { removeUser } = this.props;
|
||||
removeUser(user);
|
||||
}
|
||||
|
@ -207,7 +202,7 @@ class CreateChannelView extends React.Component {
|
|||
value: type,
|
||||
label: 'Private_Channel',
|
||||
onValueChange: (value) => {
|
||||
logEvent(events.CREATE_CHANNEL_TOGGLE_TYPE);
|
||||
logEvent(events.CR_TOGGLE_TYPE);
|
||||
// If we set the channel as public, encrypted status should be false
|
||||
this.setState(({ encrypted }) => ({ type: value, encrypted: value && encrypted }));
|
||||
}
|
||||
|
@ -221,7 +216,7 @@ class CreateChannelView extends React.Component {
|
|||
value: readOnly,
|
||||
label: 'Read_Only_Channel',
|
||||
onValueChange: (value) => {
|
||||
logEvent(events.CREATE_CHANNEL_TOGGLE_READ_ONLY);
|
||||
logEvent(events.CR_TOGGLE_READ_ONLY);
|
||||
this.setState({ readOnly: value });
|
||||
},
|
||||
disabled: broadcast
|
||||
|
@ -241,7 +236,7 @@ class CreateChannelView extends React.Component {
|
|||
value: encrypted,
|
||||
label: 'Encrypted',
|
||||
onValueChange: (value) => {
|
||||
logEvent(events.CREATE_CHANNEL_TOGGLE_ENCRYPTED);
|
||||
logEvent(events.CR_TOGGLE_ENCRYPTED);
|
||||
this.setState({ encrypted: value });
|
||||
},
|
||||
disabled: !type
|
||||
|
@ -255,7 +250,7 @@ class CreateChannelView extends React.Component {
|
|||
value: broadcast,
|
||||
label: 'Broadcast_Channel',
|
||||
onValueChange: (value) => {
|
||||
logEvent(events.CREATE_CHANNEL_TOGGLE_BROADCAST);
|
||||
logEvent(events.CR_TOGGLE_BROADCAST);
|
||||
this.setState({
|
||||
broadcast: value,
|
||||
readOnly: value ? true : readOnly
|
||||
|
@ -264,13 +259,6 @@ class CreateChannelView extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
renderSeparator = () => <View style={[sharedStyles.separator, styles.separator]} />
|
||||
|
||||
renderFormSeparator = () => {
|
||||
const { theme } = this.props;
|
||||
return <View style={[sharedStyles.separator, styles.formSeparator, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
}
|
||||
|
||||
renderItem = ({ item }) => {
|
||||
const { baseUrl, user, theme } = this.props;
|
||||
|
||||
|
@ -305,7 +293,7 @@ class CreateChannelView extends React.Component {
|
|||
}
|
||||
]}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
enableEmptySections
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
|
@ -341,13 +329,13 @@ class CreateChannelView extends React.Component {
|
|||
theme={theme}
|
||||
underlineColorAndroid='transparent'
|
||||
/>
|
||||
{this.renderFormSeparator()}
|
||||
<List.Separator />
|
||||
{this.renderType()}
|
||||
{this.renderFormSeparator()}
|
||||
<List.Separator />
|
||||
{this.renderReadOnly()}
|
||||
{this.renderFormSeparator()}
|
||||
<List.Separator />
|
||||
{this.renderEncrypted()}
|
||||
{this.renderFormSeparator()}
|
||||
<List.Separator />
|
||||
{this.renderBroadcast()}
|
||||
</View>
|
||||
<View style={styles.invitedHeader}>
|
||||
|
|
|
@ -22,7 +22,7 @@ const SelectUsers = ({
|
|||
const getUsers = debounce(async(keyword = '') => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const usersCollection = db.collections.get('users');
|
||||
const usersCollection = db.get('users');
|
||||
const res = await RocketChat.search({ text: keyword, filterRooms: false });
|
||||
let items = [...users.filter(u => selected.includes(u.name)), ...res.filter(r => !users.find(u => u.name === r.name))];
|
||||
const records = await usersCollection.query(Q.where('username', Q.oneOf(items.map(u => u.name)))).fetch();
|
||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ScrollView, Text, Switch } from 'react-native';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import Loading from '../../containers/Loading';
|
||||
import KeyboardView from '../../presentation/KeyboardView';
|
||||
|
@ -63,11 +62,12 @@ class CreateChannelView extends React.Component {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { channel, name } = this.state;
|
||||
const {
|
||||
loading, failure, error, result, isMasterDetail
|
||||
} = this.props;
|
||||
|
||||
if (!isEqual(this.state, prevState)) {
|
||||
if (channel?.rid !== prevState.channel?.rid || name !== prevState.name) {
|
||||
this.setHeader();
|
||||
}
|
||||
|
||||
|
@ -136,17 +136,17 @@ class CreateChannelView extends React.Component {
|
|||
};
|
||||
|
||||
selectChannel = ({ value }) => {
|
||||
logEvent(events.CREATE_DISCUSSION_SELECT_CHANNEL);
|
||||
logEvent(events.CD_SELECT_CHANNEL);
|
||||
this.setState({ channel: value, encrypted: value?.encrypted });
|
||||
}
|
||||
|
||||
selectUsers = ({ value }) => {
|
||||
logEvent(events.CREATE_DISCUSSION_SELECT_USERS);
|
||||
logEvent(events.CD_SELECT_USERS);
|
||||
this.setState({ users: value });
|
||||
}
|
||||
|
||||
onEncryptedChange = (value) => {
|
||||
logEvent(events.CREATE_DISCUSSION_TOGGLE_ENCRY);
|
||||
logEvent(events.CD_TOGGLE_ENCRY);
|
||||
this.setState({ encrypted: value });
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ const mapStateToProps = state => ({
|
|||
loading: state.createDiscussion.isFetching,
|
||||
result: state.createDiscussion.result,
|
||||
blockUnauthenticatedAccess: state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true,
|
||||
serverVersion: state.share.server.version || state.server.version,
|
||||
serverVersion: state.server.version,
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
encryptionEnabled: state.encryption.enabled
|
||||
});
|
||||
|
|
|
@ -84,13 +84,13 @@ export default class DirectoryOptions extends PureComponent {
|
|||
inputRange: [0, 1],
|
||||
outputRange: [-326, 0]
|
||||
});
|
||||
const backdropOpacity = this.animatedValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, 0.3]
|
||||
});
|
||||
const {
|
||||
globalUsers, toggleWorkspace, isFederationEnabled, theme
|
||||
} = this.props;
|
||||
const backdropOpacity = this.animatedValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, themes[theme].backdropOpacity]
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<TouchableWithoutFeedback onPress={this.close}>
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
View, FlatList, Text
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import * as List from '../../containers/List';
|
||||
|
||||
import Touch from '../../utils/touch';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
|
@ -182,11 +183,6 @@ class DirectoryView extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderSeparator = () => {
|
||||
const { theme } = this.props;
|
||||
return <View style={[sharedStyles.separator, styles.separator, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
}
|
||||
|
||||
renderItem = ({ item, index }) => {
|
||||
const { data, type } = this.state;
|
||||
const { baseUrl, user, theme } = this.props;
|
||||
|
@ -251,7 +247,7 @@ class DirectoryView extends React.Component {
|
|||
keyExtractor={item => item._id}
|
||||
ListHeaderComponent={this.renderHeader}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
keyboardShouldPersistTaps='always'
|
||||
ListFooterComponent={loading ? <ActivityIndicator theme={theme} /> : null}
|
||||
onEndReached={() => this.load({})}
|
||||
|
|
|
@ -94,7 +94,7 @@ class LanguageView extends React.Component {
|
|||
setUser({ language: params.language });
|
||||
|
||||
const serversDB = database.servers;
|
||||
const usersCollection = serversDB.collections.get('users');
|
||||
const usersCollection = serversDB.get('users');
|
||||
await serversDB.action(async() => {
|
||||
try {
|
||||
const userRecord = await usersCollection.find(user.id);
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
Text, View, StyleSheet, Keyboard, Alert
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import sharedStyles from './Styles';
|
||||
import Button from '../containers/Button';
|
||||
|
@ -82,7 +82,7 @@ class LoginView extends React.Component {
|
|||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
const { error } = this.props;
|
||||
if (nextProps.failure && !equal(error, nextProps.error)) {
|
||||
if (nextProps.failure && !dequal(error, nextProps.error)) {
|
||||
Alert.alert(I18n.t('Oops'), I18n.t('Login_error'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { FlatList, View, Text } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import styles from './styles';
|
||||
import Message from '../../containers/message';
|
||||
|
@ -57,7 +57,7 @@ class MessagesView extends React.Component {
|
|||
if (nextState.loading !== loading) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.messages, messages)) {
|
||||
if (!dequal(nextState.messages, messages)) {
|
||||
return true;
|
||||
}
|
||||
if (fileLoading !== nextState.fileLoading) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { connect } from 'react-redux';
|
||||
import { KeyboardAwareScrollView } from '@codler/react-native-keyboard-aware-scroll-view';
|
||||
|
||||
|
@ -94,17 +93,6 @@ class ModalBlockView extends React.Component {
|
|||
EventEmitter.addEventListener(viewId, this.handleUpdate);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (!isEqual(nextProps, this.props)) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextState, this.state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { navigation, route } = this.props;
|
||||
const oldData = prevProps.route.params?.data ?? {};
|
||||
|
|
|
@ -4,9 +4,8 @@ import {
|
|||
View, StyleSheet, FlatList, Text
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import equal from 'deep-equal';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import * as List from '../containers/List';
|
||||
|
||||
import Touch from '../utils/touch';
|
||||
import database from '../lib/database';
|
||||
|
@ -27,10 +26,9 @@ import { createChannelRequest } from '../actions/createChannel';
|
|||
import { goRoom } from '../utils/goRoom';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
|
||||
const QUERY_SIZE = 50;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
separator: {
|
||||
marginLeft: 60
|
||||
},
|
||||
button: {
|
||||
height: 46,
|
||||
flexDirection: 'row',
|
||||
|
@ -77,40 +75,20 @@ class NewMessageView extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { search, chats } = this.state;
|
||||
const { theme } = this.props;
|
||||
if (nextProps.theme !== theme) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.search, search)) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.chats, chats)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.querySubscription && this.querySubscription.unsubscribe) {
|
||||
this.querySubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
init = async() => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const observable = await db.collections
|
||||
const chats = await db.collections
|
||||
.get('subscriptions')
|
||||
.query(Q.where('t', 'd'))
|
||||
.observeWithColumns(['room_updated_at']);
|
||||
.query(
|
||||
Q.where('t', 'd'),
|
||||
Q.experimentalTake(QUERY_SIZE),
|
||||
Q.experimentalSortBy('room_updated_at', Q.desc)
|
||||
)
|
||||
.fetch();
|
||||
|
||||
this.querySubscription = observable.subscribe((data) => {
|
||||
const chats = orderBy(data, ['roomUpdatedAt'], ['desc']);
|
||||
this.setState({ chats });
|
||||
});
|
||||
this.setState({ chats });
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
|
@ -211,10 +189,6 @@ class NewMessageView extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderSeparator = () => {
|
||||
const { theme } = this.props;
|
||||
return <View style={[sharedStyles.separator, styles.separator, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
}
|
||||
|
||||
renderItem = ({ item, index }) => {
|
||||
const { search, chats } = this.state;
|
||||
|
@ -254,7 +228,7 @@ class NewMessageView extends React.Component {
|
|||
keyExtractor={item => item._id}
|
||||
ListHeaderComponent={this.renderHeader}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }}
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
|
|
|
@ -132,7 +132,7 @@ class NewServerView extends React.Component {
|
|||
queryServerHistory = async(text) => {
|
||||
const db = database.servers;
|
||||
try {
|
||||
const serversHistoryCollection = db.collections.get('servers_history');
|
||||
const serversHistoryCollection = db.get('servers_history');
|
||||
let whereClause = [
|
||||
Q.where('username', Q.notEq(null)),
|
||||
Q.experimentalSortBy('updated_at', Q.desc),
|
||||
|
@ -174,7 +174,7 @@ class NewServerView extends React.Component {
|
|||
}
|
||||
|
||||
submit = async({ fromServerHistory = false, username }) => {
|
||||
logEvent(events.NEWSERVER_CONNECT_TO_WORKSPACE);
|
||||
logEvent(events.NS_CONNECT_TO_WORKSPACE);
|
||||
const { text, certificate } = this.state;
|
||||
const { connectServer } = this.props;
|
||||
|
||||
|
@ -199,7 +199,7 @@ class NewServerView extends React.Component {
|
|||
}
|
||||
|
||||
connectOpen = () => {
|
||||
logEvent(events.NEWSERVER_JOIN_OPEN_WORKSPACE);
|
||||
logEvent(events.NS_JOIN_OPEN_WORKSPACE);
|
||||
this.setState({ connectingOpen: true });
|
||||
const { connectServer } = this.props;
|
||||
connectServer('https://open.rocket.chat');
|
||||
|
|
|
@ -6,7 +6,7 @@ import prompt from 'react-native-prompt-android';
|
|||
import SHA256 from 'js-sha256';
|
||||
import ImagePicker from 'react-native-image-crop-picker';
|
||||
import RNPickerSelect from 'react-native-picker-select';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { dequal } from 'dequal';
|
||||
import omit from 'lodash/omit';
|
||||
|
||||
import Touch from '../../utils/touch';
|
||||
|
@ -91,21 +91,11 @@ class ProfileView extends React.Component {
|
|||
* it's resetting the avatar right after
|
||||
* select some image from gallery.
|
||||
*/
|
||||
if (!isEqual(omit(user, ['status']), omit(nextProps.user, ['status']))) {
|
||||
if (!dequal(omit(user, ['status']), omit(nextProps.user, ['status']))) {
|
||||
this.init(nextProps.user);
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (!isEqual(nextState, this.state)) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextProps, this.props)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
setAvatar = (avatar) => {
|
||||
const { Accounts_AllowUserAvatarChange } = this.props;
|
||||
|
||||
|
@ -434,7 +424,7 @@ class ProfileView extends React.Component {
|
|||
}
|
||||
|
||||
logoutOtherLocations = () => {
|
||||
logEvent(events.PROFILE_LOGOUT_OTHER_LOCATIONS);
|
||||
logEvent(events.PL_OTHER_LOCATIONS);
|
||||
showConfirmationAlert({
|
||||
message: I18n.t('You_will_be_logged_out_from_other_locations'),
|
||||
confirmationText: I18n.t('Logout'),
|
||||
|
@ -443,7 +433,7 @@ class ProfileView extends React.Component {
|
|||
await RocketChat.logoutOtherLocations();
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Logged_out_of_other_clients_successfully') });
|
||||
} catch {
|
||||
logEvent(events.PROFILE_LOGOUT_OTHER_LOCATIONS_F);
|
||||
logEvent(events.PL_OTHER_LOCATIONS_F);
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Logout_failed') });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FlatList, View, Text } from 'react-native';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
import moment from 'moment';
|
||||
import { connect } from 'react-redux';
|
||||
import * as List from '../../containers/List';
|
||||
|
||||
import Avatar from '../../containers/Avatar';
|
||||
import styles from './styles';
|
||||
|
@ -55,7 +56,7 @@ class ReadReceiptView extends React.Component {
|
|||
if (nextState.loading !== loading) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextState.receipts, receipts)) {
|
||||
if (!dequal(nextState.receipts, receipts)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -121,11 +122,6 @@ class ReadReceiptView extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderSeparator = () => {
|
||||
const { theme } = this.props;
|
||||
return <View style={[styles.separator, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { receipts, loading } = this.state;
|
||||
const { theme } = this.props;
|
||||
|
@ -143,7 +139,7 @@ class ReadReceiptView extends React.Component {
|
|||
<FlatList
|
||||
data={receipts}
|
||||
renderItem={this.renderItem}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
style={[
|
||||
styles.list,
|
||||
{
|
||||
|
|
|
@ -53,7 +53,15 @@ class RoomActionsView extends React.Component {
|
|||
closeRoom: PropTypes.func,
|
||||
theme: PropTypes.string,
|
||||
fontScale: PropTypes.number,
|
||||
serverVersion: PropTypes.string
|
||||
serverVersion: PropTypes.string,
|
||||
addUserToJoinedRoomPermission: PropTypes.array,
|
||||
addUserToAnyCRoomPermission: PropTypes.array,
|
||||
addUserToAnyPRoomPermission: PropTypes.array,
|
||||
createInviteLinksPermission: PropTypes.array,
|
||||
editRoomPermission: PropTypes.array,
|
||||
toggleRoomE2EEncryptionPermission: PropTypes.array,
|
||||
viewBroadcastMemberListPermission: PropTypes.array,
|
||||
transferLivechatGuestPermission: PropTypes.array
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -118,7 +126,7 @@ class RoomActionsView extends React.Component {
|
|||
this.updateRoomMember();
|
||||
}
|
||||
|
||||
const canAutoTranslate = await RocketChat.canAutoTranslate();
|
||||
const canAutoTranslate = RocketChat.canAutoTranslate();
|
||||
this.setState({ canAutoTranslate });
|
||||
|
||||
this.canAddUser();
|
||||
|
@ -159,60 +167,62 @@ class RoomActionsView extends React.Component {
|
|||
|
||||
canAddUser = async() => {
|
||||
const { room, joined } = this.state;
|
||||
const { addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission } = this.props;
|
||||
const { rid, t } = room;
|
||||
let canAdd = false;
|
||||
let canAddUser = false;
|
||||
|
||||
const userInRoom = joined;
|
||||
const permissions = await RocketChat.hasPermission(['add-user-to-joined-room', 'add-user-to-any-c-room', 'add-user-to-any-p-room'], rid);
|
||||
const permissions = await RocketChat.hasPermission([addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission], rid);
|
||||
|
||||
if (permissions) {
|
||||
if (userInRoom && permissions['add-user-to-joined-room']) {
|
||||
canAdd = true;
|
||||
}
|
||||
if (t === 'c' && permissions['add-user-to-any-c-room']) {
|
||||
canAdd = true;
|
||||
}
|
||||
if (t === 'p' && permissions['add-user-to-any-p-room']) {
|
||||
canAdd = true;
|
||||
}
|
||||
if (userInRoom && permissions[0]) {
|
||||
canAddUser = true;
|
||||
}
|
||||
this.setState({ canAddUser: canAdd });
|
||||
if (t === 'c' && permissions[1]) {
|
||||
canAddUser = true;
|
||||
}
|
||||
if (t === 'p' && permissions[2]) {
|
||||
canAddUser = true;
|
||||
}
|
||||
this.setState({ canAddUser });
|
||||
}
|
||||
|
||||
canInviteUser = async() => {
|
||||
const { room } = this.state;
|
||||
const { createInviteLinksPermission } = this.props;
|
||||
const { rid } = room;
|
||||
const permissions = await RocketChat.hasPermission(['create-invite-links'], rid);
|
||||
const permissions = await RocketChat.hasPermission([createInviteLinksPermission], rid);
|
||||
|
||||
const canInviteUser = permissions && permissions['create-invite-links'];
|
||||
const canInviteUser = permissions[0];
|
||||
this.setState({ canInviteUser });
|
||||
}
|
||||
|
||||
canEdit = async() => {
|
||||
const { room } = this.state;
|
||||
const { editRoomPermission } = this.props;
|
||||
const { rid } = room;
|
||||
const permissions = await RocketChat.hasPermission(['edit-room'], rid);
|
||||
const permissions = await RocketChat.hasPermission([editRoomPermission], rid);
|
||||
|
||||
const canEdit = permissions && permissions['edit-room'];
|
||||
const canEdit = permissions[0];
|
||||
this.setState({ canEdit });
|
||||
}
|
||||
|
||||
canToggleEncryption = async() => {
|
||||
const { room } = this.state;
|
||||
const { toggleRoomE2EEncryptionPermission } = this.props;
|
||||
const { rid } = room;
|
||||
const permissions = await RocketChat.hasPermission(['toggle-room-e2e-encryption'], rid);
|
||||
const permissions = await RocketChat.hasPermission([toggleRoomE2EEncryptionPermission], rid);
|
||||
|
||||
const canToggleEncryption = permissions && permissions['toggle-room-e2e-encryption'];
|
||||
const canToggleEncryption = permissions[0];
|
||||
this.setState({ canToggleEncryption });
|
||||
}
|
||||
|
||||
canViewMembers = async() => {
|
||||
const { room } = this.state;
|
||||
const { viewBroadcastMemberListPermission } = this.props;
|
||||
const { rid, t, broadcast } = room;
|
||||
if (broadcast) {
|
||||
const viewBroadcastMemberListPermission = 'view-broadcast-member-list';
|
||||
const permissions = await RocketChat.hasPermission([viewBroadcastMemberListPermission], rid);
|
||||
if (!permissions[viewBroadcastMemberListPermission]) {
|
||||
if (!permissions[0]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -226,16 +236,10 @@ class RoomActionsView extends React.Component {
|
|||
|
||||
canForwardGuest = async() => {
|
||||
const { room } = this.state;
|
||||
const { transferLivechatGuestPermission } = this.props;
|
||||
const { rid } = room;
|
||||
let result = true;
|
||||
|
||||
const transferLivechatGuest = 'transfer-livechat-guest';
|
||||
const permissions = await RocketChat.hasPermission([transferLivechatGuest], rid);
|
||||
if (!permissions[transferLivechatGuest]) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
this.setState({ canForwardGuest: result });
|
||||
const permissions = await RocketChat.hasPermission([transferLivechatGuestPermission], rid);
|
||||
this.setState({ canForwardGuest: permissions[0] });
|
||||
}
|
||||
|
||||
canReturnQueue = async() => {
|
||||
|
@ -482,7 +486,7 @@ class RoomActionsView extends React.Component {
|
|||
<List.Separator />
|
||||
<List.Item
|
||||
title='Voice_call'
|
||||
onPress={() => RocketChat.callJitsi(room?.rid, true)}
|
||||
onPress={() => RocketChat.callJitsi(room, true)}
|
||||
testID='room-actions-voice'
|
||||
left={() => <List.Icon name='phone' />}
|
||||
showActionIndicator
|
||||
|
@ -490,7 +494,7 @@ class RoomActionsView extends React.Component {
|
|||
<List.Separator />
|
||||
<List.Item
|
||||
title='Video_call'
|
||||
onPress={() => RocketChat.callJitsi(room?.rid)}
|
||||
onPress={() => RocketChat.callJitsi(room)}
|
||||
testID='room-actions-video'
|
||||
left={() => <List.Icon name='camera' />}
|
||||
showActionIndicator
|
||||
|
@ -866,7 +870,15 @@ class RoomActionsView extends React.Component {
|
|||
const mapStateToProps = state => ({
|
||||
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
||||
encryptionEnabled: state.encryption.enabled,
|
||||
serverVersion: state.server.version
|
||||
serverVersion: state.server.version,
|
||||
addUserToJoinedRoomPermission: state.permissions['add-user-to-joined-room'],
|
||||
addUserToAnyCRoomPermission: state.permissions['add-user-to-any-c-room'],
|
||||
addUserToAnyPRoomPermission: state.permissions['add-user-to-any-p-room'],
|
||||
createInviteLinksPermission: state.permissions['create-invite-links'],
|
||||
editRoomPermission: state.permissions['edit-room'],
|
||||
toggleRoomE2EEncryptionPermission: state.permissions['toggle-room-e2e-encryption'],
|
||||
viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'],
|
||||
transferLivechatGuestPermission: state.permissions['transfer-livechat-guest']
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
|
|
@ -4,15 +4,13 @@ import {
|
|||
Text, View, ScrollView, TouchableOpacity, Keyboard, Alert
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import equal from 'deep-equal';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
import ImagePicker from 'react-native-image-crop-picker';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { dequal } from 'dequal';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import lt from 'semver/functions/lt';
|
||||
import coerce from 'semver/functions/coerce';
|
||||
|
||||
|
||||
import database from '../../lib/database';
|
||||
import { deleteRoom as deleteRoomAction } from '../../actions/room';
|
||||
import KeyboardView from '../../presentation/KeyboardView';
|
||||
|
@ -44,14 +42,6 @@ const PERMISSION_ARCHIVE = 'archive-room';
|
|||
const PERMISSION_UNARCHIVE = 'unarchive-room';
|
||||
const PERMISSION_DELETE_C = 'delete-c';
|
||||
const PERMISSION_DELETE_P = 'delete-p';
|
||||
const PERMISSIONS_ARRAY = [
|
||||
PERMISSION_SET_READONLY,
|
||||
PERMISSION_SET_REACT_WHEN_READONLY,
|
||||
PERMISSION_ARCHIVE,
|
||||
PERMISSION_UNARCHIVE,
|
||||
PERMISSION_DELETE_C,
|
||||
PERMISSION_DELETE_P
|
||||
];
|
||||
|
||||
class RoomInfoEditView extends React.Component {
|
||||
static navigationOptions = () => ({
|
||||
|
@ -63,7 +53,13 @@ class RoomInfoEditView extends React.Component {
|
|||
deleteRoom: PropTypes.func,
|
||||
serverVersion: PropTypes.string,
|
||||
encryptionEnabled: PropTypes.bool,
|
||||
theme: PropTypes.string
|
||||
theme: PropTypes.string,
|
||||
setReadOnlyPermission: PropTypes.array,
|
||||
setReactWhenReadOnlyPermission: PropTypes.array,
|
||||
archiveRoomPermission: PropTypes.array,
|
||||
unarchiveRoomPermission: PropTypes.array,
|
||||
deleteCPermission: PropTypes.array,
|
||||
deletePPermission: PropTypes.array
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
|
@ -90,16 +86,6 @@ class RoomInfoEditView extends React.Component {
|
|||
this.loadRoom();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (!equal(nextState, this.state)) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps, this.props)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.querySubscription && this.querySubscription.unsubscribe) {
|
||||
this.querySubscription.unsubscribe();
|
||||
|
@ -108,14 +94,22 @@ class RoomInfoEditView extends React.Component {
|
|||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
loadRoom = async() => {
|
||||
const { route } = this.props;
|
||||
const {
|
||||
route,
|
||||
setReadOnlyPermission,
|
||||
setReactWhenReadOnlyPermission,
|
||||
archiveRoomPermission,
|
||||
unarchiveRoomPermission,
|
||||
deleteCPermission,
|
||||
deletePPermission
|
||||
} = this.props;
|
||||
const rid = route.params?.rid;
|
||||
if (!rid) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const db = database.active;
|
||||
const sub = await db.collections.get('subscriptions').find(rid);
|
||||
const sub = await db.get('subscriptions').find(rid);
|
||||
const observable = sub.observe();
|
||||
|
||||
this.querySubscription = observable.subscribe((data) => {
|
||||
|
@ -123,8 +117,25 @@ class RoomInfoEditView extends React.Component {
|
|||
this.init(this.room);
|
||||
});
|
||||
|
||||
const permissions = await RocketChat.hasPermission(PERMISSIONS_ARRAY, rid);
|
||||
this.setState({ permissions });
|
||||
const result = await RocketChat.hasPermission([
|
||||
setReadOnlyPermission,
|
||||
setReactWhenReadOnlyPermission,
|
||||
archiveRoomPermission,
|
||||
unarchiveRoomPermission,
|
||||
deleteCPermission,
|
||||
deletePPermission
|
||||
], rid);
|
||||
|
||||
this.setState({
|
||||
permissions: {
|
||||
[PERMISSION_SET_READONLY]: result[0],
|
||||
[PERMISSION_SET_REACT_WHEN_READONLY]: result[1],
|
||||
[PERMISSION_ARCHIVE]: result[2],
|
||||
[PERMISSION_UNARCHIVE]: result[3],
|
||||
[PERMISSION_DELETE_C]: result[4],
|
||||
[PERMISSION_DELETE_P]: result[5]
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
|
@ -179,7 +190,7 @@ class RoomInfoEditView extends React.Component {
|
|||
&& room.t === 'p' === t
|
||||
&& room.ro === ro
|
||||
&& room.reactWhenReadOnly === reactWhenReadOnly
|
||||
&& isEqual(room.sysMes, systemMessages)
|
||||
&& dequal(room.sysMes, systemMessages)
|
||||
&& enableSysMes === (room.sysMes && room.sysMes.length > 0)
|
||||
&& room.encrypted === encrypted
|
||||
&& isEmpty(avatar)
|
||||
|
@ -239,7 +250,7 @@ class RoomInfoEditView extends React.Component {
|
|||
params.reactWhenReadOnly = reactWhenReadOnly;
|
||||
}
|
||||
|
||||
if (!isEqual(room.sysMes, systemMessages)) {
|
||||
if (!dequal(room.sysMes, systemMessages)) {
|
||||
params.systemMessages = systemMessages;
|
||||
}
|
||||
|
||||
|
@ -666,8 +677,14 @@ class RoomInfoEditView extends React.Component {
|
|||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
serverVersion: state.share.server.version || state.server.version,
|
||||
encryptionEnabled: state.encryption.enabled
|
||||
serverVersion: state.server.version,
|
||||
encryptionEnabled: state.encryption.enabled,
|
||||
setReadOnlyPermission: state.permissions[PERMISSION_SET_READONLY],
|
||||
setReactWhenReadOnlyPermission: state.permissions[PERMISSION_SET_REACT_WHEN_READONLY],
|
||||
archiveRoomPermission: state.permissions[PERMISSION_ARCHIVE],
|
||||
unarchiveRoomPermission: state.permissions[PERMISSION_UNARCHIVE],
|
||||
deleteCPermission: state.permissions[PERMISSION_DELETE_C],
|
||||
deletePPermission: state.permissions[PERMISSION_DELETE_P]
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
|
|
@ -31,7 +31,6 @@ import SafeAreaView from '../../containers/SafeAreaView';
|
|||
import { goRoom } from '../../utils/goRoom';
|
||||
import Navigation from '../../lib/Navigation';
|
||||
|
||||
const PERMISSION_EDIT_ROOM = 'edit-room';
|
||||
const getRoomTitle = (room, type, name, username, statusText, theme) => (type === 'd'
|
||||
? (
|
||||
<>
|
||||
|
@ -55,7 +54,8 @@ class RoomInfoView extends React.Component {
|
|||
rooms: PropTypes.array,
|
||||
theme: PropTypes.string,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
jitsiEnabled: PropTypes.bool
|
||||
jitsiEnabled: PropTypes.bool,
|
||||
editRoomPermission: PropTypes.array
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -136,7 +136,7 @@ class RoomInfoView extends React.Component {
|
|||
getRoleDescription = async(id) => {
|
||||
const db = database.active;
|
||||
try {
|
||||
const rolesCollection = db.collections.get('roles');
|
||||
const rolesCollection = db.get('roles');
|
||||
const role = await rolesCollection.find(id);
|
||||
if (role) {
|
||||
return role.description;
|
||||
|
@ -193,7 +193,7 @@ class RoomInfoView extends React.Component {
|
|||
|
||||
loadRoom = async() => {
|
||||
const { room: roomState } = this.state;
|
||||
const { route } = this.props;
|
||||
const { route, editRoomPermission } = this.props;
|
||||
let room = route.params?.room;
|
||||
if (room && room.observe) {
|
||||
this.roomObservable = room.observe();
|
||||
|
@ -213,8 +213,8 @@ class RoomInfoView extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const permissions = await RocketChat.hasPermission([PERMISSION_EDIT_ROOM], room.rid);
|
||||
if (permissions[PERMISSION_EDIT_ROOM] && !room.prid) {
|
||||
const permissions = await RocketChat.hasPermission([editRoomPermission], room.rid);
|
||||
if (permissions[0] && !room.prid) {
|
||||
this.setState({ showEdit: true }, () => this.setHeader());
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ class RoomInfoView extends React.Component {
|
|||
|
||||
videoCall = () => {
|
||||
const { room } = this.state;
|
||||
RocketChat.callJitsi(room.rid);
|
||||
RocketChat.callJitsi(room);
|
||||
}
|
||||
|
||||
renderAvatar = (room, roomUser) => {
|
||||
|
@ -369,7 +369,8 @@ class RoomInfoView extends React.Component {
|
|||
const mapStateToProps = state => ({
|
||||
rooms: state.room.rooms,
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
jitsiEnabled: state.settings.Jitsi_Enabled || false
|
||||
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
||||
editRoomPermission: state.permissions['edit-room']
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withTheme(RoomInfoView));
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import { FlatList } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import * as List from '../../containers/List';
|
||||
|
||||
import styles from './styles';
|
||||
import UserItem from '../../presentation/UserItem';
|
||||
|
@ -28,6 +29,12 @@ import { goRoom } from '../../utils/goRoom';
|
|||
|
||||
const PAGE_SIZE = 25;
|
||||
|
||||
const PERMISSION_MUTE_USER = 'mute-user';
|
||||
const PERMISSION_SET_LEADER = 'set-leader';
|
||||
const PERMISSION_SET_OWNER = 'set-owner';
|
||||
const PERMISSION_SET_MODERATOR = 'set-moderator';
|
||||
const PERMISSION_REMOVE_USER = 'remove-user';
|
||||
|
||||
class RoomMembersView extends React.Component {
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object,
|
||||
|
@ -43,7 +50,12 @@ class RoomMembersView extends React.Component {
|
|||
showActionSheet: PropTypes.func,
|
||||
theme: PropTypes.string,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
useRealName: PropTypes.bool
|
||||
useRealName: PropTypes.bool,
|
||||
muteUserPermission: PropTypes.array,
|
||||
setLeaderPermission: PropTypes.array,
|
||||
setOwnerPermission: PropTypes.array,
|
||||
setModeratorPermission: PropTypes.array,
|
||||
removeUserPermission: PropTypes.array
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -81,7 +93,20 @@ class RoomMembersView extends React.Component {
|
|||
this.fetchMembers();
|
||||
|
||||
const { room } = this.state;
|
||||
this.permissions = await RocketChat.hasPermission(['mute-user', 'set-leader', 'set-owner', 'set-moderator', 'remove-user'], room.rid);
|
||||
const {
|
||||
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
|
||||
} = this.props;
|
||||
const result = await RocketChat.hasPermission([
|
||||
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
|
||||
], room.rid);
|
||||
|
||||
this.permissions = {
|
||||
[PERMISSION_MUTE_USER]: result[0],
|
||||
[PERMISSION_SET_LEADER]: result[1],
|
||||
[PERMISSION_SET_OWNER]: result[2],
|
||||
[PERMISSION_SET_MODERATOR]: result[3],
|
||||
[PERMISSION_REMOVE_USER]: result[4]
|
||||
};
|
||||
|
||||
const hasSinglePermission = Object.values(this.permissions).some(p => !!p);
|
||||
if (hasSinglePermission) {
|
||||
|
@ -122,7 +147,7 @@ class RoomMembersView extends React.Component {
|
|||
navToDirectMessage = async(item) => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const subsCollection = db.collections.get('subscriptions');
|
||||
const subsCollection = db.get('subscriptions');
|
||||
const query = await subsCollection.query(Q.where('name', item.username)).fetch();
|
||||
if (query.length) {
|
||||
const [room] = query;
|
||||
|
@ -395,11 +420,6 @@ class RoomMembersView extends React.Component {
|
|||
<SearchBox onChangeText={text => this.onSearchChangeText(text)} testID='room-members-view-search' />
|
||||
)
|
||||
|
||||
renderSeparator = () => {
|
||||
const { theme } = this.props;
|
||||
return <View style={[styles.separator, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
}
|
||||
|
||||
renderItem = ({ item }) => {
|
||||
const { baseUrl, user, theme } = this.props;
|
||||
|
||||
|
@ -429,7 +449,7 @@ class RoomMembersView extends React.Component {
|
|||
renderItem={this.renderItem}
|
||||
style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]}
|
||||
keyExtractor={item => item._id}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ItemSeparatorComponent={List.Separator}
|
||||
ListHeaderComponent={this.renderSearchBar}
|
||||
ListFooterComponent={() => {
|
||||
if (isLoading) {
|
||||
|
@ -452,7 +472,12 @@ const mapStateToProps = state => ({
|
|||
baseUrl: state.server.server,
|
||||
user: getUserSelector(state),
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
useRealName: state.settings.UI_Use_Real_Name
|
||||
useRealName: state.settings.UI_Use_Real_Name,
|
||||
muteUserPermission: state.permissions[PERMISSION_MUTE_USER],
|
||||
setLeaderPermission: state.permissions[PERMISSION_SET_LEADER],
|
||||
setOwnerPermission: state.permissions[PERMISSION_SET_OWNER],
|
||||
setModeratorPermission: state.permissions[PERMISSION_SET_MODERATOR],
|
||||
removeUserPermission: state.permissions[PERMISSION_REMOVE_USER]
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withActionSheet(withTheme(RoomMembersView)));
|
||||
|
|
|
@ -168,7 +168,7 @@ const Header = React.memo(({
|
|||
theme={theme}
|
||||
/>
|
||||
</View>
|
||||
<SubTitle usersTyping={usersTyping} subtitle={subtitle} theme={theme} renderFunc={renderFunc} />
|
||||
<SubTitle usersTyping={tmid ? [] : usersTyping} subtitle={subtitle} theme={theme} renderFunc={renderFunc} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import isEqual from 'react-fast-compare';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import * as HeaderButton from '../../../containers/HeaderButton';
|
||||
import database from '../../../lib/database';
|
||||
|
@ -35,7 +35,7 @@ class RightButtonsContainer extends Component {
|
|||
const db = database.active;
|
||||
if (tmid) {
|
||||
try {
|
||||
const threadRecord = await db.collections.get('messages').find(tmid);
|
||||
const threadRecord = await db.get('messages').find(tmid);
|
||||
this.observeThread(threadRecord);
|
||||
} catch (e) {
|
||||
console.log('Can\'t find message to observe.');
|
||||
|
@ -43,7 +43,7 @@ class RightButtonsContainer extends Component {
|
|||
}
|
||||
if (rid) {
|
||||
try {
|
||||
const subCollection = db.collections.get('subscriptions');
|
||||
const subCollection = db.get('subscriptions');
|
||||
const subRecord = await subCollection.find(rid);
|
||||
this.observeSubscription(subRecord);
|
||||
} catch (e) {
|
||||
|
@ -59,15 +59,16 @@ class RightButtonsContainer extends Component {
|
|||
if (nextState.isFollowingThread !== isFollowingThread) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextState.tunread, tunread)) {
|
||||
if (!dequal(nextState.tunread, tunread)) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextState.tunreadUser, tunreadUser)) {
|
||||
if (!dequal(nextState.tunreadUser, tunreadUser)) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextState.tunreadGroup, tunreadGroup)) {
|
||||
if (!dequal(nextState.tunreadGroup, tunreadGroup)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import equal from 'deep-equal';
|
||||
import { dequal } from 'dequal';
|
||||
|
||||
import Header from './Header';
|
||||
import LeftButtons from './LeftButtons';
|
||||
|
@ -65,7 +65,7 @@ class RoomHeaderView extends Component {
|
|||
if (nextProps.height !== height) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.usersTyping, usersTyping)) {
|
||||
if (!dequal(nextProps.usersTyping, usersTyping)) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.goRoomActionsView !== goRoomActionsView) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue