[RELEASE] Merge beta into master (#1082)
* Bump version to 1.16.0 (#1014) * [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982) * ✨ Create user table * ✨ Introduce user table * 🔥 Remove unused table * ➕ Add userdefaults to storage data * 💚 Fix android build * ✨ Get credentials from iOS native client * 🔥 Remove unused code * ⏪ Revert sign xcode * 🐛 Fix first login-logout * 🎨 Use constants to UserDefaults Keys * 🐛 Fix clear server-user-info on logout * 🐛 Fix filter null value * 🚑 Remove user object in logout * ✨ Fix get servers from native-client * 🚑 Fix error on change server * [FIX] Don't run UserDefaults credentials on Android (#1015) * 🐛 Fix native credentials (android) * Fix migration loop * [IMPROVEMENT] Hide frequently used emoji tab when empty (#792) * [IMPROVEMENT] Bigger emoji in emoji only messages (#793) * issue #725: bigger emoji in emoji only message * issue-725/add storybook for Message/Emoji * issue-725: update storybook/Message jest snapshot * comment storybook import * allow spaces and line breaks in emoji only message * merge develop * revert unnecessary spacing * [FIX] Empty message if contains only a link (#787) * Fix empty message if contains only a link * 🐛 Fix empty space * [IMPROVEMENT] Refactor empty space regex on quote (#1017) * 🎨 Improve regex to empty space on quote * 🎨 Improve on regex to empty space on quote * [NEW] Custom fields on signup (#1013) * added custom feilds on registration * added flag as leftIcon and removed lable * added try and catch * typo * [CHORE] Renew provisioning profiles (#1020) * [NEW] Auto-translate (#1012) * Update realm * View original and translate working * Read AutoTranslate_Enabled setting * RocketChat.canAutoTranslate() * AutoTranslateView * Save language * Auto-translate switch * Translate message * [IMPROVEMENT] Use haptics rather than vibration (#1016) * Install expo-haptics * Use expo-haptics rather than RN's Vibration module * [IMPROVEMENT] Use Rest API for file upload (#1005) * removed rn-fetch-blob and use native XMLHttpRequest instead * removed unnessary changes * fix android bug * fix android bug * added tmid support * fix bug * fixed isssue with cacel model * fix problems with audio * done requested changes * fix bug with android * [CHORE] [CI] [TESTS] update detox to make ci pass (#1026) * feat: update detox to 12.11.3 to make CI pass * ci: comment all jobs but leave e2e-test job * commit to rerun IC e2e-test job * ci: uncomment all CI jobs * [NEW] Room swipe actions: mark as read/unread, hide, fav (#976) * added unread and fav feature * changed the layout * fix jest * done requested changes * added requested changes * [FIX] Android build (#1027) * [FIX] Android build * CircleCI error * [FIX] iOS share credentials build (#1028) * [FIX] iOS share credentials build * Use `hasMigration` as a string * [CI] Restore cache on CI (#1029) * feat: add fastlane save\restore cache config; comment not needed jobs; * install fastlane using 'bundle install' * install fastlane using 'sudo bundle install' * uncomment ios build commands * run set up google services in ios folder * add working_directory: ios to ios-build steps * remove 'cd ios' from Fastlane build step * add save\restore cache for npm modules * group save_cache steps * cache fastlane in ios-testflight job * uncomment previously commented jobs\steps * fix: add missing colon * use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }} * add names for save\restore steps * ci: add `default` step with `working_directory: ~/repo` to ios-build job * return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}` * fix: add missing curly braces * save\restore cache in e2e-test job; remove {{arch}} from cache names * add names to restore_cache steps in android-build job * add names to save_cache steps in android-build job * add names to all save\restore steps; change checksum package.json to yarn.lock * change `npm` to `NPM` in steps naming * remove {{ checksum circle ci }} from android-build job and fix naming of steps * [FIX] Rooms swipes (#1034) * Regression: on press style feedback * Action button styles * Fix animations * Styles changed * Update subscription without having to wait for socket * Calculate width on RoomsListView instead * [FIX] Decrease bigger emoji size to 30 (#1031) * [FIX] Append server URL on avatar if necessary (#1038) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Bump version to 1.16.1 (#1045) * [FIX] Set UserDefaults AppGroup on notification tap (#1047) * [FIX] Auto-translate messages as they arrive * Fix favorite button * [FIX] Swipe animations (#1044) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Fix favorite button * [FIX] Auto-translate messages as they arrive (#1049) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * [FIX] Auto-translate messages as they arrive * [i18n] Add missing de translations (#1040) * [CHORE] Switch to react-native-localize (#1043) * Bump version to 1.17.0 (#1057) * Load views as needed (#1056) * [IMPROVEMENT] Change "resend" icon position (#1048) * [NEW] Video support (#801) * [NEW] File upload (#882) * [NEW] Share extension (#942) * [FIX] Share extension CI build (#1060) * Change bundleID * Provisioning * get provisioning profile * [IMPROVEMENT] Reusable toast (#1065) * [FIX] Moment locales (#1066) * [FIX] Share Extension issues (#1064) * [FIX] Empty white list enables all media types upload (#1077) * Merge branch 'master' into develop (#1079) * [FIX] Empty white list enables all media types upload (#1080) * Create utils to media (canUpload) * Fix variable name * [CHORE] Update README (#1081)
This commit is contained in:
parent
8ea6f1647e
commit
2d58a8b983
54
README.md
54
README.md
|
@ -1,13 +1,11 @@
|
|||
# Rocket.Chat React Native Mobile
|
||||
|
||||
[![Greenkeeper badge](https://badges.greenkeeper.io/RocketChat/Rocket.Chat.ReactNative.svg)](https://greenkeeper.io/)
|
||||
[![Build Status](https://img.shields.io/travis/RocketChat/Rocket.Chat.ReactNative/master.svg)](https://travis-ci.org/RocketChat/Rocket.Chat.ReactNative)
|
||||
[![Project Dependencies](https://david-dm.org/RocketChat/Rocket.Chat.ReactNative.svg)](https://david-dm.org/RocketChat/Rocket.Chat.ReactNative)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/bb15e2392a71473ea59d3f634f35c54e)](https://www.codacy.com/app/RocketChat/Rocket.Chat.ReactNative?utm_source=github.com&utm_medium=referral&utm_content=RocketChat/Rocket.Chat.ReactNative&utm_campaign=badger)
|
||||
[![codecov](https://codecov.io/gh/RocketChat/Rocket.Chat.ReactNative/branch/master/graph/badge.svg)](https://codecov.io/gh/RocketChat/Rocket.Chat.ReactNative)
|
||||
[![CodeFactor](https://www.codefactor.io/repository/github/rocketchat/rocket.chat.reactnative/badge)](https://www.codefactor.io/repository/github/rocketchat/rocket.chat.reactnative)
|
||||
|
||||
**Supported Server Versions:** 0.66.0+
|
||||
**Supported Server Versions:** 0.70.0+
|
||||
|
||||
## Download
|
||||
<a href="https://play.google.com/store/apps/details?id=chat.rocket.reactnative">
|
||||
|
@ -59,55 +57,53 @@ If you don't need multiple servers, there is a branch `single-server` just for t
|
|||
Readme will guide you on how to config.
|
||||
|
||||
## Current priorities
|
||||
1) [NEW] Jitsi integration ([#711][i711])
|
||||
2) [NEW] Federation ([#706][i706])
|
||||
3) [NEW] Record video ([#712][i712])
|
||||
4) [NEW] Slash Commands ([#405][i405])
|
||||
5) [NEW] Share extension ([#391][i391])
|
||||
|
||||
[i711]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/711
|
||||
[i706]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/706
|
||||
[i707]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/707
|
||||
[i712]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/712
|
||||
[i708]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/708
|
||||
[i391]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/391
|
||||
[i405]: https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/405
|
||||
1) Jitsi integration
|
||||
2) Notification Preferences
|
||||
3) Two-way authentication
|
||||
4) Authentication via SAML
|
||||
5) Authentication via Custom OAuth
|
||||
6) Authentication via CAS
|
||||
7) Bugsnag
|
||||
8) Optional Analytics
|
||||
9) Typescript
|
||||
10) Prettier
|
||||
|
||||
## Features
|
||||
| Feature | Status |
|
||||
|--------------------------------------------------------------- |-------- |
|
||||
| Jitsi Integration | ❌ |
|
||||
| Federation (Directory) | ❌ |
|
||||
| Threads | ✅ |
|
||||
| Federation (Directory) | ✅ |
|
||||
| Discussions | ❌ |
|
||||
| Threads | ✅ |
|
||||
| Record Audio | ✅ |
|
||||
| Record Video | ❌ |
|
||||
| Commands | ❌ |
|
||||
| Record Video | ✅ |
|
||||
| Commands | ✅ |
|
||||
| Draft message per room | ✅ |
|
||||
| Share Extension | ❌ |
|
||||
| Share Extension | ✅ |
|
||||
| Notifications Preferences | ✅ |
|
||||
| Edited status | ✅ |
|
||||
| Upload video | ❌ |
|
||||
| Upload video | ✅ |
|
||||
| Grouped messages | ✅ |
|
||||
| Mark room as read | ❌ |
|
||||
| Mark room as unread | ❌ |
|
||||
| Mark room as read | ✅ |
|
||||
| Mark room as unread | ✅ |
|
||||
| Tablet Support | ❌ |
|
||||
| Read receipt | ❌ |
|
||||
| Read receipt | ✅ |
|
||||
| Broadbast Channel | ✅ |
|
||||
| Authentication via SAML | ❌ |
|
||||
| Authentication via CAS | ❌ |
|
||||
| Custom Fields on Signup | ❌ |
|
||||
| Report message | ❌ |
|
||||
| Custom Fields on Signup | ✅ |
|
||||
| Report message | ✅ |
|
||||
| Theming | ❌ |
|
||||
| Settings -> Review the App | ❌ |
|
||||
| Settings -> Default Browser | ❌ |
|
||||
| Admin panel | ✅ |
|
||||
| Reply message from notification | ❌ |
|
||||
| Unread counter banner on message list | ✅ |
|
||||
| E2E | ❌ |
|
||||
| E2E Encryption | ❌ |
|
||||
| Join a Protected Room | ❌ |
|
||||
| Optional Analytics | ❌ |
|
||||
| Settings -> About us | ❌ |
|
||||
| Settings -> Contact us | ❌ |
|
||||
| Settings -> Contact us | ✅ |
|
||||
| Settings -> Update App Icon | ❌ |
|
||||
| Settings -> Share | ❌ |
|
||||
| Accessibility (Medium) | ❌ |
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export const initialConstants = null;
|
||||
export const findBestAvailableLanguage = () => null;
|
|
@ -0,0 +1,3 @@
|
|||
export default {
|
||||
realmPath: ''
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -110,7 +110,7 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode VERSIONCODE as Integer
|
||||
versionName "1.16.1"
|
||||
versionName "1.17.0"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
|
@ -174,6 +174,9 @@ android {
|
|||
dependencies {
|
||||
addUnimodulesDependencies()
|
||||
implementation "org.webkit:android-jsc:r241213"
|
||||
implementation project(':rn-extensions-share')
|
||||
implementation project(':rn-fetch-blob')
|
||||
implementation project(':react-native-document-picker')
|
||||
implementation project(':react-native-firebase')
|
||||
implementation project(':react-native-webview')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
|
@ -185,7 +188,7 @@ dependencies {
|
|||
})
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-image-crop-picker')
|
||||
implementation project(':react-native-i18n')
|
||||
implementation project(':react-native-localize')
|
||||
implementation project(':react-native-audio')
|
||||
implementation project(":reactnativekeyboardinput")
|
||||
implementation project(':react-native-video')
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<application
|
||||
|
@ -25,6 +27,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
@ -36,6 +39,19 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
<activity
|
||||
android:noHistory="true"
|
||||
android:name=".share.ShareActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/share_extension_name"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -3,6 +3,7 @@ package chat.rocket.reactnative;
|
|||
import android.app.Application;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import io.github.elyx0.reactnativedocumentpicker.DocumentPickerPackage;
|
||||
import io.invertase.firebase.RNFirebasePackage;
|
||||
import io.invertase.firebase.fabric.crashlytics.RNFirebaseCrashlyticsPackage;
|
||||
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
|
||||
|
@ -15,7 +16,7 @@ import com.facebook.react.ReactPackage;
|
|||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import com.AlexanderZaytsev.RNI18n.RNI18nPackage;
|
||||
import com.reactcommunity.rnlocalize.RNLocalizePackage;
|
||||
import com.reactnative.ivpusic.imagepicker.PickerPackage;
|
||||
import com.brentvatne.react.ReactVideoPackage;
|
||||
import com.dylanvann.fastimage.FastImageViewPackage;
|
||||
|
@ -33,6 +34,8 @@ import com.learnium.RNDeviceInfo.RNDeviceInfo;
|
|||
import com.actionsheet.ActionSheetPackage;
|
||||
import io.realm.react.RealmReactPackage;
|
||||
import com.swmansion.rnscreens.RNScreensPackage;
|
||||
import chat.rocket.SharePackage;
|
||||
import com.RNFetchBlob.RNFetchBlobPackage;
|
||||
|
||||
import chat.rocket.reactnative.generated.BasePackageList;
|
||||
|
||||
|
@ -60,6 +63,7 @@ public class MainApplication extends Application implements ReactApplication, IN
|
|||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
new DocumentPickerPackage(),
|
||||
new RNFirebasePackage(),
|
||||
new RNFirebaseCrashlyticsPackage(),
|
||||
new RNFirebaseAnalyticsPackage(),
|
||||
|
@ -67,6 +71,8 @@ public class MainApplication extends Application implements ReactApplication, IN
|
|||
new RNCWebViewPackage(),
|
||||
new OrientationPackage(),
|
||||
new SplashScreenReactPackage(),
|
||||
new SharePackage(),
|
||||
new RNFetchBlobPackage(),
|
||||
new RNGestureHandlerPackage(),
|
||||
new RNScreensPackage(),
|
||||
new ActionSheetPackage(),
|
||||
|
@ -78,7 +84,7 @@ public class MainApplication extends Application implements ReactApplication, IN
|
|||
new ReactNativeAudioPackage(),
|
||||
new KeyboardInputPackage(MainApplication.this),
|
||||
new FastImageViewPackage(),
|
||||
new RNI18nPackage(),
|
||||
new RNLocalizePackage(),
|
||||
new RNNotificationsPackage(MainApplication.this),
|
||||
new ModuleRegistryAdapter(mModuleRegistryProvider)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package chat.rocket.reactnative.share;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||
|
||||
public class ShareActivity extends ReactActivity {
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "ShareRocketChatRN";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new ReactActivityDelegate(this, getMainComponentName()) {
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
return new RNGestureHandlerEnabledRootView(ShareActivity.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package chat.rocket.reactnative.share;
|
||||
|
||||
import chat.rocket.reactnative.BuildConfig;
|
||||
|
||||
import chat.rocket.SharePackage;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ShareApplication extends Application implements ReactApplication {
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
new SharePackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<resources>
|
||||
<string name="app_name">Rocket.Chat Experimental</string>
|
||||
|
||||
<string name="share_extension_name">Rocket.Chat Experimental</string>
|
||||
<string name="no_browser_found">No Browser Found</string>
|
||||
</resources>
|
||||
|
|
|
@ -2,4 +2,19 @@
|
|||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:colorEdgeEffect">#aaaaaa</item>
|
||||
</style>
|
||||
|
||||
<style name="Share.Window" parent="android:Theme">
|
||||
<item name="android:windowEnterAnimation">@null</item>
|
||||
<item name="android:windowExitAnimation">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Share.Transparent" parent="android:Theme">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowBackground">@color/primary_dark</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
<item name="android:windowAnimationStyle">@style/Share.Window</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -2,6 +2,8 @@ apply from: '../node_modules/react-native-unimodules/gradle.groovy'
|
|||
includeUnimodulesProjects()
|
||||
|
||||
rootProject.name = 'RocketChatRN'
|
||||
include ':react-native-document-picker'
|
||||
project(':react-native-document-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-document-picker/android')
|
||||
include ':react-native-firebase'
|
||||
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')
|
||||
include ':react-native-webview'
|
||||
|
@ -20,8 +22,8 @@ include ':react-native-gesture-handler'
|
|||
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
|
||||
include ':react-native-image-crop-picker'
|
||||
project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android')
|
||||
include ':react-native-i18n'
|
||||
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
|
||||
include ':react-native-localize'
|
||||
project(':react-native-localize').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-localize/android')
|
||||
include ':react-native-fast-image'
|
||||
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
||||
include ':react-native-audio'
|
||||
|
@ -36,4 +38,8 @@ include ':realm'
|
|||
project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android')
|
||||
include ':reactnativenotifications'
|
||||
project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/android')
|
||||
include ':app'
|
||||
include ':rn-fetch-blob'
|
||||
project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android')
|
||||
include ':app', ':rn-extensions-share'
|
||||
project(':rn-extensions-share').projectDir = new File(rootProject.projectDir, '../node_modules/rn-extensions-share/android')
|
||||
|
||||
|
|
1
app.json
1
app.json
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"name": "RocketChatRN",
|
||||
"share": "ShareRocketChatRN",
|
||||
"displayName": "RocketChatRN"
|
||||
}
|
|
@ -14,6 +14,11 @@ export const LOGIN = createRequestTypes('LOGIN', [
|
|||
'SET_SERVICES',
|
||||
'SET_PREFERENCE'
|
||||
]);
|
||||
export const SHARE = createRequestTypes('SHARE', [
|
||||
'SELECT_SERVER',
|
||||
'SET_USER',
|
||||
'SET_SERVER_INFO'
|
||||
]);
|
||||
export const USER = createRequestTypes('USER', ['SET']);
|
||||
export const ROOMS = createRequestTypes('ROOMS', [
|
||||
...defaultTypes,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { SHARE } from './actionsTypes';
|
||||
|
||||
export function shareSelectServer(server) {
|
||||
return {
|
||||
type: SHARE.SELECT_SERVER,
|
||||
server
|
||||
};
|
||||
}
|
||||
|
||||
export function shareSetUser(user) {
|
||||
return {
|
||||
type: SHARE.SET_USER,
|
||||
user
|
||||
};
|
||||
}
|
|
@ -68,6 +68,12 @@ export default {
|
|||
Threads_enabled: {
|
||||
type: null
|
||||
},
|
||||
FileUpload_MediaTypeWhiteList: {
|
||||
type: 'valueAsString'
|
||||
},
|
||||
FileUpload_MaxFileSize: {
|
||||
type: 'valueAsNumber'
|
||||
},
|
||||
API_Gitlab_URL: {
|
||||
type: 'valueAsString'
|
||||
},
|
||||
|
|
|
@ -5,6 +5,7 @@ import HeaderButtons, { HeaderButton, Item } from 'react-navigation-header-butto
|
|||
import { CustomIcon } from '../lib/Icons';
|
||||
import { isIOS } from '../utils/deviceInfo';
|
||||
import { COLOR_PRIMARY, COLOR_WHITE } from '../constants/colors';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const color = isIOS ? COLOR_PRIMARY : COLOR_WHITE;
|
||||
export const headerIconSize = 23;
|
||||
|
@ -32,6 +33,15 @@ export const CloseModalButton = React.memo(({ navigation, testID }) => (
|
|||
</CustomHeaderButtons>
|
||||
));
|
||||
|
||||
export const CloseShareExtensionButton = React.memo(({ onPress, testID }) => (
|
||||
<CustomHeaderButtons left>
|
||||
{isIOS
|
||||
? <Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} />
|
||||
: <Item title='close' iconName='cross' onPress={onPress} testID={testID} />
|
||||
}
|
||||
</CustomHeaderButtons>
|
||||
));
|
||||
|
||||
export const MoreButton = React.memo(({ onPress, testID }) => (
|
||||
<CustomHeaderButtons>
|
||||
<Item title='more' iconName='menu' onPress={onPress} testID={testID} />
|
||||
|
@ -50,6 +60,10 @@ CloseModalButton.propTypes = {
|
|||
navigation: PropTypes.object.isRequired,
|
||||
testID: PropTypes.string.isRequired
|
||||
};
|
||||
CloseShareExtensionButton.propTypes = {
|
||||
onPress: PropTypes.func.isRequired,
|
||||
testID: PropTypes.string.isRequired
|
||||
};
|
||||
MoreButton.propTypes = {
|
||||
onPress: PropTypes.func.isRequired,
|
||||
testID: PropTypes.string.isRequired
|
||||
|
|
|
@ -21,6 +21,8 @@ import I18n from '../i18n';
|
|||
import log from '../utils/log';
|
||||
import Navigation from '../lib/Navigation';
|
||||
import { getMessageTranslation } from './message/utils';
|
||||
import { LISTENER } from './Toast';
|
||||
import EventEmitter from '../utils/events';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -48,7 +50,6 @@ export default class MessageActions extends React.Component {
|
|||
actionsHide: PropTypes.func.isRequired,
|
||||
room: PropTypes.object.isRequired,
|
||||
actionMessage: PropTypes.object,
|
||||
toast: PropTypes.element,
|
||||
user: PropTypes.object,
|
||||
deleteRequest: PropTypes.func.isRequired,
|
||||
editInit: PropTypes.func.isRequired,
|
||||
|
@ -275,9 +276,9 @@ export default class MessageActions extends React.Component {
|
|||
}
|
||||
|
||||
handleCopy = async() => {
|
||||
const { actionMessage, toast } = this.props;
|
||||
const { actionMessage } = this.props;
|
||||
await Clipboard.setString(actionMessage.msg);
|
||||
toast.show(I18n.t('Copied_to_clipboard'));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') });
|
||||
}
|
||||
|
||||
handleShare = async() => {
|
||||
|
@ -294,10 +295,10 @@ export default class MessageActions extends React.Component {
|
|||
}
|
||||
|
||||
handlePermalink = async() => {
|
||||
const { actionMessage, toast } = this.props;
|
||||
const { actionMessage } = this.props;
|
||||
const permalink = await this.getPermalink(actionMessage);
|
||||
Clipboard.setString(permalink);
|
||||
toast.show(I18n.t('Permalink_copied_to_clipboard'));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Permalink_copied_to_clipboard') });
|
||||
}
|
||||
|
||||
handlePin = () => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|||
import {
|
||||
View, Text, StyleSheet, Image, ScrollView, TouchableHighlight
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import Modal from 'react-native-modal';
|
||||
import { responsive } from 'react-native-responsive-ui';
|
||||
|
@ -12,7 +13,11 @@ import Button from '../Button';
|
|||
import I18n from '../../i18n';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import { isIOS } from '../../utils/deviceInfo';
|
||||
import { COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE } from '../../constants/colors';
|
||||
import { canUploadFile } from '../../utils/media';
|
||||
import {
|
||||
COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_DANGER
|
||||
} from '../../constants/colors';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
|
||||
const cancelButtonColor = COLOR_BACKGROUND_CONTAINER;
|
||||
|
||||
|
@ -63,18 +68,56 @@ const styles = StyleSheet.create({
|
|||
androidButtonText: {
|
||||
fontSize: 18,
|
||||
textAlign: 'center'
|
||||
},
|
||||
fileIcon: {
|
||||
color: COLOR_PRIMARY,
|
||||
margin: 20,
|
||||
flex: 1,
|
||||
textAlign: 'center'
|
||||
},
|
||||
errorIcon: {
|
||||
color: COLOR_DANGER
|
||||
},
|
||||
fileMime: {
|
||||
...sharedStyles.textColorTitle,
|
||||
...sharedStyles.textBold,
|
||||
textAlign: 'center',
|
||||
fontSize: 20,
|
||||
marginBottom: 20
|
||||
},
|
||||
errorContainer: {
|
||||
margin: 20,
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
video: {
|
||||
flex: 1,
|
||||
borderRadius: 4,
|
||||
height: 150,
|
||||
backgroundColor: '#1f2329',
|
||||
marginBottom: 6,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@responsive
|
||||
@connect(state => ({
|
||||
FileUpload_MediaTypeWhiteList: state.settings.FileUpload_MediaTypeWhiteList,
|
||||
FileUpload_MaxFileSize: state.settings.FileUpload_MaxFileSize
|
||||
}))
|
||||
export default class UploadModal extends Component {
|
||||
static propTypes = {
|
||||
isVisible: PropTypes.bool,
|
||||
file: PropTypes.object,
|
||||
close: PropTypes.func,
|
||||
submit: PropTypes.func,
|
||||
window: PropTypes.object
|
||||
window: PropTypes.object,
|
||||
FileUpload_MediaTypeWhiteList: PropTypes.string,
|
||||
FileUpload_MaxFileSize: PropTypes.number
|
||||
}
|
||||
|
||||
state = {
|
||||
|
@ -116,12 +159,79 @@ export default class UploadModal extends Component {
|
|||
return false;
|
||||
}
|
||||
|
||||
canUploadFile = () => {
|
||||
const { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize, file } = this.props;
|
||||
if (!(file && file.path)) {
|
||||
return true;
|
||||
}
|
||||
if (file.size > FileUpload_MaxFileSize) {
|
||||
return false;
|
||||
}
|
||||
// if white list is empty, all media types are enabled
|
||||
if (!FileUpload_MediaTypeWhiteList) {
|
||||
return true;
|
||||
}
|
||||
const allowedMime = FileUpload_MediaTypeWhiteList.split(',');
|
||||
if (allowedMime.includes(file.mime)) {
|
||||
return true;
|
||||
}
|
||||
const wildCardGlob = '/*';
|
||||
const wildCards = allowedMime.filter(item => item.indexOf(wildCardGlob) > 0);
|
||||
if (wildCards.includes(file.mime.replace(/(\/.*)$/, wildCardGlob))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
submit = () => {
|
||||
const { file, submit } = this.props;
|
||||
const { name, description } = this.state;
|
||||
submit({ ...file, name, description });
|
||||
}
|
||||
|
||||
renderError = () => {
|
||||
const { file, FileUpload_MaxFileSize, close } = this.props;
|
||||
const { window: { width } } = this.props;
|
||||
const errorMessage = (FileUpload_MaxFileSize < file.size)
|
||||
? 'error-file-too-large'
|
||||
: 'error-invalid-file-type';
|
||||
return (
|
||||
<View style={[styles.container, { width: width - 32 }]}>
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={styles.title}>{I18n.t(errorMessage)}</Text>
|
||||
</View>
|
||||
<View style={styles.errorContainer}>
|
||||
<CustomIcon name='circle-cross' size={120} style={styles.errorIcon} />
|
||||
</View>
|
||||
<Text style={styles.fileMime}>{ file.mime }</Text>
|
||||
<View style={styles.buttonContainer}>
|
||||
{
|
||||
(isIOS)
|
||||
? (
|
||||
<Button
|
||||
title={I18n.t('Cancel')}
|
||||
type='secondary'
|
||||
backgroundColor={cancelButtonColor}
|
||||
style={styles.button}
|
||||
onPress={close}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<TouchableHighlight
|
||||
onPress={close}
|
||||
style={[styles.androidButton, { backgroundColor: cancelButtonColor }]}
|
||||
underlayColor={cancelButtonColor}
|
||||
activeOpacity={0.5}
|
||||
>
|
||||
<Text style={[styles.androidButtonText, { ...sharedStyles.textBold, color: COLOR_PRIMARY }]}>{I18n.t('Cancel')}</Text>
|
||||
</TouchableHighlight>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderButtons = () => {
|
||||
const { close } = this.props;
|
||||
if (isIOS) {
|
||||
|
@ -166,9 +276,27 @@ export default class UploadModal extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderPreview() {
|
||||
const { file } = this.props;
|
||||
if (file.mime && file.mime.match(/image/)) {
|
||||
return (<Image source={{ isStatic: true, uri: file.path }} style={styles.image} />);
|
||||
}
|
||||
if (file.mime && file.mime.match(/video/)) {
|
||||
return (
|
||||
<View style={styles.video}>
|
||||
<CustomIcon name='play' size={72} color={COLOR_WHITE} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (<CustomIcon name='file-generic' size={72} style={styles.fileIcon} />);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { window: { width }, isVisible, close } = this.props;
|
||||
const { name, description, file } = this.state;
|
||||
const {
|
||||
window: { width }, isVisible, close, file, FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize
|
||||
} = this.props;
|
||||
const { name, description } = this.state;
|
||||
const showError = !canUploadFile(file, { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize });
|
||||
return (
|
||||
<Modal
|
||||
isVisible={isVisible}
|
||||
|
@ -181,26 +309,29 @@ export default class UploadModal extends Component {
|
|||
hideModalContentWhileAnimating
|
||||
avoidKeyboard
|
||||
>
|
||||
<View style={[styles.container, { width: width - 32 }]}>
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text>
|
||||
</View>
|
||||
{(showError) ? this.renderError()
|
||||
: (
|
||||
<View style={[styles.container, { width: width - 32 }]}>
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text>
|
||||
</View>
|
||||
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<Image source={{ isStatic: true, uri: file.path }} style={styles.image} />
|
||||
<TextInput
|
||||
placeholder={I18n.t('File_name')}
|
||||
value={name}
|
||||
onChangeText={value => this.setState({ name: value })}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder={I18n.t('File_description')}
|
||||
value={description}
|
||||
onChangeText={value => this.setState({ description: value })}
|
||||
/>
|
||||
</ScrollView>
|
||||
{this.renderButtons()}
|
||||
</View>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{this.renderPreview()}
|
||||
<TextInput
|
||||
placeholder={I18n.t('File_name')}
|
||||
value={name}
|
||||
onChangeText={value => this.setState({ name: value })}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder={I18n.t('File_description')}
|
||||
value={description}
|
||||
onChangeText={value => this.setState({ description: value })}
|
||||
/>
|
||||
</ScrollView>
|
||||
{this.renderButtons()}
|
||||
</View>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { emojify } from 'react-emojione';
|
|||
import { KeyboardAccessoryView } from 'react-native-keyboard-input';
|
||||
import ImagePicker from 'react-native-image-crop-picker';
|
||||
import equal from 'deep-equal';
|
||||
import DocumentPicker from 'react-native-document-picker';
|
||||
import ActionSheet from 'react-native-action-sheet';
|
||||
|
||||
import { userTyping as userTypingAction } from '../../actions/room';
|
||||
|
@ -46,21 +47,22 @@ const onlyUnique = function onlyUnique(value, index, self) {
|
|||
const imagePickerConfig = {
|
||||
cropping: true,
|
||||
compressImageQuality: 0.8,
|
||||
avoidEmptySpaceAroundImage: false,
|
||||
cropperChooseText: I18n.t('Choose'),
|
||||
cropperCancelText: I18n.t('Cancel')
|
||||
avoidEmptySpaceAroundImage: false
|
||||
};
|
||||
|
||||
const libraryPickerConfig = {
|
||||
mediaType: 'any'
|
||||
};
|
||||
|
||||
const videoPickerConfig = {
|
||||
mediaType: 'video'
|
||||
};
|
||||
|
||||
const fileOptions = [I18n.t('Cancel')];
|
||||
const FILE_CANCEL_INDEX = 0;
|
||||
|
||||
// Photo
|
||||
fileOptions.push(I18n.t('Take_a_photo'));
|
||||
const FILE_PHOTO_INDEX = 1;
|
||||
|
||||
// Library
|
||||
fileOptions.push(I18n.t('Choose_from_library'));
|
||||
const FILE_LIBRARY_INDEX = 2;
|
||||
const FILE_VIDEO_INDEX = 2;
|
||||
const FILE_LIBRARY_INDEX = 3;
|
||||
const FILE_DOCUMENT_INDEX = 4;
|
||||
|
||||
class MessageBox extends Component {
|
||||
static propTypes = {
|
||||
|
@ -107,6 +109,30 @@ class MessageBox extends Component {
|
|||
this.customEmojis = [];
|
||||
this.onEmojiSelected = this.onEmojiSelected.bind(this);
|
||||
this.text = '';
|
||||
this.fileOptions = [
|
||||
I18n.t('Cancel'),
|
||||
I18n.t('Take_a_photo'),
|
||||
I18n.t('Take_a_video'),
|
||||
I18n.t('Choose_from_library'),
|
||||
I18n.t('Choose_file')
|
||||
];
|
||||
const libPickerLabels = {
|
||||
cropperChooseText: I18n.t('Choose'),
|
||||
cropperCancelText: I18n.t('Cancel'),
|
||||
loadingLabelText: I18n.t('Processing')
|
||||
};
|
||||
this.imagePickerConfig = {
|
||||
...imagePickerConfig,
|
||||
...libPickerLabels
|
||||
};
|
||||
this.libraryPickerConfig = {
|
||||
...libraryPickerConfig,
|
||||
...libPickerLabels
|
||||
};
|
||||
this.videoPickerConfig = {
|
||||
...videoPickerConfig,
|
||||
...libPickerLabels
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -462,9 +488,10 @@ class MessageBox extends Component {
|
|||
this.setShowSend(false);
|
||||
}
|
||||
|
||||
sendImageMessage = async(file) => {
|
||||
const { rid, tmid } = this.props;
|
||||
|
||||
sendMediaMessage = async(file) => {
|
||||
const {
|
||||
rid, tmid, baseUrl: server, user
|
||||
} = this.props;
|
||||
this.setState({ file: { isVisible: false } });
|
||||
const fileInfo = {
|
||||
name: file.name,
|
||||
|
@ -475,37 +502,65 @@ class MessageBox extends Component {
|
|||
path: file.path
|
||||
};
|
||||
try {
|
||||
await RocketChat.sendFileMessage(rid, fileInfo, tmid);
|
||||
await RocketChat.sendFileMessage(rid, fileInfo, tmid, server, user);
|
||||
} catch (e) {
|
||||
log('err_send_image', e);
|
||||
log('err_send_media_message', e);
|
||||
}
|
||||
}
|
||||
|
||||
takePhoto = async() => {
|
||||
try {
|
||||
const image = await ImagePicker.openCamera(imagePickerConfig);
|
||||
const image = await ImagePicker.openCamera(this.imagePickerConfig);
|
||||
this.showUploadModal(image);
|
||||
} catch (e) {
|
||||
log('err_take_photo', e);
|
||||
}
|
||||
}
|
||||
|
||||
takeVideo = async() => {
|
||||
try {
|
||||
const video = await ImagePicker.openCamera(this.videoPickerConfig);
|
||||
this.showUploadModal(video);
|
||||
} catch (e) {
|
||||
log('err_take_video', e);
|
||||
}
|
||||
}
|
||||
|
||||
chooseFromLibrary = async() => {
|
||||
try {
|
||||
const image = await ImagePicker.openPicker(imagePickerConfig);
|
||||
const image = await ImagePicker.openPicker(this.libraryPickerConfig);
|
||||
this.showUploadModal(image);
|
||||
} catch (e) {
|
||||
log('err_choose_from_library', e);
|
||||
}
|
||||
}
|
||||
|
||||
chooseFile = async() => {
|
||||
try {
|
||||
const res = await DocumentPicker.pick({
|
||||
type: [DocumentPicker.types.allFiles]
|
||||
});
|
||||
this.showUploadModal({
|
||||
filename: res.name,
|
||||
size: res.size,
|
||||
mime: res.type,
|
||||
path: res.uri
|
||||
});
|
||||
} catch (error) {
|
||||
if (!DocumentPicker.isCancel(error)) {
|
||||
log('chooseFile', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showUploadModal = (file) => {
|
||||
this.setState({ file: { ...file, isVisible: true } });
|
||||
}
|
||||
|
||||
showFileActions = () => {
|
||||
ActionSheet.showActionSheetWithOptions({
|
||||
options: fileOptions,
|
||||
options: this.fileOptions,
|
||||
cancelButtonIndex: FILE_CANCEL_INDEX
|
||||
}, (actionIndex) => {
|
||||
this.handleFileActionPress(actionIndex);
|
||||
|
@ -517,9 +572,15 @@ class MessageBox extends Component {
|
|||
case FILE_PHOTO_INDEX:
|
||||
this.takePhoto();
|
||||
break;
|
||||
case FILE_VIDEO_INDEX:
|
||||
this.takeVideo();
|
||||
break;
|
||||
case FILE_LIBRARY_INDEX:
|
||||
this.chooseFromLibrary();
|
||||
break;
|
||||
case FILE_DOCUMENT_INDEX:
|
||||
this.chooseFile();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -543,14 +604,16 @@ class MessageBox extends Component {
|
|||
}
|
||||
|
||||
finishAudioMessage = async(fileInfo) => {
|
||||
const { rid, tmid } = this.props;
|
||||
const {
|
||||
rid, tmid, baseUrl: server, user
|
||||
} = this.props;
|
||||
|
||||
this.setState({
|
||||
recording: false
|
||||
});
|
||||
if (fileInfo) {
|
||||
try {
|
||||
await RocketChat.sendFileMessage(rid, fileInfo, tmid);
|
||||
await RocketChat.sendFileMessage(rid, fileInfo, tmid, server, user);
|
||||
} catch (e) {
|
||||
if (e && e.error === 'error-file-too-large') {
|
||||
return Alert.alert(I18n.t(e.error));
|
||||
|
@ -895,7 +958,7 @@ class MessageBox extends Component {
|
|||
isVisible={(file && file.isVisible)}
|
||||
file={file}
|
||||
close={() => this.setState({ file: {} })}
|
||||
submit={this.sendImageMessage}
|
||||
submit={this.sendMediaMessage}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -7,8 +7,12 @@ import { COLOR_TEXT_DESCRIPTION } from '../constants/colors';
|
|||
const styles = StyleSheet.create({
|
||||
style: {
|
||||
marginRight: 7,
|
||||
marginTop: 3,
|
||||
tintColor: COLOR_TEXT_DESCRIPTION,
|
||||
marginTop: 3
|
||||
},
|
||||
imageColor: {
|
||||
tintColor: COLOR_TEXT_DESCRIPTION
|
||||
},
|
||||
iconColor: {
|
||||
color: COLOR_TEXT_DESCRIPTION
|
||||
},
|
||||
discussion: {
|
||||
|
@ -23,13 +27,15 @@ const RoomTypeIcon = React.memo(({ type, size, style }) => {
|
|||
|
||||
if (type === 'discussion') {
|
||||
// FIXME: These are temporary only. We should have all room icons on <Customicon />, but our design team is still working on this.
|
||||
return <CustomIcon name='chat' size={13} style={[styles.style, styles.discussion]} />;
|
||||
return <CustomIcon name='chat' size={13} style={[styles.style, styles.iconColor, styles.discussion]} />;
|
||||
}
|
||||
|
||||
if (type === 'c') {
|
||||
return <Image source={{ uri: 'hashtag' }} style={[styles.style, style, { width: size, height: size }]} />;
|
||||
return <Image source={{ uri: 'hashtag' }} style={[styles.style, styles.imageColor, style, { width: size, height: size }]} />;
|
||||
} if (type === 'd') {
|
||||
return <CustomIcon name='at' size={13} style={[styles.style, styles.iconColor, styles.discussion]} />;
|
||||
}
|
||||
return <Image source={{ uri: 'lock' }} style={[styles.style, style, { width: size, height: size }]} />;
|
||||
return <Image source={{ uri: 'lock' }} style={[styles.style, styles.imageColor, style, { width: size, height: size }]} />;
|
||||
});
|
||||
|
||||
RoomTypeIcon.propTypes = {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import React from 'react';
|
||||
import { View, StyleSheet, TextInput } from 'react-native';
|
||||
import {
|
||||
View, StyleSheet, TextInput, Text
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import Touchable from 'react-native-platform-touchable';
|
||||
|
||||
import I18n from '../i18n';
|
||||
import { isIOS } from '../utils/deviceInfo';
|
||||
|
@ -9,7 +12,10 @@ import sharedStyles from '../views/Styles';
|
|||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: isIOS ? '#F7F8FA' : '#54585E'
|
||||
backgroundColor: isIOS ? '#F7F8FA' : '#54585E',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1
|
||||
},
|
||||
searchBox: {
|
||||
alignItems: 'center',
|
||||
|
@ -21,7 +27,8 @@ const styles = StyleSheet.create({
|
|||
height: 36,
|
||||
margin: 16,
|
||||
marginVertical: 10,
|
||||
paddingHorizontal: 10
|
||||
paddingHorizontal: 10,
|
||||
flex: 1
|
||||
},
|
||||
input: {
|
||||
color: '#8E8E93',
|
||||
|
@ -31,10 +38,26 @@ const styles = StyleSheet.create({
|
|||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
cancel: {
|
||||
marginRight: 10
|
||||
},
|
||||
cancelText: {
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorHeaderBack,
|
||||
fontSize: 17
|
||||
}
|
||||
});
|
||||
|
||||
const SearchBox = ({ onChangeText, onSubmitEditing, testID }) => (
|
||||
const CancelButton = onCancelPress => (
|
||||
<Touchable onPress={onCancelPress} style={styles.cancel}>
|
||||
<Text style={styles.cancelText}>{I18n.t('Cancel')}</Text>
|
||||
</Touchable>
|
||||
);
|
||||
|
||||
const SearchBox = ({
|
||||
onChangeText, onSubmitEditing, testID, hasCancel, onCancelPress, ...props
|
||||
}) => (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.searchBox}>
|
||||
<CustomIcon name='magnifier' size={14} color='#8E8E93' />
|
||||
|
@ -50,14 +73,18 @@ const SearchBox = ({ onChangeText, onSubmitEditing, testID }) => (
|
|||
underlineColorAndroid='transparent'
|
||||
onChangeText={onChangeText}
|
||||
onSubmitEditing={onSubmitEditing}
|
||||
{...props}
|
||||
/>
|
||||
</View>
|
||||
{ hasCancel ? CancelButton(onCancelPress) : null }
|
||||
</View>
|
||||
);
|
||||
|
||||
SearchBox.propTypes = {
|
||||
onChangeText: PropTypes.func.isRequired,
|
||||
onSubmitEditing: PropTypes.func,
|
||||
hasCancel: PropTypes.bool,
|
||||
onCancelPress: PropTypes.func,
|
||||
testID: PropTypes.string
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import React from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import EasyToast from 'react-native-easy-toast';
|
||||
|
||||
import { COLOR_TOAST, COLOR_WHITE } from '../constants/colors';
|
||||
import sharedStyles from '../views/Styles';
|
||||
import EventEmitter from '../utils/events';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
toast: {
|
||||
backgroundColor: COLOR_TOAST,
|
||||
maxWidth: 300,
|
||||
padding: 10
|
||||
},
|
||||
text: {
|
||||
...sharedStyles.textRegular,
|
||||
color: COLOR_WHITE,
|
||||
fontSize: 14,
|
||||
textAlign: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
export const LISTENER = 'Toast';
|
||||
|
||||
export default class Toast extends React.Component {
|
||||
componentDidMount() {
|
||||
EventEmitter.addEventListener(LISTENER, this.showToast);
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
EventEmitter.removeListener(LISTENER);
|
||||
}
|
||||
|
||||
showToast = ({ message }) => {
|
||||
this.toast.show(message, 1000);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<EasyToast
|
||||
ref={toast => this.toast = toast}
|
||||
position='center'
|
||||
style={styles.toast}
|
||||
textStyle={styles.text}
|
||||
opacity={0.9}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { Text, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import I18n from '../../i18n';
|
||||
|
@ -12,26 +12,35 @@ const Content = React.memo((props) => {
|
|||
return <Text style={styles.textInfo}>{getInfoMessage({ ...props })}</Text>;
|
||||
}
|
||||
|
||||
let content = null;
|
||||
|
||||
if (props.tmid && !props.msg) {
|
||||
return <Text style={styles.text}>{I18n.t('Sent_an_attachment')}</Text>;
|
||||
content = <Text style={styles.text}>{I18n.t('Sent_an_attachment')}</Text>;
|
||||
} else {
|
||||
content = (
|
||||
<Markdown
|
||||
msg={props.msg}
|
||||
baseUrl={props.baseUrl}
|
||||
username={props.user.username}
|
||||
isEdited={props.isEdited}
|
||||
mentions={props.mentions}
|
||||
channels={props.channels}
|
||||
numberOfLines={props.tmid ? 1 : 0}
|
||||
getCustomEmoji={props.getCustomEmoji}
|
||||
useMarkdown={props.useMarkdown}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Markdown
|
||||
msg={props.msg}
|
||||
baseUrl={props.baseUrl}
|
||||
username={props.user.username}
|
||||
isEdited={props.isEdited}
|
||||
mentions={props.mentions}
|
||||
channels={props.channels}
|
||||
numberOfLines={props.tmid ? 1 : 0}
|
||||
getCustomEmoji={props.getCustomEmoji}
|
||||
useMarkdown={props.useMarkdown}
|
||||
/>
|
||||
<View style={props.isTemp && styles.temp}>
|
||||
{content}
|
||||
</View>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.msg === nextProps.msg);
|
||||
}, (prevProps, nextProps) => prevProps.isTemp === nextProps.isTemp && prevProps.msg === nextProps.msg);
|
||||
|
||||
Content.propTypes = {
|
||||
isTemp: PropTypes.bool,
|
||||
isInfo: PropTypes.bool,
|
||||
isEdited: PropTypes.bool,
|
||||
useMarkdown: PropTypes.bool,
|
||||
|
|
|
@ -4,7 +4,6 @@ import { View } from 'react-native';
|
|||
import Touchable from 'react-native-platform-touchable';
|
||||
|
||||
import User from './User';
|
||||
import MessageError from './MessageError';
|
||||
import styles from './styles';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import RepliedThread from './RepliedThread';
|
||||
|
@ -45,7 +44,7 @@ const Message = React.memo((props) => {
|
|||
if (props.isThreadReply || props.isThreadSequential || props.isInfo) {
|
||||
const thread = props.isThreadReply ? <RepliedThread isTemp={props.isTemp} {...props} /> : null;
|
||||
return (
|
||||
<View style={[styles.container, props.style, props.isTemp && styles.temp]}>
|
||||
<View style={[styles.container, props.style]}>
|
||||
{thread}
|
||||
<View style={[styles.flex, sharedStyles.alignItemsCenter]}>
|
||||
<MessageAvatar small {...props} />
|
||||
|
@ -62,7 +61,7 @@ const Message = React.memo((props) => {
|
|||
);
|
||||
}
|
||||
return (
|
||||
<View style={[styles.container, props.style, props.isTemp && styles.temp]}>
|
||||
<View style={[styles.container, props.style]}>
|
||||
<View style={styles.flex}>
|
||||
<MessageAvatar {...props} />
|
||||
<View
|
||||
|
@ -86,8 +85,7 @@ Message.displayName = 'Message';
|
|||
const MessageTouchable = React.memo((props) => {
|
||||
if (props.hasError) {
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
<MessageError {...props} />
|
||||
<View>
|
||||
<Message {...props} />
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -5,14 +5,15 @@ import PropTypes from 'prop-types';
|
|||
import { CustomIcon } from '../../lib/Icons';
|
||||
import { COLOR_DANGER } from '../../constants/colors';
|
||||
import styles from './styles';
|
||||
import { BUTTON_HIT_SLOP } from './utils';
|
||||
|
||||
const MessageError = React.memo(({ hasError, onErrorPress }) => {
|
||||
if (!hasError) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Touchable onPress={onErrorPress} style={styles.errorButton}>
|
||||
<CustomIcon name='circle-cross' color={COLOR_DANGER} size={20} />
|
||||
<Touchable onPress={onErrorPress} style={styles.errorButton} hitSlop={BUTTON_HIT_SLOP}>
|
||||
<CustomIcon name='warning' color={COLOR_DANGER} size={18} />
|
||||
</Touchable>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.hasError === nextProps.hasError);
|
||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import moment from 'moment';
|
||||
|
||||
import MessageError from './MessageError';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import messageStyles from './styles';
|
||||
|
||||
|
@ -31,9 +32,9 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
|
||||
const User = React.memo(({
|
||||
isHeader, useRealName, author, alias, ts, timeFormat
|
||||
isHeader, useRealName, author, alias, ts, timeFormat, hasError, ...props
|
||||
}) => {
|
||||
if (isHeader) {
|
||||
if (isHeader || hasError) {
|
||||
const username = (useRealName && author.name) || author.username;
|
||||
const aliasUsername = alias ? (<Text style={styles.alias}> @{username}</Text>) : null;
|
||||
const time = moment(ts).format(timeFormat);
|
||||
|
@ -47,6 +48,7 @@ const User = React.memo(({
|
|||
</Text>
|
||||
</View>
|
||||
<Text style={messageStyles.time}>{time}</Text>
|
||||
{ hasError && <MessageError hasError={hasError} {...props} /> }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -55,6 +57,7 @@ const User = React.memo(({
|
|||
|
||||
User.propTypes = {
|
||||
isHeader: PropTypes.bool,
|
||||
hasError: PropTypes.bool,
|
||||
useRealName: PropTypes.bool,
|
||||
author: PropTypes.object,
|
||||
alias: PropTypes.string,
|
||||
|
|
|
@ -128,6 +128,9 @@ export default class MessageContainer extends React.Component {
|
|||
const {
|
||||
item, previousItem, broadcast, Message_GroupingPeriod
|
||||
} = this.props;
|
||||
if (this.hasError || (previousItem && previousItem.status === messagesStatus.ERROR)) {
|
||||
return true;
|
||||
}
|
||||
if (previousItem && (
|
||||
(previousItem.ts.toDateString() === item.ts.toDateString())
|
||||
&& (previousItem.u.username === item.u.username)
|
||||
|
|
|
@ -114,7 +114,7 @@ export default StyleSheet.create({
|
|||
color: COLOR_PRIMARY
|
||||
},
|
||||
errorButton: {
|
||||
paddingHorizontal: 15,
|
||||
paddingLeft: 10,
|
||||
paddingVertical: 5
|
||||
},
|
||||
buttonContainer: {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import I18n from 'react-native-i18n';
|
||||
import i18n from 'i18n-js';
|
||||
import { I18nManager } from 'react-native';
|
||||
import * as RNLocalize from 'react-native-localize';
|
||||
|
||||
import en from './locales/en';
|
||||
import ru from './locales/ru';
|
||||
import fr from './locales/fr';
|
||||
|
@ -7,11 +10,22 @@ import ptBR from './locales/pt-BR';
|
|||
import zhCN from './locales/zh-CN';
|
||||
import ptPT from './locales/pt-PT';
|
||||
|
||||
I18n.fallbacks = true;
|
||||
I18n.defaultLocale = 'en';
|
||||
|
||||
I18n.translations = {
|
||||
en, ru, 'pt-BR': ptBR, 'zh-CN': zhCN, fr, de, 'pt-PT': ptPT
|
||||
i18n.translations = {
|
||||
en,
|
||||
ru,
|
||||
'pt-BR': ptBR,
|
||||
'zh-CN': zhCN,
|
||||
fr,
|
||||
de,
|
||||
'pt-PT': ptPT
|
||||
};
|
||||
i18n.fallbacks = true;
|
||||
|
||||
export default I18n;
|
||||
const defaultLanguage = { languageTag: 'en', isRTL: false };
|
||||
const availableLanguages = Object.keys(i18n.translations);
|
||||
const { languageTag, isRTL } = RNLocalize.findBestAvailableLanguage(availableLanguages) || defaultLanguage;
|
||||
|
||||
I18nManager.forceRTL(isRTL);
|
||||
i18n.locale = languageTag;
|
||||
|
||||
export default i18n;
|
||||
|
|
|
@ -99,6 +99,7 @@ export default {
|
|||
Are_you_sure_question_mark: 'Sind Sie sicher?',
|
||||
Are_you_sure_you_want_to_leave_the_room: 'Möchten Sie den Raum wirklich verlassen {{room}}?',
|
||||
Authenticating: 'Authentifizierung',
|
||||
Auto_Translate: 'Automatische Übersetzung',
|
||||
Avatar_changed_successfully: 'Avatar erfolgreich geändert!',
|
||||
Avatar_Url: 'Avatar-URL',
|
||||
Away: 'Abwesend',
|
||||
|
@ -155,11 +156,13 @@ export default {
|
|||
Email_or_password_field_is_empty: 'Das E-Mail- oder Passwortfeld ist leer',
|
||||
Email: 'Email',
|
||||
email: 'Email',
|
||||
Enable_Auto_Translate: 'Automatische Übersetzung aktivieren',
|
||||
Enable_markdown: 'Markdown aktivieren',
|
||||
Enable_notifications: 'Benachrichtigungen aktivieren',
|
||||
Everyone_can_access_this_channel: 'Jeder kann auf diesen Kanal zugreifen',
|
||||
erasing_room: 'lösche Raum',
|
||||
Error_uploading: 'Fehler beim Hochladen',
|
||||
Favorite: 'Favorisieren',
|
||||
Favorites: 'Favoriten',
|
||||
Files: 'Dateien',
|
||||
File_description: 'Dateibeschreibung',
|
||||
|
@ -173,6 +176,7 @@ export default {
|
|||
Forgot_Password: 'Passwort vergessen',
|
||||
Group_by_favorites: 'Nach Favoriten gruppieren',
|
||||
Group_by_type: 'Gruppieren nach Typ',
|
||||
Hide: 'Ausblenden',
|
||||
Has_joined_the_channel: 'Ist dem Kanal beigetreten',
|
||||
Has_joined_the_conversation: 'Hat sich dem Gespräch angeschlossen',
|
||||
Has_left_the_channel: 'Hat den Kanal verlassen',
|
||||
|
@ -266,6 +270,7 @@ export default {
|
|||
Reactions_are_disabled: 'Reaktionen sind deaktiviert',
|
||||
Reactions_are_enabled: 'Reaktionen sind aktiviert',
|
||||
Reactions: 'Reaktionen',
|
||||
Read: 'Gelesen',
|
||||
Read_Only_Channel: 'Nur-Lese-Kanal',
|
||||
Read_Only: 'Schreibgeschützt',
|
||||
Read_Receipt: 'Lesebestätigung',
|
||||
|
@ -343,12 +348,14 @@ export default {
|
|||
Timezone: 'Zeitzone',
|
||||
topic: 'Thema',
|
||||
Topic: 'Thema',
|
||||
Translate: 'Übersetzen',
|
||||
Try_again: 'Versuchen Sie es nochmal',
|
||||
Two_Factor_Authentication: 'Zwei-Faktor-Authentifizierung',
|
||||
Type_the_channel_name_here: 'Geben Sie hier den Kanalnamen ein',
|
||||
unarchive: 'wiederherstellen',
|
||||
UNARCHIVE: 'WIEDERHERSTELLEN',
|
||||
Unblock_user: 'Nutzer entblockieren',
|
||||
Unfavorite: 'Nicht mehr favorisieren',
|
||||
Unfollowed_thread: 'Thread nicht mehr folgen',
|
||||
Unmute: 'Stummschaltung aufheben',
|
||||
unmuted: 'Stummschaltung aufgehoben',
|
||||
|
@ -374,6 +381,7 @@ export default {
|
|||
Username_or_email: 'Benutzername oder E-Mail-Adresse',
|
||||
Validating: 'Validierung',
|
||||
Video_call: 'Videoanruf',
|
||||
View_Original: 'Original anzeigen',
|
||||
Voice_call: 'Sprachanruf',
|
||||
Welcome: 'Herzlich willkommen',
|
||||
Welcome_to_RocketChat: 'Willkommen bei Rocket.Chat',
|
||||
|
|
|
@ -103,6 +103,7 @@ export default {
|
|||
Avatar_changed_successfully: 'Avatar changed successfully!',
|
||||
Avatar_Url: 'Avatar URL',
|
||||
Away: 'Away',
|
||||
Back: 'Back',
|
||||
Block_user: 'Block user',
|
||||
Broadcast_channel_Description: 'Only authorized users can write new messages, but the other users will be able to reply',
|
||||
Broadcast_Channel: 'Broadcast Channel',
|
||||
|
@ -120,6 +121,7 @@ export default {
|
|||
Close_emoji_selector: 'Close emoji selector',
|
||||
Choose: 'Choose',
|
||||
Choose_from_library: 'Choose from library',
|
||||
Choose_file: 'Choose file',
|
||||
Code: 'Code',
|
||||
Collaborative: 'Collaborative',
|
||||
Confirm: 'Confirm',
|
||||
|
@ -262,6 +264,7 @@ export default {
|
|||
Private_Channel: 'Private Channel',
|
||||
Private_Groups: 'Private Groups',
|
||||
Private: 'Private',
|
||||
Processing: 'Processing...',
|
||||
Profile_saved_successfully: 'Profile saved successfully!',
|
||||
Profile: 'Profile',
|
||||
Public_Channel: 'Public Channel',
|
||||
|
@ -308,11 +311,13 @@ export default {
|
|||
Search_global_users: 'Search for global users',
|
||||
Search_global_users_description: 'If you turn-on, you can search for any user from others companies or servers.',
|
||||
Select_Avatar: 'Select Avatar',
|
||||
Select_Server: 'Select Server',
|
||||
Select_Users: 'Select Users',
|
||||
Send: 'Send',
|
||||
Send_audio_message: 'Send audio message',
|
||||
Send_crash_report: 'Send crash report',
|
||||
Send_message: 'Send message',
|
||||
Send_to: 'Send to...',
|
||||
Sent_an_attachment: 'Sent an attachment',
|
||||
Server: 'Server',
|
||||
Servers: 'Servers',
|
||||
|
@ -335,6 +340,7 @@ export default {
|
|||
Started_discussion: 'Started a discussion:',
|
||||
Submit: 'Submit',
|
||||
Take_a_photo: 'Take a photo',
|
||||
Take_a_video: 'Take a video',
|
||||
tap_to_change_status: 'tap to change status',
|
||||
Tap_to_view_servers_list: 'Tap to view servers list',
|
||||
Terms_of_Service: ' Terms of Service ',
|
||||
|
@ -346,6 +352,7 @@ export default {
|
|||
Thread: 'Thread',
|
||||
Threads: 'Threads',
|
||||
Timezone: 'Timezone',
|
||||
To: 'To',
|
||||
topic: 'topic',
|
||||
Topic: 'Topic',
|
||||
Translate: 'Translate',
|
||||
|
@ -386,6 +393,7 @@ export default {
|
|||
Welcome: 'Welcome',
|
||||
Welcome_to_RocketChat: 'Welcome to Rocket.Chat',
|
||||
Whats_your_2fa: 'What\'s your 2FA code?',
|
||||
Without_Servers: 'Without Servers',
|
||||
Yes_action_it: 'Yes, {{action}} it!',
|
||||
Yesterday: 'Yesterday',
|
||||
You_are_in_preview_mode: 'You are in preview mode',
|
||||
|
@ -395,6 +403,7 @@ export default {
|
|||
you_were_mentioned: 'you were mentioned',
|
||||
you: 'you',
|
||||
You: 'You',
|
||||
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'You need to access at least one Rocket.Chat server to share something.',
|
||||
Version_no: 'Version: {{version}}',
|
||||
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
|
||||
Change_Language: 'Change Language',
|
||||
|
|
|
@ -108,6 +108,7 @@ export default {
|
|||
Avatar_changed_successfully: 'Avatar alterado com sucesso!',
|
||||
Avatar_Url: 'Avatar URL',
|
||||
Away: 'Ausente',
|
||||
Back: 'Voltar',
|
||||
Block_user: 'Bloquear usuário',
|
||||
Broadcast_channel_Description: 'Somente usuários autorizados podem escrever novas mensagens, mas os outros usuários poderão responder',
|
||||
Broadcast_Channel: 'Canal de Transmissão',
|
||||
|
@ -125,6 +126,7 @@ export default {
|
|||
Close_emoji_selector: 'Fechar seletor de emojis',
|
||||
Choose: 'Escolher',
|
||||
Choose_from_library: 'Escolha da biblioteca',
|
||||
Choose_file: 'Enviar arquivo',
|
||||
Code: 'Código',
|
||||
Collaborative: 'Colaborativo',
|
||||
Confirm: 'Confirmar',
|
||||
|
@ -255,6 +257,7 @@ export default {
|
|||
Private_Channel: 'Canal Privado',
|
||||
Private_Groups: 'Grupo Privado',
|
||||
Private: 'Privado',
|
||||
Processing: 'Processando...',
|
||||
Profile_saved_successfully: 'Perfil salvo com sucesso!',
|
||||
Profile: 'Perfil',
|
||||
Public_Channel: 'Canal Público',
|
||||
|
@ -299,10 +302,12 @@ export default {
|
|||
Search_global_users: 'Busca por usuários globais',
|
||||
Search_global_users_description: 'Caso ativado, busca por usuários de outras empresas ou servidores.',
|
||||
Select_Avatar: 'Selecionar Avatar',
|
||||
Select_Server: 'Selecionar Servidor',
|
||||
Select_Users: 'Selecionar Usuários',
|
||||
Send: 'Enviar',
|
||||
Send_audio_message: 'Enviar mensagem de áudio',
|
||||
Send_message: 'Enviar mensagem',
|
||||
Send_to: 'Enviar para...',
|
||||
Sent_an_attachment: 'Enviou um anexo',
|
||||
Server: 'Servidor',
|
||||
Set_username_subtitle: 'O usuário é utilizado para permitir que você seja mencionado em mensagens',
|
||||
|
@ -322,6 +327,7 @@ export default {
|
|||
Started_discussion: 'Iniciou uma discussão:',
|
||||
Submit: 'Enviar',
|
||||
Take_a_photo: 'Tirar uma foto',
|
||||
Take_a_video: 'Gravar um vídeo',
|
||||
Terms_of_Service: ' Termos de Serviço ',
|
||||
The_URL_is_invalid: 'A URL fornecida é inválida ou não acessível. Por favor tente novamente, mas com uma url diferente.',
|
||||
There_was_an_error_while_action: 'Aconteceu um erro {{action}}!',
|
||||
|
@ -330,6 +336,7 @@ export default {
|
|||
Thread: 'Tópico',
|
||||
Threads: 'Tópicos',
|
||||
Timezone: 'Fuso horário',
|
||||
To: 'Para',
|
||||
topic: 'tópico',
|
||||
Topic: 'Tópico',
|
||||
Try_again: 'Tentar novamente',
|
||||
|
@ -366,6 +373,7 @@ export default {
|
|||
Welcome: 'Bem vindo',
|
||||
Welcome_to_RocketChat: 'Bem vindo ao Rocket.Chat',
|
||||
Whats_your_2fa: 'Qual seu código de autenticação?',
|
||||
Without_Servers: 'Sem Servidores',
|
||||
Yes_action_it: 'Sim, {{action}}!',
|
||||
Yesterday: 'Ontem',
|
||||
You_are_in_preview_mode: 'Está é uma prévia do canal',
|
||||
|
@ -375,5 +383,6 @@ export default {
|
|||
you_were_mentioned: 'você foi mencionado',
|
||||
you: 'você',
|
||||
You: 'Você',
|
||||
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'Você precisa acessar ao menos um servidor Rocket.Chat para compartilhar.',
|
||||
You_will_not_be_able_to_recover_this_message: 'Você não será capaz de recuperar essa mensagem!'
|
||||
};
|
||||
|
|
185
app/index.js
185
app/index.js
|
@ -5,47 +5,18 @@ import {
|
|||
import { Provider } from 'react-redux';
|
||||
import { useScreens } from 'react-native-screens'; // eslint-disable-line import/no-unresolved
|
||||
import { Linking } from 'react-native';
|
||||
import firebase from 'react-native-firebase';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { appInit } from './actions';
|
||||
import { deepLinkingOpen } from './actions/deepLinking';
|
||||
import OnboardingView from './views/OnboardingView';
|
||||
import NewServerView from './views/NewServerView';
|
||||
import LoginSignupView from './views/LoginSignupView';
|
||||
import AuthLoadingView from './views/AuthLoadingView';
|
||||
import RoomsListView from './views/RoomsListView';
|
||||
import RoomView from './views/RoomView';
|
||||
import NewMessageView from './views/NewMessageView';
|
||||
import DirectoryView from './views/DirectoryView';
|
||||
import LoginView from './views/LoginView';
|
||||
import Navigation from './lib/Navigation';
|
||||
import Sidebar from './views/SidebarView';
|
||||
import ProfileView from './views/ProfileView';
|
||||
import SettingsView from './views/SettingsView';
|
||||
import LanguageView from './views/LanguageView';
|
||||
import AdminPanelView from './views/AdminPanelView';
|
||||
import RoomActionsView from './views/RoomActionsView';
|
||||
import RoomInfoView from './views/RoomInfoView';
|
||||
import RoomInfoEditView from './views/RoomInfoEditView';
|
||||
import RoomMembersView from './views/RoomMembersView';
|
||||
import SearchMessagesView from './views/SearchMessagesView';
|
||||
import ReadReceiptsView from './views/ReadReceiptView';
|
||||
import ThreadMessagesView from './views/ThreadMessagesView';
|
||||
import MessagesView from './views/MessagesView';
|
||||
import AutoTranslateView from './views/AutoTranslateView';
|
||||
import SelectedUsersView from './views/SelectedUsersView';
|
||||
import CreateChannelView from './views/CreateChannelView';
|
||||
import LegalView from './views/LegalView';
|
||||
import ForgotPasswordView from './views/ForgotPasswordView';
|
||||
import RegisterView from './views/RegisterView';
|
||||
import OAuthView from './views/OAuthView';
|
||||
import SetUsernameView from './views/SetUsernameView';
|
||||
import { HEADER_BACKGROUND, HEADER_TITLE, HEADER_BACK } from './constants/colors';
|
||||
import parseQuery from './lib/methods/helpers/parseQuery';
|
||||
import { initializePushNotifications, onNotification } from './notifications/push';
|
||||
import store from './lib/createStore';
|
||||
import NotificationBadge from './notifications/inApp';
|
||||
import { defaultHeader, onNavigationStateChange } from './utils/navigation';
|
||||
import Toast from './containers/Toast';
|
||||
|
||||
useScreens();
|
||||
|
||||
|
@ -63,35 +34,38 @@ const parseDeepLinking = (url) => {
|
|||
return null;
|
||||
};
|
||||
|
||||
const defaultHeader = {
|
||||
headerStyle: {
|
||||
backgroundColor: HEADER_BACKGROUND
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: HEADER_TITLE
|
||||
},
|
||||
headerBackTitle: null,
|
||||
headerTintColor: HEADER_BACK
|
||||
};
|
||||
|
||||
// Outside
|
||||
const OutsideStack = createStackNavigator({
|
||||
OnboardingView: {
|
||||
screen: OnboardingView,
|
||||
getScreen: () => require('./views/OnboardingView').default,
|
||||
header: null
|
||||
},
|
||||
NewServerView,
|
||||
LoginSignupView,
|
||||
LoginView,
|
||||
ForgotPasswordView,
|
||||
RegisterView,
|
||||
LegalView
|
||||
NewServerView: {
|
||||
getScreen: () => require('./views/NewServerView').default
|
||||
},
|
||||
LoginSignupView: {
|
||||
getScreen: () => require('./views/LoginSignupView').default
|
||||
},
|
||||
LoginView: {
|
||||
getScreen: () => require('./views/LoginView').default
|
||||
},
|
||||
ForgotPasswordView: {
|
||||
getScreen: () => require('./views/ForgotPasswordView').default
|
||||
},
|
||||
RegisterView: {
|
||||
getScreen: () => require('./views/RegisterView').default
|
||||
},
|
||||
LegalView: {
|
||||
getScreen: () => require('./views/LegalView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
||||
const OAuthStack = createStackNavigator({
|
||||
OAuthView
|
||||
OAuthView: {
|
||||
getScreen: () => require('./views/OAuthView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
@ -107,19 +81,45 @@ const OutsideStackModal = createStackNavigator({
|
|||
|
||||
// Inside
|
||||
const ChatsStack = createStackNavigator({
|
||||
RoomsListView,
|
||||
RoomView,
|
||||
RoomActionsView,
|
||||
RoomInfoView,
|
||||
RoomInfoEditView,
|
||||
RoomMembersView,
|
||||
SearchMessagesView,
|
||||
SelectedUsersView,
|
||||
ThreadMessagesView,
|
||||
MessagesView,
|
||||
AutoTranslateView,
|
||||
ReadReceiptsView,
|
||||
DirectoryView
|
||||
RoomsListView: {
|
||||
getScreen: () => require('./views/RoomsListView').default
|
||||
},
|
||||
RoomView: {
|
||||
getScreen: () => require('./views/RoomView').default
|
||||
},
|
||||
RoomActionsView: {
|
||||
getScreen: () => require('./views/RoomActionsView').default
|
||||
},
|
||||
RoomInfoView: {
|
||||
getScreen: () => require('./views/RoomInfoView').default
|
||||
},
|
||||
RoomInfoEditView: {
|
||||
getScreen: () => require('./views/RoomInfoEditView').default
|
||||
},
|
||||
RoomMembersView: {
|
||||
getScreen: () => require('./views/RoomMembersView').default
|
||||
},
|
||||
SearchMessagesView: {
|
||||
getScreen: () => require('./views/SearchMessagesView').default
|
||||
},
|
||||
SelectedUsersView: {
|
||||
getScreen: () => require('./views/SelectedUsersView').default
|
||||
},
|
||||
ThreadMessagesView: {
|
||||
getScreen: () => require('./views/ThreadMessagesView').default
|
||||
},
|
||||
MessagesView: {
|
||||
getScreen: () => require('./views/MessagesView').default
|
||||
},
|
||||
AutoTranslateView: {
|
||||
getScreen: () => require('./views/AutoTranslateView').default
|
||||
},
|
||||
ReadReceiptsView: {
|
||||
getScreen: () => require('./views/ReadReceiptView').default
|
||||
},
|
||||
DirectoryView: {
|
||||
getScreen: () => require('./views/DirectoryView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
@ -135,7 +135,9 @@ ChatsStack.navigationOptions = ({ navigation }) => {
|
|||
};
|
||||
|
||||
const ProfileStack = createStackNavigator({
|
||||
ProfileView
|
||||
ProfileView: {
|
||||
getScreen: () => require('./views/ProfileView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
@ -151,14 +153,20 @@ ProfileStack.navigationOptions = ({ navigation }) => {
|
|||
};
|
||||
|
||||
const SettingsStack = createStackNavigator({
|
||||
SettingsView,
|
||||
LanguageView
|
||||
SettingsView: {
|
||||
getScreen: () => require('./views/SettingsView').default
|
||||
},
|
||||
LanguageView: {
|
||||
getScreen: () => require('./views/LanguageView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
||||
const AdminPanelStack = createStackNavigator({
|
||||
AdminPanelView
|
||||
AdminPanelView: {
|
||||
getScreen: () => require('./views/AdminPanelView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
@ -183,9 +191,15 @@ const ChatsDrawer = createDrawerNavigator({
|
|||
});
|
||||
|
||||
const NewMessageStack = createStackNavigator({
|
||||
NewMessageView,
|
||||
SelectedUsersViewCreateChannel: SelectedUsersView,
|
||||
CreateChannelView
|
||||
NewMessageView: {
|
||||
getScreen: () => require('./views/NewMessageView').default
|
||||
},
|
||||
SelectedUsersViewCreateChannel: {
|
||||
getScreen: () => require('./views/SelectedUsersView').default
|
||||
},
|
||||
CreateChannelView: {
|
||||
getScreen: () => require('./views/CreateChannelView').default
|
||||
}
|
||||
}, {
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
@ -200,7 +214,9 @@ const InsideStackModal = createStackNavigator({
|
|||
});
|
||||
|
||||
const SetUsernameStack = createStackNavigator({
|
||||
SetUsernameView
|
||||
SetUsernameView: {
|
||||
getScreen: () => require('./views/SetUsernameView').default
|
||||
}
|
||||
});
|
||||
|
||||
class CustomInsideStack extends React.Component {
|
||||
|
@ -216,6 +232,7 @@ class CustomInsideStack extends React.Component {
|
|||
<React.Fragment>
|
||||
<InsideStackModal navigation={navigation} />
|
||||
<NotificationBadge navigation={navigation} />
|
||||
<Toast />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -225,7 +242,9 @@ const App = createAppContainer(createSwitchNavigator(
|
|||
{
|
||||
OutsideStack: OutsideStackModal,
|
||||
InsideStack: CustomInsideStack,
|
||||
AuthLoading: AuthLoadingView,
|
||||
AuthLoading: {
|
||||
getScreen: () => require('./views/AuthLoadingView').default
|
||||
},
|
||||
SetUsernameStack
|
||||
},
|
||||
{
|
||||
|
@ -233,28 +252,6 @@ const App = createAppContainer(createSwitchNavigator(
|
|||
}
|
||||
));
|
||||
|
||||
// gets the current screen from navigation state
|
||||
const getActiveRouteName = (navigationState) => {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
const route = navigationState.routes[navigationState.index];
|
||||
// dive into nested navigators
|
||||
if (route.routes) {
|
||||
return getActiveRouteName(route);
|
||||
}
|
||||
return route.routeName;
|
||||
};
|
||||
|
||||
const onNavigationStateChange = (prevState, currentState) => {
|
||||
const currentScreen = getActiveRouteName(currentState);
|
||||
const prevScreen = getActiveRouteName(prevState);
|
||||
|
||||
if (prevScreen !== currentScreen) {
|
||||
firebase.analytics().setCurrentScreen(currentScreen);
|
||||
}
|
||||
};
|
||||
|
||||
export default class Root extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { NavigationActions } from 'react-navigation';
|
||||
|
||||
let _shareNavigator;
|
||||
|
||||
function setTopLevelNavigator(navigatorRef) {
|
||||
_shareNavigator = navigatorRef;
|
||||
}
|
||||
|
||||
function navigate(routeName, params) {
|
||||
_shareNavigator.dispatch(
|
||||
NavigationActions.navigate({
|
||||
routeName,
|
||||
params
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
navigate,
|
||||
setTopLevelNavigator
|
||||
};
|
|
@ -40,6 +40,15 @@ export default async function() {
|
|||
if (setting._id === 'Site_Name') {
|
||||
updateServer.call(this, { name: setting.valueAsString });
|
||||
}
|
||||
if (setting._id === 'UI_Use_Real_Name') {
|
||||
updateServer.call(this, { useRealName: setting.valueAsBoolean });
|
||||
}
|
||||
if (setting._id === 'FileUpload_MediaTypeWhiteList') {
|
||||
updateServer.call(this, { FileUpload_MediaTypeWhiteList: setting.valueAsString });
|
||||
}
|
||||
if (setting._id === 'FileUpload_MaxFileSize') {
|
||||
updateServer.call(this, { FileUpload_MaxFileSize: setting.valueAsNumber });
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import reduxStore from '../createStore';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
|
||||
|
@ -23,11 +22,12 @@ export function cancelUpload(path) {
|
|||
}
|
||||
}
|
||||
|
||||
export function sendFileMessage(rid, fileInfo, tmid) {
|
||||
export function sendFileMessage(rid, fileInfo, tmid, server, user) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const { FileUpload_MaxFileSize, Site_Url } = reduxStore.getState().settings;
|
||||
const { id, token } = reduxStore.getState().login.user;
|
||||
const { serversDB } = database.databases;
|
||||
const { FileUpload_MaxFileSize, id: Site_Url } = serversDB.objectForPrimaryKey('servers', server);
|
||||
const { id, token } = user;
|
||||
|
||||
// -1 maxFileSize means there is no limit
|
||||
if (FileUpload_MaxFileSize > -1 && fileInfo.size > FileUpload_MaxFileSize) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import messagesStatus from '../../constants/messagesStatus';
|
||||
import buildMessage from './helpers/buildMessage';
|
||||
import database from '../realm';
|
||||
import reduxStore from '../createStore';
|
||||
import log from '../../utils/log';
|
||||
import random from '../../utils/random';
|
||||
|
||||
export const getMessage = (rid, msg = '', tmid) => {
|
||||
export const getMessage = (rid, msg = '', tmid, user) => {
|
||||
const _id = random(17);
|
||||
const { id, username } = user;
|
||||
const message = {
|
||||
_id,
|
||||
rid,
|
||||
|
@ -16,8 +16,8 @@ export const getMessage = (rid, msg = '', tmid) => {
|
|||
_updatedAt: new Date(),
|
||||
status: messagesStatus.TEMP,
|
||||
u: {
|
||||
_id: reduxStore.getState().login.user.id || '1',
|
||||
username: reduxStore.getState().login.user.username
|
||||
_id: id || '1',
|
||||
username
|
||||
}
|
||||
};
|
||||
try {
|
||||
|
@ -43,9 +43,9 @@ export async function sendMessageCall(message) {
|
|||
return data;
|
||||
}
|
||||
|
||||
export default async function(rid, msg, tmid) {
|
||||
export default async function(rid, msg, tmid, user) {
|
||||
try {
|
||||
const message = getMessage(rid, msg, tmid);
|
||||
const message = getMessage(rid, msg, tmid, user);
|
||||
const [room] = database.objects('subscriptions').filtered('rid == $0', rid);
|
||||
|
||||
if (room) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Realm from 'realm';
|
||||
import RNRealmPath from 'react-native-realm-path';
|
||||
|
||||
// import { AsyncStorage } from 'react-native';
|
||||
// Realm.clearTestState();
|
||||
|
@ -25,6 +26,9 @@ const serversSchema = {
|
|||
id: 'string',
|
||||
name: { type: 'string', optional: true },
|
||||
iconURL: { type: 'string', optional: true },
|
||||
useRealName: { type: 'bool', optional: true },
|
||||
FileUpload_MediaTypeWhiteList: { type: 'string', optional: true },
|
||||
FileUpload_MaxFileSize: { type: 'int', optional: true },
|
||||
roomsUpdatedAt: { type: 'date', optional: true },
|
||||
version: 'string?'
|
||||
}
|
||||
|
@ -408,12 +412,12 @@ const inMemorySchema = [usersTypingSchema, activeUsersSchema];
|
|||
class DB {
|
||||
databases = {
|
||||
serversDB: new Realm({
|
||||
path: 'default.realm',
|
||||
path: `${ RNRealmPath.realmPath }default.realm`,
|
||||
schema: [
|
||||
userSchema,
|
||||
serversSchema
|
||||
],
|
||||
schemaVersion: 9,
|
||||
schemaVersion: 10,
|
||||
migration: (oldRealm, newRealm) => {
|
||||
if (oldRealm.schemaVersion >= 1 && newRealm.schemaVersion <= 9) {
|
||||
const newServers = newRealm.objects('servers');
|
||||
|
@ -426,7 +430,7 @@ class DB {
|
|||
}
|
||||
}),
|
||||
inMemoryDB: new Realm({
|
||||
path: 'memory.realm',
|
||||
path: `${ RNRealmPath.realmPath }memory.realm`,
|
||||
schema: inMemorySchema,
|
||||
schemaVersion: 2,
|
||||
inMemory: true
|
||||
|
@ -468,7 +472,7 @@ class DB {
|
|||
setActiveDB(database = '') {
|
||||
const path = database.replace(/(^\w+:|^)\/\//, '');
|
||||
return this.databases.activeDB = new Realm({
|
||||
path: `${ path }.realm`,
|
||||
path: `${ RNRealmPath.realmPath }${ path }.realm`,
|
||||
schema,
|
||||
schemaVersion: 13,
|
||||
migration: (oldRealm, newRealm) => {
|
||||
|
|
|
@ -14,6 +14,9 @@ import {
|
|||
setUser, setLoginServices, loginRequest, loginFailure, logout
|
||||
} from '../actions/login';
|
||||
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
|
||||
import {
|
||||
shareSelectServer, shareSetUser
|
||||
} from '../actions/share';
|
||||
|
||||
import subscribeRooms from './methods/subscriptions/rooms';
|
||||
import subscribeRoom from './methods/subscriptions/room';
|
||||
|
@ -217,6 +220,35 @@ const RocketChat = {
|
|||
});
|
||||
},
|
||||
|
||||
async shareExtensionInit(server) {
|
||||
database.setActiveDB(server);
|
||||
|
||||
if (this.sdk) {
|
||||
this.sdk.disconnect();
|
||||
this.sdk = null;
|
||||
}
|
||||
|
||||
// Use useSsl: false only if server url starts with http://
|
||||
const useSsl = !/http:\/\//.test(server);
|
||||
|
||||
this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl });
|
||||
|
||||
// set Server
|
||||
const { serversDB } = database.databases;
|
||||
reduxStore.dispatch(shareSelectServer(server));
|
||||
|
||||
// set User info
|
||||
const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
const user = userId && serversDB.objectForPrimaryKey('user', userId);
|
||||
reduxStore.dispatch(shareSetUser({
|
||||
id: user.id,
|
||||
token: user.token,
|
||||
username: user.username
|
||||
}));
|
||||
|
||||
await RocketChat.login({ resume: user.token });
|
||||
},
|
||||
|
||||
register(credentials) {
|
||||
// RC 0.50.0
|
||||
return this.sdk.post('users.register', credentials, false);
|
||||
|
@ -730,14 +762,14 @@ const RocketChat = {
|
|||
return JSON.parse(useMarkdown);
|
||||
},
|
||||
async getSortPreferences() {
|
||||
const prefs = await AsyncStorage.getItem(SORT_PREFS_KEY);
|
||||
return JSON.parse(prefs);
|
||||
const prefs = await RNUserDefaults.objectForKey(SORT_PREFS_KEY);
|
||||
return prefs;
|
||||
},
|
||||
async saveSortPreference(param) {
|
||||
try {
|
||||
let prefs = await RocketChat.getSortPreferences();
|
||||
prefs = { ...prefs, ...param };
|
||||
return await AsyncStorage.setItem(SORT_PREFS_KEY, JSON.stringify(prefs));
|
||||
return await RNUserDefaults.setObjectForKey(SORT_PREFS_KEY, prefs);
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ import PropTypes from 'prop-types';
|
|||
import Avatar from '../../containers/Avatar';
|
||||
import Touch from '../../utils/touch';
|
||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||
import styles from './styles';
|
||||
import styles, { ROW_HEIGHT } from './styles';
|
||||
|
||||
export { ROW_HEIGHT };
|
||||
|
||||
const DirectoryItemLabel = React.memo(({ text }) => {
|
||||
if (!text) {
|
||||
|
@ -30,10 +32,10 @@ const DirectoryItem = ({
|
|||
/>
|
||||
<View style={styles.directoryItemTextContainer}>
|
||||
<View style={styles.directoryItemTextTitle}>
|
||||
<RoomTypeIcon type='c' />
|
||||
<RoomTypeIcon type={type} />
|
||||
<Text style={styles.directoryItemName} numberOfLines={1}>{title}</Text>
|
||||
</View>
|
||||
<Text style={styles.directoryItemUsername} numberOfLines={1}>{description}</Text>
|
||||
{ description ? <Text style={styles.directoryItemUsername} numberOfLines={1}>{description}</Text> : null }
|
||||
</View>
|
||||
<DirectoryItemLabel text={rightLabel} />
|
||||
</View>
|
|
@ -0,0 +1,49 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import { COLOR_WHITE } from '../../constants/colors';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
|
||||
export const ROW_HEIGHT = 54;
|
||||
|
||||
export default StyleSheet.create({
|
||||
directoryItemButton: {
|
||||
height: ROW_HEIGHT,
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
directoryItemContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 15
|
||||
},
|
||||
directoryItemAvatar: {
|
||||
marginRight: 12
|
||||
},
|
||||
directoryItemTextTitle: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
directoryItemTextContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
directoryItemName: {
|
||||
flex: 1,
|
||||
fontSize: 17,
|
||||
...sharedStyles.textMedium,
|
||||
...sharedStyles.textColorNormal
|
||||
},
|
||||
directoryItemUsername: {
|
||||
fontSize: 14,
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorDescription
|
||||
},
|
||||
directoryItemLabel: {
|
||||
fontSize: 14,
|
||||
paddingLeft: 10,
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorDescription
|
||||
}
|
||||
});
|
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, Text, Animated } from 'react-native';
|
||||
import { RectButton, PanGestureHandler, State } from 'react-native-gesture-handler';
|
||||
|
@ -12,6 +11,7 @@ import styles, {
|
|||
import UnreadBadge from './UnreadBadge';
|
||||
import TypeIcon from './TypeIcon';
|
||||
import LastMessage from './LastMessage';
|
||||
import { capitalize, formatDate } from '../../utils/room';
|
||||
import { LeftActions, RightActions } from './Actions';
|
||||
|
||||
export { ROW_HEIGHT };
|
||||
|
@ -203,19 +203,12 @@ export default class RoomItem extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
formatDate = date => moment(date).calendar(null, {
|
||||
lastDay: `[${ I18n.t('Yesterday') }]`,
|
||||
sameDay: 'h:mm A',
|
||||
lastWeek: 'dddd',
|
||||
sameElse: 'MMM D'
|
||||
})
|
||||
|
||||
render() {
|
||||
const {
|
||||
unread, userMentions, name, _updatedAt, alert, testID, type, avatarSize, baseUrl, userId, username, token, id, prid, showLastMessage, lastMessage, isRead, width, favorite
|
||||
} = this.props;
|
||||
|
||||
const date = this.formatDate(_updatedAt);
|
||||
const date = formatDate(_updatedAt);
|
||||
|
||||
let accessibilityLabel = name;
|
||||
if (unread === 1) {
|
||||
|
@ -275,7 +268,7 @@ export default class RoomItem extends React.Component {
|
|||
<View style={styles.titleContainer}>
|
||||
<TypeIcon type={type} id={id} prid={prid} />
|
||||
<Text style={[styles.title, alert && styles.alert]} ellipsizeMode='tail' numberOfLines={1}>{ name }</Text>
|
||||
{_updatedAt ? <Text style={[styles.date, alert && styles.updateAlert]} ellipsizeMode='tail' numberOfLines={1}>{ date }</Text> : null}
|
||||
{_updatedAt ? <Text style={[styles.date, alert && styles.updateAlert]} ellipsizeMode='tail' numberOfLines={1}>{ capitalize(date) }</Text> : null}
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<LastMessage lastMessage={lastMessage} type={type} showLastMessage={showLastMessage} username={username} alert={alert} />
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, Text } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { RectButton } from 'react-native-gesture-handler';
|
||||
|
||||
import log from '../../utils/log';
|
||||
import Check from '../../containers/Check';
|
||||
import styles, { ROW_HEIGHT } from './styles';
|
||||
|
||||
export { ROW_HEIGHT };
|
||||
|
||||
const ServerItem = React.memo(({
|
||||
server, item, onPress, hasCheck
|
||||
}) => (
|
||||
<RectButton onPress={onPress} style={styles.serverItem} testID={`rooms-list-header-server-${ item.id }`}>
|
||||
<View style={styles.serverItemContainer}>
|
||||
{item.iconURL
|
||||
? (
|
||||
<FastImage
|
||||
source={{
|
||||
uri: item.iconURL,
|
||||
priority: FastImage.priority.high
|
||||
}}
|
||||
defaultSource={{ uri: 'logo' }}
|
||||
style={styles.serverIcon}
|
||||
onError={() => log('err_loading_server_icon')}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<FastImage
|
||||
source={{ uri: 'logo' }}
|
||||
style={styles.serverIcon}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<View style={styles.serverTextContainer}>
|
||||
<Text style={styles.serverName}>{item.name || item.id}</Text>
|
||||
<Text style={styles.serverUrl}>{item.id}</Text>
|
||||
</View>
|
||||
{item.id === server && hasCheck ? <Check /> : null}
|
||||
</View>
|
||||
</RectButton>
|
||||
));
|
||||
|
||||
ServerItem.propTypes = {
|
||||
onPress: PropTypes.func.isRequired,
|
||||
item: PropTypes.object.isRequired,
|
||||
hasCheck: PropTypes.bool,
|
||||
server: PropTypes.string
|
||||
};
|
||||
|
||||
export default ServerItem;
|
|
@ -0,0 +1,39 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import { COLOR_WHITE } from '../../constants/colors';
|
||||
|
||||
export const ROW_HEIGHT = 56;
|
||||
|
||||
export default StyleSheet.create({
|
||||
serverItem: {
|
||||
height: ROW_HEIGHT,
|
||||
backgroundColor: COLOR_WHITE,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
serverItemContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
serverIcon: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
marginHorizontal: 15,
|
||||
borderRadius: 4
|
||||
},
|
||||
serverTextContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
serverName: {
|
||||
fontSize: 18,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textSemibold
|
||||
},
|
||||
serverUrl: {
|
||||
fontSize: 15,
|
||||
...sharedStyles.textColorDescription,
|
||||
...sharedStyles.textRegular
|
||||
}
|
||||
});
|
|
@ -11,6 +11,7 @@ import app from './app';
|
|||
import sortPreferences from './sortPreferences';
|
||||
import notification from './notification';
|
||||
import markdown from './markdown';
|
||||
import share from './share';
|
||||
|
||||
export default combineReducers({
|
||||
settings,
|
||||
|
@ -24,5 +25,6 @@ export default combineReducers({
|
|||
rooms,
|
||||
sortPreferences,
|
||||
notification,
|
||||
markdown
|
||||
markdown,
|
||||
share
|
||||
});
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import { SHARE } from '../actions/actionsTypes';
|
||||
|
||||
const initialState = {
|
||||
user: {},
|
||||
server: ''
|
||||
};
|
||||
|
||||
export default function share(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case SHARE.SELECT_SERVER:
|
||||
return {
|
||||
...state,
|
||||
server: action.server
|
||||
};
|
||||
case SHARE.SET_USER:
|
||||
return {
|
||||
...state,
|
||||
user: action.user
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,15 @@ import {
|
|||
put, call, takeLatest, select, take, fork, cancel
|
||||
} from 'redux-saga/effects';
|
||||
import RNUserDefaults from 'rn-user-defaults';
|
||||
import moment from 'moment';
|
||||
import 'moment/min/locales';
|
||||
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import { appStart } from '../actions';
|
||||
import { serverFinishAdd, selectServerRequest } from '../actions/server';
|
||||
import { loginFailure, loginSuccess, setUser } from '../actions/login';
|
||||
import { roomsRequest } from '../actions/rooms';
|
||||
import { toMomentLocale } from '../utils/moment';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import log from '../utils/log';
|
||||
import I18n from '../i18n';
|
||||
|
@ -72,6 +75,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
|||
yield fork(fetchUserPresence);
|
||||
|
||||
I18n.locale = user.language;
|
||||
moment.locale(toMomentLocale(user.language));
|
||||
|
||||
const { serversDB } = database.databases;
|
||||
serversDB.write(() => {
|
||||
|
@ -132,6 +136,7 @@ const handleLogout = function* handleLogout() {
|
|||
const handleSetUser = function handleSetUser({ user }) {
|
||||
if (user && user.language) {
|
||||
I18n.locale = user.language;
|
||||
moment.locale(toMomentLocale(user.language));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { createAppContainer, createStackNavigator, createSwitchNavigator } from 'react-navigation';
|
||||
import { Provider } from 'react-redux';
|
||||
import RNUserDefaults from 'rn-user-defaults';
|
||||
|
||||
import Navigation from './lib/ShareNavigation';
|
||||
import store from './lib/createStore';
|
||||
import sharedStyles from './views/Styles';
|
||||
import { isNotch, isIOS } from './utils/deviceInfo';
|
||||
import { defaultHeader, onNavigationStateChange } from './utils/navigation';
|
||||
import RocketChat from './lib/rocketchat';
|
||||
|
||||
const InsideNavigator = createStackNavigator({
|
||||
ShareListView: {
|
||||
getScreen: () => require('./views/ShareListView').default
|
||||
},
|
||||
ShareView: {
|
||||
getScreen: () => require('./views/ShareView').default
|
||||
},
|
||||
SelectServerView: {
|
||||
getScreen: () => require('./views/SelectServerView').default
|
||||
}
|
||||
}, {
|
||||
initialRouteName: 'ShareListView',
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
||||
const OutsideNavigator = createStackNavigator({
|
||||
WithoutServersView: {
|
||||
getScreen: () => require('./views/WithoutServersView').default
|
||||
}
|
||||
}, {
|
||||
initialRouteName: 'WithoutServersView',
|
||||
defaultNavigationOptions: defaultHeader
|
||||
});
|
||||
|
||||
const AppContainer = createAppContainer(createSwitchNavigator({
|
||||
OutsideStack: OutsideNavigator,
|
||||
InsideStack: InsideNavigator,
|
||||
AuthLoading: {
|
||||
getScreen: () => require('./views/AuthLoadingView').default
|
||||
}
|
||||
},
|
||||
{
|
||||
initialRouteName: 'AuthLoading'
|
||||
}));
|
||||
|
||||
class Root extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isLandscape: false
|
||||
};
|
||||
this.init();
|
||||
}
|
||||
|
||||
init = async() => {
|
||||
if (isIOS) {
|
||||
await RNUserDefaults.setName('group.ios.chat.rocket');
|
||||
}
|
||||
const currentServer = await RNUserDefaults.get('currentServer');
|
||||
const token = await RNUserDefaults.get(RocketChat.TOKEN_KEY);
|
||||
|
||||
if (currentServer && token) {
|
||||
await Navigation.navigate('InsideStack');
|
||||
await RocketChat.shareExtensionInit(currentServer);
|
||||
} else {
|
||||
await Navigation.navigate('OutsideStack');
|
||||
}
|
||||
}
|
||||
|
||||
handleLayout = (event) => {
|
||||
const { width, height } = event.nativeEvent.layout;
|
||||
this.setState({ isLandscape: width > height });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isLandscape } = this.state;
|
||||
return (
|
||||
<View
|
||||
style={[sharedStyles.container, isLandscape && isNotch ? sharedStyles.notchLandscapeContainer : {}]}
|
||||
onLayout={this.handleLayout}
|
||||
>
|
||||
<Provider store={store}>
|
||||
<AppContainer
|
||||
ref={(navigatorRef) => {
|
||||
Navigation.setTopLevelNavigator(navigatorRef);
|
||||
}}
|
||||
onNavigationStateChange={onNavigationStateChange}
|
||||
/>
|
||||
</Provider>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Root;
|
|
@ -1,32 +1,3 @@
|
|||
import React from 'react';
|
||||
import { Alert, StyleSheet } from 'react-native';
|
||||
import EasyToast from 'react-native-easy-toast';
|
||||
import { Alert } from 'react-native';
|
||||
|
||||
import { COLOR_TOAST, COLOR_WHITE } from '../constants/colors';
|
||||
import { isNotch } from './deviceInfo';
|
||||
import sharedStyles from '../views/Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
toast: {
|
||||
backgroundColor: COLOR_TOAST
|
||||
},
|
||||
text: {
|
||||
...sharedStyles.textRegular,
|
||||
color: COLOR_WHITE,
|
||||
fontSize: 14
|
||||
}
|
||||
});
|
||||
|
||||
const positionValue = isNotch ? 230 : 200;
|
||||
|
||||
export const Toast = React.forwardRef((props, ref) => (
|
||||
<EasyToast
|
||||
{...props}
|
||||
ref={ref}
|
||||
positionValue={positionValue}
|
||||
style={styles.toast}
|
||||
textStyle={styles.text}
|
||||
opacity={0.8}
|
||||
/>
|
||||
));
|
||||
export const showErrorAlert = (message, title, onPress = () => {}) => Alert.alert(title, message, [{ text: 'OK', onPress }], { cancelable: true });
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
export const canUploadFile = (file, serverInfo) => {
|
||||
const { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize } = serverInfo;
|
||||
if (!(file && file.path)) {
|
||||
return true;
|
||||
}
|
||||
if (file.size > FileUpload_MaxFileSize) {
|
||||
return false;
|
||||
}
|
||||
// if white list is empty, all media types are enabled
|
||||
if (!FileUpload_MediaTypeWhiteList) {
|
||||
return true;
|
||||
}
|
||||
const allowedMime = FileUpload_MediaTypeWhiteList.split(',');
|
||||
if (allowedMime.includes(file.mime)) {
|
||||
return true;
|
||||
}
|
||||
const wildCardGlob = '/*';
|
||||
const wildCards = allowedMime.filter(item => item.indexOf(wildCardGlob) > 0);
|
||||
if (wildCards.includes(file.mime.replace(/(\/.*)$/, wildCardGlob))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
const localeKeys = {
|
||||
en: 'en',
|
||||
ru: 'ru',
|
||||
'pt-BR': 'pt-br',
|
||||
'zh-CN': 'zh-cn',
|
||||
fr: 'fr',
|
||||
de: 'de',
|
||||
'pt-PT': 'pt'
|
||||
};
|
||||
|
||||
export const toMomentLocale = locale => localeKeys[locale];
|
|
@ -0,0 +1,36 @@
|
|||
import firebase from 'react-native-firebase';
|
||||
|
||||
import { HEADER_BACKGROUND, HEADER_TITLE, HEADER_BACK } from '../constants/colors';
|
||||
|
||||
export const defaultHeader = {
|
||||
headerStyle: {
|
||||
backgroundColor: HEADER_BACKGROUND
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: HEADER_TITLE
|
||||
},
|
||||
headerBackTitle: null,
|
||||
headerTintColor: HEADER_BACK
|
||||
};
|
||||
|
||||
// gets the current screen from navigation state
|
||||
export const getActiveRouteName = (navigationState) => {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
const route = navigationState.routes[navigationState.index];
|
||||
// dive into nested navigators
|
||||
if (route.routes) {
|
||||
return getActiveRouteName(route);
|
||||
}
|
||||
return route.routeName;
|
||||
};
|
||||
|
||||
export const onNavigationStateChange = (prevState, currentState) => {
|
||||
const currentScreen = getActiveRouteName(currentState);
|
||||
const prevScreen = getActiveRouteName(prevState);
|
||||
|
||||
if (prevScreen !== currentScreen) {
|
||||
firebase.analytics().setCurrentScreen(currentScreen);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import moment from 'moment';
|
||||
|
||||
import I18n from '../i18n';
|
||||
|
||||
export const isOwner = room => room && room.roles && room.roles.length && !!room.roles.find(role => role === 'owner');
|
||||
|
||||
export const isMuted = (room, user) => room && room.muted && room.muted.find && !!room.muted.find(m => m === user.username);
|
||||
|
||||
export const isReadOnly = (room, user) => {
|
||||
if (isOwner(room)) {
|
||||
return false;
|
||||
}
|
||||
return (room && room.ro) || isMuted(room, user);
|
||||
};
|
||||
|
||||
export const isBlocked = (room) => {
|
||||
if (room) {
|
||||
const { t, blocked, blocker } = room;
|
||||
if (t === 'd' && (blocked || blocker)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const capitalize = (s) => {
|
||||
if (typeof s !== 'string') { return ''; }
|
||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||
};
|
||||
|
||||
export const formatDate = date => moment(date).calendar(null, {
|
||||
lastDay: `[${ I18n.t('Yesterday') }]`,
|
||||
sameDay: 'LT',
|
||||
lastWeek: 'dddd',
|
||||
sameElse: 'MMM D'
|
||||
});
|
|
@ -7,7 +7,7 @@ import { connect } from 'react-redux';
|
|||
import { SafeAreaView } from 'react-navigation';
|
||||
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import DirectoryItem from './DirectoryItem';
|
||||
import DirectoryItem from '../../presentation/DirectoryItem';
|
||||
import sharedStyles from '../Styles';
|
||||
import I18n from '../../i18n';
|
||||
import Touch from '../../utils/touch';
|
||||
|
|
|
@ -98,46 +98,6 @@ export default StyleSheet.create({
|
|||
marginHorizontal: 15,
|
||||
flex: 1
|
||||
},
|
||||
directoryItemButton: {
|
||||
height: 54,
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
directoryItemContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 15
|
||||
},
|
||||
directoryItemAvatar: {
|
||||
marginRight: 12
|
||||
},
|
||||
directoryItemTextTitle: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
directoryItemTextContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
directoryItemName: {
|
||||
flex: 1,
|
||||
fontSize: 17,
|
||||
...sharedStyles.textMedium,
|
||||
...sharedStyles.textColorNormal
|
||||
},
|
||||
directoryItemUsername: {
|
||||
fontSize: 14,
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorDescription
|
||||
},
|
||||
directoryItemLabel: {
|
||||
fontSize: 14,
|
||||
paddingLeft: 10,
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorDescription
|
||||
},
|
||||
inverted: {
|
||||
transform: [{ scaleY: -1 }]
|
||||
},
|
||||
|
|
|
@ -13,7 +13,9 @@ import KeyboardView from '../../presentation/KeyboardView';
|
|||
import sharedStyles from '../Styles';
|
||||
import styles from './styles';
|
||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import { showErrorAlert, Toast } from '../../utils/info';
|
||||
import { showErrorAlert } from '../../utils/info';
|
||||
import { LISTENER } from '../../containers/Toast';
|
||||
import EventEmitter from '../../utils/events';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import RCTextInput from '../../containers/TextInput';
|
||||
import log from '../../utils/log';
|
||||
|
@ -222,7 +224,7 @@ export default class ProfileView extends React.Component {
|
|||
setUser({ ...params });
|
||||
}
|
||||
this.setState({ saving: false, showPasswordAlert: false });
|
||||
this.toast.show(I18n.t('Profile_saved_successfully'));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Profile_saved_successfully') });
|
||||
this.init();
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -235,7 +237,7 @@ export default class ProfileView extends React.Component {
|
|||
try {
|
||||
const { user } = this.props;
|
||||
await RocketChat.resetAvatar(user.id);
|
||||
this.toast.show(I18n.t('Avatar_changed_successfully'));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Avatar_changed_successfully') });
|
||||
this.init();
|
||||
} catch (e) {
|
||||
this.handleError(e, 'resetAvatar', 'changing_avatar');
|
||||
|
@ -386,7 +388,6 @@ export default class ProfileView extends React.Component {
|
|||
keyboardVerticalOffset={128}
|
||||
>
|
||||
<StatusBar />
|
||||
<Toast ref={toast => this.toast = toast} />
|
||||
<ScrollView
|
||||
contentContainerStyle={sharedStyles.containerScrollView}
|
||||
testID='profile-view-list'
|
||||
|
|
|
@ -12,7 +12,9 @@ import KeyboardView from '../../presentation/KeyboardView';
|
|||
import sharedStyles from '../Styles';
|
||||
import styles from './styles';
|
||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import { showErrorAlert, Toast } from '../../utils/info';
|
||||
import { showErrorAlert } from '../../utils/info';
|
||||
import { LISTENER } from '../../containers/Toast';
|
||||
import EventEmitter from '../../utils/events';
|
||||
import database, { safeAddListener } from '../../lib/realm';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import RCTextInput from '../../containers/TextInput';
|
||||
|
@ -215,7 +217,7 @@ export default class RoomInfoEditView extends React.Component {
|
|||
if (error) {
|
||||
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_settings') }));
|
||||
} else {
|
||||
this.toast.show(I18n.t('Settings_succesfully_changed'));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Settings_succesfully_changed') });
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
@ -428,7 +430,6 @@ export default class RoomInfoEditView extends React.Component {
|
|||
<Text style={[sharedStyles.button_inverted, styles.colorDanger]} accessibilityTraits='button'>{I18n.t('DELETE')}</Text>
|
||||
</TouchableOpacity>
|
||||
<Loading visible={saving} />
|
||||
<Toast ref={toast => this.toast = toast} />
|
||||
</SafeAreaView>
|
||||
</ScrollView>
|
||||
</KeyboardView>
|
||||
|
|
|
@ -12,7 +12,8 @@ import UserItem from '../../presentation/UserItem';
|
|||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import database, { safeAddListener } from '../../lib/realm';
|
||||
import { Toast } from '../../utils/info';
|
||||
import { LISTENER } from '../../containers/Toast';
|
||||
import EventEmitter from '../../utils/events';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
import SearchBox from '../../containers/SearchBox';
|
||||
|
@ -232,7 +233,7 @@ export default class RoomMembersView extends React.Component {
|
|||
const { rid, userLongPressed } = this.state;
|
||||
try {
|
||||
await RocketChat.toggleMuteUserInRoom(rid, userLongPressed.username, !userLongPressed.muted);
|
||||
this.toast.show(I18n.t('User_has_been_key', { key: userLongPressed.muted ? I18n.t('unmuted') : I18n.t('muted') }));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('User_has_been_key', { key: userLongPressed.muted ? I18n.t('unmuted') : I18n.t('muted') }) });
|
||||
} catch (e) {
|
||||
log('err_handle_mute', e);
|
||||
}
|
||||
|
@ -299,7 +300,6 @@ export default class RoomMembersView extends React.Component {
|
|||
windowSize={10}
|
||||
{...scrollPersistTaps}
|
||||
/>
|
||||
<Toast ref={toast => this.toast = toast} />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,13 @@ const styles = StyleSheet.create({
|
|||
export default class UploadProgress extends Component {
|
||||
static propTypes = {
|
||||
window: PropTypes.object,
|
||||
rid: PropTypes.string
|
||||
rid: PropTypes.string,
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
token: PropTypes.string.isRequired
|
||||
}),
|
||||
baseUrl: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -124,13 +130,13 @@ export default class UploadProgress extends Component {
|
|||
}
|
||||
|
||||
tryAgain = async(item) => {
|
||||
const { rid } = this.props;
|
||||
const { rid, baseUrl: server, user } = this.props;
|
||||
|
||||
try {
|
||||
database.write(() => {
|
||||
item.error = false;
|
||||
});
|
||||
await RocketChat.sendFileMessage(rid, item);
|
||||
await RocketChat.sendFileMessage(rid, item, undefined, server, user);
|
||||
} catch (e) {
|
||||
log('err_upload_progress_try_again', e);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ import debounce from '../../utils/debounce';
|
|||
import buildMessage from '../../lib/methods/helpers/buildMessage';
|
||||
import FileModal from '../../containers/FileModal';
|
||||
import ReactionsModal from '../../containers/ReactionsModal';
|
||||
import { Toast } from '../../utils/info';
|
||||
import { LISTENER } from '../../containers/Toast';
|
||||
import { isReadOnly, isBlocked } from '../../utils/room';
|
||||
|
||||
@connect(state => ({
|
||||
user: {
|
||||
|
@ -409,8 +410,9 @@ export default class RoomView extends React.Component {
|
|||
}
|
||||
|
||||
sendMessage = (message, tmid) => {
|
||||
const { user } = this.props;
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
RocketChat.sendMessage(this.rid, message, this.tmid || tmid).then(() => {
|
||||
RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => {
|
||||
this.setLastOpen(null);
|
||||
});
|
||||
};
|
||||
|
@ -455,37 +457,6 @@ export default class RoomView extends React.Component {
|
|||
}
|
||||
};
|
||||
|
||||
isOwner = () => {
|
||||
const { room } = this.state;
|
||||
return room && room.roles && room.roles.length && !!room.roles.find(role => role === 'owner');
|
||||
}
|
||||
|
||||
isMuted = () => {
|
||||
const { room } = this.state;
|
||||
const { user } = this.props;
|
||||
return room && room.muted && room.muted.find && !!room.muted.find(m => m === user.username);
|
||||
}
|
||||
|
||||
isReadOnly = () => {
|
||||
const { room } = this.state;
|
||||
if (this.isOwner()) {
|
||||
return false;
|
||||
}
|
||||
return (room && room.ro) || this.isMuted();
|
||||
}
|
||||
|
||||
isBlocked = () => {
|
||||
const { room } = this.state;
|
||||
|
||||
if (room) {
|
||||
const { t, blocked, blocker } = room;
|
||||
if (t === 'd' && (blocked || blocker)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
fetchThreadName = async(tmid) => {
|
||||
try {
|
||||
|
@ -502,7 +473,7 @@ export default class RoomView extends React.Component {
|
|||
toggleFollowThread = async(isFollowingThread) => {
|
||||
try {
|
||||
await RocketChat.toggleFollowMessage(this.tmid, !isFollowingThread);
|
||||
this.toast.show(isFollowingThread ? 'Unfollowed thread' : 'Following thread');
|
||||
EventEmitter.emit(LISTENER, { message: isFollowingThread ? 'Unfollowed thread' : 'Following thread' });
|
||||
} catch (e) {
|
||||
log('err_toggle_follow_thread', e);
|
||||
}
|
||||
|
@ -576,7 +547,7 @@ export default class RoomView extends React.Component {
|
|||
|
||||
renderFooter = () => {
|
||||
const { joined, room } = this.state;
|
||||
const { navigation } = this.props;
|
||||
const { navigation, user } = this.props;
|
||||
|
||||
if (!joined && !this.tmid) {
|
||||
return (
|
||||
|
@ -593,14 +564,14 @@ export default class RoomView extends React.Component {
|
|||
</View>
|
||||
);
|
||||
}
|
||||
if (this.isReadOnly()) {
|
||||
if (isReadOnly(room, user)) {
|
||||
return (
|
||||
<View style={styles.readOnly}>
|
||||
<Text style={styles.previewMode}>{I18n.t('This_room_is_read_only')}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (this.isBlocked()) {
|
||||
if (isBlocked(room)) {
|
||||
return (
|
||||
<View style={styles.readOnly}>
|
||||
<Text style={styles.previewMode}>{I18n.t('This_room_is_blocked')}</Text>
|
||||
|
@ -630,7 +601,7 @@ export default class RoomView extends React.Component {
|
|||
return (
|
||||
<React.Fragment>
|
||||
{room._id && showActions
|
||||
? <MessageActions room={room} tmid={this.tmid} user={user} toast={this.toast} />
|
||||
? <MessageActions room={room} tmid={this.tmid} user={user} />
|
||||
: null
|
||||
}
|
||||
{showErrorActions ? <MessageErrorActions /> : null}
|
||||
|
@ -653,7 +624,7 @@ export default class RoomView extends React.Component {
|
|||
{this.renderFooter()}
|
||||
{this.renderActions()}
|
||||
<ReactionPicker onEmojiSelected={this.onReactionPress} />
|
||||
<UploadProgress rid={this.rid} />
|
||||
<UploadProgress rid={this.rid} user={user} baseUrl={baseUrl} />
|
||||
<FileModal
|
||||
attachment={selectedAttachment}
|
||||
isVisible={photoModalVisible}
|
||||
|
@ -668,7 +639,6 @@ export default class RoomView extends React.Component {
|
|||
user={user}
|
||||
baseUrl={baseUrl}
|
||||
/>
|
||||
<Toast ref={toast => this.toast = toast} />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
FlatList, StyleSheet, View
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { SafeAreaView } from 'react-navigation';
|
||||
|
||||
import I18n from '../i18n';
|
||||
import database from '../lib/realm';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { COLOR_BACKGROUND_CONTAINER } from '../constants/colors';
|
||||
import Navigation from '../lib/ShareNavigation';
|
||||
import ServerItem, { ROW_HEIGHT } from '../presentation/ServerItem';
|
||||
import sharedStyles from './Styles';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
|
||||
const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index });
|
||||
const keyExtractor = item => item.id;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
},
|
||||
list: {
|
||||
marginVertical: 32,
|
||||
...sharedStyles.separatorVertical
|
||||
},
|
||||
separator: {
|
||||
...sharedStyles.separatorBottom,
|
||||
marginLeft: 48
|
||||
}
|
||||
});
|
||||
|
||||
@connect(({ share }) => ({
|
||||
server: share.server
|
||||
}))
|
||||
export default class SelectServerView extends React.Component {
|
||||
static navigationOptions = () => ({
|
||||
title: I18n.t('Select_Server')
|
||||
})
|
||||
|
||||
static propTypes = {
|
||||
server: PropTypes.string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { serversDB } = database.databases;
|
||||
const servers = serversDB.objects('servers');
|
||||
const filteredServers = servers.filter(server => server.roomsUpdatedAt);
|
||||
this.state = {
|
||||
servers: filteredServers
|
||||
};
|
||||
}
|
||||
|
||||
select = async(server) => {
|
||||
const {
|
||||
server: currentServer
|
||||
} = this.props;
|
||||
|
||||
Navigation.navigate('ShareListView');
|
||||
if (currentServer !== server) {
|
||||
await RocketChat.shareExtensionInit(server);
|
||||
}
|
||||
}
|
||||
|
||||
renderItem = ({ item }) => {
|
||||
const { server } = this.props;
|
||||
return (
|
||||
<ServerItem
|
||||
server={server}
|
||||
onPress={() => this.select(item.id)}
|
||||
item={item}
|
||||
hasCheck
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSeparator = () => <View style={styles.separator} />;
|
||||
|
||||
render() {
|
||||
const { servers } = this.state;
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={styles.container}
|
||||
forceInset={{ bottom: 'never' }}
|
||||
>
|
||||
<StatusBar />
|
||||
<View style={styles.list}>
|
||||
<FlatList
|
||||
data={servers}
|
||||
keyExtractor={keyExtractor}
|
||||
renderItem={this.renderItem}
|
||||
getItemLayout={getItemLayout}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
enableEmptySections
|
||||
removeClippedSubviews
|
||||
keyboardShouldPersistTaps='always'
|
||||
windowSize={7}
|
||||
bounces={false}
|
||||
/>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
View, StyleSheet, Text, TextInput
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import I18n from '../../../i18n';
|
||||
import { COLOR_WHITE, HEADER_TITLE } from '../../../constants/colors';
|
||||
import sharedStyles from '../../Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
search: {
|
||||
fontSize: 20,
|
||||
color: COLOR_WHITE,
|
||||
...sharedStyles.textRegular,
|
||||
marginHorizontal: 14
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
...sharedStyles.textBold,
|
||||
color: HEADER_TITLE,
|
||||
marginHorizontal: 16
|
||||
}
|
||||
});
|
||||
|
||||
const Header = React.memo(({ searching, onChangeSearchText }) => {
|
||||
if (searching) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TextInput
|
||||
style={styles.search}
|
||||
placeholder={I18n.t('Search')}
|
||||
placeholderTextColor='rgba(255, 255, 255, 0.5)'
|
||||
onChangeText={onChangeSearchText}
|
||||
autoFocus
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return <Text style={styles.title}>{I18n.t('Send_to')}</Text>;
|
||||
});
|
||||
|
||||
Header.propTypes = {
|
||||
searching: PropTypes.bool,
|
||||
onChangeSearchText: PropTypes.func
|
||||
};
|
||||
|
||||
export default Header;
|
|
@ -0,0 +1,76 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Keyboard, LayoutAnimation, View, StyleSheet
|
||||
} from 'react-native';
|
||||
import ShareExtension from 'rn-extensions-share';
|
||||
|
||||
import SearchBox from '../../../containers/SearchBox';
|
||||
import { CloseShareExtensionButton } from '../../../containers/HeaderButton';
|
||||
import { HEADER_BACKGROUND } from '../../../constants/colors';
|
||||
|
||||
import sharedStyles from '../../Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: HEADER_BACKGROUND,
|
||||
flexDirection: 'row',
|
||||
...sharedStyles.separatorBottom
|
||||
}
|
||||
});
|
||||
|
||||
const Header = React.memo(({
|
||||
searching, onChangeSearchText, initSearch, cancelSearch
|
||||
}) => {
|
||||
const [text, setText] = useState('');
|
||||
|
||||
const onChangeText = (searchText) => {
|
||||
onChangeSearchText(searchText);
|
||||
setText(searchText);
|
||||
};
|
||||
|
||||
const onCancelPress = () => {
|
||||
Keyboard.dismiss();
|
||||
onChangeText('');
|
||||
cancelSearch();
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
};
|
||||
|
||||
const onFocus = () => {
|
||||
initSearch();
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{
|
||||
!searching
|
||||
? (
|
||||
<CloseShareExtensionButton
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<SearchBox
|
||||
value={text}
|
||||
hasCancel={searching}
|
||||
onFocus={onFocus}
|
||||
onCancelPress={onCancelPress}
|
||||
onChangeText={onChangeText}
|
||||
testID='rooms-list-view-search'
|
||||
key='rooms-list-view-search'
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
||||
Header.propTypes = {
|
||||
searching: PropTypes.bool,
|
||||
onChangeSearchText: PropTypes.func,
|
||||
initSearch: PropTypes.func,
|
||||
cancelSearch: PropTypes.func
|
||||
};
|
||||
|
||||
export default Header;
|
|
@ -0,0 +1,30 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Header from './Header';
|
||||
|
||||
const ShareListHeader = React.memo(({
|
||||
searching, initSearch, cancelSearch, search
|
||||
}) => {
|
||||
const onSearchChangeText = (text) => {
|
||||
search(text.trim());
|
||||
};
|
||||
|
||||
return (
|
||||
<Header
|
||||
searching={searching}
|
||||
initSearch={initSearch}
|
||||
cancelSearch={cancelSearch}
|
||||
onChangeSearchText={onSearchChangeText}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
ShareListHeader.propTypes = {
|
||||
searching: PropTypes.bool,
|
||||
initSearch: PropTypes.func,
|
||||
cancelSearch: PropTypes.func,
|
||||
search: PropTypes.func
|
||||
};
|
||||
|
||||
export default ShareListHeader;
|
|
@ -0,0 +1,417 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
View, Text, LayoutAnimation, FlatList, ActivityIndicator, Keyboard, BackHandler
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-navigation';
|
||||
import ShareExtension from 'rn-extensions-share';
|
||||
import { connect } from 'react-redux';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import * as mime from 'react-native-mime-types';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import Navigation from '../../lib/ShareNavigation';
|
||||
import database from '../../lib/realm';
|
||||
import { isIOS, isAndroid } from '../../utils/deviceInfo';
|
||||
import I18n from '../../i18n';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import log from '../../utils/log';
|
||||
import { canUploadFile } from '../../utils/media';
|
||||
import DirectoryItem, { ROW_HEIGHT } from '../../presentation/DirectoryItem';
|
||||
import ServerItem from '../../presentation/ServerItem';
|
||||
import { CloseShareExtensionButton, CustomHeaderButtons, Item } from '../../containers/HeaderButton';
|
||||
import ShareListHeader from './Header';
|
||||
|
||||
import styles from './styles';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
|
||||
const LIMIT = 50;
|
||||
const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index });
|
||||
const keyExtractor = item => item.rid;
|
||||
|
||||
@connect(({ share }) => ({
|
||||
userId: share.user && share.user.id,
|
||||
token: share.user && share.user.token,
|
||||
server: share.server,
|
||||
baseUrl: share ? share.server : ''
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class ShareListView extends React.Component {
|
||||
static navigationOptions = ({ navigation }) => {
|
||||
const searching = navigation.getParam('searching');
|
||||
const initSearch = navigation.getParam('initSearch', () => {});
|
||||
const cancelSearch = navigation.getParam('cancelSearch', () => {});
|
||||
const search = navigation.getParam('search', () => {});
|
||||
|
||||
if (isIOS) {
|
||||
return {
|
||||
headerTitle: (
|
||||
<ShareListHeader
|
||||
searching={searching}
|
||||
initSearch={initSearch}
|
||||
cancelSearch={cancelSearch}
|
||||
search={search}
|
||||
/>
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
headerBackTitle: null,
|
||||
headerLeft: searching
|
||||
? (
|
||||
<CustomHeaderButtons left>
|
||||
<Item title='cancel' iconName='cross' onPress={cancelSearch} />
|
||||
</CustomHeaderButtons>
|
||||
)
|
||||
: (
|
||||
<CloseShareExtensionButton
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
),
|
||||
headerTitle: <ShareListHeader searching={searching} search={search} />,
|
||||
headerRight: (
|
||||
searching
|
||||
? null
|
||||
: (
|
||||
<CustomHeaderButtons>
|
||||
{isAndroid ? <Item title='search' iconName='magnifier' onPress={initSearch} /> : null}
|
||||
</CustomHeaderButtons>
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object,
|
||||
server: PropTypes.string,
|
||||
baseUrl: PropTypes.string,
|
||||
token: PropTypes.string,
|
||||
userId: PropTypes.string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.data = [];
|
||||
this.state = {
|
||||
showError: false,
|
||||
searching: false,
|
||||
searchText: '',
|
||||
value: '',
|
||||
isMedia: false,
|
||||
mediaLoading: false,
|
||||
fileInfo: null,
|
||||
searchResults: [],
|
||||
chats: [],
|
||||
servers: [],
|
||||
loading: true,
|
||||
serverInfo: null
|
||||
};
|
||||
this.didFocusListener = props.navigation.addListener('didFocus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
||||
this.willBlurListener = props.navigation.addListener('willBlur', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { navigation, server } = this.props;
|
||||
navigation.setParams({
|
||||
initSearch: this.initSearch,
|
||||
cancelSearch: this.cancelSearch,
|
||||
search: this.search
|
||||
});
|
||||
|
||||
try {
|
||||
const { value, type } = await ShareExtension.data();
|
||||
let fileInfo = null;
|
||||
const isMedia = (type === 'media');
|
||||
if (isMedia) {
|
||||
this.setState({ mediaLoading: true });
|
||||
const data = await RNFetchBlob.fs.stat(this.uriToPath(value));
|
||||
fileInfo = {
|
||||
name: data.filename,
|
||||
description: '',
|
||||
size: data.size,
|
||||
mime: mime.lookup(data.path),
|
||||
store: 'Uploads',
|
||||
path: isIOS ? data.path : `file://${ data.path }`
|
||||
};
|
||||
}
|
||||
this.setState({
|
||||
value, fileInfo, isMedia, mediaLoading: false
|
||||
});
|
||||
} catch (e) {
|
||||
log('err_process_media_share_extension', e);
|
||||
this.setState({ mediaLoading: false });
|
||||
}
|
||||
|
||||
this.getSubscriptions(server);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { server } = this.props;
|
||||
if (nextProps.server !== server) {
|
||||
this.getSubscriptions(nextProps.server);
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { searching } = this.state;
|
||||
if (nextState.searching !== searching) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const { isMedia } = this.state;
|
||||
if (nextState.isMedia !== isMedia) {
|
||||
this.getSubscriptions(nextProps.server, nextState.fileInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
const { server } = this.props;
|
||||
if (server !== nextProps.server) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const { searchResults } = this.state;
|
||||
if (!isEqual(nextState.searchResults, searchResults)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
internalSetState = (...args) => {
|
||||
const { navigation } = this.props;
|
||||
if (isIOS && navigation.isFocused()) {
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
}
|
||||
this.setState(...args);
|
||||
}
|
||||
|
||||
getSubscriptions = (server, fileInfo) => {
|
||||
const { fileInfo: fileData } = this.state;
|
||||
const { serversDB } = database.databases;
|
||||
|
||||
if (server) {
|
||||
this.data = database.objects('subscriptions').filtered('archived != true && open == true').sorted('roomUpdatedAt', true);
|
||||
this.servers = serversDB.objects('servers');
|
||||
this.chats = this.data.slice(0, LIMIT);
|
||||
const serverInfo = serversDB.objectForPrimaryKey('servers', server);
|
||||
|
||||
this.internalSetState({
|
||||
chats: this.chats ? this.chats.slice() : [],
|
||||
servers: this.servers ? this.servers.slice() : [],
|
||||
loading: false,
|
||||
showError: !canUploadFile(fileInfo || fileData, serverInfo),
|
||||
serverInfo
|
||||
});
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
uriToPath = uri => decodeURIComponent(isIOS ? uri.replace(/^file:\/\//, '') : uri);
|
||||
|
||||
getRoomTitle = (item) => {
|
||||
const { serverInfo } = this.state;
|
||||
const { useRealName } = serverInfo;
|
||||
return ((item.prid || useRealName) && item.fname) || item.name;
|
||||
}
|
||||
|
||||
shareMessage = (item) => {
|
||||
const { value, isMedia, fileInfo } = this.state;
|
||||
const { navigation } = this.props;
|
||||
|
||||
navigation.navigate('ShareView', {
|
||||
rid: item.rid,
|
||||
value,
|
||||
isMedia,
|
||||
fileInfo,
|
||||
name: this.getRoomTitle(item)
|
||||
});
|
||||
}
|
||||
|
||||
search = (text) => {
|
||||
const result = database.objects('subscriptions').filtered('name CONTAINS[c] $0', text);
|
||||
this.internalSetState({
|
||||
searchResults: result.slice(0, LIMIT),
|
||||
searchText: text
|
||||
});
|
||||
}
|
||||
|
||||
initSearch = () => {
|
||||
const { chats } = this.state;
|
||||
const { navigation } = this.props;
|
||||
this.setState({ searching: true, searchResults: chats });
|
||||
navigation.setParams({ searching: true });
|
||||
}
|
||||
|
||||
cancelSearch = () => {
|
||||
const { navigation } = this.props;
|
||||
this.internalSetState({ searching: false, searchResults: [], searchText: '' });
|
||||
navigation.setParams({ searching: false });
|
||||
Keyboard.dismiss();
|
||||
}
|
||||
|
||||
handleBackPress = () => {
|
||||
const { searching } = this.state;
|
||||
if (searching) {
|
||||
this.cancelSearch();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
renderSectionHeader = (header) => {
|
||||
const { searching } = this.state;
|
||||
if (searching) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.headerContainer}>
|
||||
<Text style={styles.headerText}>
|
||||
{I18n.t(header)}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderItem = ({ item }) => {
|
||||
const { userId, token, baseUrl } = this.props;
|
||||
return (
|
||||
<DirectoryItem
|
||||
user={{
|
||||
userId,
|
||||
token
|
||||
}}
|
||||
title={this.getRoomTitle(item)}
|
||||
baseUrl={baseUrl}
|
||||
avatar={this.getRoomTitle(item)}
|
||||
description={
|
||||
item.t === 'c'
|
||||
? (item.topic || item.description)
|
||||
: item.fname
|
||||
}
|
||||
type={item.t}
|
||||
onPress={() => this.shareMessage(item)}
|
||||
testID={`share-extension-item-${ item.name }`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSeparator = () => <View style={styles.separator} />;
|
||||
|
||||
renderBorderBottom = () => <View style={styles.borderBottom} />;
|
||||
|
||||
renderSelectServer = () => {
|
||||
const { servers } = this.state;
|
||||
const { server } = this.props;
|
||||
const currentServer = servers.find(serverFiltered => serverFiltered.id === server);
|
||||
return currentServer ? (
|
||||
<React.Fragment>
|
||||
{this.renderSectionHeader('Select_Server')}
|
||||
<View style={styles.bordered}>
|
||||
<ServerItem
|
||||
server={server}
|
||||
onPress={() => Navigation.navigate('SelectServerView')}
|
||||
item={currentServer}
|
||||
/>
|
||||
</View>
|
||||
</React.Fragment>
|
||||
) : null;
|
||||
}
|
||||
|
||||
renderEmptyComponent = () => (
|
||||
<View style={[styles.container, styles.emptyContainer]}>
|
||||
<Text style={styles.title}>{I18n.t('No_results_found')}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
renderHeader = () => {
|
||||
const { searching } = this.state;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ !searching
|
||||
? (
|
||||
<React.Fragment>
|
||||
{this.renderSelectServer()}
|
||||
{this.renderSectionHeader('Chats')}
|
||||
</React.Fragment>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent = () => {
|
||||
const {
|
||||
chats, mediaLoading, loading, searchResults, searching, searchText
|
||||
} = this.state;
|
||||
|
||||
if (mediaLoading || loading) {
|
||||
return <ActivityIndicator style={styles.loading} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
data={searching ? searchResults : chats}
|
||||
keyExtractor={keyExtractor}
|
||||
style={styles.flatlist}
|
||||
renderItem={this.renderItem}
|
||||
getItemLayout={getItemLayout}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ListHeaderComponent={this.renderHeader}
|
||||
ListFooterComponent={!searching && this.renderBorderBottom}
|
||||
ListHeaderComponentStyle={!searching ? styles.borderBottom : {}}
|
||||
ListEmptyComponent={searching && searchText ? this.renderEmptyComponent : null}
|
||||
enableEmptySections
|
||||
removeClippedSubviews
|
||||
keyboardShouldPersistTaps='always'
|
||||
initialNumToRender={12}
|
||||
windowSize={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderError = () => {
|
||||
const {
|
||||
fileInfo: file, loading, searching, serverInfo
|
||||
} = this.state;
|
||||
const { FileUpload_MaxFileSize } = serverInfo;
|
||||
const errorMessage = (FileUpload_MaxFileSize < file.size)
|
||||
? 'error-file-too-large'
|
||||
: 'error-invalid-file-type';
|
||||
|
||||
if (loading) {
|
||||
return <ActivityIndicator style={styles.loading} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{ !searching
|
||||
? (
|
||||
<React.Fragment>
|
||||
{this.renderSelectServer()}
|
||||
</React.Fragment>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<View style={[styles.container, styles.centered]}>
|
||||
<Text style={styles.title}>{I18n.t(errorMessage)}</Text>
|
||||
<CustomIcon name='circle-cross' size={120} style={styles.errorIcon} />
|
||||
<Text style={styles.fileMime}>{ file.mime }</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { showError } = this.state;
|
||||
return (
|
||||
<SafeAreaView style={styles.container} forceInset={{ bottom: 'never' }}>
|
||||
<StatusBar />
|
||||
{ showError ? this.renderError() : this.renderContent() }
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
import { isIOS } from '../../utils/deviceInfo';
|
||||
import sharedStyles from '../Styles';
|
||||
|
||||
import {
|
||||
COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_DANGER
|
||||
} from '../../constants/colors';
|
||||
|
||||
export default StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
},
|
||||
emptyContainer: {
|
||||
padding: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
backgroundColor: isIOS ? COLOR_WHITE : '#E1E5E8',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
centered: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
flatlist: {
|
||||
marginTop: isIOS ? 6 : 0, // the height of the navigation bar with the searchbar is larger
|
||||
width: '100%',
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
},
|
||||
bordered: {
|
||||
...sharedStyles.separatorVertical
|
||||
},
|
||||
borderBottom: {
|
||||
...sharedStyles.separatorBottom
|
||||
},
|
||||
headerContainer: {
|
||||
paddingHorizontal: 15,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER,
|
||||
paddingBottom: 10,
|
||||
paddingTop: 17
|
||||
},
|
||||
headerText: {
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular,
|
||||
fontSize: 17,
|
||||
letterSpacing: 0.27
|
||||
},
|
||||
separator: {
|
||||
...sharedStyles.separatorBottom,
|
||||
marginLeft: 48
|
||||
},
|
||||
loading: {
|
||||
flex: 1
|
||||
},
|
||||
errorIcon: {
|
||||
color: COLOR_DANGER
|
||||
},
|
||||
fileMime: {
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textBold,
|
||||
...sharedStyles.textAlignCenter,
|
||||
fontSize: 20,
|
||||
marginBottom: 20
|
||||
},
|
||||
title: {
|
||||
fontSize: 14,
|
||||
...sharedStyles.textColorTitle,
|
||||
...sharedStyles.textBold
|
||||
}
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
StyleSheet, ActivityIndicator, View
|
||||
} from 'react-native';
|
||||
import { COLOR_TEXT } from '../../constants/colors';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
const Loading = React.memo(() => (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator size='large' color={COLOR_TEXT} />
|
||||
</View>
|
||||
));
|
||||
|
||||
export default Loading;
|
|
@ -0,0 +1,245 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
View, Text, TextInput, Image
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import ShareExtension from 'rn-extensions-share';
|
||||
|
||||
import {
|
||||
COLOR_TEXT_DESCRIPTION
|
||||
} from '../../constants/colors';
|
||||
import I18n from '../../i18n';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import log from '../../utils/log';
|
||||
import styles from './styles';
|
||||
import Loading from './Loading';
|
||||
import database from '../../lib/realm';
|
||||
import { CustomHeaderButtons, Item } from '../../containers/HeaderButton';
|
||||
import { isReadOnly, isBlocked } from '../../utils/room';
|
||||
|
||||
@connect(({ share }) => ({
|
||||
user: {
|
||||
id: share.user && share.user.id,
|
||||
username: share.user && share.user.username,
|
||||
token: share.user && share.user.token
|
||||
},
|
||||
baseUrl: share ? share.server : ''
|
||||
}))
|
||||
export default class ShareView extends React.Component {
|
||||
static navigationOptions = ({ navigation }) => {
|
||||
const canSend = navigation.getParam('canSend', true);
|
||||
|
||||
return ({
|
||||
title: I18n.t('Share'),
|
||||
headerRight:
|
||||
canSend
|
||||
? (
|
||||
<CustomHeaderButtons>
|
||||
<Item
|
||||
title={I18n.t('Send')}
|
||||
onPress={navigation.getParam('sendMessage')}
|
||||
testID='send-message-share-view'
|
||||
buttonStyle={styles.send}
|
||||
/>
|
||||
</CustomHeaderButtons>
|
||||
)
|
||||
: null
|
||||
});
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object,
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
token: PropTypes.string.isRequired
|
||||
}),
|
||||
baseUrl: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { navigation } = this.props;
|
||||
const rid = navigation.getParam('rid', '');
|
||||
const name = navigation.getParam('name', '');
|
||||
const value = navigation.getParam('value', '');
|
||||
const isMedia = navigation.getParam('isMedia', false);
|
||||
const fileInfo = navigation.getParam('fileInfo', {});
|
||||
|
||||
this.rooms = database.objects('subscriptions').filtered('rid = $0', rid);
|
||||
|
||||
this.state = {
|
||||
rid,
|
||||
value,
|
||||
isMedia,
|
||||
name,
|
||||
fileInfo,
|
||||
loading: false,
|
||||
room: this.rooms[0] || { rid },
|
||||
file: {
|
||||
name: fileInfo ? fileInfo.name : '',
|
||||
description: ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { room } = this.state;
|
||||
const { navigation, user } = this.props;
|
||||
const { username } = user;
|
||||
navigation.setParams({ sendMessage: this._sendMessage, canSend: !(isReadOnly(room, { username }) || isBlocked(room)) });
|
||||
}
|
||||
|
||||
bytesToSize = bytes => `${ (bytes / 1048576).toFixed(2) }MB`;
|
||||
|
||||
_sendMessage = async() => {
|
||||
const { isMedia } = this.state;
|
||||
this.setState({ loading: true });
|
||||
|
||||
if (isMedia) {
|
||||
await this.sendMediaMessage();
|
||||
} else {
|
||||
await this.sendTextMessage();
|
||||
}
|
||||
|
||||
this.setState({ loading: false });
|
||||
ShareExtension.close();
|
||||
}
|
||||
|
||||
sendMediaMessage = async() => {
|
||||
const { rid, fileInfo, file } = this.state;
|
||||
const { baseUrl: server, user } = this.props;
|
||||
const { name, description } = file;
|
||||
const fileMessage = { ...fileInfo, name, description };
|
||||
if (fileInfo && rid !== '') {
|
||||
try {
|
||||
await RocketChat.sendFileMessage(rid, fileMessage, undefined, server, user);
|
||||
} catch (e) {
|
||||
log('err_send_media_message', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendTextMessage = async() => {
|
||||
const { value, rid } = this.state;
|
||||
const { user } = this.props;
|
||||
if (value !== '' && rid !== '') {
|
||||
try {
|
||||
await RocketChat.sendMessage(rid, value, undefined, user);
|
||||
} catch (error) {
|
||||
log('err_share_extension_send_message', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
renderPreview = () => {
|
||||
const { fileInfo } = this.state;
|
||||
|
||||
const icon = fileInfo.mime.match(/image/)
|
||||
? <Image source={{ isStatic: true, uri: fileInfo.path }} style={styles.mediaImage} />
|
||||
: (
|
||||
<View style={styles.mediaIconContainer}>
|
||||
<CustomIcon name='file-generic' style={styles.mediaIcon} />
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.mediaContent}>
|
||||
{icon}
|
||||
<View style={styles.mediaInfo}>
|
||||
<Text style={styles.mediaText} numberOfLines={1}>{fileInfo.name}</Text>
|
||||
<Text style={styles.mediaText}>{this.bytesToSize(fileInfo.size)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
renderMediaContent = () => {
|
||||
const { fileInfo, file } = this.state;
|
||||
return fileInfo ? (
|
||||
<View style={styles.mediaContainer}>
|
||||
{this.renderPreview()}
|
||||
<View style={styles.mediaInputContent}>
|
||||
<TextInput
|
||||
style={[styles.mediaNameInput, styles.input]}
|
||||
placeholder={I18n.t('File_name')}
|
||||
onChangeText={name => this.setState({ file: { ...file, name } })}
|
||||
underlineColorAndroid='transparent'
|
||||
defaultValue={file.name}
|
||||
placeholderTextColor={COLOR_TEXT_DESCRIPTION}
|
||||
/>
|
||||
<TextInput
|
||||
style={[styles.mediaDescriptionInput, styles.input]}
|
||||
placeholder={I18n.t('File_description')}
|
||||
onChangeText={description => this.setState({ file: { ...file, description } })}
|
||||
underlineColorAndroid='transparent'
|
||||
defaultValue={file.description}
|
||||
multiline
|
||||
textAlignVertical='top'
|
||||
placeholderTextColor={COLOR_TEXT_DESCRIPTION}
|
||||
autoFocus
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
) : null;
|
||||
};
|
||||
|
||||
renderInput = () => {
|
||||
const { value } = this.state;
|
||||
return (
|
||||
<TextInput
|
||||
style={[styles.input, styles.textInput]}
|
||||
placeholder=''
|
||||
onChangeText={handleText => this.setState({ value: handleText })}
|
||||
underlineColorAndroid='transparent'
|
||||
defaultValue={value}
|
||||
multiline
|
||||
textAlignVertical='top'
|
||||
placeholderTextColor={COLOR_TEXT_DESCRIPTION}
|
||||
autoFocus
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderError = () => {
|
||||
const { room } = this.state;
|
||||
return (
|
||||
<View style={[styles.container, styles.centered]}>
|
||||
<Text style={styles.title}>
|
||||
{
|
||||
isBlocked(room) ? I18n.t('This_room_is_blocked') : I18n.t('This_room_is_read_only')
|
||||
}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { user } = this.props;
|
||||
const { username } = user;
|
||||
const {
|
||||
name, loading, isMedia, room
|
||||
} = this.state;
|
||||
|
||||
if (isReadOnly(room, { username }) || isBlocked(room)) {
|
||||
return this.renderError();
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={isMedia ? styles.toContent : styles.toContentText}>
|
||||
<Text style={styles.text} numberOfLines={1}>
|
||||
<Text style={styles.to}>{`${ I18n.t('To') }: `}</Text>
|
||||
<Text style={styles.name}>{`${ name }`}</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.content}>
|
||||
{isMedia ? this.renderMediaContent() : this.renderInput()}
|
||||
</View>
|
||||
{ loading ? <Loading /> : null }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import sharedStyles from '../Styles';
|
||||
import {
|
||||
COLOR_BACKGROUND_CONTAINER, COLOR_WHITE
|
||||
} from '../../constants/colors';
|
||||
|
||||
export default StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
},
|
||||
centered: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
...sharedStyles.textBold,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textAlignCenter
|
||||
},
|
||||
text: {
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 8,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
to: {
|
||||
...sharedStyles.textColorDescription,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
toContent: {
|
||||
width: '100%',
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
toContentText: {
|
||||
width: '100%',
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
name: {
|
||||
...sharedStyles.textRegular,
|
||||
...sharedStyles.textColorTitle
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
mediaContainer: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
},
|
||||
mediaContent: {
|
||||
flexDirection: 'row',
|
||||
padding: 16,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER,
|
||||
alignItems: 'center'
|
||||
},
|
||||
mediaImage: {
|
||||
height: 64,
|
||||
width: 64
|
||||
},
|
||||
mediaIcon: {
|
||||
fontSize: 64,
|
||||
...sharedStyles.textColorNormal
|
||||
},
|
||||
mediaIconContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
mediaInfo: {
|
||||
marginLeft: 16,
|
||||
flex: 1
|
||||
},
|
||||
mediaText: {
|
||||
fontSize: 16,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
mediaInputContent: {
|
||||
width: '100%',
|
||||
...sharedStyles.separatorVertical,
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
input: {
|
||||
fontSize: 16,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular,
|
||||
backgroundColor: COLOR_WHITE
|
||||
},
|
||||
textInput: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 16
|
||||
},
|
||||
mediaNameInput: {
|
||||
marginLeft: 16,
|
||||
paddingRight: 16,
|
||||
paddingVertical: 8,
|
||||
backgroundColor: COLOR_WHITE,
|
||||
...sharedStyles.separatorBottom
|
||||
},
|
||||
mediaDescriptionInput: {
|
||||
marginLeft: 16,
|
||||
paddingRight: 16,
|
||||
marginVertical: 8,
|
||||
backgroundColor: COLOR_WHITE,
|
||||
height: 100
|
||||
},
|
||||
send: {
|
||||
...sharedStyles.textColorHeaderBack,
|
||||
...sharedStyles.textSemibold,
|
||||
fontSize: 16
|
||||
}
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import { StyleSheet, Platform } from 'react-native';
|
||||
|
||||
import {
|
||||
COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_PRIMARY
|
||||
COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_PRIMARY, HEADER_BACK
|
||||
} from '../constants/colors';
|
||||
|
||||
export default StyleSheet.create({
|
||||
|
@ -72,6 +72,9 @@ export default StyleSheet.create({
|
|||
textAlignRight: {
|
||||
textAlign: 'right'
|
||||
},
|
||||
textAlignCenter: {
|
||||
textAlign: 'center'
|
||||
},
|
||||
opacity5: {
|
||||
opacity: 0.5
|
||||
},
|
||||
|
@ -176,6 +179,9 @@ export default StyleSheet.create({
|
|||
textColorDescription: {
|
||||
color: COLOR_TEXT_DESCRIPTION
|
||||
},
|
||||
textColorHeaderBack: {
|
||||
color: HEADER_BACK
|
||||
},
|
||||
colorPrimary: {
|
||||
color: COLOR_PRIMARY
|
||||
},
|
||||
|
@ -192,5 +198,10 @@ export default StyleSheet.create({
|
|||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
backgroundColor: COLOR_WHITE,
|
||||
marginVertical: 10
|
||||
},
|
||||
notchLandscapeContainer: {
|
||||
marginTop: -34,
|
||||
paddingHorizontal: 30,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
StyleSheet, View, Text
|
||||
} from 'react-native';
|
||||
import ShareExtension from 'rn-extensions-share';
|
||||
|
||||
import { CloseShareExtensionButton } from '../containers/HeaderButton';
|
||||
import sharedStyles from './Styles';
|
||||
import I18n from '../i18n';
|
||||
import { COLOR_WHITE } from '../constants/colors';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: COLOR_WHITE,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 15
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
...sharedStyles.textBold,
|
||||
...sharedStyles.textColorNormal
|
||||
},
|
||||
content: {
|
||||
fontSize: 14,
|
||||
...sharedStyles.textAlignCenter,
|
||||
...sharedStyles.textColorNormal,
|
||||
...sharedStyles.textRegular
|
||||
}
|
||||
});
|
||||
|
||||
export default class WithoutServerView extends React.Component {
|
||||
static navigationOptions = () => ({
|
||||
headerLeft: (
|
||||
<CloseShareExtensionButton
|
||||
onPress={ShareExtension.close}
|
||||
testID='share-extension-close'
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>{I18n.t('Without_Servers')}</Text>
|
||||
<Text style={styles.content}>{I18n.t('You_need_to_access_at_least_one_RocketChat_server_to_share_something')}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
6
index.js
6
index.js
|
@ -2,10 +2,10 @@ import 'react-native-console-time-polyfill';
|
|||
|
||||
import './app/ReactotronConfig';
|
||||
import { AppRegistry } from 'react-native';
|
||||
import App from './app/index';
|
||||
import { name as appName } from './app.json';
|
||||
import { name as appName, share as shareName } from './app.json';
|
||||
|
||||
AppRegistry.registerComponent(appName, () => App);
|
||||
AppRegistry.registerComponent(appName, () => require('./app/index').default);
|
||||
AppRegistry.registerComponent(shareName, () => require('./app/share').default);
|
||||
|
||||
// For storybook, comment everything above and uncomment below
|
||||
// import './storybook';
|
||||
|
|
40
ios/Podfile
40
ios/Podfile
|
@ -27,12 +27,14 @@ target 'RocketChatRN' do
|
|||
|
||||
pod 'RNImageCropPicker', :path => '../node_modules/react-native-image-crop-picker'
|
||||
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
|
||||
pod 'RNLocalize', :path => '../node_modules/react-native-localize'
|
||||
|
||||
pod 'RNScreens', :path => '../node_modules/react-native-screens'
|
||||
|
||||
pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'
|
||||
|
||||
pod 'react-native-orientation-locker', :path => '../node_modules/react-native-orientation-locker'
|
||||
pod 'react-native-realm-path', :path => '../node_modules/react-native-realm-path'
|
||||
|
||||
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
|
@ -45,11 +47,49 @@ target 'RocketChatRN' do
|
|||
pod 'Crashlytics', '~> 3.12.0'
|
||||
pod 'GoogleIDFASupport', '~> 3.14.0'
|
||||
pod 'Firebase/Performance', '~> 5.20.1'
|
||||
pod 'react-native-document-picker', :path => '../node_modules/react-native-document-picker'
|
||||
|
||||
use_unimodules!
|
||||
|
||||
end
|
||||
|
||||
target 'ShareRocketChatRN' do
|
||||
|
||||
rn_path = '../node_modules/react-native'
|
||||
|
||||
pod 'React', path: rn_path, subspecs: [
|
||||
'Core',
|
||||
'RCTActionSheet',
|
||||
'RCTAnimation',
|
||||
# 'RCTGeolocation',
|
||||
'RCTImage',
|
||||
'RCTLinkingIOS',
|
||||
'RCTNetwork',
|
||||
'RCTSettings',
|
||||
'RCTText',
|
||||
'RCTVibration',
|
||||
'RCTWebSocket'
|
||||
]
|
||||
|
||||
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
|
||||
pod 'RNLocalize', :path => '../node_modules/react-native-localize'
|
||||
|
||||
pod 'react-native-realm-path', :path => '../node_modules/react-native-realm-path'
|
||||
pod 'rn-extensions-share', :path => '../node_modules/rn-extensions-share'
|
||||
|
||||
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
|
||||
pod 'Firebase/Core', '~> 5.20.1'
|
||||
pod 'Fabric', '~> 1.9.0'
|
||||
pod 'Crashlytics', '~> 3.12.0'
|
||||
pod 'GoogleIDFASupport', '~> 3.14.0'
|
||||
pod 'Firebase/Performance', '~> 5.20.1'
|
||||
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
if target.name == "React"
|
||||
|
|
|
@ -109,8 +109,12 @@ PODS:
|
|||
- QBImagePickerController (3.4.0)
|
||||
- React (0.59.8):
|
||||
- React/Core (= 0.59.8)
|
||||
- react-native-document-picker (3.2.2):
|
||||
- React
|
||||
- react-native-orientation-locker (1.1.5):
|
||||
- React
|
||||
- react-native-realm-path (1.2.11):
|
||||
- React
|
||||
- react-native-splash-screen (3.2.0):
|
||||
- React
|
||||
- react-native-webview (5.8.1):
|
||||
|
@ -141,12 +145,16 @@ PODS:
|
|||
- React/Core
|
||||
- React/fishhook
|
||||
- React/RCTBlob
|
||||
- rn-extensions-share (2.3.10):
|
||||
- React
|
||||
- RNDeviceInfo (1.6.1):
|
||||
- React
|
||||
- RNImageCropPicker (0.21.1):
|
||||
- RNImageCropPicker (0.24.1):
|
||||
- QBImagePickerController
|
||||
- React/Core
|
||||
- RSKImageCropper
|
||||
- RNLocalize (1.1.4):
|
||||
- React
|
||||
- RNScreens (1.0.0-alpha.22):
|
||||
- React
|
||||
- RSKImageCropper (2.2.1)
|
||||
|
@ -182,7 +190,9 @@ DEPENDENCIES:
|
|||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- GoogleIDFASupport (~> 3.14.0)
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||
- react-native-realm-path (from `../node_modules/react-native-realm-path`)
|
||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||
- React/Core (from `../node_modules/react-native`)
|
||||
|
@ -195,8 +205,10 @@ DEPENDENCIES:
|
|||
- React/RCTText (from `../node_modules/react-native`)
|
||||
- React/RCTVibration (from `../node_modules/react-native`)
|
||||
- React/RCTWebSocket (from `../node_modules/react-native`)
|
||||
- rn-extensions-share (from `../node_modules/rn-extensions-share`)
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`)
|
||||
- UMCameraInterface (from `../node_modules/unimodules-camera-interface/ios`)
|
||||
|
@ -261,16 +273,24 @@ EXTERNAL SOURCES:
|
|||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
React:
|
||||
:path: "../node_modules/react-native"
|
||||
react-native-document-picker:
|
||||
:path: "../node_modules/react-native-document-picker"
|
||||
react-native-orientation-locker:
|
||||
:path: "../node_modules/react-native-orientation-locker"
|
||||
react-native-realm-path:
|
||||
:path: "../node_modules/react-native-realm-path"
|
||||
react-native-splash-screen:
|
||||
:path: "../node_modules/react-native-splash-screen"
|
||||
react-native-webview:
|
||||
:path: "../node_modules/react-native-webview"
|
||||
rn-extensions-share:
|
||||
:path: "../node_modules/rn-extensions-share"
|
||||
RNDeviceInfo:
|
||||
:path: "../node_modules/react-native-device-info"
|
||||
RNImageCropPicker:
|
||||
:path: "../node_modules/react-native-image-crop-picker"
|
||||
RNLocalize:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
UMBarCodeScannerInterface:
|
||||
|
@ -341,11 +361,15 @@ SPEC CHECKSUMS:
|
|||
Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a
|
||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
||||
react-native-document-picker: 94a07ce0494c559e2ae9fa86621d6c624d810fec
|
||||
react-native-orientation-locker: 132a63bab4dddd2a5709f6f7935ad9676b0af7c5
|
||||
react-native-realm-path: 868473ea0bc4629850f1ec51a70d81055c06d091
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-webview: f3e28b48461c78db833f727feec08b13285e7b61
|
||||
rn-extensions-share: 4bfee75806ad54aadeff1dfa535697a6345a50b8
|
||||
RNDeviceInfo: 958a1ed6f94e04557b865b8ef848cfc83db0ebba
|
||||
RNImageCropPicker: e608efe182652dc8690268cb99cb5a201f2b5ea3
|
||||
RNImageCropPicker: 6134b66a3d5bc13e2895a97c630a4254006902b4
|
||||
RNLocalize: 62a949d2ec5bee0eb8f39a80a48f01e2f4f67080
|
||||
RNScreens: 720a9e6968beb73e8196239801e887d8401f86ed
|
||||
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
||||
UMBarCodeScannerInterface: d5602e23de37f95bb4ee49ee3b2711e128058ae9
|
||||
|
@ -362,6 +386,6 @@ SPEC CHECKSUMS:
|
|||
UMTaskManagerInterface: 296793ab2a7e181fe5ebe2ba9b40ae208ab4b8fa
|
||||
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
||||
|
||||
PODFILE CHECKSUM: b5e15bac5f306ea636e16393a7a6eb42c017ea99
|
||||
PODFILE CHECKSUM: bfa056aa2707bd200eb8a39ada130c51b702380c
|
||||
|
||||
COCOAPODS: 1.6.2
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-localize/ios/RNLocalize.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-document-picker/ios/RNDocumentPicker/RNDocumentPicker.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-realm-path/ios/RNRealmPath.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/rn-extensions-share/ios/ReactNativeShareExtension.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-localize/ios/RNLocalize.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-document-picker/ios/RNDocumentPicker/RNDocumentPicker.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/react-native-realm-path/ios/RNRealmPath.h
|
|
@ -0,0 +1 @@
|
|||
../../../../../node_modules/rn-extensions-share/ios/ReactNativeShareExtension.h
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "RNImageCropPicker",
|
||||
"version": "0.21.1",
|
||||
"version": "0.24.1",
|
||||
"summary": "Select single or multiple images, with cropping option",
|
||||
"requires_arc": true,
|
||||
"license": "MIT",
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "RNLocalize",
|
||||
"dependencies": {
|
||||
"React": [
|
||||
|
||||
]
|
||||
},
|
||||
"version": "1.1.4",
|
||||
"license": "MIT",
|
||||
"description": "A toolbox for your React Native app localization.",
|
||||
"summary": "A toolbox for your React Native app localization.",
|
||||
"authors": "Mathieu Acthernoene <zoontek@gmail.com>",
|
||||
"homepage": "https://github.com/react-native-community/react-native-localize",
|
||||
"platforms": {
|
||||
"ios": "9.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/react-native-community/react-native-localize.git",
|
||||
"tag": "1.1.4"
|
||||
},
|
||||
"source_files": "ios/*.{h,m}"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "react-native-document-picker",
|
||||
"version": "3.2.2",
|
||||
"summary": "A react native interface to access Documents from dropbox google drive, iCloud",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/Elyx0/react-native-document-picker#readme",
|
||||
"authors": {
|
||||
"Elyx0": "elyx00@gmail.com"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/Elyx0/react-native-document-picker"
|
||||
},
|
||||
"source_files": "ios/RNDocumentPicker/*.{h,m}",
|
||||
"platforms": {
|
||||
"ios": "7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"React": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "react-native-realm-path",
|
||||
"version": "1.2.11",
|
||||
"summary": "A helper to Realm Path on AppGroup iOS.",
|
||||
"license": "MIT",
|
||||
"authors": "Djorkaeff Alexandre",
|
||||
"homepage": "https://github.com/rocketchat/react-native-realm-path",
|
||||
"platforms": {
|
||||
"ios": "10.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/RocketChat/react-native-realm-path.git",
|
||||
"tag": "v1.2.11"
|
||||
},
|
||||
"source_files": "ios/**/*.{h,m}",
|
||||
"dependencies": {
|
||||
"React": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "rn-extensions-share",
|
||||
"version": "2.3.10",
|
||||
"summary": "Share-Extension using react-native for both ios and android",
|
||||
"license": "MIT",
|
||||
"authors": {
|
||||
"name": "Djorkaeff Alexandre",
|
||||
"email": "djorkaeffalexandre@gmail.com",
|
||||
"url": "http://github.com/djorkaeffalexandre"
|
||||
},
|
||||
"homepage": "https://github.com/RocketChat/rn-extensions-share",
|
||||
"platforms": {
|
||||
"ios": "8.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/RocketChat/rn-extensions-share.git",
|
||||
"tag": "master"
|
||||
},
|
||||
"source_files": "ios/*.{h,m}",
|
||||
"dependencies": {
|
||||
"React": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
|
@ -109,8 +109,12 @@ PODS:
|
|||
- QBImagePickerController (3.4.0)
|
||||
- React (0.59.8):
|
||||
- React/Core (= 0.59.8)
|
||||
- react-native-document-picker (3.2.2):
|
||||
- React
|
||||
- react-native-orientation-locker (1.1.5):
|
||||
- React
|
||||
- react-native-realm-path (1.2.11):
|
||||
- React
|
||||
- react-native-splash-screen (3.2.0):
|
||||
- React
|
||||
- react-native-webview (5.8.1):
|
||||
|
@ -141,12 +145,16 @@ PODS:
|
|||
- React/Core
|
||||
- React/fishhook
|
||||
- React/RCTBlob
|
||||
- rn-extensions-share (2.3.10):
|
||||
- React
|
||||
- RNDeviceInfo (1.6.1):
|
||||
- React
|
||||
- RNImageCropPicker (0.21.1):
|
||||
- RNImageCropPicker (0.24.1):
|
||||
- QBImagePickerController
|
||||
- React/Core
|
||||
- RSKImageCropper
|
||||
- RNLocalize (1.1.4):
|
||||
- React
|
||||
- RNScreens (1.0.0-alpha.22):
|
||||
- React
|
||||
- RSKImageCropper (2.2.1)
|
||||
|
@ -182,7 +190,9 @@ DEPENDENCIES:
|
|||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- GoogleIDFASupport (~> 3.14.0)
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||
- react-native-realm-path (from `../node_modules/react-native-realm-path`)
|
||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||
- React/Core (from `../node_modules/react-native`)
|
||||
|
@ -195,8 +205,10 @@ DEPENDENCIES:
|
|||
- React/RCTText (from `../node_modules/react-native`)
|
||||
- React/RCTVibration (from `../node_modules/react-native`)
|
||||
- React/RCTWebSocket (from `../node_modules/react-native`)
|
||||
- rn-extensions-share (from `../node_modules/rn-extensions-share`)
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`)
|
||||
- UMCameraInterface (from `../node_modules/unimodules-camera-interface/ios`)
|
||||
|
@ -261,16 +273,24 @@ EXTERNAL SOURCES:
|
|||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
React:
|
||||
:path: "../node_modules/react-native"
|
||||
react-native-document-picker:
|
||||
:path: "../node_modules/react-native-document-picker"
|
||||
react-native-orientation-locker:
|
||||
:path: "../node_modules/react-native-orientation-locker"
|
||||
react-native-realm-path:
|
||||
:path: "../node_modules/react-native-realm-path"
|
||||
react-native-splash-screen:
|
||||
:path: "../node_modules/react-native-splash-screen"
|
||||
react-native-webview:
|
||||
:path: "../node_modules/react-native-webview"
|
||||
rn-extensions-share:
|
||||
:path: "../node_modules/rn-extensions-share"
|
||||
RNDeviceInfo:
|
||||
:path: "../node_modules/react-native-device-info"
|
||||
RNImageCropPicker:
|
||||
:path: "../node_modules/react-native-image-crop-picker"
|
||||
RNLocalize:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
UMBarCodeScannerInterface:
|
||||
|
@ -341,11 +361,15 @@ SPEC CHECKSUMS:
|
|||
Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a
|
||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
||||
react-native-document-picker: 94a07ce0494c559e2ae9fa86621d6c624d810fec
|
||||
react-native-orientation-locker: 132a63bab4dddd2a5709f6f7935ad9676b0af7c5
|
||||
react-native-realm-path: 868473ea0bc4629850f1ec51a70d81055c06d091
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-webview: f3e28b48461c78db833f727feec08b13285e7b61
|
||||
rn-extensions-share: 4bfee75806ad54aadeff1dfa535697a6345a50b8
|
||||
RNDeviceInfo: 958a1ed6f94e04557b865b8ef848cfc83db0ebba
|
||||
RNImageCropPicker: e608efe182652dc8690268cb99cb5a201f2b5ea3
|
||||
RNImageCropPicker: 6134b66a3d5bc13e2895a97c630a4254006902b4
|
||||
RNLocalize: 62a949d2ec5bee0eb8f39a80a48f01e2f4f67080
|
||||
RNScreens: 720a9e6968beb73e8196239801e887d8401f86ed
|
||||
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
||||
UMBarCodeScannerInterface: d5602e23de37f95bb4ee49ee3b2711e128058ae9
|
||||
|
@ -362,6 +386,6 @@ SPEC CHECKSUMS:
|
|||
UMTaskManagerInterface: 296793ab2a7e181fe5ebe2ba9b40ae208ab4b8fa
|
||||
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
||||
|
||||
PODFILE CHECKSUM: b5e15bac5f306ea636e16393a7a6eb42c017ea99
|
||||
PODFILE CHECKSUM: bfa056aa2707bd200eb8a39ada130c51b702380c
|
||||
|
||||
COCOAPODS: 1.6.2
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1568,6 +1568,31 @@ redistribute it freely, subject to the following restrictions:
|
|||
distribution.
|
||||
|
||||
|
||||
## react-native-document-picker
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Elyx0
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
## react-native-orientation-locker
|
||||
|
||||
MIT License
|
||||
|
|
|
@ -1739,6 +1739,37 @@ redistribute it freely, subject to the following restrictions:
|
|||
<key>FooterText</key>
|
||||
<string>MIT License
|
||||
|
||||
Copyright (c) 2016 Elyx0
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>MIT</string>
|
||||
<key>Title</key>
|
||||
<string>react-native-document-picker</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>MIT License
|
||||
|
||||
Copyright (c) 2017 Wonday (@wonday.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"QBImagePickerController" -l"RNDeviceInfo" -l"RNImageCropPicker" -l"RNScreens" -l"RSKImageCropper" -l"React" -l"UMCore" -l"UMReactNativeAdapter" -l"c++" -l"glog" -l"nanopb" -l"react-native-orientation-locker" -l"react-native-splash-screen" -l"react-native-webview" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-realm-path" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-realm-path" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"QBImagePickerController" -l"RNDeviceInfo" -l"RNImageCropPicker" -l"RNLocalize" -l"RNScreens" -l"RSKImageCropper" -l"React" -l"UMCore" -l"UMReactNativeAdapter" -l"c++" -l"glog" -l"nanopb" -l"react-native-document-picker" -l"react-native-orientation-locker" -l"react-native-realm-path" -l"react-native-splash-screen" -l"react-native-webview" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"QBImagePickerController" -l"RNDeviceInfo" -l"RNImageCropPicker" -l"RNScreens" -l"RSKImageCropper" -l"React" -l"UMCore" -l"UMReactNativeAdapter" -l"c++" -l"glog" -l"nanopb" -l"react-native-orientation-locker" -l"react-native-splash-screen" -l"react-native-webview" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-realm-path" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-realm-path" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"QBImagePickerController" -l"RNDeviceInfo" -l"RNImageCropPicker" -l"RNLocalize" -l"RNScreens" -l"RSKImageCropper" -l"React" -l"UMCore" -l"UMReactNativeAdapter" -l"c++" -l"glog" -l"nanopb" -l"react-native-document-picker" -l"react-native-orientation-locker" -l"react-native-realm-path" -l"react-native-splash-screen" -l"react-native-webview" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
|
|
1511
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-acknowledgements.markdown
generated
Normal file
1511
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-acknowledgements.markdown
generated
Normal file
File diff suppressed because it is too large
Load Diff
1675
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-acknowledgements.plist
generated
Normal file
1675
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-acknowledgements.plist
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-dummy.m
generated
Normal file
5
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN-dummy.m
generated
Normal file
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_ShareRocketChatRN : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_ShareRocketChatRN
|
||||
@end
|
9
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN.debug.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN.debug.xcconfig
generated
Normal file
|
@ -0,0 +1,9 @@
|
|||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-realm-path" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-realm-path" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNDeviceInfo" -l"RNLocalize" -l"React" -l"c++" -l"glog" -l"nanopb" -l"react-native-realm-path" -l"rn-extensions-share" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
9
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN.release.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-ShareRocketChatRN/Pods-ShareRocketChatRN.release.xcconfig
generated
Normal file
|
@ -0,0 +1,9 @@
|
|||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-realm-path" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-realm-path" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" "${PODS_ROOT}/GoogleIDFASupport/Libraries"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"AdIdAccessLibrary" -l"DoubleConversion" -l"FirebaseCore" -l"FirebaseInstanceID" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNDeviceInfo" -l"RNLocalize" -l"React" -l"c++" -l"glog" -l"nanopb" -l"react-native-realm-path" -l"rn-extensions-share" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "AdSupport" -framework "CoreTelephony" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "JavaScriptCore" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_RNLocalize : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_RNLocalize
|
||||
@end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue