diff --git a/__mocks__/react-native-gesture-handler.js b/__mocks__/react-native-gesture-handler.js
new file mode 100644
index 000000000..4701ac260
--- /dev/null
+++ b/__mocks__/react-native-gesture-handler.js
@@ -0,0 +1,3 @@
+export const RectButton = () => 'View';
+export const State = () => 'View';
+export const LongPressGestureHandler = () => 'View';
diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap
index 2464e0f55..b70a35999 100644
--- a/__tests__/__snapshots__/Storyshots.test.js.snap
+++ b/__tests__/__snapshots__/Storyshots.test.js.snap
@@ -3037,211 +3037,7 @@ exports[`Storyshots Message list 1`] = `
}
>
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
Simple
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
-
-
-
-
-
-
-
-
+ View
Long message
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- …
-
-
-
-
-
-
-
-
-
-
-
-
-
- R
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Different user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This is the third message
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This is the second message
-
-
-
-
-
-
-
-
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- This is the first message
-
-
-
-
-
-
-
-
+ View
+ View
+ View
+ View
+ View
Grouped messages
-
-
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
Without header
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- Diego Mello
-
-
- @
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
With alias
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
- (edited)
-
-
-
-
-
-
-
+ View
Edited
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
Static avatar
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- Diego Mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
Full name
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
- rocket.cat
-
-
-
-
-
-
-
- diego.mello
-
-
-
-
-
-
-
- all
-
-
-
-
-
-
-
- here
-
-
-
-
-
-
- #
- general
-
-
-
-
-
-
-
-
-
+ View
Mentions
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- 👊🤙👏
-
-
-
-
-
-
-
-
+ View
Emojis
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ View
Custom Emojis
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10 November 2017
-
-
-
-
-
-
- Testing
-
-
-
-
-
-
-
-
+ View
Time format
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Reactions
-
-
-
-
-
-
-
-
- 😂
-
-
- 3
-
-
-
-
-
-
-
- 13
-
-
-
-
-
-
- 🤔
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
+ View
Reactions
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Multiple Reactions
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- ❤️
-
-
- 1
-
-
-
-
-
-
- 🐶
-
-
- 1
-
-
-
-
-
-
- 😀
-
-
- 1
-
-
-
-
-
-
- 😬
-
-
- 1
-
-
-
-
-
-
- 😁
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
+ View
Multiple reactions
-
-
-
-
-
- R
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Fourth message
-
-
-
-
-
-
-
-
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Third message
-
-
-
-
-
-
-
-
-
-
-
-
-
- R
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Second message
-
-
-
-
-
-
-
-
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- First message
-
-
-
-
-
-
-
-
+ View
+ View
+ View
+ View
Intercalated users
-
-
-
-
-
- R
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Fourth message
-
-
-
-
-
-
-
-
+ View
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Third message
-
-
-
-
-
-
-
-
+ View
-
-
-
-
-
-
-
-
- Second message
-
-
-
-
-
-
-
-
-
-
-
-
-
- R
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Second message
-
-
-
-
-
-
-
-
+ View
+ View
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- First message
-
-
-
-
-
-
-
-
+ View
Date and Unread separators
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
-
- This is a description
-
-
-
-
-
-
-
-
-
-
-
- This is a title
-
-
- This is a description
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
-
- This is a description
-
-
-
-
-
-
-
-
-
-
-
- This is a title
-
-
- This is a description
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ View
+ View
With image
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
-
- This is a description
-
-
-
-
-
-
-
-
- Video
-
-
-
-
-
-
+ View
With video
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Video
-
-
-
-
-
-
-
-
-
-
- 00:00
-
-
-
-
-
-
- This is a description
-
-
-
-
-
-
-
-
+ View
With audio
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
- https://rocket.chat
-
-
- Rocket.Chat - Free, Open Source, Enterprise Team Chat
-
-
- Rocket.Chat is the leading open source team chat software solution. Free, unlimited and completely customizable with on-premises and SaaS cloud hosting.
-
-
-
-
-
-
-
-
- https://google.com
-
-
- Google
-
-
- Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.
-
-
-
-
-
-
-
-
+ View
URL
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Custom fields
-
-
-
-
-
-
-
- Field 1
-
-
- Value 1
-
-
-
-
- Field 2
-
-
- Value 2
-
-
-
-
- Field 3
-
-
- Value 3
-
-
-
-
- Field 4
-
-
- Value 4
-
-
-
-
- Field 5
-
-
- Value 5
-
-
-
-
-
-
-
-
-
+ View
Custom fields
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Custom fields
-
-
-
-
-
-
-
- Field 1
-
-
- Value 1
-
-
-
-
- Field 2
-
-
- Value 2
-
-
-
-
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- Custom fields 2
-
-
-
-
-
-
-
- Field 1
-
-
- Value 1
-
-
-
-
- Field 2
-
-
- Value 2
-
-
-
-
-
-
-
-
-
+ View
Two short custom fields
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Broadcasted message
-
-
-
-
-
-
-
-
- Reply
-
-
-
-
-
-
-
+ View
Broadcast
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- This message is inside an archived room
-
-
-
-
-
-
-
-
+ View
Archived
-
-
-
-
-
-
-
-
-
-
-
- This message has error too
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- This message has error
-
-
-
-
-
-
-
-
+ View
+ View
Error
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Temp message
-
-
-
-
-
-
-
-
+ View
Temp
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message being edited
-
-
-
-
-
-
-
-
+ View
Editing
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Message removed
-
-
-
-
-
+ View
Removed
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Has joined the channel
-
-
-
-
-
+ View
Joined
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Room name changed to: New name by diego.mello
-
-
-
-
-
+ View
Room name changed
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Message pinned
-
-
-
-
-
- rocket.cat
-
-
- 10:00 AM
-
-
-
-
-
-
- First message
-
-
-
-
-
-
-
-
-
-
+ View
Message pinned
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Has left the channel
-
-
-
-
-
+ View
Has left the channel
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- User rocket.cat removed by diego.mello
-
-
-
-
-
+ View
User removed
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- User rocket.cat added by diego.mello
-
-
-
-
-
+ View
User added
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- User rocket.cat muted by diego.mello
-
-
-
-
-
+ View
User muted
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- User rocket.cat unmuted by diego.mello
-
-
-
-
-
+ View
User unmuted
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- rocket.cat was set admin by diego.mello
-
-
-
-
-
+ View
Role added
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- rocket.cat is no longer admin by diego.mello
-
-
-
-
-
+ View
Role removed
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Room description changed to: new description by diego.mello
-
-
-
-
-
+ View
Changed description
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Room announcement changed to: new announcement by diego.mello
-
-
-
-
-
+ View
Changed announcement
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Room topic changed to: new topic by diego.mello
-
-
-
-
-
+ View
Changed topic
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
- Room type changed to: public by diego.mello
-
-
-
-
-
+ View
Changed type
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Message
-
-
-
-
-
-
-
-
+ View
Custom style
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Italic with
-
-
-
- asterisks
-
-
-
- or
-
-
-
- underscores
-
-
-
- . Bold with
-
-
-
- asterisks
-
-
-
- or
-
-
-
- underscores
-
-
-
- .
-
-
-
- Strikethrough
-
-
-
-
-
-
-
-
-
+ View
Markdown emphasis
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- H1
-
-
-
-
-
-
- H2
-
-
-
-
-
-
- H3
-
-
-
-
-
-
- H4
-
-
-
-
-
-
- H5
-
-
-
-
-
-
- H6
-
-
-
-
-
-
-
-
+ View
Markdown headers
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Support
-
-
-
- Google
-
-
-
-
-
-
-
- I\`m an inline-style link
-
-
-
- https://google.com
-
-
-
-
-
-
-
-
+ View
Markdown links
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
-
-
+ View
Markdown image
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
- Inline
-
-
- code
-
-
- has
-
-
- back-ticks around
-
-
- it.
-
-
-
-
- Code block
-
-
-
-
-
-
-
+ View
Markdown code
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
- Quote
-
-
-
-
-
-
-
-
-
+ View
Markdown quote
-
-
-
-
-
- D
-
-
-
-
-
-
-
-
- diego.mello
-
-
- 10:00 AM
-
-
-
-
-
-
-
-
-
- First Header
-
-
-
-
-
-
- Second Header
-
-
-
-
-
-
-
-
-
-
- Content from cell 1
-
-
-
-
-
-
- Content from cell 2
-
-
-
-
-
-
-
-
- Content in the first column
-
-
-
-
-
-
- Content in the second column
-
-
-
-
-
-
-
-
-
-
-
+ View
createAdditionalReactPackages() {
return Arrays.asList(
new MainReactPackage(),
+ new RNDeviceInfo(),
+ new RNGestureHandlerPackage(),
new PickerPackage(),
new SvgPackage(),
new VectorIconsPackage(),
diff --git a/android/app/src/main/res/drawable-hdpi/connect_server.png b/android/app/src/main/res/drawable-hdpi/connect_server.png
new file mode 100644
index 000000000..538ed5db6
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/connect_server.png differ
diff --git a/android/app/src/main/res/drawable-hdpi/logo_onboarding.png b/android/app/src/main/res/drawable-hdpi/logo_onboarding.png
new file mode 100644
index 000000000..069c9ce8d
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/logo_onboarding.png differ
diff --git a/android/app/src/main/res/drawable-hdpi/new_server.png b/android/app/src/main/res/drawable-hdpi/new_server.png
new file mode 100644
index 000000000..fae62c0e0
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/new_server.png differ
diff --git a/android/app/src/main/res/drawable-hdpi/onboarding.png b/android/app/src/main/res/drawable-hdpi/onboarding.png
new file mode 100644
index 000000000..f1228b3f1
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/onboarding.png differ
diff --git a/android/app/src/main/res/drawable-hdpi/plus_onboarding.png b/android/app/src/main/res/drawable-hdpi/plus_onboarding.png
new file mode 100644
index 000000000..344a59aa0
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/plus_onboarding.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/connect_server.png b/android/app/src/main/res/drawable-mdpi/connect_server.png
new file mode 100644
index 000000000..bb72a2233
Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/connect_server.png differ
diff --git a/app/static/images/logoSmall.png b/android/app/src/main/res/drawable-mdpi/logo_onboarding.png
similarity index 90%
rename from app/static/images/logoSmall.png
rename to android/app/src/main/res/drawable-mdpi/logo_onboarding.png
index 75d82a00d..a5fcdfbca 100644
Binary files a/app/static/images/logoSmall.png and b/android/app/src/main/res/drawable-mdpi/logo_onboarding.png differ
diff --git a/app/static/images/server.png b/android/app/src/main/res/drawable-mdpi/new_server.png
similarity index 98%
rename from app/static/images/server.png
rename to android/app/src/main/res/drawable-mdpi/new_server.png
index 68d0a3a91..ea8e06f9b 100644
Binary files a/app/static/images/server.png and b/android/app/src/main/res/drawable-mdpi/new_server.png differ
diff --git a/app/static/images/onboarding.png b/android/app/src/main/res/drawable-mdpi/onboarding.png
similarity index 99%
rename from app/static/images/onboarding.png
rename to android/app/src/main/res/drawable-mdpi/onboarding.png
index c3b3f90fb..55656e242 100644
Binary files a/app/static/images/onboarding.png and b/android/app/src/main/res/drawable-mdpi/onboarding.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/plus_onboarding.png b/android/app/src/main/res/drawable-mdpi/plus_onboarding.png
new file mode 100644
index 000000000..d24cf823d
Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/plus_onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/connect_server.png b/android/app/src/main/res/drawable-xhdpi/connect_server.png
new file mode 100644
index 000000000..c71be4d8f
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/connect_server.png differ
diff --git a/app/static/images/logoSmall@2x.png b/android/app/src/main/res/drawable-xhdpi/logo_onboarding.png
similarity index 96%
rename from app/static/images/logoSmall@2x.png
rename to android/app/src/main/res/drawable-xhdpi/logo_onboarding.png
index a3e70aa1f..bf3e6a526 100644
Binary files a/app/static/images/logoSmall@2x.png and b/android/app/src/main/res/drawable-xhdpi/logo_onboarding.png differ
diff --git a/app/static/images/server@2x.png b/android/app/src/main/res/drawable-xhdpi/new_server.png
similarity index 99%
rename from app/static/images/server@2x.png
rename to android/app/src/main/res/drawable-xhdpi/new_server.png
index faa77e0bc..4b1e11cb4 100644
Binary files a/app/static/images/server@2x.png and b/android/app/src/main/res/drawable-xhdpi/new_server.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/onboarding.png b/android/app/src/main/res/drawable-xhdpi/onboarding.png
new file mode 100644
index 000000000..67764cd13
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/plus_onboarding.png b/android/app/src/main/res/drawable-xhdpi/plus_onboarding.png
new file mode 100644
index 000000000..c27a984a7
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/plus_onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/connect_server.png b/android/app/src/main/res/drawable-xxhdpi/connect_server.png
new file mode 100644
index 000000000..15dff0b30
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/connect_server.png differ
diff --git a/app/static/images/logoSmall@3x.png b/android/app/src/main/res/drawable-xxhdpi/logo_onboarding.png
similarity index 92%
rename from app/static/images/logoSmall@3x.png
rename to android/app/src/main/res/drawable-xxhdpi/logo_onboarding.png
index 0eb81e2e2..a95427d0a 100644
Binary files a/app/static/images/logoSmall@3x.png and b/android/app/src/main/res/drawable-xxhdpi/logo_onboarding.png differ
diff --git a/app/static/images/server@3x.png b/android/app/src/main/res/drawable-xxhdpi/new_server.png
similarity index 98%
rename from app/static/images/server@3x.png
rename to android/app/src/main/res/drawable-xxhdpi/new_server.png
index 402786c78..5c1b8fb5e 100644
Binary files a/app/static/images/server@3x.png and b/android/app/src/main/res/drawable-xxhdpi/new_server.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/onboarding.png b/android/app/src/main/res/drawable-xxhdpi/onboarding.png
new file mode 100644
index 000000000..fa8a8d2e8
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/plus_onboarding.png b/android/app/src/main/res/drawable-xxhdpi/plus_onboarding.png
new file mode 100644
index 000000000..d19853d71
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/plus_onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/connect_server.png b/android/app/src/main/res/drawable-xxxhdpi/connect_server.png
new file mode 100644
index 000000000..fffbb0946
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/connect_server.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/logo_onboarding.png b/android/app/src/main/res/drawable-xxxhdpi/logo_onboarding.png
new file mode 100644
index 000000000..df1c5467f
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/logo_onboarding.png differ
diff --git a/app/static/images/message_empty.png b/android/app/src/main/res/drawable-xxxhdpi/message_empty.png
similarity index 100%
rename from app/static/images/message_empty.png
rename to android/app/src/main/res/drawable-xxxhdpi/message_empty.png
diff --git a/android/app/src/main/res/drawable-xxxhdpi/new_server.png b/android/app/src/main/res/drawable-xxxhdpi/new_server.png
new file mode 100644
index 000000000..8a45bca89
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/new_server.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/onboarding.png b/android/app/src/main/res/drawable-xxxhdpi/onboarding.png
new file mode 100644
index 000000000..eaa2a3bcf
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/onboarding.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/plus_onboarding.png b/android/app/src/main/res/drawable-xxxhdpi/plus_onboarding.png
new file mode 100644
index 000000000..6bb7da177
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/plus_onboarding.png differ
diff --git a/android/settings.gradle b/android/settings.gradle
index 7a7576153..173139f83 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,4 +1,8 @@
rootProject.name = 'RocketChatRN'
+include ':react-native-device-info'
+project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
+include ':react-native-gesture-handler'
+project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
include ':@remobile/react-native-toast'
project(':@remobile/react-native-toast').projectDir = new File(rootProject.projectDir, '../node_modules/@remobile/react-native-toast/android')
include ':rn-fetch-blob'
diff --git a/app/containers/MessageBox/index.js b/app/containers/MessageBox/index.js
index 3c520def0..f256466f1 100644
--- a/app/containers/MessageBox/index.js
+++ b/app/containers/MessageBox/index.js
@@ -266,7 +266,7 @@ export default class MessageBox extends React.PureComponent {
await RocketChat.sendFileMessage(this.props.rid, fileInfo);
} catch (e) {
if (e && e.error === 'error-file-too-large') {
- return Alert.alert('File is too large!');
+ return Alert.alert(I18n.t(e.error));
}
log('finishAudioMessage', e);
}
diff --git a/app/containers/message/Audio.js b/app/containers/message/Audio.js
index b23e92475..45bc4f898 100644
--- a/app/containers/message/Audio.js
+++ b/app/containers/message/Audio.js
@@ -1,9 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { View, StyleSheet, TouchableOpacity, Text, Easing, Image } from 'react-native';
+import { View, StyleSheet, Text, Easing, Image } from 'react-native';
import Video from 'react-native-video';
import Slider from 'react-native-slider';
import moment from 'moment';
+import { BorderlessButton } from 'react-native-gesture-handler';
import Markdown from './Markdown';
@@ -116,7 +117,7 @@ export default class Audio extends React.PureComponent {
paused={paused}
repeat={false}
/>
- this.togglePlayPause()}
>
@@ -125,7 +126,7 @@ export default class Audio extends React.PureComponent {
:
}
-
+
{
+ this.setState({ isPressed: state });
}
render() {
+ const { isPressed } = this.state;
const { baseUrl, file, user } = this.props;
const img = `${ baseUrl }${ file.image_url }?rc_uid=${ user.id }&rc_token=${ user.token }`;
@@ -45,18 +50,20 @@ export default class extends React.PureComponent {
return (
[
- this._onPressButton()}
+ onPress={() => this.onPressButton()}
+ onActiveStateChange={this.isPressed}
style={styles.imageContainer}
+ underlayColor='#fff'
>
{this.getDescription()}
- ,
+ ,
alert(`Username ${ content }`)}
- style={mentionStyle}
- >
+
{content}
);
},
hashtag: node => (
- alert(`Room #${ node.content }`)} style={styles.mention}>
+
#{node.content}
),
diff --git a/app/containers/message/Message.js b/app/containers/message/Message.js
index 665b97d78..5ff1b465c 100644
--- a/app/containers/message/Message.js
+++ b/app/containers/message/Message.js
@@ -1,9 +1,10 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
-import { View, Text, TouchableOpacity, ViewPropTypes, Image as ImageRN } from 'react-native';
+import { View, Text, ViewPropTypes, Image as ImageRN } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import moment from 'moment';
import { KeyboardUtils } from 'react-native-keyboard-input';
+import { State, RectButton, LongPressGestureHandler } from 'react-native-gesture-handler';
import Image from './Image';
import User from './User';
@@ -16,7 +17,6 @@ import Reply from './Reply';
import ReactionsModal from './ReactionsModal';
import Emoji from './Emoji';
import styles from './styles';
-import Touch from '../../utils/touch';
import I18n from '../../i18n';
import messagesStatus from '../../constants/messagesStatus';
@@ -247,25 +247,31 @@ export default class Message extends PureComponent {
renderReaction = (reaction) => {
const reacted = reaction.usernames.findIndex(item => item.value === this.props.user.username) !== -1;
- const reactedContainerStyle = reacted && styles.reactedContainer;
+ const underlayColor = reacted ? '#fff' : '#e1e5e8';
return (
- this.props.onReactionPress(reaction.emoji)}
- onLongPress={this.props.onReactionLongPress}
+ nativeEvent.state === State.ACTIVE && this.props.onReactionLongPress()}
>
-
-
- { reaction.usernames.length }
-
-
+ this.props.onReactionPress(reaction.emoji)}
+ testID={`message-reaction-${ reaction.emoji }`}
+ style={[styles.reactionButton, reacted && { backgroundColor: '#e8f2ff' }]}
+ activeOpacity={0.8}
+ underlayColor={underlayColor}
+ >
+
+
+ { reaction.usernames.length }
+
+
+
);
}
@@ -277,14 +283,18 @@ export default class Message extends PureComponent {
return (
{reactions.map(this.renderReaction)}
-
-
-
+
+
+
+
);
}
@@ -292,15 +302,15 @@ export default class Message extends PureComponent {
renderBroadcastReply() {
if (this.props.broadcast && !this.isOwn()) {
return (
-
-
-
- Reply
-
-
+
+ {I18n.t('Reply')}
+
);
}
return null;
@@ -313,39 +323,46 @@ export default class Message extends PureComponent {
const accessibilityLabel = I18n.t('Message_accessibility', { user: author.username, time: moment(ts).format(timeFormat), message: msg });
return (
- nativeEvent.state === State.ACTIVE && onLongPress()}
>
-
-
- {this.renderError()}
- {this.renderAvatar()}
-
- {this.renderUsername()}
- {this.renderContent()}
- {this.renderAttachment()}
- {this.renderUrl()}
- {this.renderReactions()}
- {this.renderBroadcastReply()}
+
+
+
+ {this.renderError()}
+ {this.renderAvatar()}
+
+ {this.renderUsername()}
+ {this.renderContent()}
+ {this.renderAttachment()}
+ {this.renderUrl()}
+ {this.renderReactions()}
+ {this.renderBroadcastReply()}
+
+ {reactionsModal ?
+
+ : null
+ }
- {reactionsModal ?
-
- : null
- }
-
-
+
+
);
}
}
diff --git a/app/containers/message/QuoteMark.js b/app/containers/message/QuoteMark.js
deleted file mode 100644
index 2c010c6e2..000000000
--- a/app/containers/message/QuoteMark.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import { View, StyleSheet } from 'react-native';
-import PropTypes from 'prop-types';
-
-const styles = StyleSheet.create({
- quoteSign: {
- borderWidth: 2,
- borderRadius: 4,
- height: '100%',
- marginRight: 5
- }
-});
-
-const QuoteMark = ({ color }) => ;
-
-QuoteMark.propTypes = {
- color: PropTypes.string
-};
-
-export default QuoteMark;
diff --git a/app/containers/message/Reply.js b/app/containers/message/Reply.js
index 2516f9d53..02632ad5e 100644
--- a/app/containers/message/Reply.js
+++ b/app/containers/message/Reply.js
@@ -2,10 +2,10 @@ import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import moment from 'moment';
+import { RectButton } from 'react-native-gesture-handler';
import Markdown from './Markdown';
import openLink from '../../utils/openLink';
-import Touch from '../../utils/touch';
const styles = StyleSheet.create({
button: {
@@ -13,13 +13,13 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
marginTop: 15,
- alignSelf: 'flex-end'
+ alignSelf: 'flex-end',
+ backgroundColor: '#f3f4f5'
},
attachmentContainer: {
flex: 1,
borderRadius: 4,
flexDirection: 'column',
- backgroundColor: '#f3f4f5',
padding: 15
},
authorContainer: {
@@ -55,12 +55,15 @@ const styles = StyleSheet.create({
}
});
-const onPress = (attachment) => {
- const url = attachment.title_link || attachment.author_link;
+const onPress = (attachment, baseUrl, user) => {
+ let url = attachment.title_link || attachment.author_link;
if (!url) {
return;
}
- openLink(attachment.title_link || attachment.author_link);
+ if (attachment.type === 'file') {
+ url = `${ baseUrl }${ url }?rc_uid=${ user.id }&rc_token=${ user.token }`;
+ }
+ openLink(url);
};
const Reply = ({
@@ -91,9 +94,19 @@ const Reply = ({
);
};
- const renderText = () => (
- attachment.text ? : null
- );
+ const renderText = () => {
+ const text = attachment.text || attachment.title;
+ if (text) {
+ return (
+
+ );
+ }
+ };
const renderFields = () => {
if (!attachment.fields) {
@@ -113,16 +126,18 @@ const Reply = ({
};
return (
- onPress(attachment)}
+ onPress(attachment, baseUrl, user)}
style={[styles.button, index > 0 && styles.marginTop]}
+ activeOpacity={0.5}
+ underlayColor='#fff'
>
{renderTitle()}
{renderText()}
{renderFields()}
-
+
);
};
diff --git a/app/containers/message/Url.js b/app/containers/message/Url.js
index 8de51c798..b7fea7d24 100644
--- a/app/containers/message/Url.js
+++ b/app/containers/message/Url.js
@@ -2,9 +2,9 @@ import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import FastImage from 'react-native-fast-image';
+import { RectButton } from 'react-native-gesture-handler';
import openLink from '../../utils/openLink';
-import Touch from '../../utils/touch';
const styles = StyleSheet.create({
button: {
@@ -58,16 +58,19 @@ const Url = ({ url, index }) => {
return null;
}
return (
- onPress(url.url)} style={[styles.button, index > 0 && styles.marginTop]}>
-
- {url.image ? : null}
-
- {url.url}
- {url.title}
- {url.description}
-
+ onPress(url.url)}
+ style={[styles.button, index > 0 && styles.marginTop, styles.container]}
+ activeOpacity={0.5}
+ underlayColor='#fff'
+ >
+ {url.image ? : null}
+
+ {url.url}
+ {url.title}
+ {url.description}
-
+
);
};
diff --git a/app/containers/message/User.js b/app/containers/message/User.js
index 2b988acc8..6356709ba 100644
--- a/app/containers/message/User.js
+++ b/app/containers/message/User.js
@@ -36,8 +36,7 @@ export default class User extends React.PureComponent {
username: PropTypes.string,
alias: PropTypes.string,
ts: PropTypes.instanceOf(Date),
- temp: PropTypes.bool,
- onPress: PropTypes.func
+ temp: PropTypes.bool
}
render() {
@@ -55,7 +54,7 @@ export default class User extends React.PureComponent {
return (
-
+
{alias || username}
{aliasUsername}
diff --git a/app/containers/message/Video.js b/app/containers/message/Video.js
index 208382c21..2e926b859 100644
--- a/app/containers/message/Video.js
+++ b/app/containers/message/Video.js
@@ -1,8 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { StyleSheet, TouchableOpacity, Image, Platform, View } from 'react-native';
+import { StyleSheet, Image, Platform, View } from 'react-native';
import Modal from 'react-native-modal';
import VideoPlayer from 'react-native-video-controls';
+import { RectButton } from 'react-native-gesture-handler';
+
import Markdown from './Markdown';
import openLink from '../../utils/openLink';
@@ -70,15 +72,17 @@ export default class Video extends React.PureComponent {
return (
[
- this.open()}
+ activeOpacity={0.5}
+ underlayColor='#fff'
>
-
+
,
{
- database.create('subscriptions', tpm, true);
- database.delete(rooms);
- });
+ if (type === 'removed') {
+ let messages = [];
+ const [subscription] = database.objects('subscriptions').filtered('_id == $0', data._id);
+
+ if (subscription) {
+ messages = database.objects('messages').filtered('rid == $0', subscription.rid);
+ }
+ database.write(() => {
+ database.delete(messages);
+ database.delete(subscription);
+ });
+ } else {
+ const rooms = database.objects('rooms').filtered('_id == $0', data.rid);
+ const tpm = merge(data, rooms[0]);
+ database.write(() => {
+ database.create('subscriptions', tpm, true);
+ database.delete(rooms);
+ });
+ }
}
if (/rooms/.test(ev)) {
if (type === 'updated') {
@@ -93,9 +106,8 @@ export default async function subscribeRooms(id) {
}
try {
- await subscriptions;
+ await promises;
} catch (e) {
log('subscribeRooms', e);
}
- // console.log(this.ddp.subscriptions);
}
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index 368149106..b8cadb1b6 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -470,9 +470,11 @@ const RocketChat = {
log('rocketchat.logout', e);
}
}
- // database.deleteAll();
AsyncStorage.removeItem(TOKEN_KEY);
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`);
+ setTimeout(() => {
+ database.deleteAll();
+ }, 1000);
},
registerPushToken(userId) {
@@ -750,7 +752,7 @@ const RocketChat = {
// transform room roles to array
const roomRoles = Array.from(Object.keys(roles), i => roles[i].value);
// get user roles on the server from redux
- const userRoles = reduxStore.getState().login.user.roles || [];
+ const userRoles = (reduxStore.getState().login.user && reduxStore.getState().login.user.roles) || [];
// merge both roles
const mergedRoles = [...new Set([...roomRoles, ...userRoles])];
diff --git a/app/sagas/createChannel.js b/app/sagas/createChannel.js
index bd5ff2d91..47200ae16 100644
--- a/app/sagas/createChannel.js
+++ b/app/sagas/createChannel.js
@@ -26,11 +26,7 @@ const handleRequest = function* handleRequest({ data }) {
screen: 'RoomView',
title: name,
backButtonTitle: '',
- passProps: {
- room: { rid, name },
- rid,
- name
- }
+ passProps: { rid }
});
} catch (err) {
yield put(createChannelFailure(err));
diff --git a/app/sagas/messages.js b/app/sagas/messages.js
index 556b66a7d..ece23915f 100644
--- a/app/sagas/messages.js
+++ b/app/sagas/messages.js
@@ -80,12 +80,9 @@ const goRoom = function* goRoom({ rid, name }) {
yield delay(1000);
NavigationActions.push({
screen: 'RoomView',
+ title: name,
backButtonTitle: '',
- passProps: {
- room: { rid, name },
- rid,
- name
- }
+ passProps: { rid }
});
};
diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js
index 50c372c43..9dc0e6ece 100644
--- a/app/sagas/rooms.js
+++ b/app/sagas/rooms.js
@@ -10,6 +10,7 @@ import { messagesRequest, editCancel, replyCancel } from '../actions/messages';
import RocketChat from '../lib/rocketchat';
import database from '../lib/realm';
import log from '../utils/log';
+import I18n from '../i18n';
import { NavigationActions } from '../Navigation';
const leaveRoom = rid => RocketChat.leaveRoom(rid);
@@ -63,41 +64,40 @@ const handleMessageReceived = function* handleMessageReceived({ message }) {
database.create('messages', message, true);
});
- RocketChat.readMessages(room.rid);
+ if (room._id) {
+ RocketChat.readMessages(room.rid);
+ }
}
} catch (e) {
console.warn('handleMessageReceived', e);
}
};
+let opened = false;
+
const watchRoomOpen = function* watchRoomOpen({ room }) {
try {
- yield put(messagesRequest({ ...room }));
- // const { open } = yield race({
- // messages: take(types.MESSAGES.SUCCESS),
- // open: take(types.ROOM.OPEN)
- // });
- //
- // if (open) {
- // return;
- // }
+ if (opened) {
+ return;
+ }
+ opened = true;
- RocketChat.readMessages(room.rid);
+ yield put(messagesRequest({ ...room }));
+
+ if (room._id) {
+ RocketChat.readMessages(room.rid);
+ }
sub = yield RocketChat.subscribeRoom(room);
- // const subscriptions = yield Promise.all([RocketChat.subscribe('stream-room-messages', room.rid, false), RocketChat.subscribe('stream-notify-room', `${ room.rid }/typing`, false)]);
thread = yield fork(usersTyping, { rid: room.rid });
yield race({
open: take(types.ROOM.OPEN),
close: take(types.ROOM.CLOSE)
});
+ opened = false;
cancel(thread);
sub.stop();
yield put(editCancel());
yield put(replyCancel());
-
- // subscriptions.forEach((sub) => {
- // sub.unsubscribe().catch(e => alert(e));
- // });
} catch (e) {
log('watchRoomOpen', e);
}
@@ -161,9 +161,9 @@ const handleLeaveRoom = function* handleLeaveRoom({ rid }) {
yield goRoomsListAndDelete(rid);
} catch (e) {
if (e.error === 'error-you-are-last-owner') {
- Alert.alert('You are the last owner. Please set new owner before leaving the room.');
+ Alert.alert(e.error);
} else {
- Alert.alert('Something happened when leaving room!');
+ Alert.alert(I18n.t('There_was_an_error_while_action', { action: I18n.t('leaving_room') }));
}
}
};
@@ -174,7 +174,7 @@ const handleEraseRoom = function* handleEraseRoom({ rid }) {
yield call(eraseRoom, rid);
yield goRoomsListAndDelete(rid);
} catch (e) {
- Alert.alert('Something happened when erasing room!');
+ Alert.alert(I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') }));
}
};
diff --git a/app/static/images/connectServer.png b/app/static/images/connectServer.png
deleted file mode 100644
index e5e2c021f..000000000
Binary files a/app/static/images/connectServer.png and /dev/null differ
diff --git a/app/static/images/connectServer@2x.png b/app/static/images/connectServer@2x.png
deleted file mode 100644
index 5cd548403..000000000
Binary files a/app/static/images/connectServer@2x.png and /dev/null differ
diff --git a/app/static/images/connectServer@3x.png b/app/static/images/connectServer@3x.png
deleted file mode 100644
index a75cf1fa7..000000000
Binary files a/app/static/images/connectServer@3x.png and /dev/null differ
diff --git a/app/static/images/plusWhite.png b/app/static/images/plusWhite.png
deleted file mode 100644
index 4cceffccc..000000000
Binary files a/app/static/images/plusWhite.png and /dev/null differ
diff --git a/app/static/images/plusWhite@2x.png b/app/static/images/plusWhite@2x.png
deleted file mode 100644
index 69276aa00..000000000
Binary files a/app/static/images/plusWhite@2x.png and /dev/null differ
diff --git a/app/static/images/plusWhite@3x.png b/app/static/images/plusWhite@3x.png
deleted file mode 100644
index 5a9c0ceee..000000000
Binary files a/app/static/images/plusWhite@3x.png and /dev/null differ
diff --git a/app/utils/deviceInfo.js b/app/utils/deviceInfo.js
new file mode 100644
index 000000000..dc963537a
--- /dev/null
+++ b/app/utils/deviceInfo.js
@@ -0,0 +1,7 @@
+import DeviceInfo from 'react-native-device-info';
+
+export default {
+ isNotch: () => DeviceInfo.getModel() === 'iPhone X',
+ getBrand: () => DeviceInfo.getBrand(),
+ getReadableVersion: () => DeviceInfo.getReadableVersion()
+};
diff --git a/app/views/LoginSignupView.js b/app/views/LoginSignupView.js
index a9e86e178..592d09aef 100644
--- a/app/views/LoginSignupView.js
+++ b/app/views/LoginSignupView.js
@@ -37,8 +37,8 @@ const styles = StyleSheet.create({
fontWeight: '700'
},
planetImage: {
- width: 200,
- height: 162,
+ width: 210,
+ height: 171,
marginVertical: 20
}
});
@@ -283,10 +283,7 @@ export default class LoginSignupView extends LoggedView {
{I18n.t('Welcome_title_pt_1')}
{I18n.t('Welcome_title_pt_2')}
-
+