diff --git a/.circleci/config.yml b/.circleci/config.yml index 7667897cc..8203bba7d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ defaults: &defaults macos: &macos macos: - xcode: "11.5.0" + xcode: "12.1.0" bash-env: &bash-env BASH_ENV: "~/.nvm/nvm.sh" @@ -343,12 +343,11 @@ jobs: agvtool new-version -all $CIRCLE_BUILD_NUM /usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist - if [[ $MATCH_KEYCHAIN_NAME ]]; then + if [[ $APP_STORE_CONNECT_API_KEY ]]; then + echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8 bundle exec fastlane ios release else - export MATCH_KEYCHAIN_NAME="temp" - export MATCH_KEYCHAIN_PASSWORD="temp" - bundle exec fastlane ios build + bundle exec fastlane ios build_fork fi working_directory: ios @@ -381,6 +380,7 @@ jobs: - run: name: Fastlane Tesflight Upload command: | + echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8 bundle exec fastlane ios beta working_directory: ios diff --git a/.gitignore b/.gitignore index 18624dd0b..3d1baa215 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,6 @@ coverage artifacts .vscode/ e2e/docker/rc_test_env/docker-compose.yml -e2e/docker/data/db \ No newline at end of file +e2e/docker/data/db + +*.p8 \ No newline at end of file diff --git a/README.md b/README.md index f5197c4ca..e4e7bdecf 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - **Supported server versions:** 0.70.0+ - **Supported iOS versions**: 11+ -- **Supported Android versions**: 5.0+ +- **Supported Android versions**: 6.0+ ## Download @@ -35,7 +35,7 @@ Do you want to make the app run on your own server only? [Follow our whitelabel ## Engage with us ### Share your story -We’d love to hear about [your experience](https://survey.zohopublic.com/zs/e4BUFG) and potentially feature it on our [Blog](https://rocket.chat/case-studies/?utm_source=github&utm_medium=readme&utm_campaign=community). +We’d love to hear about [your experience](https://survey.zohopublic.com/zs/e4BUFG) and potentially feature it on our [blog](https://rocket.chat/case-studies/?utm_source=github&utm_medium=readme&utm_campaign=community). ### Subscribe for Updates -Once a month our marketing team releases an email update with news about product releases, company related topics, events and use cases. [Sign Up!](https://rocket.chat/newsletter/?utm_source=github&utm_medium=readme&utm_campaign=community) +Once a month our marketing team releases an email update with news about product releases, company related topics, events and use cases. [Sign up!](https://rocket.chat/newsletter/?utm_source=github&utm_medium=readme&utm_campaign=community) diff --git a/__mocks__/expo-keep-awake.js b/__mocks__/expo-keep-awake.js index 947b94723..4df99a606 100644 --- a/__mocks__/expo-keep-awake.js +++ b/__mocks__/expo-keep-awake.js @@ -1,4 +1,4 @@ -export default { - activateKeepAwake: () => '', - deactivateKeepAwake: () => '' -}; +const activateKeepAwake = () => ''; +const deactivateKeepAwake = () => ''; + +export { activateKeepAwake, deactivateKeepAwake }; diff --git a/__mocks__/react-native-gesture-handler.js b/__mocks__/react-native-gesture-handler.js index 2f9960f4a..349fd1210 100644 --- a/__mocks__/react-native-gesture-handler.js +++ b/__mocks__/react-native-gesture-handler.js @@ -1,5 +1,5 @@ -export const RectButton = () => 'View'; +export const RectButton = ({ children }) => children; export const State = () => 'View'; -export const LongPressGestureHandler = () => 'View'; -export const BorderlessButton = () => 'View'; -export const PanGestureHandler = () => 'View'; +export const LongPressGestureHandler = ({ children }) => children; +export const BorderlessButton = ({ children }) => children; +export const PanGestureHandler = ({ children }) => children; diff --git a/__tests__/Storyshots.test.js b/__tests__/Storyshots.test.js index 9b14d0d54..0395eef24 100644 --- a/__tests__/Storyshots.test.js +++ b/__tests__/Storyshots.test.js @@ -1,3 +1,6 @@ import initStoryshots from '@storybook/addon-storyshots'; +jest.mock('../app/lib/database', () => jest.fn(() => null)); +global.Date.now = jest.fn(() => new Date('2019-10-10').getTime()); + initStoryshots(); diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index 20dab567c..7d0605ac7 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -1,5 +1,9637 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Storyshots Avatar list Avatar 1`] = ` + + + + Avatar by text + + + + + + + + Avatar by roomId + + + + + + + + Avatar by url + + + + + + + + Avatar by path + + + + + + + + With ETag + + + + + + + + Without ETag + + + + + + + + Emoji + + + + + + + + Direct + + + + + + + + Channel + + + + + + + + Touchable + + + + + + + + + + Static + + + + + + + + Custom borderRadius + + + + + + + + Children + + + + + + + + + Wrong server + + + + + + + + Custom style + + + + + + + + +`; + +exports[`Storyshots Header Buttons badge 1`] = ` + + + + + +  + + + + 1 + + + + + +  + + + + 1 + + + + + +  + + + + 1 + + + + + + + +`; + +exports[`Storyshots Header Buttons common 1`] = ` +Array [ + + + + + +  + + + + + + , + + + + + +  + + + + + + , + + + + + + Cancel + + + + + + , + + + + + + +  + + + + + , + + + + + + +  + + + + + , + + + + + + +  + + + + + , + + + + + + +  + + + + + , +] +`; + +exports[`Storyshots Header Buttons icons 1`] = ` +Array [ + + + + + +  + + + + + + + +  + + + + + , + + + + + +  + + + + +  + + + + + + + +  + + + + +  + + + + + , +] +`; + +exports[`Storyshots Header Buttons themes 1`] = ` +Array [ + + + + + +  + + + + + + + + Threads + + + + +  + + + + 1 + + + + + + , + + + + + +  + + + + + + + + Threads + + + + +  + + + + 1 + + + + + + , + + + + + +  + + + + + + + + Threads + + + + +  + + + + 1 + + + + + + , +] +`; + +exports[`Storyshots Header Buttons title 1`] = ` +Array [ + + + + + + threads + + + + + + + + threads + + + + + , + + + + + + threads + + + + + search + + + + + + + + threads + + + + + search + + + + + , +] +`; + +exports[`Storyshots List header 1`] = ` + + + + + Chats + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + +`; + +exports[`Storyshots List icon 1`] = ` + + + + +  + + + + +`; + +exports[`Storyshots List pressable 1`] = ` + + + + + + + Press me + + + + + + + + I'm disabled + + + + + + +`; + +exports[`Storyshots List separator 1`] = ` + + + + + +`; + +exports[`Storyshots List title and subtitle 1`] = ` + + + + + + + + Chats + + + + + + + + + + Chats + + + All + + + + + + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + + + +`; + +exports[`Storyshots List with FlatList 1`] = ` + + + + + + + + + + + + 0 + + + + + + + + + + + + 1 + + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + 4 + + + + + + + + + + + + 5 + + + + + + + + + + + + 6 + + + + + + + + + + + + 7 + + + + + + + + + + + + 8 + + + + + + + + + + + + 9 + + + + + + + + + + + + + +`; + +exports[`Storyshots List with bigger font 1`] = ` + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + +`; + +exports[`Storyshots List with black theme 1`] = ` + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + +`; + +exports[`Storyshots List with custom color 1`] = ` + + + + + + + + Chats + + + + + + + +`; + +exports[`Storyshots List with dark theme 1`] = ` + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + +`; + +exports[`Storyshots List with icon 1`] = ` + + + + + + + + +  + + + + + + Icon Left + + + + + + + + + + Icon Right + + + + + +  + + + + + + + + + + + +  + + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + +  + + + + + + + + + + + Show Action Indicator + + + + + +  + + + + + + + + +`; + +exports[`Storyshots List with section and info 1`] = ` + + + + + + + + + + Section Item + + + + + + + + + + Section Item + + + + + + + + + + + + + Section Item + + + + + + + + + + Section Item + + + + + + + + + + Chats + + + + + + + + Section Item + + + + + + + + + + Section Item + + + + + + + + Chats + + + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + + + + Section Item + + + + + + + + + + Section Item + + + + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + + +`; + +exports[`Storyshots List with small font 1`] = ` + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + + Chats + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + + +  + + + + + + Chats + + + All + + + + + +  + + + + + + + + Chats + + + + + + +`; + exports[`Storyshots Markdown list Markdown 1`] = ` @@ -1255,6 +10861,7 @@ exports[`Storyshots Markdown list Markdown 1`] = ` "fontSize": 16, "fontWeight": "400", }, + Object {}, ] } > @@ -1303,10 +10910,13 @@ exports[`Storyshots Markdown list Markdown 1`] = ` Object { "overflow": "hidden", }, - Object { - "height": 20, - "width": 20, - }, + Array [ + Object { + "height": 20, + "width": 20, + }, + Object {}, + ], ] } > @@ -1361,10 +10971,13 @@ exports[`Storyshots Markdown list Markdown 1`] = ` Object { "overflow": "hidden", }, - Object { - "height": 20, - "width": 20, - }, + Array [ + Object { + "height": 20, + "width": 20, + }, + Object {}, + ], ] } > @@ -1419,10 +11032,13 @@ exports[`Storyshots Markdown list Markdown 1`] = ` Object { "overflow": "hidden", }, - Object { - "height": 20, - "width": 20, - }, + Array [ + Object { + "height": 20, + "width": 20, + }, + Object {}, + ], ] } > @@ -1499,6 +11115,7 @@ exports[`Storyshots Markdown list Markdown 1`] = ` "fontSize": 30, "fontWeight": "400", }, + Object {}, ] } > @@ -1541,10 +11158,13 @@ exports[`Storyshots Markdown list Markdown 1`] = ` Object { "overflow": "hidden", }, - Object { - "height": 30, - "width": 30, - }, + Array [ + Object { + "height": 30, + "width": 30, + }, + Object {}, + ], ] } > @@ -3193,7 +12813,454 @@ exports[`Storyshots Markdown list Markdown 1`] = ` "marginHorizontal": 15, } } - /> + > + + + + + + + + + First Header + + + + + + + Second Header + + + + + + + + + Content from cell 1 + + + + + + + Content from cell 2 + + + + + + + + + Content in the first column + + + + + + + Content in the second column + + + + + + + + + Click to see full table + + + `; @@ -3228,6 +13295,235 @@ exports[`Storyshots Message list message 1`] = ` > Simple + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message + + + + + + + + Long message + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + Grouped messages + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + ... + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + 10:00 AM + + + + + + Different user + + + + + + + + + + + + + + + + + This is the third message + + + + + + + + + + + + + + + + + This is the second message + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + This is the first message + + + + + + + + Without header + + + + + + + + + Message + + + + + + + + With alias + + + + + + + + + + + + + + + + Diego Mello + + @ + diego.mello + + + + + 10:00 AM + + + + + + Message + + + + + + + + + + + + + + + + + + + + + + + + Diego Mello + + @ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + 10:00 AM + + + + + + Message + + + + + + + + Edited + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message + + + + + + + + Encrypted + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + Message + + + + + +  + + + + + + + + + + + + + + + + + + + + Message Encrypted without Header + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + Message Encrypted with Reactions + + + + + +  + + + + + + + + + 😂 + + + 1 + + + + + + + + + + 1 + + + + + + + 🤔 + + + 1 + + + + + + +  + + + + + + + + + + + + + + +  + + + Thread with emoji🙂 😂 + + + +  + + + + + + + + + + + + + + + Thread reply encrypted + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + Temp message encrypted + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + Message Edited encrypted + + + + + +  + + + + + + + + + + > + + + + + + + + + diego.mello + + 10:00 AM + + +  + + + + +  + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + Read Receipt encrypted with Header + + + + + +  + + + + + + +  + + + + + + + + + + + + + + + + Read Receipt encrypted without Header + + + + + +  + + + + + + +  + + + + + Block Quote + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + Testing block quote + + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + Testing block quote + + + + + + + Testing block quote + + + + + + + + Lists + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + • + + + + + + Dogs + + + + + + ◦ + + + + + + cats + + + + + + + + ◦ + + + + + + cats + + + + + + + + + + + + Numerated lists + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + 1. + + + + + + Dogs + + + + + + + + 2. + + + + + + Cats + + + + + + + + + + Numerated lists in separated messages + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + 1. + + + + + + Dogs + + + + + + + + + + + + + + + + + + + + 2. + + + + + + Cats + + + + + + + + + + Static avatar + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message + + + + + + + + Full name + + + + + + + + + + + + + + + + Diego Mello + + + + 10:00 AM + + + + + + Message + + + + + + + + Mentions + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + rocket.cat + + + + + + diego.mello + + + + + + all + + + + + + here + + + + + + #general + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + rocket.cat + + + Lorem ipsum dolor + + + diego.mello + + + sit amet, + + + all + + + consectetur adipiscing + + + here + + + elit, sed do eiusmod tempor + + + #general + + + incididunt ut labore et dolore magna aliqua. + + + + + + + + Emojis + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + 👊🤙👏 + + + + + + + + Single Emoji + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + 👏 + + + + + + + + Custom Emojis + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + + + + + + + + + + + + + + + + + Single Custom Emojis + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + + + + + Normal Emoji + Custom Emojis + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + 🤙 + + + + + + + + + + + Four emoji + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + 🤙 + + + + + + 🤙🤙 + + + + + + + + Time format + + + + + + + + + + + + + + + + diego.mello + + + + 10 November 2017 + + + + + + Testing + + + + + + + + Reactions + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Reactions + + + + + + + + 😂 + + + 3 + + + + + + + + + + 13 + + + + + + + 🤔 + + + 1 + + + + + + +  + + + + + + + + + Multiple reactions + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Multiple Reactions + + + + + + + + + + + 1 + + + + + + + + + + 1 + + + + + + + + + + 1 + + + + + + + ❤️ + + + 1 + + + + + + + 🐶 + + + 1 + + + + + + + 😀 + + + 1 + + + + + + + 😬 + + + 1 + + + + + + + 😁 + + + 1 + + + + + + +  + + + + + + + + + Intercalated users + + + + + + + + + + + + + + + + rocket.cat + + + + 10:00 AM + + + + + + Fourth message + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Third message + + + + + + + + + + + + + + + + + + + + + + + + rocket.cat + + + + 10:00 AM + + + + + + Second message + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + First message + + + + + + + + Date and Unread separators + + + + + + + + + + + + + + + + rocket.cat + + + + 10:00 AM + + + + + + Fourth message + + + + + + + + - Nov 10, 2017 + November 10, 2017 + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Third message + + + + + + + + + + + + + + + + + Second message + + + + + + + + + + + + + + + + + + + + + + + + rocket.cat + + + + 10:00 AM + + + + + + Second message + + + + + + + + - Nov 10, 2017 + November 10, 2017 + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + First message + + + + + + + + With image + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + + + + This is a description + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + + + + This is a description + + + + + + + + + + + + With video + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + +  + + + + + This is a description + + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + +  + + + + + + + With audio + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + 00:00 + + + + + This is a description + + + + + + + + + + + + + + + + + + + First message + + + + + + + + + + + + + + + + + + + + + 00:00 + + + + + This is a description + + + + + + + + + + + + + + + + + + + + 00:00 + + + + + + + + + + + + + + + + + + + + 00:00 + + + + + + + + + With file + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + File.pdf + + + + + + + This is a description + + + + + + + + + + + + + + + + + + + + + File.pdf + + + + + + + This is a description + + + + + + + + + + Message with reply + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + I'm fine! + + + + + + + + I'm a very long long title and I'll break + + + 10:00 AM + + + + + How are you? + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + I'm fine! + + + + + + + + rocket.cat + + + 10:00 AM + + + + + How are you? + + + + + + + + + + + + Message with read receipt + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + I'm fine! + + + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + I'm fine! + + + + + +  + + + + + + + + + + + + + + I'm fine! + + + + + +  + + + + + Message with thread + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + How are you? + + + + + + +  + + + 1 reply + + + + November 10, 2017 + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + How are you? + + + + + + +  + + + +999 replies + + + + November 10, 2017 + + + + +  + + + + + + + + + + + + + +  + + + How are you? + + + +  + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + +  + + + Thread with emoji🙂 😂 + + + +  + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + +  + + + Markdown: link block code + + + +  + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + +  + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + +  + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + +  + + + How are you? + + + +  + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + +  + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + +  + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + +  + + + Thread with attachment + + + +  + + + + + + + + + + + + + + + Sent an attachment + + + + + + + Sequential thread messages following thread button + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + How are you? + + + + + + +  + + + 1 reply + + + + November 10, 2017 + + + + +  + + + + + + + + + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + + + + + + + + + + + Sent an attachment + + + + + + + Sequential thread messages following thread reply + + + + + +  + + + How are you? + + + +  + + + + + + + + + + + + + + + I'm fine! + + + + + + + + + + + + + + + + + + + + + + Cool! + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + + + + + + + + + + + Sent an attachment + + + + + + + Discussion + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + Started a discussion: + + + This is a discussion + + + + +  + + + No messages yet + + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + Started a discussion: + + + This is a discussion + + + + +  + + + 1 message + + + + November 10, 2017 + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + Started a discussion: + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + +  + + + 10 messages + + + + November 10, 2017 + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + Started a discussion: + + + This is a discussion + + + + +  + + + +999 messages + + + + November 10, 2017 + + + + + + + URL + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + 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. + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message + + + + + + + + + + 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. + + + + + + + + + + + + + + + + + + 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. + + + + + + + + Custom fields + + + + + + + + + + + + + + + + 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 + + + + + + + + + + Two short custom fields + + + + + + + + + + + + + + + + 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 + + + + + + + + + + Broadcast + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Broadcasted message + + + + + + +  + + + Reply + + + + + + + + Archived + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + This message is inside an archived room + + + + + + + + + > + + + + + + + + + diego.mello + + 10:00 AM + + +  + + + + + diego.mello + + 10:00 AM + + +  + + Temp + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Temp message + + + + + + + + Editing + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message being edited + + + + + + + + Removed + + + + + + + + + + + + + + Message removed + + + + + + Joined + + + + + + + + + + + + + + Has joined the channel + + + + + + Room name changed + + + + + + + + + + + + + + Room name changed to: New name by diego.mello + + + + + + Message pinned + + + + + + + + + + + + + + Message pinned + + + + + + Has left the channel + + + + + + + + + + + + + + Has left the channel + + + + + + User removed + + + + + + + + + + + + + + User rocket.cat removed by diego.mello + + + + + + User added + + + + + + + + + + + + + + User rocket.cat added by diego.mello + + + + + + User muted + + + + + + + + + + + + + + User rocket.cat muted by diego.mello + + + + + + User unmuted + + + + + + + + + + + + + + User rocket.cat unmuted by diego.mello + + + + + + Role added + + + + + + + + + + + + + + rocket.cat was set admin by diego.mello + + + + + + Role removed + + + + + + + + + + + + + + rocket.cat is no longer admin by diego.mello + + + + + + Changed description + + + + + + + + + + + + + + Room description changed to: new description by diego.mello + + + + + + Changed announcement + + + + + + + + + + + + + + Room announcement changed to: new announcement by diego.mello + + + + + + Changed topic + + + + + + + + + + + + + + Room topic changed to: new topic by diego.mello + + + + + + Changed type + + + + + + + + + + + + + + Room type changed to: public by diego.mello + + + + + + Custom style + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Message + + + + + + + + Markdown emphasis + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Italic with single + + + underscore + + + or double + + + underscores + + + . Bold with single + + + asterisk + + + or double + + + asterisks + + + . Strikethrough with single + + + Strikethrough + + + or double + + + Strikethrough + + + + + + + + Markdown headers + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + H1 + + + + + H2 + + + + + H3 + + + + + H4 + + + + + H5 + + + + + H6 + + + + + + + + Markdown links + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Support + + + + Google + + + + + + + + I\`m an inline-style link + + + + + + + + https://google.com + + + + + + + + + Markdown image + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + + + + Markdown code + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + Inline + + + code + + + has + + + back-ticks around + + + it. + + + + Code block + + + + + + + + Markdown quote + + + + + + + + + + + + + + + + diego.mello + + + + 10:00 AM + + + + + + + + + Quote + + + + + + + + + + Markdown table + + + + + + + + + + + + + + + + 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 + + + + + + + + + Click to see full table + + + + + + + + `; @@ -5121,7 +46259,368 @@ exports[`Storyshots RoomItem list roomitem 1`] = ` > Basic - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + User - View - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + diego.mello + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + + Type - View - View - View - View - View - View - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + +  + + + rocket.cat + + + + + + User status - View - View - View - View - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + Alerts - View - View - View - View - View - View - View - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + unread + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + unread + + + + +999 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + user mentions + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + group mentions + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + thread unread + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + thread unread user + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + thread unread group + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + user mentions priority 1 + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + group mentions priority 2 + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + thread unread priority 3 + + + + 1 + + + + + + + Last Message - View - View - View - View - View - View - View + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + No Message + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + 2 + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + You: 1 + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + 1 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + +999 + + + + + + + + + + + + +  + + + Read + + + + + + + +  + + + Favorite + + + + +  + + + Hide + + + + + + + + + + + + + + + rocket.cat + + + 10:00 + + + + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + + 1 + + + + + + + + + +`; + +exports[`Storyshots Thread Messages.Item badge 1`] = ` + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + +`; + +exports[`Storyshots Thread Messages.Item content 1`] = ` + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1000 + + + + +  + + + 1000 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Attachment title + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + Rocket Cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + +`; + +exports[`Storyshots Thread Messages.Item themes 1`] = ` + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + + + + + + + + + + rocket.cat + + + November 10, 2020 + + + + Message content + + + + +  + + + 1 + + + + +  + + + 1 + + + + +  + + + November 10, 2020 + + + + + + + + + `; @@ -5718,3 +63639,1289 @@ exports[`Storyshots UiKitModal list UiKitModal 1`] = ` `; + +exports[`Storyshots Unread Badge all 1`] = ` + + + + 9 + + + + + +99 + + + + + 9 + + + + + +999 + + + + + 9 + + + + + 9 + + + + + 9 + + + +`; + +exports[`Storyshots Unread Badge different mention types 1`] = ` + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + +`; + +exports[`Storyshots Unread Badge normal 1`] = ` + + + + 9 + + + + + +999 + + + +`; + +exports[`Storyshots Unread Badge small 1`] = ` + + + + 9 + + + + + +99 + + + +`; + +exports[`Storyshots Unread Badge themes 1`] = ` +Array [ + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + , + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + , + + + + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + , +] +`; diff --git a/android/app/build.gradle b/android/app/build.gradle index cce840546..39da119b4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -148,8 +148,8 @@ android { vectorDrawables.useSupportLibrary = true if (isPlay) { manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] + missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below! } - missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below! } signingConfigs { @@ -195,14 +195,26 @@ android { flavorDimensions "type" productFlavors { foss { + applicationId "chat.rocket.android" dimension = "type" buildConfigField "boolean", "FDROID_BUILD", "true" + resValue "string", "rn_config_reader_custom_package", "chat.rocket.reactnative" } play { dimension = "type" buildConfigField "boolean", "FDROID_BUILD", "false" } } + sourceSets { + playDebug { + java.srcDirs = ['src/main/java', 'src/play/java'] + manifest.srcFile 'src/play/AndroidManifest.xml' + } + playRelease { + java.srcDirs = ['src/main/java', 'src/play/java'] + manifest.srcFile 'src/play/AndroidManifest.xml' + } + } applicationVariants.all { variant -> variant.outputs.each { output -> @@ -233,9 +245,12 @@ android { dependencies { addUnimodulesDependencies() implementation project(':watermelondb') - implementation project(':reactnativenotifications') implementation project(":reactnativekeyboardinput") implementation project(':@react-native-community_viewpager') + playImplementation project(':reactnativenotifications') + playImplementation project(':@react-native-firebase_app') + playImplementation project(':@react-native-firebase_analytics') + playImplementation project(':@react-native-firebase_crashlytics') implementation fileTree(dir: "libs", include: ["*.jar"]) //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules diff --git a/android/app/src/foss/ic_launcher-web.png b/android/app/src/foss/ic_launcher-web.png new file mode 100644 index 000000000..ee9b88757 Binary files /dev/null and b/android/app/src/foss/ic_launcher-web.png differ diff --git a/android/app/src/foss/java/chat/rocket/reactnative/AdditionalModules.java b/android/app/src/foss/java/chat/rocket/reactnative/AdditionalModules.java new file mode 100644 index 000000000..b7f868cdc --- /dev/null +++ b/android/app/src/foss/java/chat/rocket/reactnative/AdditionalModules.java @@ -0,0 +1,14 @@ +package chat.rocket.reactnative; + +import android.app.Application; + +import com.facebook.react.ReactPackage; + +import java.util.Arrays; +import java.util.List; + +public class AdditionalModules { + public List getAdditionalModules(Application application) { + return Arrays.asList(); + } +} diff --git a/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java b/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java deleted file mode 100644 index d8c0502eb..000000000 --- a/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java +++ /dev/null @@ -1,20 +0,0 @@ -package chat.rocket.reactnative; - -import android.content.Context; -import android.os.Bundle; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.wix.reactnativenotifications.core.AppLaunchHelper; -import com.wix.reactnativenotifications.core.AppLifecycleFacade; -import com.wix.reactnativenotifications.core.JsIOHelper; -import com.wix.reactnativenotifications.core.notification.PushNotification; - -public class CustomPushNotification extends PushNotification { - public static ReactApplicationContext reactApplicationContext; - - public CustomPushNotification(Context context, Bundle bundle, AppLifecycleFacade appLifecycleFacade, AppLaunchHelper appLaunchHelper, JsIOHelper jsIoHelper) { - super(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper); - reactApplicationContext = new ReactApplicationContext(context); - } - -} diff --git a/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java b/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java deleted file mode 100644 index 48350be51..000000000 --- a/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java +++ /dev/null @@ -1,12 +0,0 @@ -package chat.rocket.reactnative; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class DismissNotification extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - - } -} diff --git a/android/app/src/foss/java/chat/rocket/reactnative/Ejson.java b/android/app/src/foss/java/chat/rocket/reactnative/Ejson.java deleted file mode 100644 index baf263260..000000000 --- a/android/app/src/foss/java/chat/rocket/reactnative/Ejson.java +++ /dev/null @@ -1,97 +0,0 @@ -package chat.rocket.reactnative; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.Callback; - -import com.ammarahmed.mmkv.SecureKeystore; -import com.tencent.mmkv.MMKV; - -import java.math.BigInteger; - -class RNCallback implements Callback { - public void invoke(Object... args) { - - } -} - -class Utils { - static public String toHex(String arg) { - try { - return String.format("%x", new BigInteger(1, arg.getBytes("UTF-8"))); - } catch (Exception e) { - return ""; - } - } -} - -public class Ejson { - String host; - String rid; - String type; - Sender sender; - String messageId; - String notificationType; - - private MMKV mmkv; - - private String TOKEN_KEY = "reactnativemeteor_usertoken-"; - - public Ejson() { - ReactApplicationContext reactApplicationContext = CustomPushNotification.reactApplicationContext; - - // Start MMKV container - MMKV.initialize(reactApplicationContext); - SecureKeystore secureKeystore = new SecureKeystore(reactApplicationContext); - - // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31 - String alias = Utils.toHex("com.MMKV.default"); - - // Retrieve container password - secureKeystore.getSecureKey(alias, new RNCallback() { - @Override - public void invoke(Object... args) { - String error = (String) args[0]; - if (error == null) { - String password = (String) args[1]; - mmkv = MMKV.mmkvWithID("default", MMKV.SINGLE_PROCESS_MODE, password); - } - } - }); - } - - public String getAvatarUri() { - if (type == null) { - return null; - } - return serverURL() + "/avatar/" + this.sender.username + "?rc_token=" + token() + "&rc_uid=" + userId(); - } - - public String token() { - String userId = userId(); - if (mmkv != null && userId != null) { - return mmkv.decodeString(TOKEN_KEY.concat(userId)); - } - return ""; - } - - public String userId() { - String serverURL = serverURL(); - if (mmkv != null && serverURL != null) { - return mmkv.decodeString(TOKEN_KEY.concat(serverURL)); - } - return ""; - } - - public String serverURL() { - String url = this.host; - if (url != null && url.endsWith("/")) { - url = url.substring(0, url.length() - 1); - } - return url; - } - - public class Sender { - String username; - String _id; - } -} \ No newline at end of file diff --git a/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java b/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java deleted file mode 100644 index 5203495b8..000000000 --- a/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java +++ /dev/null @@ -1,13 +0,0 @@ -package chat.rocket.reactnative; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class ReplyBroadcast extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - - } -} diff --git a/android/app/src/foss/res/drawable-xxhdpi/splash.png b/android/app/src/foss/res/drawable-xxhdpi/splash.png new file mode 100644 index 000000000..6fd1cbc91 Binary files /dev/null and b/android/app/src/foss/res/drawable-xxhdpi/splash.png differ diff --git a/android/app/src/foss/res/drawable/ic_launcher_background.xml b/android/app/src/foss/res/drawable/ic_launcher_background.xml index 1369c4c71..d5d367da7 100644 --- a/android/app/src/foss/res/drawable/ic_launcher_background.xml +++ b/android/app/src/foss/res/drawable/ic_launcher_background.xml @@ -3,7 +3,10 @@ android:height="108dp" android:viewportWidth="512" android:viewportHeight="512"> - + + + + diff --git a/android/app/src/foss/res/drawable/ic_launcher_foreground.xml b/android/app/src/foss/res/drawable/ic_launcher_foreground.xml index 4fb25367c..f7009c7e0 100644 --- a/android/app/src/foss/res/drawable/ic_launcher_foreground.xml +++ b/android/app/src/foss/res/drawable/ic_launcher_foreground.xml @@ -1,19 +1,24 @@ - - - - - + android:viewportWidth="731.4286" + android:viewportHeight="731.4286"> + + + + + + + + diff --git a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml index b3ee0dad1..bbd3e0212 100644 --- a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - + - + \ No newline at end of file diff --git a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml index b3ee0dad1..bbd3e0212 100644 --- a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - + - + \ No newline at end of file diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png index f1878e47b..8b836cf4a 100644 Binary files a/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png deleted file mode 100644 index 8538bed39..000000000 Binary files a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png and /dev/null differ diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png index bd72cd260..864332a8d 100644 Binary files a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png index 1e3da8a39..41e6ee164 100644 Binary files a/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png deleted file mode 100644 index a92ccfafb..000000000 Binary files a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png and /dev/null differ diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png index dfb390737..53a7f92cb 100644 Binary files a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png index ce6abf0d6..3e6741203 100644 Binary files a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png deleted file mode 100644 index 3ba37c9e9..000000000 Binary files a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png and /dev/null differ diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png index 710fac56a..576a3f64d 100644 Binary files a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png index 1ba89143e..d359e0319 100644 Binary files a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png deleted file mode 100644 index 07f6de5a9..000000000 Binary files a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png and /dev/null differ diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png index 86822fdd2..d13c3f15b 100644 Binary files a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png index 2830a1249..c0404b544 100644 Binary files a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png deleted file mode 100644 index 5ae3008fe..000000000 Binary files a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png and /dev/null differ diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png index a17913dc1..60f50d2b6 100644 Binary files a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/foss/res/values/colors.xml b/android/app/src/foss/res/values/colors.xml index 35e0dfb6d..8f2cb7421 100644 --- a/android/app/src/foss/res/values/colors.xml +++ b/android/app/src/foss/res/values/colors.xml @@ -1,6 +1,6 @@ #660B0B0B - #eeeff1 - #CC3333 - + #F5455C + #F5455C + \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f95275dfe..81171a699 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,11 +8,12 @@ - - - getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); - if (!BuildConfig.FDROID_BUILD) { - packages.add(new RNNotificationsPackage(MainApplication.this)); - } packages.add(new KeyboardInputPackage(MainApplication.this)); packages.add(new WatermelonDBPackage()); packages.add(new RNCViewPagerPackage()); - // packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider)); List unimodules = Arrays.asList( new ModuleRegistryAdapter(mModuleRegistryProvider) ); packages.addAll(unimodules); + List additionalModules = new AdditionalModules().getAdditionalModules(MainApplication.this); + packages.addAll(additionalModules); return packages; } @@ -84,15 +68,4 @@ public class MainApplication extends Application implements ReactApplication, IN super.onCreate(); SoLoader.init(this, /* native exopackage */ false); } - - @Override - public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) { - return new CustomPushNotification( - context, - bundle, - defaultFacade, - defaultAppLaunchHelper, - new JsIOHelper() - ); - } } diff --git a/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml b/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml new file mode 100644 index 000000000..a04cafb8d --- /dev/null +++ b/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable-hdpi/ic_notification.png b/android/app/src/main/res/drawable-hdpi/ic_notification.png new file mode 100644 index 000000000..c1ca2bde0 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-hdpi/logo.png b/android/app/src/main/res/drawable-hdpi/logo.png old mode 100755 new mode 100644 index 6d56e9f5d..b4d275593 Binary files a/android/app/src/main/res/drawable-hdpi/logo.png and b/android/app/src/main/res/drawable-hdpi/logo.png differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_notification.png b/android/app/src/main/res/drawable-mdpi/ic_notification.png new file mode 100644 index 000000000..dbb89065f Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-mdpi/logo.png b/android/app/src/main/res/drawable-mdpi/logo.png old mode 100755 new mode 100644 index 375dae9cc..9b3c622a0 Binary files a/android/app/src/main/res/drawable-mdpi/logo.png and b/android/app/src/main/res/drawable-mdpi/logo.png differ diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_background.xml b/android/app/src/main/res/drawable-v24/ic_launcher_background.xml deleted file mode 100644 index 6e2c4fed1..000000000 --- a/android/app/src/main/res/drawable-v24/ic_launcher_background.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - diff --git a/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/android/app/src/main/res/drawable-xhdpi/ic_notification.png new file mode 100644 index 000000000..ee3978a3f Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/logo.png b/android/app/src/main/res/drawable-xhdpi/logo.png old mode 100755 new mode 100644 index 3e85a65d2..b1d639a32 Binary files a/android/app/src/main/res/drawable-xhdpi/logo.png and b/android/app/src/main/res/drawable-xhdpi/logo.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png new file mode 100644 index 000000000..f9405b448 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/logo.png b/android/app/src/main/res/drawable-xxhdpi/logo.png old mode 100755 new mode 100644 index a13087a4e..86ef8a102 Binary files a/android/app/src/main/res/drawable-xxhdpi/logo.png and b/android/app/src/main/res/drawable-xxhdpi/logo.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/logo.png b/android/app/src/main/res/drawable-xxxhdpi/logo.png old mode 100755 new mode 100644 index 8adfb1674..c08988975 Binary files a/android/app/src/main/res/drawable-xxxhdpi/logo.png and b/android/app/src/main/res/drawable-xxxhdpi/logo.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/splash.png b/android/app/src/main/res/drawable-xxxhdpi/splash.png deleted file mode 100644 index ad69ba207..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100755 index 283cd03d7..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 22ba3f90c..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index b5e406531..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_notification.png b/android/app/src/main/res/mipmap-hdpi/ic_notification.png deleted file mode 100644 index 08b68046a..000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-ldpi/ic_launcher.png b/android/app/src/main/res/mipmap-ldpi/ic_launcher.png deleted file mode 100644 index 2fc62c96b..000000000 Binary files a/android/app/src/main/res/mipmap-ldpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-ldpi/ic_notification.png b/android/app/src/main/res/mipmap-ldpi/ic_notification.png deleted file mode 100644 index 6dfec747b..000000000 Binary files a/android/app/src/main/res/mipmap-ldpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100755 index 7058008e3..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index 63495400d..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 3296da8bc..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_notification.png b/android/app/src/main/res/mipmap-mdpi/ic_notification.png deleted file mode 100644 index 6dfec747b..000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100755 index 27fe2a7e9..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index 707e83311..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 6a05faa33..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xhdpi/ic_notification.png deleted file mode 100644 index 31ebe6059..000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100755 index 84884b9e3..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index bc656a040..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d1a0abb0e..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png deleted file mode 100644 index 556047f2e..000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100755 index 4b60c7eb8..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index 4eeb42539..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 02cec6d94..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png deleted file mode 100644 index a252c5dfd..000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png and /dev/null differ diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml index 1e24e3159..d5d36f2f5 100644 --- a/android/app/src/main/res/values-night/colors.xml +++ b/android/app/src/main/res/values-night/colors.xml @@ -1,4 +1,5 @@ #000000 + #1D74F5 \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 8ba17e337..cdcd7c53a 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ #660B0B0B - #eeeff1 - #CC3333 + #1D74F5 + #1D74F5 \ No newline at end of file diff --git a/android/app/src/play/AndroidManifest.xml b/android/app/src/play/AndroidManifest.xml index ebfb8c74d..9bbd460cb 100644 --- a/android/app/src/play/AndroidManifest.xml +++ b/android/app/src/play/AndroidManifest.xml @@ -1,49 +1,16 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/android/app/src/play/ic_launcher-web.png b/android/app/src/play/ic_launcher-web.png new file mode 100644 index 000000000..cc5e2e30b Binary files /dev/null and b/android/app/src/play/ic_launcher-web.png differ diff --git a/android/app/src/play/java/chat/rocket/reactnative/AdditionalModules.java b/android/app/src/play/java/chat/rocket/reactnative/AdditionalModules.java new file mode 100644 index 000000000..2b3dd08c9 --- /dev/null +++ b/android/app/src/play/java/chat/rocket/reactnative/AdditionalModules.java @@ -0,0 +1,24 @@ +package chat.rocket.reactnative; + +import android.app.Application; + +import com.facebook.react.ReactPackage; +import com.wix.reactnativenotifications.RNNotificationsPackage; + +import java.util.Arrays; +import java.util.List; + +import io.invertase.firebase.analytics.ReactNativeFirebaseAnalyticsPackage; +import io.invertase.firebase.app.ReactNativeFirebaseAppPackage; +import io.invertase.firebase.crashlytics.ReactNativeFirebaseCrashlyticsPackage; + +public class AdditionalModules { + public List getAdditionalModules(Application application) { + return Arrays.asList( + new ReactNativeFirebaseAnalyticsPackage(), + new ReactNativeFirebaseAppPackage(), + new ReactNativeFirebaseCrashlyticsPackage(), + new RNNotificationsPackage(application) + ); + } +} diff --git a/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java b/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java index d9b8ebf5a..23179fd60 100644 --- a/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java +++ b/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java @@ -4,39 +4,36 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.Person; import android.app.RemoteInput; -import android.content.Intent; import android.content.Context; +import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Icon; import android.os.Build; import android.os.Bundle; -import android.app.Person; import androidx.annotation.Nullable; -import com.google.gson.Gson; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; - -import java.util.concurrent.ExecutionException; -import java.lang.InterruptedException; - import com.facebook.react.bridge.ReactApplicationContext; +import com.google.gson.Gson; import com.wix.reactnativenotifications.core.AppLaunchHelper; import com.wix.reactnativenotifications.core.AppLifecycleFacade; import com.wix.reactnativenotifications.core.JsIOHelper; import com.wix.reactnativenotifications.core.notification.PushNotification; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME; @@ -187,7 +184,7 @@ public class CustomPushNotification extends PushNotification { private Bitmap largeIcon() { final Resources res = mContext.getResources(); String packageName = mContext.getPackageName(); - int largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); + int largeIconResId = res.getIdentifier("ic_notification", "drawable", packageName); Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId); return largeIconBitmap; } @@ -196,7 +193,7 @@ public class CustomPushNotification extends PushNotification { final Resources res = mContext.getResources(); String packageName = mContext.getPackageName(); - int smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName); + int smallIconResId = res.getIdentifier("ic_notification", "drawable", packageName); Gson gson = new Gson(); Ejson ejson = gson.fromJson(bundle.getString("ejson", "{}"), Ejson.class); @@ -213,9 +210,11 @@ public class CustomPushNotification extends PushNotification { String CHANNEL_ID = "rocketchatrn_channel_01"; String CHANNEL_NAME = "All"; + // User-visible importance level: Urgent - Makes a sound and appears as a heads-up notification + // https://developer.android.com/training/notify-user/channels#importance NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, - NotificationManager.IMPORTANCE_DEFAULT); + NotificationManager.IMPORTANCE_HIGH); final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); @@ -324,7 +323,7 @@ public class CustomPushNotification extends PushNotification { final Resources res = mContext.getResources(); String packageName = mContext.getPackageName(); - int smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName); + int smallIconResId = res.getIdentifier("ic_notification", "drawable", packageName); Intent replyIntent = new Intent(mContext, ReplyBroadcast.class); replyIntent.setAction(KEY_REPLY); diff --git a/android/app/src/play/java/chat/rocket/reactnative/Ejson.java b/android/app/src/play/java/chat/rocket/reactnative/Ejson.java index 0ce466349..e44c6b722 100644 --- a/android/app/src/play/java/chat/rocket/reactnative/Ejson.java +++ b/android/app/src/play/java/chat/rocket/reactnative/Ejson.java @@ -41,6 +41,10 @@ public class Ejson { public Ejson() { ReactApplicationContext reactApplicationContext = CustomPushNotification.reactApplicationContext; + if (reactApplicationContext == null) { + return; + } + // Start MMKV container MMKV.initialize(reactApplicationContext); SecureKeystore secureKeystore = new SecureKeystore(reactApplicationContext); diff --git a/android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java b/android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java index 20d1313dc..6b6ad6beb 100644 --- a/android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java +++ b/android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java @@ -57,9 +57,16 @@ public class LoadNotification { final OkHttpClient client = new OkHttpClient(); HttpUrl.Builder url = HttpUrl.parse(ejson.serverURL().concat("/api/v1/push.get")).newBuilder(); + final String userId = ejson.userId(); + final String userToken = ejson.token(); + + if (userId == null || userToken == null) { + return; + } + Request request = new Request.Builder() - .header("x-user-id", ejson.userId()) - .header("x-auth-token", ejson.token()) + .header("x-user-id", userId) + .header("x-auth-token", userToken) .url(url.addQueryParameter("id", ejson.messageId).build()) .build(); diff --git a/android/app/src/play/java/chat/rocket/reactnative/MainPlayApplication.java b/android/app/src/play/java/chat/rocket/reactnative/MainPlayApplication.java new file mode 100644 index 000000000..b78dd0ea5 --- /dev/null +++ b/android/app/src/play/java/chat/rocket/reactnative/MainPlayApplication.java @@ -0,0 +1,23 @@ +package chat.rocket.reactnative; + +import android.content.Context; +import android.os.Bundle; + +import com.wix.reactnativenotifications.core.AppLaunchHelper; +import com.wix.reactnativenotifications.core.AppLifecycleFacade; +import com.wix.reactnativenotifications.core.JsIOHelper; +import com.wix.reactnativenotifications.core.notification.INotificationsApplication; +import com.wix.reactnativenotifications.core.notification.IPushNotification; + +public class MainPlayApplication extends MainApplication implements INotificationsApplication { + @Override + public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) { + return new CustomPushNotification( + context, + bundle, + defaultFacade, + defaultAppLaunchHelper, + new JsIOHelper() + ); + } +} diff --git a/android/app/src/play/res/drawable-v24/ic_launcher_background.xml b/android/app/src/play/res/drawable-v24/ic_launcher_background.xml new file mode 100644 index 000000000..9e9d5fe99 --- /dev/null +++ b/android/app/src/play/res/drawable-v24/ic_launcher_background.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/android/app/src/play/res/drawable-xxhdpi/splash.png b/android/app/src/play/res/drawable-xxhdpi/splash.png new file mode 100644 index 000000000..23285f1ba Binary files /dev/null and b/android/app/src/play/res/drawable-xxhdpi/splash.png differ diff --git a/android/app/src/play/res/drawable/ic_launcher_foreground.xml b/android/app/src/play/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 000000000..a2b8f09ba --- /dev/null +++ b/android/app/src/play/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/play/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 68% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to android/app/src/play/res/mipmap-anydpi-v26/ic_launcher.xml index c4a603d4c..bbd3e0212 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/play/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/play/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 68% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to android/app/src/play/res/mipmap-anydpi-v26/ic_launcher_round.xml index c4a603d4c..bbd3e0212 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/play/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/android/app/src/play/res/mipmap-hdpi/ic_launcher.png b/android/app/src/play/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..d5c886a8a Binary files /dev/null and b/android/app/src/play/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/play/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/play/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..0de94dd9d Binary files /dev/null and b/android/app/src/play/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/play/res/mipmap-mdpi/ic_launcher.png b/android/app/src/play/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..2e9096323 Binary files /dev/null and b/android/app/src/play/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/play/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/play/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..bdae6c61e Binary files /dev/null and b/android/app/src/play/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/play/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/play/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..4ccdd432d Binary files /dev/null and b/android/app/src/play/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/play/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/play/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..e0c30d443 Binary files /dev/null and b/android/app/src/play/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/play/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/play/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..eeabae5da Binary files /dev/null and b/android/app/src/play/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/play/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/play/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..2c89a60a9 Binary files /dev/null and b/android/app/src/play/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..13fbc0d6b Binary files /dev/null and b/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..6bcdf733a Binary files /dev/null and b/android/app/src/play/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/build.gradle b/android/build.gradle index 13ea8c1ee..ae769e0c7 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,14 +1,25 @@ +def safeExtGet(prop, fallback) { + rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback +} + // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() + def isPlay = !taskRequests.contains("foss") + ext { buildToolsVersion = "29.0.2" - minSdkVersion = 21 + minSdkVersion = 23 compileSdkVersion = 29 targetSdkVersion = 29 glideVersion = "4.9.0" kotlin_version = "1.3.50" supportLibVersion = "28.0.0" + libre_build = !(isPlay.toBoolean()) + jitsi_url = isPlay ? "https://github.com/RocketChat/jitsi-maven-repository/raw/master/releases" : "https://github.com/RocketChat/jitsi-maven-repository/raw/libre/releases" + jitsi_version = isPlay ? "+" : "2.10.0-libre" } + repositories { mavenLocal() google() @@ -18,9 +29,6 @@ buildscript { } } - def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() - def isPlay = !taskRequests.contains("foss") - dependencies { if (isPlay) { classpath 'com.google.gms:google-services:4.2.0' @@ -44,7 +52,7 @@ allprojects { url("$rootDir/../node_modules/jsc-android/dist") } maven { - url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases" + url safeExtGet("jitsi_url", "https://github.com/RocketChat/jitsi-maven-repository/raw/master/releases") } google() diff --git a/android/gradle.properties b/android/gradle.properties index 459ae3568..1fefdcd0c 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -26,7 +26,7 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true APPLICATIONID=chat.rocket.reactnative -VERSIONNAME=4.11.0 +VERSIONNAME=4.12.0 VERSIONCODE=1 BugsnagAPIKey= KEYSTORE=my-upload-key.keystore diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7578b974b..070cf7caf 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index 26f8adaaf..ed2f78c10 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -10,5 +10,11 @@ include ':reactnativekeyboardinput' project(':reactnativekeyboardinput').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keyboard-input/lib/android') include ':@react-native-community_viewpager' project(':@react-native-community_viewpager').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/viewpager/android') +include ':@react-native-firebase_app' +project(':@react-native-firebase_app').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/app/android') +include ':@react-native-firebase_analytics' +project(':@react-native-firebase_analytics').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/analytics/android') +include ':@react-native-firebase_crashlytics' +project(':@react-native-firebase_crashlytics').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/crashlytics/android') apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 4e5f9443e..e27a3d11e 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -18,6 +18,7 @@ export const LOGIN = createRequestTypes('LOGIN', [ export const SHARE = createRequestTypes('SHARE', [ 'SELECT_SERVER', 'SET_USER', + 'SET_SETTINGS', 'SET_SERVER_INFO' ]); export const USER = createRequestTypes('USER', ['SET']); diff --git a/app/actions/share.js b/app/actions/share.js index 56e8ced9b..ff4d5a592 100644 --- a/app/actions/share.js +++ b/app/actions/share.js @@ -7,6 +7,13 @@ export function shareSelectServer(server) { }; } +export function shareSetSettings(settings) { + return { + type: SHARE.SET_SETTINGS, + settings + }; +} + export function shareSetUser(user) { return { type: SHARE.SET_USER, diff --git a/app/constants/colors.js b/app/constants/colors.js index f3ad72dc4..6a2e33f38 100644 --- a/app/constants/colors.js +++ b/app/constants/colors.js @@ -11,13 +11,13 @@ export const SWITCH_TRACK_COLOR = { }; const mentions = { - unreadBackground: '#414852', - mentionMeColor: '#f5455c', - mentionMeBackground: '#ffe9ec', - mentionGroupColor: '#f38c39', - mentionGroupBackground: '#fde8d7', - mentionOtherColor: '#b68d00', - mentionOtherBackground: '#fff6d6' + unreadBackground: '#6C727A', + tunreadBackground: '#1d74f5', + mentionMeColor: '#DB0C27', + mentionMeBackground: '#F5455C', + mentionGroupColor: '#E26D0E', + mentionGroupBackground: '#F38C39', + mentionOtherColor: '#DFAC00' }; export const themes = { @@ -37,7 +37,7 @@ export const themes = { auxiliaryText: '#9ca2a8', infoText: '#6d6d72', tintColor: '#1d74f5', - auxiliaryTintColor: '#caced1', + auxiliaryTintColor: '#6C727A', actionTintColor: '#1d74f5', separatorColor: '#cbcbcc', navbarBackground: '#ffffff', @@ -82,7 +82,7 @@ export const themes = { auxiliaryText: '#9297a2', infoText: '#6D6D72', tintColor: '#1d74f5', - auxiliaryTintColor: '#cdcdcd', + auxiliaryTintColor: '#f9f9f9', actionTintColor: '#1d74f5', separatorColor: '#2b2b2d', navbarBackground: '#0b182c', @@ -127,7 +127,7 @@ export const themes = { auxiliaryText: '#b2b8c6', infoText: '#6d6d72', tintColor: '#1e9bfe', - auxiliaryTintColor: '#cdcdcd', + auxiliaryTintColor: '#f9f9f9', actionTintColor: '#1e9bfe', separatorColor: '#272728', navbarBackground: '#0d0d0d', diff --git a/app/constants/settings.js b/app/constants/settings.js index ccb1803e2..359dff092 100644 --- a/app/constants/settings.js +++ b/app/constants/settings.js @@ -20,6 +20,9 @@ export default { Accounts_AllowUsernameChange: { type: 'valueAsBoolean' }, + Accounts_AvatarBlockUnauthenticatedAccess: { + type: 'valueAsBoolean' + }, Accounts_CustomFields: { type: 'valueAsString' }, diff --git a/app/containers/ActionSheet/ActionSheet.js b/app/containers/ActionSheet/ActionSheet.js index f7c009368..81b3496ae 100644 --- a/app/containers/ActionSheet/ActionSheet.js +++ b/app/containers/ActionSheet/ActionSheet.js @@ -27,7 +27,7 @@ import { Button } from './Button'; import { themes } from '../../constants/colors'; import styles, { ITEM_HEIGHT } from './styles'; import { isTablet, isIOS } from '../../utils/deviceInfo'; -import Separator from '../Separator'; +import * as List from '../List'; import I18n from '../../i18n'; import { useOrientation, useDimensions } from '../../dimensions'; @@ -142,8 +142,6 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => { ) : null)); - const renderSeparator = useCallback(() => ); - const renderItem = useCallback(({ item }) => ); const animatedPosition = React.useRef(new Value(0)); @@ -191,8 +189,8 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => { keyExtractor={item => item.title} style={{ backgroundColor: themes[theme].focusedBackground }} contentContainerStyle={styles.content} - ItemSeparatorComponent={renderSeparator} - ListHeaderComponent={renderSeparator} + ItemSeparatorComponent={List.Separator} + ListHeaderComponent={List.Separator} ListFooterComponent={renderFooter} getItemLayout={getItemLayout} removeClippedSubviews={isIOS} diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js deleted file mode 100644 index c4ed0ba7c..000000000 --- a/app/containers/Avatar.js +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { View } from 'react-native'; -import FastImage from '@rocket.chat/react-native-fast-image'; -import Touchable from 'react-native-platform-touchable'; -import { settings as RocketChatSettings } from '@rocket.chat/sdk'; - -import { avatarURL } from '../utils/avatar'; -import Emoji from './markdown/Emoji'; - -const Avatar = React.memo(({ - text, size, baseUrl, borderRadius, style, avatar, type, children, userId, token, onPress, theme, emoji, getCustomEmoji -}) => { - const avatarStyle = { - width: size, - height: size, - borderRadius - }; - - if (!text && !avatar) { - return null; - } - - const uri = avatarURL({ - type, text, size, userId, token, avatar, baseUrl - }); - - let image = emoji ? ( - - ) : ( - - ); - - if (onPress) { - image = ( - - {image} - - ); - } - - return ( - - {image} - {children} - - ); -}); - -Avatar.propTypes = { - baseUrl: PropTypes.string.isRequired, - style: PropTypes.any, - text: PropTypes.string, - avatar: PropTypes.string, - emoji: PropTypes.string, - size: PropTypes.number, - borderRadius: PropTypes.number, - type: PropTypes.string, - children: PropTypes.object, - userId: PropTypes.string, - token: PropTypes.string, - theme: PropTypes.string, - onPress: PropTypes.func, - getCustomEmoji: PropTypes.func -}; - -Avatar.defaultProps = { - text: '', - size: 25, - type: 'd', - borderRadius: 4 -}; - -export default Avatar; diff --git a/app/containers/Avatar/Avatar.js b/app/containers/Avatar/Avatar.js new file mode 100644 index 000000000..0b898a3c8 --- /dev/null +++ b/app/containers/Avatar/Avatar.js @@ -0,0 +1,130 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { View } from 'react-native'; +import FastImage from '@rocket.chat/react-native-fast-image'; +import Touchable from 'react-native-platform-touchable'; +import { settings as RocketChatSettings } from '@rocket.chat/sdk'; + +import { avatarURL } from '../../utils/avatar'; +import Emoji from '../markdown/Emoji'; + +const Avatar = React.memo(({ + text, + size, + server, + borderRadius, + style, + avatar, + type, + children, + user, + onPress, + emoji, + theme, + getCustomEmoji, + avatarETag, + isStatic, + rid, + blockUnauthenticatedAccess, + serverVersion +}) => { + if ((!text && !avatar && !emoji && !rid) || !server) { + return null; + } + + const avatarStyle = { + width: size, + height: size, + borderRadius + }; + + let image; + if (emoji) { + image = ( + + ); + } else { + let uri = avatar; + if (!isStatic) { + uri = avatarURL({ + type, + text, + size, + user, + avatar, + server, + avatarETag, + serverVersion, + rid, + blockUnauthenticatedAccess + }); + } + + image = ( + + ); + } + + if (onPress) { + image = ( + + {image} + + ); + } + + + return ( + + {image} + {children} + + ); +}); + +Avatar.propTypes = { + server: PropTypes.string, + style: PropTypes.any, + text: PropTypes.string, + avatar: PropTypes.string, + emoji: PropTypes.string, + size: PropTypes.number, + borderRadius: PropTypes.number, + type: PropTypes.string, + children: PropTypes.object, + user: PropTypes.shape({ + id: PropTypes.string, + token: PropTypes.string + }), + theme: PropTypes.string, + onPress: PropTypes.func, + getCustomEmoji: PropTypes.func, + avatarETag: PropTypes.string, + isStatic: PropTypes.bool, + rid: PropTypes.string, + blockUnauthenticatedAccess: PropTypes.bool, + serverVersion: PropTypes.string +}; + +Avatar.defaultProps = { + text: '', + size: 25, + type: 'd', + borderRadius: 4 +}; + +export default Avatar; diff --git a/app/containers/Avatar/index.js b/app/containers/Avatar/index.js new file mode 100644 index 000000000..73314a17d --- /dev/null +++ b/app/containers/Avatar/index.js @@ -0,0 +1,107 @@ +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'; +import Avatar from './Avatar'; + +class AvatarContainer extends React.Component { + static propTypes = { + rid: PropTypes.string, + text: PropTypes.string, + type: PropTypes.string, + blockUnauthenticatedAccess: PropTypes.bool, + serverVersion: PropTypes.string + }; + + static defaultProps = { + text: '', + type: 'd' + }; + + constructor(props) { + super(props); + this.mounted = false; + this.state = { avatarETag: '' }; + this.init(); + } + + componentDidMount() { + this.mounted = true; + } + + componentDidUpdate(prevProps) { + if (!isEqual(prevProps, this.props)) { + this.init(); + } + } + + componentWillUnmount() { + if (this.subscription?.unsubscribe) { + this.subscription.unsubscribe(); + } + } + + get isDirect() { + const { type } = this.props; + return type === 'd'; + } + + init = async() => { + const db = database.active; + const usersCollection = db.collections.get('users'); + const subsCollection = db.collections.get('subscriptions'); + + let record; + try { + if (this.isDirect) { + const { text } = this.props; + const [user] = await usersCollection.query(Q.where('username', text)).fetch(); + record = user; + } else { + const { rid } = this.props; + record = await subsCollection.find(rid); + } + } catch { + // Record not found + } + + if (record) { + const observable = record.observe(); + this.subscription = observable.subscribe((r) => { + const { avatarETag } = r; + if (this.mounted) { + this.setState({ avatarETag }); + } else { + this.state.avatarETag = avatarETag; + } + }); + } + } + + render() { + const { avatarETag } = this.state; + const { serverVersion } = this.props; + return ( + + ); + } +} + +const mapStateToProps = state => ({ + user: getUserSelector(state), + server: state.share.server.server || state.server.server, + serverVersion: state.share.server.version || state.server.version, + blockUnauthenticatedAccess: + state.share.settings?.Accounts_AvatarBlockUnauthenticatedAccess + ?? state.settings.Accounts_AvatarBlockUnauthenticatedAccess + ?? true +}); +export default connect(mapStateToProps)(AvatarContainer); diff --git a/app/containers/Button/index.js b/app/containers/Button/index.js index 0f573f876..ccc847b39 100644 --- a/app/containers/Button/index.js +++ b/app/containers/Button/index.js @@ -82,6 +82,7 @@ export default class Button extends React.PureComponent { { color: textColor }, fontSize && { fontSize } ]} + accessibilityLabel={title} > {title} diff --git a/app/containers/DisclosureIndicator.js b/app/containers/DisclosureIndicator.js deleted file mode 100644 index e33dbe816..000000000 --- a/app/containers/DisclosureIndicator.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { View, StyleSheet } from 'react-native'; -import PropTypes from 'prop-types'; - -import { themes } from '../constants/colors'; -import { CustomIcon } from '../lib/Icons'; - -const styles = StyleSheet.create({ - disclosureContainer: { - marginLeft: 6, - marginRight: 9, - alignItems: 'center', - justifyContent: 'center' - } -}); - -export const DisclosureImage = React.memo(({ theme }) => ( - -)); -DisclosureImage.propTypes = { - theme: PropTypes.string -}; - -const DisclosureIndicator = React.memo(({ theme }) => ( - - - -)); -DisclosureIndicator.propTypes = { - theme: PropTypes.string -}; - -export default DisclosureIndicator; diff --git a/app/containers/FormContainer.js b/app/containers/FormContainer.js index 46a550546..ac58502c7 100644 --- a/app/containers/FormContainer.js +++ b/app/containers/FormContainer.js @@ -31,14 +31,14 @@ const FormContainer = ({ contentContainerStyle={sharedStyles.container} keyboardVerticalOffset={128} > - + - + {children} diff --git a/app/containers/Header/index.js b/app/containers/Header/index.js index 2137a71ad..ca734c6ed 100644 --- a/app/containers/Header/index.js +++ b/app/containers/Header/index.js @@ -5,6 +5,7 @@ import { View, StyleSheet } from 'react-native'; import { themes } from '../../constants/colors'; import { themedHeader } from '../../utils/navigation'; import { isIOS, isTablet } from '../../utils/deviceInfo'; +import { withTheme } from '../../theme'; // Get from https://github.com/react-navigation/react-navigation/blob/master/packages/stack/src/views/Header/HeaderSegment.tsx#L69 export const headerHeight = isIOS ? 44 : 56; @@ -20,9 +21,9 @@ export const getHeaderHeight = (isLandscape) => { return 56; }; -export const getHeaderTitlePosition = insets => ({ - left: 60 + insets.left, - right: 80 + insets.right +export const getHeaderTitlePosition = ({ insets, numIconsRight }) => ({ + left: insets.left + 60, + right: insets.right + (45 * numIconsRight) }); const styles = StyleSheet.create({ @@ -53,4 +54,4 @@ Header.propTypes = { headerRight: PropTypes.element }; -export default Header; +export default withTheme(Header); diff --git a/app/containers/HeaderButton.js b/app/containers/HeaderButton.js deleted file mode 100644 index 4dc72f8cc..000000000 --- a/app/containers/HeaderButton.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { HeaderButtons, HeaderButton, Item } from 'react-navigation-header-buttons'; - -import { CustomIcon } from '../lib/Icons'; -import { isIOS } from '../utils/deviceInfo'; -import { themes } from '../constants/colors'; -import I18n from '../i18n'; -import { withTheme } from '../theme'; - -export const headerIconSize = 23; - -const CustomHeaderButton = React.memo(withTheme(({ theme, ...props }) => ( - -))); - -export const CustomHeaderButtons = React.memo(props => ( - -)); - -export const DrawerButton = React.memo(({ navigation, testID, ...otherProps }) => ( - - - -)); - -export const CloseModalButton = React.memo(({ - navigation, testID, onPress = () => navigation.pop(), ...props -}) => ( - - - -)); - -export const CancelModalButton = React.memo(({ onPress, testID }) => ( - - {isIOS - ? - : - } - -)); - -export const MoreButton = React.memo(({ onPress, testID }) => ( - - - -)); - -export const SaveButton = React.memo(({ onPress, testID, ...props }) => ( - - - -)); - -export const PreferencesButton = React.memo(({ onPress, testID, ...props }) => ( - - - -)); - -export const LegalButton = React.memo(({ navigation, testID }) => ( - navigation.navigate('LegalView')} testID={testID} /> -)); - -CustomHeaderButton.propTypes = { - theme: PropTypes.string -}; -DrawerButton.propTypes = { - navigation: PropTypes.object.isRequired, - testID: PropTypes.string.isRequired -}; -CloseModalButton.propTypes = { - navigation: PropTypes.object.isRequired, - testID: PropTypes.string.isRequired, - onPress: PropTypes.func -}; -CancelModalButton.propTypes = { - onPress: PropTypes.func.isRequired, - testID: PropTypes.string.isRequired -}; -MoreButton.propTypes = { - onPress: PropTypes.func.isRequired, - testID: PropTypes.string.isRequired -}; -SaveButton.propTypes = { - onPress: PropTypes.func.isRequired, - testID: PropTypes.string.isRequired -}; -PreferencesButton.propTypes = { - onPress: PropTypes.func.isRequired, - testID: PropTypes.string.isRequired -}; -LegalButton.propTypes = { - navigation: PropTypes.object.isRequired, - testID: PropTypes.string.isRequired -}; - -export { Item }; diff --git a/app/containers/HeaderButton/Common.js b/app/containers/HeaderButton/Common.js new file mode 100644 index 000000000..a1d55bd4e --- /dev/null +++ b/app/containers/HeaderButton/Common.js @@ -0,0 +1,84 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { isIOS } from '../../utils/deviceInfo'; +import I18n from '../../i18n'; +import Container from './HeaderButtonContainer'; +import Item from './HeaderButtonItem'; + +// Left +export const Drawer = React.memo(({ navigation, testID, ...props }) => ( + + navigation.toggleDrawer()} testID={testID} {...props} /> + +)); + +export const CloseModal = React.memo(({ + navigation, testID, onPress = () => navigation.pop(), ...props +}) => ( + + + +)); + +export const CancelModal = React.memo(({ onPress, testID }) => ( + + {isIOS + ? + : + } + +)); + +// Right +export const More = React.memo(({ onPress, testID }) => ( + + + +)); + +export const Download = React.memo(({ onPress, testID, ...props }) => ( + + + +)); + +export const Preferences = React.memo(({ onPress, testID, ...props }) => ( + + + +)); + +export const Legal = React.memo(({ navigation, testID }) => ( + navigation.navigate('LegalView')} testID={testID} /> +)); + +Drawer.propTypes = { + navigation: PropTypes.object.isRequired, + testID: PropTypes.string.isRequired +}; +CloseModal.propTypes = { + navigation: PropTypes.object.isRequired, + testID: PropTypes.string.isRequired, + onPress: PropTypes.func +}; +CancelModal.propTypes = { + onPress: PropTypes.func.isRequired, + testID: PropTypes.string.isRequired +}; +More.propTypes = { + onPress: PropTypes.func.isRequired, + testID: PropTypes.string.isRequired +}; +Download.propTypes = { + onPress: PropTypes.func.isRequired, + testID: PropTypes.string.isRequired +}; +Preferences.propTypes = { + onPress: PropTypes.func.isRequired, + testID: PropTypes.string.isRequired +}; +Legal.propTypes = { + navigation: PropTypes.object.isRequired, + testID: PropTypes.string.isRequired +}; diff --git a/app/containers/HeaderButton/HeaderButtonContainer.js b/app/containers/HeaderButton/HeaderButtonContainer.js new file mode 100644 index 000000000..1521faa95 --- /dev/null +++ b/app/containers/HeaderButton/HeaderButtonContainer.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { View, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center' + }, + left: { + marginLeft: 5 + }, + right: { + marginRight: 5 + } +}); + +const Container = ({ children, left }) => ( + + {children} + +); + +Container.propTypes = { + children: PropTypes.arrayOf(PropTypes.element), + left: PropTypes.bool +}; + +Container.defaultProps = { + left: false +}; + +Container.displayName = 'HeaderButton.Container'; + +export default Container; diff --git a/app/containers/HeaderButton/HeaderButtonItem.js b/app/containers/HeaderButton/HeaderButtonItem.js new file mode 100644 index 000000000..5e9bb8631 --- /dev/null +++ b/app/containers/HeaderButton/HeaderButtonItem.js @@ -0,0 +1,58 @@ +import React from 'react'; +import { Text, StyleSheet, Platform } from 'react-native'; +import PropTypes from 'prop-types'; +import Touchable from 'react-native-platform-touchable'; + +import { CustomIcon } from '../../lib/Icons'; +import { withTheme } from '../../theme'; +import { themes } from '../../constants/colors'; +import sharedStyles from '../../views/Styles'; + +export const BUTTON_HIT_SLOP = { + top: 5, right: 5, bottom: 5, left: 5 +}; + +const styles = StyleSheet.create({ + container: { + marginHorizontal: 6 + }, + title: { + ...Platform.select({ + android: { + fontSize: 14 + }, + default: { + fontSize: 17 + } + }), + ...sharedStyles.textRegular + } +}); + +const Item = ({ + title, iconName, onPress, testID, theme, badge +}) => ( + + <> + { + iconName + ? + : {title} + } + {badge ? badge() : null} + + +); + +Item.propTypes = { + onPress: PropTypes.func.isRequired, + title: PropTypes.string, + iconName: PropTypes.string, + testID: PropTypes.string, + theme: PropTypes.string, + badge: PropTypes.func +}; + +Item.displayName = 'HeaderButton.Item'; + +export default withTheme(Item); diff --git a/app/containers/HeaderButton/HeaderButtonItemBadge.js b/app/containers/HeaderButton/HeaderButtonItemBadge.js new file mode 100644 index 000000000..9a760b828 --- /dev/null +++ b/app/containers/HeaderButton/HeaderButtonItemBadge.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { StyleSheet } from 'react-native'; + +import UnreadBadge from '../../presentation/UnreadBadge'; + +const styles = StyleSheet.create({ + badgeContainer: { + padding: 2, + position: 'absolute', + right: -3, + top: -3, + borderRadius: 10, + alignItems: 'center', + justifyContent: 'center' + } +}); + +export const Badge = ({ ...props }) => ( + +); + +export default Badge; diff --git a/app/containers/HeaderButton/index.js b/app/containers/HeaderButton/index.js new file mode 100644 index 000000000..d1d66baaf --- /dev/null +++ b/app/containers/HeaderButton/index.js @@ -0,0 +1,4 @@ +export { default as Container } from './HeaderButtonContainer'; +export { default as Item } from './HeaderButtonItem'; +export { default as Badge } from './HeaderButtonItemBadge'; +export * from './Common'; diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index be0896c7a..b69704359 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -11,7 +11,6 @@ import { CustomIcon } from '../../lib/Icons'; import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; import { useTheme } from '../../theme'; -import { getUserSelector } from '../../selectors/login'; import { ROW_HEIGHT } from '../../presentation/RoomItem'; import { goRoom } from '../../utils/goRoom'; import Navigation from '../../lib/Navigation'; @@ -65,22 +64,19 @@ const styles = StyleSheet.create({ const hideNotification = () => Notifier.hideNotification(); -const NotifierComponent = React.memo(({ - baseUrl, user, notification, isMasterDetail -}) => { +const NotifierComponent = React.memo(({ notification, isMasterDetail }) => { const { theme } = useTheme(); const insets = useSafeAreaInsets(); const { isLandscape } = useOrientation(); - const { id: userId, token } = user; const { text, payload } = notification; - const { type } = payload; + const { type, rid } = payload; const name = type === 'd' ? payload.sender.username : payload.name; // if sub is not on local database, title and avatar will be null, so we use payload from notification const { title = name, avatar = name } = notification; const onPress = () => { - const { rid, prid } = payload; + const { prid } = payload; if (!rid) { return; } @@ -115,7 +111,7 @@ const NotifierComponent = React.memo(({ background={Touchable.SelectableBackgroundBorderless()} > <> - + {title} {text} @@ -134,15 +130,11 @@ const NotifierComponent = React.memo(({ }); NotifierComponent.propTypes = { - baseUrl: PropTypes.string, - user: PropTypes.object, notification: PropTypes.object, isMasterDetail: PropTypes.bool }; const mapStateToProps = state => ({ - user: getUserSelector(state), - baseUrl: state.server.server, isMasterDetail: state.app.isMasterDetail }); diff --git a/app/containers/ItemInfo.js b/app/containers/ItemInfo.js deleted file mode 100644 index c7d541e64..000000000 --- a/app/containers/ItemInfo.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import { View, Text, StyleSheet } from 'react-native'; -import PropTypes from 'prop-types'; - -import sharedStyles from '../views/Styles'; -import { themes } from '../constants/colors'; - -const styles = StyleSheet.create({ - infoContainer: { - padding: 15 - }, - infoText: { - fontSize: 14, - ...sharedStyles.textRegular - } -}); - -const ItemInfo = React.memo(({ info, theme }) => ( - - {info} - -)); - -ItemInfo.propTypes = { - info: PropTypes.string, - theme: PropTypes.string -}; - -export default ItemInfo; diff --git a/app/containers/List/ListContainer.js b/app/containers/List/ListContainer.js new file mode 100644 index 000000000..f1be3705a --- /dev/null +++ b/app/containers/List/ListContainer.js @@ -0,0 +1,30 @@ +import React from 'react'; +import { ScrollView, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; +import { withTheme } from '../../theme'; +import scrollPersistTaps from '../../utils/scrollPersistTaps'; + +const styles = StyleSheet.create({ + container: { + paddingVertical: 16 + } +}); + +const ListContainer = React.memo(({ children, ...props }) => ( + + {children} + +)); + +ListContainer.propTypes = { + children: PropTypes.array.isRequired +}; + +ListContainer.displayName = 'List.Container'; + +export default withTheme(ListContainer); diff --git a/app/containers/List/ListHeader.js b/app/containers/List/ListHeader.js new file mode 100644 index 000000000..1166e25bd --- /dev/null +++ b/app/containers/List/ListHeader.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; + +import sharedStyles from '../../views/Styles'; +import { themes } from '../../constants/colors'; +import I18n from '../../i18n'; +import { withTheme } from '../../theme'; +import { PADDING_HORIZONTAL } from './constants'; + +const styles = StyleSheet.create({ + container: { + paddingBottom: 12, + paddingHorizontal: PADDING_HORIZONTAL + }, + title: { + fontSize: 16, + ...sharedStyles.textRegular + } +}); + +const ListHeader = React.memo(({ title, theme, translateTitle }) => ( + + {translateTitle ? I18n.t(title) : title} + +)); + +ListHeader.propTypes = { + title: PropTypes.string, + theme: PropTypes.string, + translateTitle: PropTypes.bool +}; + +ListHeader.defaultProps = { + translateTitle: true +}; + +ListHeader.displayName = 'List.Header'; + +export default withTheme(ListHeader); diff --git a/app/containers/List/ListIcon.js b/app/containers/List/ListIcon.js new file mode 100644 index 000000000..1a1b3164c --- /dev/null +++ b/app/containers/List/ListIcon.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { View, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; + +import { themes } from '../../constants/colors'; +import { CustomIcon } from '../../lib/Icons'; +import { withTheme } from '../../theme'; + +const styles = StyleSheet.create({ + icon: { + alignItems: 'center', + justifyContent: 'center' + } +}); + +const ListIcon = React.memo(({ theme, name, color }) => ( + + + +)); + +ListIcon.propTypes = { + theme: PropTypes.string, + name: PropTypes.string, + color: PropTypes.string +}; + +ListIcon.displayName = 'List.Icon'; + +export default withTheme(ListIcon); diff --git a/app/containers/List/ListInfo.js b/app/containers/List/ListInfo.js new file mode 100644 index 000000000..e0cb9eae7 --- /dev/null +++ b/app/containers/List/ListInfo.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; + +import sharedStyles from '../../views/Styles'; +import { themes } from '../../constants/colors'; +import { withTheme } from '../../theme'; +import { PADDING_HORIZONTAL } from './constants'; +import I18n from '../../i18n'; + +const styles = StyleSheet.create({ + container: { + paddingTop: 8, + paddingHorizontal: PADDING_HORIZONTAL + }, + text: { + fontSize: 14, + ...sharedStyles.textRegular + } +}); + +const ListInfo = React.memo(({ info, translateInfo, theme }) => ( + + {translateInfo ? I18n.t(info) : info} + +)); + +ListInfo.propTypes = { + info: PropTypes.string, + theme: PropTypes.string, + translateInfo: PropTypes.bool +}; + +ListInfo.defaultProps = { + translateInfo: true +}; + +ListInfo.displayName = 'List.Info'; + +export default withTheme(ListInfo); diff --git a/app/containers/List/ListItem.js b/app/containers/List/ListItem.js new file mode 100644 index 000000000..0dcf2a6d7 --- /dev/null +++ b/app/containers/List/ListItem.js @@ -0,0 +1,137 @@ +import React from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import PropTypes from 'prop-types'; + +import Touch from '../../utils/touch'; +import { themes } from '../../constants/colors'; +import sharedStyles from '../../views/Styles'; +import { withTheme } from '../../theme'; +import I18n from '../../i18n'; +import { Icon } from '.'; +import { BASE_HEIGHT, PADDING_HORIZONTAL } from './constants'; +import { withDimensions } from '../../dimensions'; + +const styles = StyleSheet.create({ + container: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + paddingHorizontal: PADDING_HORIZONTAL + }, + leftContainer: { + paddingRight: PADDING_HORIZONTAL + }, + rightContainer: { + paddingLeft: PADDING_HORIZONTAL + }, + disabled: { + opacity: 0.3 + }, + textContainer: { + flex: 1, + justifyContent: 'center' + }, + title: { + fontSize: 16, + ...sharedStyles.textRegular + }, + subtitle: { + fontSize: 14, + ...sharedStyles.textRegular + } +}); + +const Content = React.memo(({ + title, subtitle, disabled, testID, left, right, color, theme, translateTitle, translateSubtitle, showActionIndicator, fontScale +}) => ( + + {left + ? ( + + {left()} + + ) + : null} + + {translateTitle ? I18n.t(title) : title} + {subtitle + ? {translateSubtitle ? I18n.t(subtitle) : subtitle} + : null + } + + {right || showActionIndicator + ? ( + + {right ? right() : null} + {showActionIndicator ? : null} + + ) + : null} + +)); + +const Button = React.memo(({ + onPress, ...props +}) => ( + onPress(props.title)} + style={{ backgroundColor: themes[props.theme].backgroundColor }} + enabled={!props.disabled} + theme={props.theme} + > + + +)); + +const ListItem = React.memo(({ ...props }) => { + if (props.onPress) { + return