diff --git a/android/app/build.gradle b/android/app/build.gradle index f2976d8064..b634e7607f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -93,7 +93,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode VERSIONCODE as Integer - versionName "4.51.0" + versionName "4.52.0" vectorDrawables.useSupportLibrary = true if (!isFoss) { manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] diff --git a/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.java b/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.java deleted file mode 100644 index 366efc3b8a..0000000000 --- a/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.java +++ /dev/null @@ -1,10 +0,0 @@ -package chat.rocket.reactnative.share; - -import com.facebook.react.ReactActivity; - -public class ShareActivity extends ReactActivity { - @Override - protected String getMainComponentName() { - return "ShareRocketChatRN"; - } -} \ No newline at end of file diff --git a/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.kt b/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.kt new file mode 100644 index 0000000000..40dc45832c --- /dev/null +++ b/android/app/src/main/java/chat/rocket/reactnative/share/ShareActivity.kt @@ -0,0 +1,137 @@ +package chat.rocket.reactnative.share + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import java.io.File +import java.io.FileOutputStream +import java.util.* + +class ShareActivity : AppCompatActivity() { + + private val appScheme = "rocketchat" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + handleIntent(intent) + } + + private fun handleIntent(intent: Intent?) { + // Check if the intent contains shared content + if (intent?.action == Intent.ACTION_SEND || intent?.action == Intent.ACTION_SEND_MULTIPLE) { + when { + intent.type?.startsWith("text/") == true -> handleText(intent) + intent.type?.startsWith("image/") == true -> handleMedia(intent, "data") + intent.type?.startsWith("video/") == true -> handleMedia(intent, "data") + intent.type?.startsWith("application/") == true -> handleMedia(intent, "data") + intent.type == "*/*" -> handleMedia(intent, "data") + intent.type == "text/plain" -> handleText(intent) + else -> completeRequest() // No matching type, complete the request + } + } else { + completeRequest() // No relevant intent action, complete the request + } + } + + private fun handleText(intent: Intent) { + // Handle sharing text + val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT) + if (sharedText != null) { + val encoded = Uri.encode(sharedText) + val url = Uri.parse("$appScheme://shareextension?text=$encoded") + openURL(url) + } + completeRequest() + } + + private fun handleMedia(intent: Intent, type: String) { + val mediaUris = StringBuilder() + var valid = true + + val uris = when (intent.action) { + Intent.ACTION_SEND -> listOf(intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri?) + Intent.ACTION_SEND_MULTIPLE -> intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM) + else -> null + } + + uris?.forEachIndexed { index, uri -> + val mediaUri = uri?.let { handleMediaUri(it, type) } + if (mediaUri != null) { + mediaUris.append(mediaUri) + if (index < uris.size - 1) { + mediaUris.append(",") + } + } else { + valid = false + } + } + + if (valid) { + val encoded = Uri.encode(mediaUris.toString()) + val url = Uri.parse("$appScheme://shareextension?mediaUris=$encoded") + openURL(url) + } + completeRequest() + } + + private fun handleMediaUri(uri: Uri, type: String): String? { + return try { + val inputStream = contentResolver.openInputStream(uri) + val originalFilename = getFileName(uri) + val filename = originalFilename ?: UUID.randomUUID().toString() + getFileExtension(uri, type) + val fileUri = saveDataToCacheDir(inputStream?.readBytes(), filename) + fileUri?.toString() + } catch (e: Exception) { + Log.e("ShareRocketChat", "Failed to process media", e) + null + } + } + + private fun getFileName(uri: Uri): String? { + // Attempt to get the original filename from the Uri + val cursor = contentResolver.query(uri, null, null, null, null) + return cursor?.use { + if (it.moveToFirst()) { + val nameIndex = it.getColumnIndex("_display_name") + if (nameIndex != -1) it.getString(nameIndex) else null + } else null + } + } + + private fun getFileExtension(uri: Uri, type: String): String { + // Determine the file extension based on the mime type, with fallbacks + val mimeType = contentResolver.getType(uri) + return when { + mimeType?.startsWith("image/") == true -> ".jpeg" + mimeType?.startsWith("video/") == true -> ".mp4" + else -> "" // Ignore the file if the type is not recognized + } + } + + private fun saveDataToCacheDir(data: ByteArray?, filename: String): Uri? { + // Save the shared data to the app's cache directory and return the file URI + return try { + val file = File(cacheDir, filename) + FileOutputStream(file).use { it.write(data) } + Uri.fromFile(file) // Return the file URI with file:// scheme + } catch (e: Exception) { + Log.e("ShareRocketChat", "Failed to save data", e) + null + } + } + + private fun openURL(uri: Uri) { + // Open the custom URI in the associated app + val intent = Intent(Intent.ACTION_VIEW, uri) + if (intent.resolveActivity(packageManager) != null) { + startActivity(intent) + } + } + + private fun completeRequest() { + // Finish the share activity + finish() + } +} diff --git a/android/app/src/main/java/chat/rocket/reactnative/share/ShareApplication.java b/android/app/src/main/java/chat/rocket/reactnative/share/ShareApplication.java deleted file mode 100644 index 94cd8b8610..0000000000 --- a/android/app/src/main/java/chat/rocket/reactnative/share/ShareApplication.java +++ /dev/null @@ -1,38 +0,0 @@ -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 getPackages() { - return Arrays.asList( - new MainReactPackage(), - new SharePackage() - ); - } - }; - - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } -} \ No newline at end of file diff --git a/app.json b/app.json index 5b802fd60f..5d8e300850 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,3 @@ { - "name": "RocketChatRN", - "share": "ShareRocketChatRN", - "displayName": "RocketChatRN" + "name": "RocketChatRN" } diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx index a1e99822c8..bfd1a8cc66 100644 --- a/app/AppContainer.tsx +++ b/app/AppContainer.tsx @@ -14,6 +14,7 @@ import SetUsernameView from './views/SetUsernameView'; import OutsideStack from './stacks/OutsideStack'; import InsideStack from './stacks/InsideStack'; import MasterDetailStack from './stacks/MasterDetailStack'; +import ShareExtensionStack from './stacks/ShareExtensionStack'; import { ThemeContext } from './theme'; import { setCurrentScreen } from './lib/methods/helpers/log'; @@ -57,13 +58,18 @@ const App = memo(({ root, isMasterDetail }: { root: string; isMasterDetail: bool Navigation.routeNameRef.current = currentRouteName; }}> - {root === RootEnum.ROOT_LOADING ? : null} + {root === RootEnum.ROOT_LOADING || root === RootEnum.ROOT_LOADING_SHARE_EXTENSION ? ( + + ) : null} {root === RootEnum.ROOT_OUTSIDE ? : null} {root === RootEnum.ROOT_INSIDE && isMasterDetail ? ( ) : null} {root === RootEnum.ROOT_INSIDE && !isMasterDetail ? : null} {root === RootEnum.ROOT_SET_USERNAME ? : null} + {root === RootEnum.ROOT_SHARE_EXTENSION ? ( + + ) : null} ); diff --git a/app/actions/actionsTypes.ts b/app/actions/actionsTypes.ts index fe6fb521e8..af1f261b3e 100644 --- a/app/actions/actionsTypes.ts +++ b/app/actions/actionsTypes.ts @@ -10,7 +10,7 @@ function createRequestTypes(base = {}, types = defaultTypes): Record { return ( - {item.icon ? : null} + {item.icon ? : null} {item.title} diff --git a/app/containers/ActionSheet/styles.ts b/app/containers/ActionSheet/styles.ts index 00d34935a7..7bd1fb3d1c 100644 --- a/app/containers/ActionSheet/styles.ts +++ b/app/containers/ActionSheet/styles.ts @@ -24,7 +24,7 @@ export default StyleSheet.create({ }, title: { fontSize: 16, - ...sharedStyles.textRegular + ...sharedStyles.textMedium }, handle: { justifyContent: 'center', diff --git a/app/containers/Avatar/AvatarContainer.tsx b/app/containers/Avatar/AvatarContainer.tsx index e8e6a07542..3e1282d429 100644 --- a/app/containers/Avatar/AvatarContainer.tsx +++ b/app/containers/Avatar/AvatarContainer.tsx @@ -21,8 +21,8 @@ const AvatarContainer = ({ isStatic, rid }: IAvatar): React.ReactElement => { - const server = useSelector((state: IApplicationState) => state.share.server.server || state.server.server); - const serverVersion = useSelector((state: IApplicationState) => state.share.server.version || state.server.version); + const server = useSelector((state: IApplicationState) => state.server.server); + const serverVersion = useSelector((state: IApplicationState) => state.server.version); const { id, token, username } = useSelector( (state: IApplicationState) => ({ id: getUserSelector(state).id, @@ -38,11 +38,8 @@ const AvatarContainer = ({ cdnPrefix: state.settings.CDN_PREFIX as string })); const blockUnauthenticatedAccess = useSelector( - (state: IApplicationState) => - (state.share.settings?.Accounts_AvatarBlockUnauthenticatedAccess as boolean) ?? - state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? - true - ); + (state: IApplicationState) => state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true + ) as boolean; const { avatarETag } = useAvatarETag({ username, text, type, rid, id }); diff --git a/app/containers/EmojiPicker/CustomEmoji.tsx b/app/containers/EmojiPicker/CustomEmoji.tsx index 02768f29d0..296439cae0 100644 --- a/app/containers/EmojiPicker/CustomEmoji.tsx +++ b/app/containers/EmojiPicker/CustomEmoji.tsx @@ -12,7 +12,7 @@ interface ICustomEmojiProps { const CustomEmoji = React.memo( ({ emoji, style }: ICustomEmojiProps) => { - const baseUrl = useAppSelector(state => state.share.server.server || state.server.server); + const baseUrl = useAppSelector(state => state.server.server); return ( ( - - - -); +const ListIcon = ({ name, color, style, testID, size }: IListIcon): React.ReactElement => { + const { colors } = useTheme(); + return ( + + + + ); +}; ListIcon.displayName = 'List.Icon'; diff --git a/app/containers/List/ListItem.tsx b/app/containers/List/ListItem.tsx index 8c8a4013ac..a39df4a0e5 100644 --- a/app/containers/List/ListItem.tsx +++ b/app/containers/List/ListItem.tsx @@ -42,7 +42,7 @@ const styles = StyleSheet.create({ title: { flexShrink: 1, fontSize: 16, - ...sharedStyles.textRegular + ...sharedStyles.textMedium }, subtitle: { fontSize: 14, @@ -124,7 +124,7 @@ const Content = React.memo( {left ? {left()} : null} - + {translateTitle && title ? I18n.t(title) : title} {alert ? ( diff --git a/app/containers/List/constants.ts b/app/containers/List/constants.ts index 8144096d39..71d877c633 100644 --- a/app/containers/List/constants.ts +++ b/app/containers/List/constants.ts @@ -1,3 +1,3 @@ export const PADDING_HORIZONTAL = 12; export const BASE_HEIGHT = 46; -export const ICON_SIZE = 20; +export const ICON_SIZE = 24; diff --git a/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap b/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap index 37b42b978f..e6e8b47ee2 100644 --- a/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap +++ b/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap @@ -626,10 +626,12 @@ exports[`MessageComposer Quote Add quote \`abc\` 1`] = ` "fontFamily": "Inter", "fontSize": 16, "fontWeight": "400", + "lineHeight": 22, "textAlign": "left", }, { "color": "#2F343D", + "lineHeight": undefined, }, { "backgroundColor": "transparent", @@ -1044,10 +1046,12 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = ` "fontFamily": "Inter", "fontSize": 16, "fontWeight": "400", + "lineHeight": 22, "textAlign": "left", }, { "color": "#2F343D", + "lineHeight": undefined, }, { "backgroundColor": "transparent", @@ -1219,10 +1223,12 @@ exports[`MessageComposer Quote Add quote \`def\` 1`] = ` "fontFamily": "Inter", "fontSize": 16, "fontWeight": "400", + "lineHeight": 22, "textAlign": "left", }, { "color": "#2F343D", + "lineHeight": undefined, }, { "backgroundColor": "transparent", @@ -1637,10 +1643,12 @@ exports[`MessageComposer Quote Remove a quote 1`] = ` "fontFamily": "Inter", "fontSize": 16, "fontWeight": "400", + "lineHeight": 22, "textAlign": "left", }, { "color": "#2F343D", + "lineHeight": undefined, }, { "backgroundColor": "transparent", @@ -1812,10 +1820,12 @@ exports[`MessageComposer Quote Remove a quote 1`] = ` "fontFamily": "Inter", "fontSize": 16, "fontWeight": "400", + "lineHeight": 22, "textAlign": "left", }, { "color": "#2F343D", + "lineHeight": undefined, }, { "backgroundColor": "transparent", diff --git a/app/containers/ServerItem/index.tsx b/app/containers/ServerItem/index.tsx index 780b5640c7..cd2fc45b45 100644 --- a/app/containers/ServerItem/index.tsx +++ b/app/containers/ServerItem/index.tsx @@ -30,12 +30,11 @@ const ServerItem = React.memo(({ item, onPress, onLongPress, hasCheck }: IServer onLongPress?.()} - testID={`rooms-list-header-server-${item.id}`} + testID={`server-item-${item.id}`} android_ripple={{ color: themes[theme].surfaceNeutral }} style={({ pressed }: { pressed: boolean }) => ({ backgroundColor: isIOS && pressed ? themes[theme].surfaceNeutral : themes[theme].surfaceRoom - })} - > + })}> {item.iconURL ? ( {m} diff --git a/app/containers/markdown/styles.ts b/app/containers/markdown/styles.ts index a0fcba0a48..d558ef4146 100644 --- a/app/containers/markdown/styles.ts +++ b/app/containers/markdown/styles.ts @@ -32,9 +32,11 @@ export default StyleSheet.create({ }, plainText: { fontSize: 16, - flexShrink: 1 + flexShrink: 1, + lineHeight: 22 }, text: { + lineHeight: 22, fontSize: 16, ...sharedStyles.textRegular }, @@ -75,6 +77,7 @@ export default StyleSheet.create({ }, codeInline: { fontSize: 16, + lineHeight: 22, ...sharedStyles.textRegular, ...codeFontFamily, borderWidth: 1, @@ -89,6 +92,7 @@ export default StyleSheet.create({ }, codeBlockText: { fontSize: 16, + lineHeight: 22, ...sharedStyles.textRegular, ...codeFontFamily }, diff --git a/app/definitions/navigationTypes.ts b/app/definitions/navigationTypes.ts index 960b35b5df..cd8e34d123 100644 --- a/app/definitions/navigationTypes.ts +++ b/app/definitions/navigationTypes.ts @@ -29,6 +29,7 @@ export type StackParamList = { InsideStack: NavigatorScreenParams; MasterDetailStack: NavigatorScreenParams; SetUsernameStack: NavigatorScreenParams; + ShareExtensionStack: NavigatorScreenParams; }; export type ShareInsideStackParamList = { @@ -44,13 +45,3 @@ export type ShareInsideStackParamList = { }; SelectServerView: undefined; }; - -export type ShareOutsideStackParamList = { - WithoutServersView: undefined; -}; - -export type ShareAppStackParamList = { - AuthLoading?: undefined; - OutsideStack?: NavigatorScreenParams; - InsideStack?: NavigatorScreenParams; -}; diff --git a/app/definitions/redux/TRootEnum.ts b/app/definitions/redux/TRootEnum.ts index 8b0faca42e..4c39c38d3e 100644 --- a/app/definitions/redux/TRootEnum.ts +++ b/app/definitions/redux/TRootEnum.ts @@ -2,5 +2,7 @@ export enum RootEnum { ROOT_OUTSIDE = 'outside', ROOT_INSIDE = 'inside', ROOT_LOADING = 'loading', - ROOT_SET_USERNAME = 'setUsername' + ROOT_SET_USERNAME = 'setUsername', + ROOT_SHARE_EXTENSION = 'shareextension', + ROOT_LOADING_SHARE_EXTENSION = 'loadingshareextension' } diff --git a/app/definitions/rest/v1/e2e.ts b/app/definitions/rest/v1/e2e.ts index 6c4ef7c8f7..bf4db5b117 100644 --- a/app/definitions/rest/v1/e2e.ts +++ b/app/definitions/rest/v1/e2e.ts @@ -2,7 +2,7 @@ import { IUser } from '../../IUser'; export type E2eEndpoints = { 'e2e.setUserPublicAndPrivateKeys': { - POST: (params: { public_key: string; private_key: string }) => void; + POST: (params: { public_key: string; private_key: string; force?: boolean }) => void; }; 'e2e.getUsersOfRoomWithoutKey': { GET: (params: { rid: string }) => { diff --git a/app/i18n/locales/ar.json b/app/i18n/locales/ar.json index e360ee137c..c3bac972bf 100644 --- a/app/i18n/locales/ar.json +++ b/app/i18n/locales/ar.json @@ -459,7 +459,7 @@ "Users": "مستخدمين", "Uses_server_configuration": "يستخدم إعداد الخادم", "Verify_email_desc": "لقد أرسلنا إليك بريداً إلكترونياً لتأكيد تسجيلك. إذا لم تتلق البريد الإلكتروني قريباً، فيرجى العودة والمحاولة مرة أخرى", - "Version_no": "النسخة: {{version}}", + "Version_no": "إصدار التطبيق: {{version}}", "View_Original": "عرض المحتوى الأصلي", "Wait_activation_warning": "يحب تفعيل حسابك من المشرف قبل تسجيل الدخول", "Waiting_for_network": "بانتظار توفر شبكة...", diff --git a/app/i18n/locales/bn-IN.json b/app/i18n/locales/bn-IN.json index 14ed0f168d..06719eb495 100644 --- a/app/i18n/locales/bn-IN.json +++ b/app/i18n/locales/bn-IN.json @@ -712,7 +712,7 @@ "Users": "ব্যবহারকারীগণ", "Uses_server_configuration": "ওয়ার্কস্পেস কনফিগারেশন ব্যবহার করে", "Verify_email_desc": "আমরা আপনার নিবন্ধন নিশ্চিত করতে একটি ইমেল পাঠিয়েছি। যদি আপনি শীঘ্রই একটি ইমেল পাননি, তবে দয়া করে ফিরে এসে আবার চেষ্টা করুন।", - "Version_no": "সংস্করণ: {{version}}", + "Version_no": "অ্যাপ সংস্করণ: {{version}}", "Video": "ভিডিও", "video-conf-provider-not-configured-body": "একটি কার্যক্ষম প্রশাসককে প্রথমে কনফারেন্স কল বৈশিষ্ট্যটি চালু করতে হবে।", "video-conf-provider-not-configured-header": "কনফারেন্স কল সক্ষম হয়নি", diff --git a/app/i18n/locales/cs.json b/app/i18n/locales/cs.json index 95405c892d..a5334a0ec1 100644 --- a/app/i18n/locales/cs.json +++ b/app/i18n/locales/cs.json @@ -783,7 +783,7 @@ "Uses_server_configuration": "Používá konfiguraci pracovního prostoru", "Verify": "Ověřit", "Verify_email_desc": "Poslali jsme vám e-mail pro potvrzení vaší registrace. Pokud e-mail brzy neobdržíte, vraťte se a zkuste to znovu.", - "Version_no": "Verze: {{version}}", + "Version_no": "Verze aplikace: {{version}}", "Vibrate": "Vibrovat", "Video": "Video", "video-conf-provider-not-configured-body": "Správce pracovního prostoru musí nejprve povolit funkci konferenčních hovorů.", diff --git a/app/i18n/locales/de.json b/app/i18n/locales/de.json index 5dfca2a5dc..bf58637a52 100644 --- a/app/i18n/locales/de.json +++ b/app/i18n/locales/de.json @@ -706,7 +706,7 @@ "Users": "Benutzer", "Uses_server_configuration": "Nutzt Servereinstellungen", "Verify_email_desc": "Wir haben Ihnen eine Email geschickt um Ihre Anmeldung zu bestätigen. Wenn Sie keine Email erhalten, versuchen Sie es später noch einmal.", - "Version_no": "Version: {{version}}", + "Version_no": "App-Version: {{version}}", "video-conf-provider-not-configured-body": "Ein Arbeitsbereich-Administrator muss die Funktion für Telefonkonferenzen zuerst aktivieren.", "video-conf-provider-not-configured-header": "Telefonkonferenz nicht aktiviert", "View_Original": "Original anzeigen", diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index ef334c408d..ab49887112 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -803,7 +803,7 @@ "Uses_server_configuration": "Uses workspace configuration", "Verify": "Verify", "Verify_email_desc": "We have sent you an email to confirm your registration. If you do not receive an email shortly, please come back and try again.", - "Version_no": "Version: {{version}}", + "Version_no": "App version: {{version}}", "Vibrate": "Vibrate", "Video": "Video", "video-conf-provider-not-configured-body": "A workspace admin needs to enable the conference calls feature first.", diff --git a/app/i18n/locales/es.json b/app/i18n/locales/es.json index 06993033f6..6273ba700c 100644 --- a/app/i18n/locales/es.json +++ b/app/i18n/locales/es.json @@ -283,7 +283,7 @@ "Username": "Nombre de usuario", "Username_or_email": "Nombre de usuario o email", "Users": "Usuarios", - "Version_no": "Versión: {{version}}", + "Version_no": "Versión de la aplicación: {{version}}", "View_Original": "Ver original", "Websocket_disabled": "Websocket está deshabilitado para este servidor.\n{{contact}}", "Whats_the_password_for_your_certificate": "¿Cuál es la contraseña de tu certificado?", diff --git a/app/i18n/locales/fi.json b/app/i18n/locales/fi.json index 768cf6e09f..97f5504a4c 100644 --- a/app/i18n/locales/fi.json +++ b/app/i18n/locales/fi.json @@ -680,7 +680,7 @@ "Users": "Käyttäjät", "Uses_server_configuration": "Käyttää palvelimen määrityksiä", "Verify_email_desc": "Lähetimme rekisteröitymisvahvistuksen sähköpostiisi. Jos et saa sähköpostia pian, yritä uudelleen.", - "Version_no": "Versio: {{version}}", + "Version_no": "Sovelluksen versio: {{version}}", "View_Original": "Näytä alkuperäinen", "Wait_activation_warning": "Ennen kuin voit kirjautua, järjestelmänvalvojan on aktivoitava tilisi manuaalisesti.", "Waiting_for_answer": "Odotetaan vastausta", diff --git a/app/i18n/locales/fr.json b/app/i18n/locales/fr.json index ef66bd48fd..0458384c79 100644 --- a/app/i18n/locales/fr.json +++ b/app/i18n/locales/fr.json @@ -600,7 +600,7 @@ "Users": "Utilisateurs", "Uses_server_configuration": "Utilise la configuration du serveur", "Verify_email_desc": "Nous vous avons envoyé un e-mail pour confirmer votre inscription. Si vous ne recevez pas d'e-mail sous peu, veuillez revenir et réessayer.", - "Version_no": "Version : {{version}}", + "Version_no": "Version de l'application : {{version}}", "View_Original": "Voir l'original", "Wait_activation_warning": "Avant de pouvoir vous connecter, votre compte doit être activé manuellement par un administrateur.", "Waiting_for_network": "En attente du réseau...", diff --git a/app/i18n/locales/hi-IN.json b/app/i18n/locales/hi-IN.json index 52a39d5f24..a3b9d1b525 100644 --- a/app/i18n/locales/hi-IN.json +++ b/app/i18n/locales/hi-IN.json @@ -712,7 +712,7 @@ "Users": "उपयोगकर्ताएँ", "Uses_server_configuration": "कार्यस्थान समरूपण का उपयोग करता है", "Verify_email_desc": "हमने आपको आपके पंजीकरण की पुष्टि के लिए एक ईमेल भेजा है। यदि आपको शीघ्र एक ईमेल प्राप्त नहीं होता है, तो कृपया वापस आकर पुनः प्रयास करें।", - "Version_no": "संस्करण: {{version}}", + "Version_no": "ऐप संस्करण: {{version}}", "Video": "वीडियो", "video-conf-provider-not-configured-body": "कार्यक्षेत्र प्रबंधक को पहले कॉन्फ़्रेंस कॉल सुविधा सक्षम करनी होगी।", "video-conf-provider-not-configured-header": "कॉन्फ़्रेंस कॉल सक्षम नहीं है", diff --git a/app/i18n/locales/hu.json b/app/i18n/locales/hu.json index ff4bdd2991..1964200302 100644 --- a/app/i18n/locales/hu.json +++ b/app/i18n/locales/hu.json @@ -714,7 +714,7 @@ "Users": "Felhasználók", "Uses_server_configuration": "Használja a munkaterület konfigurációját", "Verify_email_desc": "Küldtünk Önnek egy e-mailt a regisztrációja megerősítéséhez. Ha nem kap rövidesen e-mailt, akkor térjen vissza, és próbálja meg újra.", - "Version_no": "Verzió: {{version}}", + "Version_no": "Alkalmazás verzió: {{version}}", "Video": "Videó", "video-conf-provider-not-configured-body": "A munkaterület adminisztrátorának először engedélyeznie kell a konferenciahívások funkciót.", "video-conf-provider-not-configured-header": "Konferenciahívás nem engedélyezett", diff --git a/app/i18n/locales/it.json b/app/i18n/locales/it.json index dd13c20f87..d894666f8f 100644 --- a/app/i18n/locales/it.json +++ b/app/i18n/locales/it.json @@ -507,7 +507,7 @@ "Users": "Utenti", "Uses_server_configuration": "Usa la configurazione del server", "Verify_email_desc": "Ti abbiamo inviato una e-mail per confermare la tua registrazione. Se non la ricevi, ritorna qui e riprova", - "Version_no": "Versione: {{version}}", + "Version_no": "Versione dell'app: {{version}}", "View_Original": "Mostra originale", "Wait_activation_warning": "Prima di poter accedere, il tuo account deve essere attivato manualmente da un amministratore.", "Waiting_for_network": "In attesa di connessione ...", diff --git a/app/i18n/locales/ja.json b/app/i18n/locales/ja.json index 37593ad945..4641bf86aa 100644 --- a/app/i18n/locales/ja.json +++ b/app/i18n/locales/ja.json @@ -387,7 +387,7 @@ "Username_or_email": "ユーザー名かメールアドレス", "Users": "ユーザー", "Uses_server_configuration": "サーバー構成を使用する", - "Version_no": "バージョン: {{version}}", + "Version_no": "アプリバージョン: {{version}}", "View_Original": "オリジナルを見る", "Websocket_disabled": "Websocketはこのサーバーでは無効化されています。\n{{contact}}", "Whats_the_password_for_your_certificate": "証明書のパスワードはなんですか?", diff --git a/app/i18n/locales/nl.json b/app/i18n/locales/nl.json index 5503286e08..8a003fd2b7 100644 --- a/app/i18n/locales/nl.json +++ b/app/i18n/locales/nl.json @@ -600,7 +600,7 @@ "Users": "Gebruikers", "Uses_server_configuration": "Gebruikt serverconfiguratie", "Verify_email_desc": "We hebben je een e-mail gestuurd om je inschrijving te bevestigen. Als je binnenkort geen e-mail ontvangt, gelieve terug te komen en het opnieuw te proberen.", - "Version_no": "Versie: {{version}}", + "Version_no": "App-versie: {{version}}", "View_Original": "Bekijk origineel", "Wait_activation_warning": "Voordat u kunt inloggen, moet uw account handmatig worden geactiveerd door een beheerder.", "Waiting_for_network": "Wachten op netwerk...", diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index 568349fc1e..54fb56cf32 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -792,7 +792,7 @@ "Uses_server_configuration": "Usar configuração da workspace", "Verify": "Verificar", "Verify_email_desc": "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.", - "Version_no": "Versão: {{version}}", + "Version_no": "Versão do aplicativo: {{version}}", "Vibrate": "Vibrar", "Video": "Vídeo", "video-conf-provider-not-configured-body": "Um administrador do workspace precisa ativar o recurso de chamadas de conferência primeiro.", diff --git a/app/i18n/locales/ru.json b/app/i18n/locales/ru.json index e2cc7379c9..96a69220b3 100644 --- a/app/i18n/locales/ru.json +++ b/app/i18n/locales/ru.json @@ -648,7 +648,7 @@ "Users": "Пользователи", "Uses_server_configuration": "Используется конфигурация сервера", "Verify_email_desc": "Вам был отправлен email для подтверждения регистрации. Если вы не получили этого сообщения, пожалуйста, попробуйте еще раз.", - "Version_no": "Версия: {{version}}", + "Version_no": "Версия приложения: {{version}}", "View_Original": "Посмотреть оригинал", "Wait_activation_warning": "До того как вы сможете войти, ваш аккаунт должен быть вручную активирован администратором сервера.", "Waiting_for_answer": "Ожидание ответа", diff --git a/app/i18n/locales/sl-SI.json b/app/i18n/locales/sl-SI.json index d07e948eb6..9d3fed05d7 100644 --- a/app/i18n/locales/sl-SI.json +++ b/app/i18n/locales/sl-SI.json @@ -615,7 +615,7 @@ "Users": "Uporabniki", "Uses_server_configuration": "Uporablja konfiguracijo strežnika", "Verify_email_desc": "Poslali smo vam e -poštno sporočilo za potrditev vaše registracije. Če v kratkem ne prejmete e -pošte, se vrnite in poskusite znova.", - "Version_no": "Različica: {{version}}", + "Version_no": "Različica aplikacije: {{version}}", "View_Original": "Pogled original", "Wait_activation_warning": "Preden se lahko prijavite, mora skrbnik ročno aktivirati vaš račun.", "Waiting_for_network": "Čakanje na omrežje ...", diff --git a/app/i18n/locales/sv.json b/app/i18n/locales/sv.json index d779af5573..376b7e61c0 100644 --- a/app/i18n/locales/sv.json +++ b/app/i18n/locales/sv.json @@ -678,7 +678,7 @@ "Users": "Användare", "Uses_server_configuration": "Använder serverkonfiguration", "Verify_email_desc": "Vi har skickat ett e-postmeddelande för att bekräfta din registrering. Om du inte får e-postmeddelandet försöker du igen.", - "Version_no": "Version: {{version}}", + "Version_no": "Appversion: {{version}}", "View_Original": "Visa original", "Wait_activation_warning": "Innan du kan logga in måste ditt konto aktiveras manuellt av en administratör.", "Waiting_for_answer": "Väntar på svar", diff --git a/app/i18n/locales/ta-IN.json b/app/i18n/locales/ta-IN.json index d574c8e2c4..8923e20e4a 100644 --- a/app/i18n/locales/ta-IN.json +++ b/app/i18n/locales/ta-IN.json @@ -712,7 +712,7 @@ "Users": "பயனர்கள்", "Uses_server_configuration": "பணியில் உள்ளேயே உபயோகிக்குகின்றது", "Verify_email_desc": "உங்களுக்கு உங்கள் பதிவுக்கு உறுதிப்படுத்த ஒரு மின்னஞ்சல் அனுப்பினோம். உங்களுக்கு விரைவில் ஒரு மின்னஞ்சல் பெறாதிருக்கின்றார்கள், தயவுசெய்து மீண்டும் வாருங்கள் மற்றும் முயற்சிக்கவும்.", - "Version_no": "பதிப்பு: {{version}}", + "Version_no": "நிரல் பதிப்பு: {{version}}", "Video": "காணொளி", "video-conf-provider-not-configured-body": "காரிகள் ஆட்சேர்க்கலாம் என்பதற்கு முகப்பு நிர்வாகி முதலாளியின் அனுமதி தேவை.", "video-conf-provider-not-configured-header": "காந்ஃபரன்ஸ் கால் கொள்ளை இயக்கப்படவில்லை", diff --git a/app/i18n/locales/te-IN.json b/app/i18n/locales/te-IN.json index 1d8a195319..1af32b3aa1 100644 --- a/app/i18n/locales/te-IN.json +++ b/app/i18n/locales/te-IN.json @@ -712,7 +712,7 @@ "Users": "వాడుకరులు", "Uses_server_configuration": "పనితనం ఆకృతి ఉపయోగిస్తుంది", "Verify_email_desc": "మేము మీ నమోదుని ధ్యానంలోకి పెంపొందాం. మీరు తక్షణం ఒక ఇమెయిల్ పొందరాక, దయచేసి మళ్ళీ ప్రయత్నించండి.", - "Version_no": "పరిస్థితి: {{version}}", + "Version_no": "అనువర్తనం సంచిక: {{version}}", "Video": "వీడియో", "video-conf-provider-not-configured-body": "వార్క్‌స్పేస్ యాడ్మిన్ మొదలు కాన్ఫరెన్స్ కాల్స్ విశేషాలు ఏర్పాట్లో ఉన్నాయి.", "video-conf-provider-not-configured-header": "కాన్ఫరెన్స్ కాల్ అనేకంగా లేదు", diff --git a/app/i18n/locales/tr.json b/app/i18n/locales/tr.json index 79d28e1941..e28f4727b4 100644 --- a/app/i18n/locales/tr.json +++ b/app/i18n/locales/tr.json @@ -490,7 +490,7 @@ "Users": "Kullanıcılar", "Uses_server_configuration": "Sunucu yapılandırmasını kullanır", "Verify_email_desc": "Kaydınızı onaylamak için size bir e-posta gönderdik. Kısa süre içinde bir e-posta almazsanız, lütfen geri gelin ve tekrar deneyin.", - "Version_no": "Versiyon: {{version}}", + "Version_no": "Uygulama sürümü: {{version}}", "View_Original": "Orijinali Görüntüle", "Wait_activation_warning": "Giriş yapmadan önce, hesabınız bir yönetici tarafından manuel olarak etkinleştirilmelidir.", "Waiting_for_network": "Ağ bağlantısı bekleniyor ...", diff --git a/app/i18n/locales/zh-CN.json b/app/i18n/locales/zh-CN.json index def1f53deb..8f434a0cfd 100644 --- a/app/i18n/locales/zh-CN.json +++ b/app/i18n/locales/zh-CN.json @@ -450,7 +450,7 @@ "Users": "用戶", "Uses_server_configuration": "使用服务器设置", "Verify_email_desc": "我们已经送出一封电子邮件,以确认您的注册。如果您没有很快收到,请再试一次。", - "Version_no": "版本: {{version}}", + "Version_no": "应用版本: {{version}}", "View_Original": "检视原文", "Wait_activation_warning": "您的帐号必须由管理员手动启用后才能登入。", "Waiting_for_network": "等待网路连接", diff --git a/app/i18n/locales/zh-TW.json b/app/i18n/locales/zh-TW.json index 773f8bc3d4..f9a9114e10 100644 --- a/app/i18n/locales/zh-TW.json +++ b/app/i18n/locales/zh-TW.json @@ -479,7 +479,7 @@ "Users": "使用者", "Uses_server_configuration": "使用伺服器設定", "Verify_email_desc": "我們已經送出一封電子郵件,以確認您的註冊。如果您沒有很快收到,請再試一次。", - "Version_no": "版本: {{version}}", + "Version_no": "應用程式版本: {{version}}", "View_Original": "檢視原文", "Wait_activation_warning": "您的帳號必須由管理員手動啟用後才能登入。", "Waiting_for_network": "等待網路連線", diff --git a/app/index.tsx b/app/index.tsx index 338fb9c01d..84670f7213 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -4,7 +4,6 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context'; import RNScreens from 'react-native-screens'; import { Provider } from 'react-redux'; -import Clipboard from '@react-native-clipboard/clipboard'; import AppContainer from './AppContainer'; import { appInit, appInitLocalSettings, setMasterDetail as setMasterDetailAction } from './actions/app'; @@ -59,14 +58,23 @@ interface IState { const parseDeepLinking = (url: string) => { if (url) { url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, ''); - const regex = /^(room|auth|invite)\?/; - if (url.match(regex)) { - url = url.replace(regex, '').trim(); - if (url) { - return parseQuery(url); + const regex = /^(room|auth|invite|shareextension)\?/; + const match = url.match(regex); + if (match) { + const matchedPattern = match[1]; + const query = url.replace(regex, '').trim(); + + if (query) { + const parsedQuery = parseQuery(query); + return { + ...parsedQuery, + type: matchedPattern + }; } } } + + // Return null if the URL doesn't match or is not valid return null; }; @@ -131,7 +139,6 @@ export default class Root extends React.Component<{}, IState> { const deepLinking = await Linking.getInitialURL(); const parsedDeepLinkingURL = parseDeepLinking(deepLinking!); if (parsedDeepLinkingURL) { - Clipboard.setString(JSON.stringify(parsedDeepLinkingURL)); store.dispatch(deepLinkingOpen(parsedDeepLinkingURL)); return; } diff --git a/app/lib/constants/defaultSettings.ts b/app/lib/constants/defaultSettings.ts index dc51e79c1a..ab1b4ea150 100644 --- a/app/lib/constants/defaultSettings.ts +++ b/app/lib/constants/defaultSettings.ts @@ -105,6 +105,9 @@ export const defaultSettings = { E2E_Enabled_Default_PrivateRooms: { type: 'valueAsBoolean' }, + E2E_Enable_Encrypt_Files: { + type: 'valueAsBoolean' + }, Accounts_Directory_DefaultView: { type: 'valueAsString' }, @@ -249,10 +252,10 @@ export const defaultSettings = { CDN_PREFIX: { type: 'valueAsString' }, - Accounts_RequirePasswordConfirmation:{ + Accounts_RequirePasswordConfirmation: { type: 'valueAsBoolean' }, - Accounts_ConfirmPasswordPlaceholder:{ + Accounts_ConfirmPasswordPlaceholder: { type: 'valueAsString' }, ...deprecatedSettings diff --git a/app/lib/database/index.ts b/app/lib/database/index.ts index 4f871fda25..6b503bcc6b 100644 --- a/app/lib/database/index.ts +++ b/app/lib/database/index.ts @@ -64,7 +64,6 @@ export const getDatabase = (database = ''): Database => { }; interface IDatabases { - shareDB?: TAppDatabase | null; serversDB: TServerDatabase; activeDB?: TAppDatabase; } @@ -82,51 +81,14 @@ class DB { }) as TServerDatabase }; - // Expected at least one database get active(): TAppDatabase { - return this.databases.shareDB || this.databases.activeDB!; - } - - get share() { - return this.databases.shareDB; - } - - set share(db) { - this.databases.shareDB = db; + return this.databases.activeDB!; } get servers() { return this.databases.serversDB; } - setShareDB(database = '') { - const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.'); - const dbName = getDatabasePath(path); - - const adapter = new SQLiteAdapter({ - dbName, - schema: appSchema, - migrations, - jsi: true - }); - - this.databases.shareDB = new Database({ - adapter, - modelClasses: [ - Subscription, - Message, - Thread, - ThreadMessage, - Upload, - Permission, - CustomEmoji, - FrequentlyUsedEmoji, - Setting, - User - ] - }) as TAppDatabase; - } - setActiveDB(database: string) { this.databases.activeDB = getDatabase(database) as TAppDatabase; } diff --git a/app/lib/encryption/encryption.ts b/app/lib/encryption/encryption.ts index 7ccadbfe31..4b7dee5c61 100644 --- a/app/lib/encryption/encryption.ts +++ b/app/lib/encryption/encryption.ts @@ -27,6 +27,7 @@ import { getSubscriptionByRoomId } from '../database/services/Subscription'; import log from '../methods/helpers/log'; import protectedFunction from '../methods/helpers/protectedFunction'; import UserPreferences from '../methods/userPreferences'; +import { compareServerVersion } from '../methods/helpers'; import { Services } from '../services'; import { store } from '../store/auxStore'; import { MAX_CONCURRENT_QUEUE } from './constants'; @@ -228,8 +229,15 @@ class Encryption { throw new Error('Public key not found in local storage, password not changed'); } + // Only send force param for newer worspace versions + const { version } = store.getState().server; + let force = false; + if (compareServerVersion(version, 'greaterThanOrEqualTo', '6.10.0')) { + force = true; + } + // Send the new keys to the server - await Services.e2eSetUserPublicAndPrivateKeys(publicKey, encodedPrivateKey); + await Services.e2eSetUserPublicAndPrivateKeys(publicKey, encodedPrivateKey, force); }; // get a encryption room instance @@ -531,7 +539,8 @@ class Encryption { throw new Error('Subscription not found'); } - if (!subscription.encrypted) { + const { E2E_Enable_Encrypt_Files } = store.getState().settings; + if (!subscription.encrypted || (E2E_Enable_Encrypt_Files !== undefined && !E2E_Enable_Encrypt_Files)) { // Send a non encrypted message return { file }; } diff --git a/app/lib/methods/helpers/askAndroidMediaPermissions.ts b/app/lib/methods/helpers/askAndroidMediaPermissions.ts deleted file mode 100644 index 56b3f5f340..0000000000 --- a/app/lib/methods/helpers/askAndroidMediaPermissions.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Permission, PermissionsAndroid, Platform, Rationale } from 'react-native'; - -import i18n from '../../../i18n'; - -// Define a type for the permissions map -type PermissionsMap = { [key: string]: string }; - -/** - * Rationale for requesting read permissions on Android. - */ -const readExternalStorageRationale: Rationale = { - title: i18n.t('Read_External_Permission'), - message: i18n.t('Read_External_Permission_Message'), - buttonPositive: i18n.t('Ok') -}; - -/** - * Checks if all requested permissions are granted. - * - * @param {PermissionsMap} permissionsStatus - The object containing the statuses of the permissions. - * @param {string[]} permissions - The list of permissions to check. - * @return {boolean} Whether all permissions are granted. - */ -const areAllPermissionsGranted = (permissionsStatus: PermissionsMap, permissions: string[]): boolean => - permissions.every(permission => permissionsStatus[permission] === PermissionsAndroid.RESULTS.GRANTED); - -/** - * Requests permission for reading media on Android. - * - * @return {Promise} A promise that resolves to a boolean indicating whether the permissions were granted. - */ -export const askAndroidMediaPermissions = async (): Promise => { - if (Platform.OS !== 'android') return true; - - // For Android versions that require the new permissions model (API Level >= 33) - if (Platform.constants.Version >= 33) { - const permissions = [ - 'android.permission.READ_MEDIA_IMAGES', - 'android.permission.READ_MEDIA_VIDEO', - 'android.permission.READ_MEDIA_AUDIO' - ]; - - const permissionsStatus = await PermissionsAndroid.requestMultiple(permissions as Permission[]); - return areAllPermissionsGranted(permissionsStatus, permissions); - } - - // For older Android versions - const result = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE, - readExternalStorageRationale - ); - - return result === PermissionsAndroid.RESULTS.GRANTED; -}; diff --git a/app/lib/methods/helpers/helpers.ts b/app/lib/methods/helpers/helpers.ts index 46074f1ad2..5e73f4350d 100644 --- a/app/lib/methods/helpers/helpers.ts +++ b/app/lib/methods/helpers/helpers.ts @@ -83,9 +83,8 @@ export function isRead(item) { } export function hasRole(role): boolean { - const shareUser = reduxStore.getState().share.user; const loginUser = reduxStore.getState().login.user; - const userRoles = shareUser?.roles || loginUser?.roles || []; + const userRoles = loginUser?.roles || []; return userRoles.indexOf(role) > -1; } @@ -106,10 +105,8 @@ export async function hasPermission(permissions, rid?: any): Promise } try { - const shareUser = reduxStore.getState().share.user; const loginUser = reduxStore.getState().login.user; - // get user roles on the server from redux - const userRoles = shareUser?.roles || loginUser?.roles || []; + const userRoles = loginUser?.roles || []; const mergedRoles = [...new Set([...roomRoles, ...userRoles])]; return permissions.map(permission => permission?.some(r => mergedRoles.includes(r) ?? false)); } catch (e) { diff --git a/app/lib/methods/helpers/index.ts b/app/lib/methods/helpers/index.ts index 58dfa6fefe..ebe3110493 100644 --- a/app/lib/methods/helpers/index.ts +++ b/app/lib/methods/helpers/index.ts @@ -15,7 +15,6 @@ export * from './isSsl'; export * from './isValidEmail'; export * from './random'; export * from './image'; -export * from './askAndroidMediaPermissions'; export * from './emitter'; export * from './parseJson'; export * from './fileDownload'; diff --git a/app/lib/methods/helpers/parseQuery.ts b/app/lib/methods/helpers/parseQuery.ts index c6e2bb5fdf..8e3d7abe8c 100644 --- a/app/lib/methods/helpers/parseQuery.ts +++ b/app/lib/methods/helpers/parseQuery.ts @@ -10,6 +10,10 @@ */ export default function (query: string) { + if (query.startsWith('url=')) { + return { text: decodeURIComponent(query.replace('url=', '').trim()) }; + } + return (/^[?#]/.test(query) ? query.slice(1) : query).split('&').reduce((params: { [key: string]: string }, param) => { const [key, value] = param.split('='); params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : ''; diff --git a/app/lib/methods/shareExtension.ts b/app/lib/methods/shareExtension.ts deleted file mode 100644 index f7ae6c0733..0000000000 --- a/app/lib/methods/shareExtension.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Q } from '@nozbe/watermelondb'; - -import { shareSetSettings, shareSelectServer, shareSetUser } from '../../actions/share'; -import SSLPinning from './helpers/sslPinning'; -import log from './helpers/log'; -import { IShareServer, IShareUser } from '../../reducers/share'; -import UserPreferences from './userPreferences'; -import database from '../database'; -import { encryptionInit } from '../../actions/encryption'; -import { store } from '../store/auxStore'; -import sdk from '../services/sdk'; -import { CERTIFICATE_KEY, TOKEN_KEY } from '../constants'; -import { setCustomEmojis } from './getCustomEmojis'; -import { Services } from '../services'; -import { parseSettings } from './parseSettings'; - -export async function shareExtensionInit(server: string) { - database.setShareDB(server); - - try { - const certificate = UserPreferences.getString(`${CERTIFICATE_KEY}-${server}`); - if (SSLPinning && certificate) { - await SSLPinning.setCertificate(certificate, server); - } - } catch { - // Do nothing - } - - // sdk.current.disconnect(); - sdk.initializeShareExtension(server); - - // set Server - const currentServer: IShareServer = { - server, - version: '' - }; - const serversDB = database.servers; - const serversCollection = serversDB.get('servers'); - try { - const serverRecord = await serversCollection.find(server); - currentServer.version = serverRecord.version; - } catch { - // Record not found - } - store.dispatch(shareSelectServer(currentServer)); - - setCustomEmojis(); - - try { - // set Settings - const settings = ['Accounts_AvatarBlockUnauthenticatedAccess']; - const db = database.active; - const settingsCollection = db.get('settings'); - const settingsRecords = await settingsCollection.query(Q.where('id', Q.oneOf(settings))).fetch(); - const parsed = Object.values(settingsRecords).map(item => ({ - _id: item.id, - valueAsString: item.valueAsString, - valueAsBoolean: item.valueAsBoolean, - valueAsNumber: item.valueAsNumber, - valueAsArray: item.valueAsArray, - _updatedAt: item._updatedAt - })); - store.dispatch(shareSetSettings(parseSettings(parsed))); - - // set User info - const userId = UserPreferences.getString(`${TOKEN_KEY}-${server}`); - const userCollections = serversDB.get('users'); - let user = null; - if (userId) { - const userRecord = await userCollections.find(userId); - user = { - id: userRecord.id, - token: userRecord.token, - username: userRecord.username, - roles: userRecord.roles - }; - } - store.dispatch(shareSetUser(user as IShareUser)); - if (user) { - await Services.login({ resume: user.token }); - } - store.dispatch(encryptionInit()); - } catch (e) { - log(e); - } -} - -export function closeShareExtension() { - sdk.disconnect(); - database.share = null; - - store.dispatch(shareSelectServer({})); - store.dispatch(shareSetUser({})); - store.dispatch(shareSetSettings({})); -} diff --git a/app/lib/methods/useServer.ts b/app/lib/methods/useServer.ts index 60e367a01c..ddda07c9b0 100644 --- a/app/lib/methods/useServer.ts +++ b/app/lib/methods/useServer.ts @@ -6,7 +6,6 @@ import { useAppSelector } from '../hooks'; export default function useServer() { const [server, setServer] = useState(null); - const shareServer = useAppSelector((state: IApplicationState) => state.share.server.server); const appServer = useAppSelector((state: IApplicationState) => state.server.server); useEffect(() => { @@ -15,7 +14,7 @@ export default function useServer() { const serversCollection = serversDB.get('servers'); let serverInfo = null; try { - serverInfo = await serversCollection.find(shareServer || appServer); + serverInfo = await serversCollection.find(appServer); setServer(serverInfo); } catch { setServer(serverInfo); diff --git a/app/lib/services/restApi.ts b/app/lib/services/restApi.ts index ce42c92986..e201628ac6 100644 --- a/app/lib/services/restApi.ts +++ b/app/lib/services/restApi.ts @@ -54,9 +54,9 @@ export const createChannel = ({ return sdk.post(type ? 'groups.create' : 'channels.create', params); }; -export const e2eSetUserPublicAndPrivateKeys = (public_key: string, private_key: string) => +export const e2eSetUserPublicAndPrivateKeys = (public_key: string, private_key: string, force: boolean = false) => // RC 2.2.0 - sdk.post('e2e.setUserPublicAndPrivateKeys', { public_key, private_key }); + sdk.post('e2e.setUserPublicAndPrivateKeys', { public_key, private_key, ...(force && { force: true }) }); export const e2eRequestSubscriptionKeys = (): Promise => // RC 0.72.0 diff --git a/app/lib/services/sdk.ts b/app/lib/services/sdk.ts index 0bfe8d2507..d1572e61fc 100644 --- a/app/lib/services/sdk.ts +++ b/app/lib/services/sdk.ts @@ -10,7 +10,6 @@ import { compareServerVersion, random } from '../methods/helpers'; class Sdk { private sdk: typeof Rocketchat; - private shareSdk?: typeof Rocketchat; private code: any; private initializeSdk(server: string): typeof Rocketchat { @@ -25,12 +24,8 @@ class Sdk { return this.sdk; } - initializeShareExtension(server: string) { - this.shareSdk = this.initializeSdk(server); - } - get current() { - return this.shareSdk || this.sdk; + return this.sdk; } /** @@ -38,11 +33,6 @@ class Sdk { * I'm returning "null" because we need to remove both instances of this.sdk here and on rocketchat.js */ disconnect() { - if (this.shareSdk) { - this.shareSdk.disconnect(); - this.shareSdk = null; - return null; - } if (this.sdk) { this.sdk.disconnect(); this.sdk = null; diff --git a/app/reducers/share.test.ts b/app/reducers/share.test.ts index 851e7ad269..22b3a534f1 100644 --- a/app/reducers/share.test.ts +++ b/app/reducers/share.test.ts @@ -1,4 +1,4 @@ -import { shareSelectServer, shareSetSettings, shareSetUser } from '../actions/share'; +import { shareSetParams } from '../actions/share'; import { mockedStore } from './mockedStore'; import { initialState } from './share'; @@ -8,34 +8,22 @@ describe('test share reducer', () => { expect(state).toEqual(initialState); }); - it('should return modified store after shareSelectServer', () => { - const server = { - server: 'https://open.rocket.chat', - version: '4.4.0' + it('should return correctly updated state after calling setParams action', () => { + const params: Record = { + mediaUris: 'test' }; - mockedStore.dispatch(shareSelectServer(server)); - const state = mockedStore.getState().share.server; - expect(state).toEqual(server); - }); - - it('should return modified store after shareSetSettings', () => { - const settings = { - Admin: false - }; - mockedStore.dispatch(shareSetSettings(settings)); - const state = mockedStore.getState().share.settings; - expect(state).toEqual(settings); + mockedStore.dispatch(shareSetParams(params)); + const state = mockedStore.getState().share; + expect(state).toEqual({ + ...initialState, + params + }); }); - it('should return modified store after shareSetUser', () => { - const user = { - id: 'dig-joy', - token: 'token', - username: 'rocket.chat', - roles: ['admin'] - }; - mockedStore.dispatch(shareSetUser(user)); - const state = mockedStore.getState().share.user; - expect(state).toEqual(user); + it('should reset params to an empty object', () => { + const params: Record = {}; + mockedStore.dispatch(shareSetParams(params)); + const state = mockedStore.getState().share; + expect(state).toEqual(initialState); }); }); diff --git a/app/reducers/share.ts b/app/reducers/share.ts index d62f9c5848..147ef620c5 100644 --- a/app/reducers/share.ts +++ b/app/reducers/share.ts @@ -1,48 +1,22 @@ import { TActionsShare } from '../actions/share'; import { SHARE } from '../actions/actionsTypes'; -export interface IShareServer { - server?: string; - version?: string; -} - -export type TShareSettings = Record; - -export interface IShareUser { - id?: string; - token?: string; - username?: string; - roles?: string[]; -} +export type TShareParams = Record; export interface IShare { - user: IShareUser; - server: IShareServer; - settings: TShareSettings; + params: TShareParams; } export const initialState: IShare = { - user: {}, - server: {}, - settings: {} + params: {} }; export default function share(state = initialState, action: TActionsShare): IShare { switch (action.type) { - case SHARE.SELECT_SERVER: - return { - ...state, - server: action.server - }; - case SHARE.SET_USER: - return { - ...state, - user: action.user - }; - case SHARE.SET_SETTINGS: + case SHARE.SET_PARAMS: return { ...state, - settings: action.settings + params: action.params }; default: return state; diff --git a/app/sagas/deepLinking.js b/app/sagas/deepLinking.js index 4e72134011..bf72854640 100644 --- a/app/sagas/deepLinking.js +++ b/app/sagas/deepLinking.js @@ -1,5 +1,6 @@ import { all, call, delay, put, select, take, takeLatest } from 'redux-saga/effects'; +import { shareSetParams } from '../actions/share'; import * as types from '../actions/actionsTypes'; import { appInit, appStart } from '../actions/app'; import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks'; @@ -17,6 +18,7 @@ import log from '../lib/methods/helpers/log'; import UserPreferences from '../lib/methods/userPreferences'; import { videoConfJoin } from '../lib/methods/videoConf'; import { Services } from '../lib/services'; +import sdk from '../lib/services/sdk'; const roomTypes = { channel: 'c', @@ -84,7 +86,31 @@ const handleOAuth = function* handleOAuth({ params }) { } }; +const handleShareExtension = function* handleOpen({ params }) { + const server = UserPreferences.getString(CURRENT_SERVER); + const user = UserPreferences.getString(`${TOKEN_KEY}-${server}`); + + if (!user) { + yield put(appInit()); + return; + } + + yield put(appStart({ root: RootEnum.ROOT_LOADING_SHARE_EXTENSION })); + yield localAuthenticate(server); + yield put(selectServerRequest(server)); + if (sdk.current?.client?.host !== server) { + yield take(types.LOGIN.SUCCESS); + } + yield put(shareSetParams(params)); + yield put(appStart({ root: RootEnum.ROOT_SHARE_EXTENSION })); +}; + const handleOpen = function* handleOpen({ params }) { + if (params.type === 'shareextension') { + yield handleShareExtension({ params }); + return; + } + const serversDB = database.servers; const serversCollection = serversDB.get('servers'); diff --git a/app/sagas/encryption.js b/app/sagas/encryption.js index 0b8e3e0e7c..a2e9a9aba6 100644 --- a/app/sagas/encryption.js +++ b/app/sagas/encryption.js @@ -11,7 +11,7 @@ import log from '../lib/methods/helpers/log'; import { E2E_BANNER_TYPE, E2E_PRIVATE_KEY, E2E_PUBLIC_KEY, E2E_RANDOM_PASSWORD_KEY } from '../lib/constants'; import { Services } from '../lib/services'; -const getServer = state => state.share.server.server || state.server.server; +const getServer = state => state.server.server; const getE2eEnable = state => state.settings.E2E_Enable; const handleEncryptionInit = function* handleEncryptionInit() { diff --git a/app/sagas/init.js b/app/sagas/init.js index 5de30417d1..37e072fcec 100644 --- a/app/sagas/init.js +++ b/app/sagas/init.js @@ -1,4 +1,4 @@ -import { call, put, takeLatest } from 'redux-saga/effects'; +import { call, put, select, takeLatest } from 'redux-saga/effects'; import RNBootSplash from 'react-native-bootsplash'; import AsyncStorage from '@react-native-async-storage/async-storage'; @@ -23,6 +23,7 @@ export const initLocalSettings = function* initLocalSettings() { const BIOMETRY_MIGRATION_KEY = 'kBiometryMigration'; const restore = function* restore() { + console.log('RESTORE'); try { const server = UserPreferences.getString(CURRENT_SERVER); let userId = UserPreferences.getString(`${TOKEN_KEY}-${server}`); @@ -84,7 +85,11 @@ const restore = function* restore() { }; const start = function* start() { - yield RNBootSplash.hide({ fade: true }); + const currentRoot = yield select(state => state.app.root); + + if (currentRoot !== RootEnum.ROOT_LOADING_SHARE_EXTENSION) { + yield RNBootSplash.hide({ fade: true }); + } }; const root = function* root() { diff --git a/app/sagas/login.js b/app/sagas/login.js index c5348c40c4..fb2fcabc69 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -240,7 +240,10 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) { }); yield put(setUser(user)); EventEmitter.emit('connected'); - yield put(appStart({ root: RootEnum.ROOT_INSIDE })); + const currentRoot = yield select(state => state.app.root); + if (currentRoot !== RootEnum.ROOT_SHARE_EXTENSION && currentRoot !== RootEnum.ROOT_LOADING_SHARE_EXTENSION) { + yield put(appStart({ root: RootEnum.ROOT_INSIDE })); + } const inviteLinkToken = yield select(state => state.inviteLinks.token); if (inviteLinkToken) { yield put(inviteLinksRequest(inviteLinkToken)); diff --git a/app/sagas/selectServer.ts b/app/sagas/selectServer.ts index 8433e72a64..883dd8b68e 100644 --- a/app/sagas/selectServer.ts +++ b/app/sagas/selectServer.ts @@ -185,7 +185,10 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch yield put(clearSettings()); yield put(setUser(user)); yield connect({ server, logoutOnError: true }); - yield put(appStart({ root: RootEnum.ROOT_INSIDE })); + const currentRoot = yield* appSelector(state => state.app.root); + if (currentRoot !== RootEnum.ROOT_SHARE_EXTENSION && currentRoot !== RootEnum.ROOT_LOADING_SHARE_EXTENSION) { + yield put(appStart({ root: RootEnum.ROOT_INSIDE })); + } UserPreferences.setString(CURRENT_SERVER, server); // only set server after have a user } else { yield put(clearUser()); diff --git a/app/selectors/login.ts b/app/selectors/login.ts index f8a5198078..1f14068e08 100644 --- a/app/selectors/login.ts +++ b/app/selectors/login.ts @@ -1,5 +1,4 @@ import { createSelector } from 'reselect'; -import isEmpty from 'lodash/isEmpty'; import { IApplicationState, IUser } from '../definitions'; @@ -13,12 +12,7 @@ export interface IServices { wordpress: { clientId: string; serverURL: string }; } -const getUser = (state: IApplicationState): IUser => { - if (!isEmpty(state.share?.user)) { - return state.share.user as IUser; - } - return state.login?.user as IUser; -}; +const getUser = (state: IApplicationState): IUser => state.login?.user as IUser; const getLoginServices = (state: IApplicationState) => (state.login.services as IServices) || {}; const getShowFormLoginSetting = (state: IApplicationState) => (state.settings.Accounts_ShowFormLogin as boolean) || false; const getIframeEnabledSetting = (state: IApplicationState) => (state.settings.Accounts_iframe_enabled as boolean) || false; diff --git a/app/share.tsx b/app/share.tsx deleted file mode 100644 index 0f0f730baa..0000000000 --- a/app/share.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React, { useContext, useEffect, useLayoutEffect, useState } from 'react'; -import { Dimensions } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; -import { Provider } from 'react-redux'; - -import { getTheme, setNativeTheme, initialTheme as initialThemeFunction, unsubscribeTheme } from './lib/methods/helpers/theme'; -import UserPreferences from './lib/methods/userPreferences'; -import Navigation from './lib/navigation/shareNavigation'; -import store from './lib/store'; -import { initStore } from './lib/store/auxStore'; -import { closeShareExtension, shareExtensionInit } from './lib/methods/shareExtension'; -import { defaultHeader, getActiveRouteName, navigationTheme, themedHeader } from './lib/methods/helpers/navigation'; -import { ThemeContext } from './theme'; -import { localAuthenticate } from './lib/methods/helpers/localAuthentication'; -import ScreenLockedView from './views/ScreenLockedView'; -// Outside Stack -import WithoutServersView from './views/WithoutServersView'; -// Inside Stack -import ShareListView from './views/ShareListView'; -import ShareView from './views/ShareView'; -import SelectServerView from './views/SelectServerView'; -import { setCurrentScreen } from './lib/methods/helpers/log'; -import AuthLoadingView from './views/AuthLoadingView'; -import { DimensionsContext } from './dimensions'; -import { ShareInsideStackParamList, ShareOutsideStackParamList, ShareAppStackParamList } from './definitions/navigationTypes'; -import { colors, CURRENT_SERVER } from './lib/constants'; -import Loading from './containers/Loading'; - -initStore(store); - -const Inside = createStackNavigator(); -const InsideStack = () => { - const { theme } = useContext(ThemeContext); - - const screenOptions = { - ...defaultHeader, - ...themedHeader(theme) - }; - screenOptions.headerStyle = { ...screenOptions.headerStyle, height: 57 }; - - return ( - - {/* @ts-ignore */} - - {/* @ts-ignore */} - - - - ); -}; - -const Outside = createStackNavigator(); -const OutsideStack = () => { - const { theme } = useContext(ThemeContext); - - return ( - - - - ); -}; - -// App -const Stack = createStackNavigator(); -export const App = ({ root }: { root: string }): React.ReactElement => ( - - <> - {!root ? : null} - {root === 'outside' ? : null} - {root === 'inside' ? : null} - - -); - -const { width, height, scale, fontScale } = Dimensions.get('screen'); -const initialTheme = initialThemeFunction(); -const theme = getTheme(initialTheme); - -const Root = (): React.ReactElement => { - const [root, setRoot] = useState(''); - const navTheme = navigationTheme(theme); - - useLayoutEffect(() => { - setNativeTheme(initialTheme); - }, []); - - useEffect(() => { - const authenticateShare = async (currentServer: string) => { - await localAuthenticate(currentServer); - setRoot('inside'); - await shareExtensionInit(currentServer); - }; - - const currentServer = UserPreferences.getString(CURRENT_SERVER); - if (currentServer) { - authenticateShare(currentServer); - } else { - setRoot('outside'); - } - - const state = Navigation.navigationRef.current?.getRootState(); - const currentRouteName = getActiveRouteName(state); - Navigation.routeNameRef.current = currentRouteName; - setCurrentScreen(currentRouteName); - - return () => { - closeShareExtension(); - unsubscribeTheme(); - }; - }, []); - - return ( - - - - { - const previousRouteName = Navigation.routeNameRef.current; - const currentRouteName = getActiveRouteName(state); - if (previousRouteName !== currentRouteName) { - setCurrentScreen(currentRouteName); - } - Navigation.routeNameRef.current = currentRouteName; - }}> - - - - - - - - ); -}; - -export default Root; diff --git a/app/stacks/ShareExtensionStack.tsx b/app/stacks/ShareExtensionStack.tsx new file mode 100644 index 0000000000..07d4aa31c7 --- /dev/null +++ b/app/stacks/ShareExtensionStack.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { createStackNavigator, StackNavigationOptions } from '@react-navigation/stack'; + +import { ThemeContext } from '../theme'; +import { StackAnimation, defaultHeader, themedHeader } from '../lib/methods/helpers/navigation'; +import SelectServerView from '../views/SelectServerView'; +import ShareListView from '../views/ShareListView'; +import ShareView from '../views/ShareView'; + +const ShareExtension = createStackNavigator(); +const ShareExtensionStack = () => { + const { theme } = React.useContext(ThemeContext); + + return ( + + {/* @ts-ignore */} + + {/* @ts-ignore */} + + + + ); +}; + +export default ShareExtensionStack; diff --git a/app/views/MediaAutoDownloadView/index.tsx b/app/views/MediaAutoDownloadView/index.tsx index 5dae262e26..e9b3910386 100644 --- a/app/views/MediaAutoDownloadView/index.tsx +++ b/app/views/MediaAutoDownloadView/index.tsx @@ -36,11 +36,13 @@ const MediaAutoDownload = () => { + + diff --git a/app/views/SelectServerView.tsx b/app/views/SelectServerView.tsx index ceddb088f8..d3beecf215 100644 --- a/app/views/SelectServerView.tsx +++ b/app/views/SelectServerView.tsx @@ -3,25 +3,27 @@ import { FlatList } from 'react-native'; import { StackNavigationProp } from '@react-navigation/stack'; import { Q } from '@nozbe/watermelondb'; import { useNavigation } from '@react-navigation/native'; +import { useDispatch } from 'react-redux'; import I18n from '../i18n'; import StatusBar from '../containers/StatusBar'; import ServerItem, { ROW_HEIGHT } from '../containers/ServerItem'; -import { shareExtensionInit } from '../lib/methods/shareExtension'; import database from '../lib/database'; import SafeAreaView from '../containers/SafeAreaView'; import * as List from '../containers/List'; import { ShareInsideStackParamList } from '../definitions/navigationTypes'; import { TServerModel } from '../definitions'; import { useAppSelector } from '../lib/hooks'; +import { selectServerRequest } from '../actions/server'; const getItemLayout = (data: any, index: number) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index }); const keyExtractor = (item: TServerModel) => item.id; const SelectServerView = () => { const [servers, setServers] = React.useState([]); + const dispatch = useDispatch(); - const server = useAppSelector(state => state.share.server.server); + const server = useAppSelector(state => state.server.server); const navigation = useNavigation>(); useLayoutEffect(() => { @@ -40,15 +42,15 @@ const SelectServerView = () => { init(); }, []); - const select = async (serverSelected: string) => { - navigation.navigate('ShareListView'); + const select = (serverSelected: string) => { if (serverSelected !== server) { - await shareExtensionInit(serverSelected); + dispatch(selectServerRequest(serverSelected)); } + navigation.pop(); }; return ( - + { - navigateToScreen('DisplayPrefsView')} showActionIndicator /> + navigateToScreen('DisplayPrefsView')} + showActionIndicator + left={() => } + /> navigateToScreen('ProfileView')} showActionIndicator testID='settings-profile' + left={() => } /> @@ -192,29 +198,21 @@ const SettingsView = (): React.ReactElement => { ) : null} - - navigateToScreen('LanguageView')} showActionIndicator testID='settings-view-language' + left={() => } /> - {!isFDroidBuild ? ( - <> - - - ) : null} - - - navigateToScreen('DefaultBrowserView')} testID='settings-view-default-browser' + left={() => } /> { showActionIndicator onPress={() => navigateToScreen('ThemeView')} testID='settings-view-theme' + left={() => } /> { showActionIndicator onPress={() => navigateToScreen('MediaAutoDownloadView')} testID='settings-view-media-auto-download' + left={() => } /> { showActionIndicator onPress={() => navigateToScreen('SecurityPrivacyView')} testID='settings-view-security-privacy' + left={() => } /> - - + } + /> + + } + right={() => } + /> + + {!isFDroidBuild ? ( + <> + } + right={() => } + /> + + ) : null} + + } + right={() => } + /> } /> { testID='settings-view-server-version' translateTitle={false} translateSubtitle={false} + left={() => } /> @@ -268,16 +304,16 @@ const SettingsView = (): React.ReactElement => { title='Clear_cache' testID='settings-view-clear-cache' onPress={handleClearCache} - showActionIndicator - color={colors.buttonBackgroundDangerDefault} + color={colors.fontDanger} + left={() => } /> } /> diff --git a/app/views/ShareListView/Header/Header.ios.tsx b/app/views/ShareListView/Header/Header.ios.tsx deleted file mode 100644 index ddd61acd90..0000000000 --- a/app/views/ShareListView/Header/Header.ios.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useState } from 'react'; -import { Keyboard, StyleSheet, View } from 'react-native'; -import ShareExtension from 'rn-extensions-share'; - -import SearchBox from './SearchBox'; -import * as HeaderButton from '../../../containers/HeaderButton'; -import { themes } from '../../../lib/constants'; -import sharedStyles from '../../Styles'; -import { animateNextTransition } from '../../../lib/methods/helpers/layoutAnimation'; -import { IShareListHeaderIos } from './interface'; - -const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - ...sharedStyles.separatorBottom - } -}); - -const Header = React.memo(({ searching, onChangeSearchText, initSearch, cancelSearch, theme }: IShareListHeaderIos) => { - const [text, setText] = useState(''); - - const onChangeText = (searchText: string) => { - onChangeSearchText(searchText); - setText(searchText); - }; - - const onCancelPress = () => { - Keyboard.dismiss(); - onChangeText(''); - cancelSearch(); - animateNextTransition(); - }; - - const onFocus = () => { - initSearch(); - animateNextTransition(); - }; - - return ( - - {!searching ? : null} - - - ); -}); - -export default Header; diff --git a/app/views/ShareListView/Header/Header.tsx b/app/views/ShareListView/Header/Header.tsx deleted file mode 100644 index f835aa3e8e..0000000000 --- a/app/views/ShareListView/Header/Header.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; - -import { TextInput } from '../../../containers/TextInput'; -import I18n from '../../../i18n'; -import { themes } from '../../../lib/constants'; -import sharedStyles from '../../Styles'; -import { IShareListHeader } from './interface'; - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center' - }, - search: { - fontSize: 20, - ...sharedStyles.textRegular, - marginHorizontal: 14 - }, - title: { - fontSize: 20, - ...sharedStyles.textBold, - marginHorizontal: 16 - } -}); - -const Header = React.memo(({ searching, onChangeSearchText, theme }: IShareListHeader) => { - const titleColorStyle = { color: themes[theme].fontSecondaryInfo }; - const isLight = theme === 'light'; - if (searching) { - return ( - - - - ); - } - return {I18n.t('Send_to')}; -}); - -export default Header; diff --git a/app/views/ShareListView/Header/SearchBox.tsx b/app/views/ShareListView/Header/SearchBox.tsx deleted file mode 100644 index 92296fcf15..0000000000 --- a/app/views/ShareListView/Header/SearchBox.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, TextInput as RNTextInput, TextInputProps, View } from 'react-native'; -import Touchable from 'react-native-platform-touchable'; - -import { themes } from '../../../lib/constants'; -import I18n from '../../../i18n'; -import { CustomIcon } from '../../../containers/CustomIcon'; -import { TextInput } from '../../../containers/TextInput'; -import { useTheme } from '../../../theme'; -import { isIOS } from '../../../lib/methods/helpers'; -import sharedStyles from '../../Styles'; - -const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - alignItems: 'center', - flex: 1 - }, - searchBox: { - alignItems: 'center', - borderRadius: 10, - flexDirection: 'row', - fontSize: 17, - height: 36, - margin: 16, - marginVertical: 10, - paddingHorizontal: 10, - flex: 1 - }, - input: { - flex: 1, - fontSize: 17, - marginLeft: 8, - paddingTop: 0, - paddingBottom: 0, - ...sharedStyles.textRegular - }, - cancel: { - marginRight: 15 - }, - cancelText: { - ...sharedStyles.textRegular, - fontSize: 17 - } -}); - -interface ISearchBox extends TextInputProps { - value?: string; - hasCancel?: boolean; - onCancelPress?: () => void; - inputRef?: React.Ref; -} - -const CancelButton = ({ onCancelPress }: { onCancelPress?: () => void }) => { - const { theme } = useTheme(); - return ( - - {I18n.t('Cancel')} - - ); -}; - -const SearchBox = ({ hasCancel, onCancelPress, inputRef, ...props }: ISearchBox): React.ReactElement => { - const { theme } = useTheme(); - return ( - - - - - - {hasCancel && onCancelPress ? : null} - - ); -}; - -export default SearchBox; diff --git a/app/views/ShareListView/Header/index.tsx b/app/views/ShareListView/Header/index.tsx deleted file mode 100644 index e1feab435b..0000000000 --- a/app/views/ShareListView/Header/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; - -import Header from './Header'; -import { IShareListHeader } from './interface'; - -const ShareListHeader = React.memo(({ searching, initSearch, cancelSearch, onChangeSearchText, theme }: IShareListHeader) => { - const onSearchChangeText = (text: string) => { - onChangeSearchText(text.trim()); - }; - - return ( -
- ); -}); - -export default ShareListHeader; diff --git a/app/views/ShareListView/Header/interface.ts b/app/views/ShareListView/Header/interface.ts deleted file mode 100644 index 23c1057201..0000000000 --- a/app/views/ShareListView/Header/interface.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TextInputProps } from 'react-native'; - -import { TSupportedThemes } from '../../../theme'; - -type RequiredOnChangeText = Required>; - -export interface IShareListHeader { - searching: boolean; - onChangeSearchText: RequiredOnChangeText['onChangeText']; - theme: TSupportedThemes; - initSearch?: () => void; - cancelSearch?: () => void; -} - -export type IShareListHeaderIos = Required; diff --git a/app/views/ShareListView/index.tsx b/app/views/ShareListView/index.tsx index 30dc719d63..976548af17 100644 --- a/app/views/ShareListView/index.tsx +++ b/app/views/ShareListView/index.tsx @@ -1,8 +1,7 @@ import React from 'react'; import { Dispatch } from 'redux'; import { StackNavigationProp } from '@react-navigation/stack'; -import { BackHandler, FlatList, Keyboard, ScrollView, Text, View } from 'react-native'; -import ShareExtension from 'rn-extensions-share'; +import { BackHandler, FlatList, Keyboard, Text, View } from 'react-native'; import * as FileSystem from 'expo-file-system'; import { connect } from 'react-redux'; import * as mime from 'react-native-mime-types'; @@ -16,21 +15,18 @@ import ServerItem from '../../containers/ServerItem'; import * as HeaderButton from '../../containers/HeaderButton'; import ActivityIndicator from '../../containers/ActivityIndicator'; import * as List from '../../containers/List'; +import SearchHeader from '../../containers/SearchHeader'; import { themes } from '../../lib/constants'; import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation'; import { TSupportedThemes, withTheme } from '../../theme'; import SafeAreaView from '../../containers/SafeAreaView'; import { sanitizeLikeString } from '../../lib/database/utils'; import styles from './styles'; -import ShareListHeader from './Header'; -import { IApplicationState, TServerModel, TSubscriptionModel } from '../../definitions'; +import { IApplicationState, RootEnum, TServerModel, TSubscriptionModel } from '../../definitions'; import { ShareInsideStackParamList } from '../../definitions/navigationTypes'; -import { getRoomAvatar, isAndroid, isIOS, askAndroidMediaPermissions } from '../../lib/methods/helpers'; - -interface IDataFromShare { - value: string; - type: string; -} +import { getRoomAvatar, isAndroid, isIOS } from '../../lib/methods/helpers'; +import { shareSetParams } from '../../actions/share'; +import { appStart } from '../../actions/app'; interface IFileToShare { filename: string; @@ -50,7 +46,6 @@ interface IState { text: string; loading: boolean; serverInfo: TServerModel; - needsPermission: boolean; } interface INavigationOption { @@ -59,9 +54,12 @@ interface INavigationOption { interface IShareListViewProps extends INavigationOption { server: string; + connecting: boolean; + isAuthenticated: boolean; token: string; userId: string; theme: TSupportedThemes; + shareExtensionParams: Record; dispatch: Dispatch; } @@ -82,10 +80,9 @@ class ShareListView extends React.Component { chats: [], serversCount: 0, attachments: [], - text: '', + text: props.shareExtensionParams.text, loading: true, - serverInfo: {} as TServerModel, - needsPermission: isAndroid || false + serverInfo: {} as TServerModel }; this.setHeader(); if (isAndroid) { @@ -99,64 +96,72 @@ class ShareListView extends React.Component { } async componentDidMount() { - try { - const data = (await ShareExtension.data()) as IDataFromShare[]; - if (isAndroid) { - await this.askForPermission(data); + const { shareExtensionParams } = this.props; + const { mediaUris } = shareExtensionParams; + if (mediaUris) { + try { + const info = await Promise.all(mediaUris.split(',').map((uri: string) => FileSystem.getInfoAsync(uri, { size: true }))); + const attachments = info.map(file => { + if (!file.exists) { + return null; + } + + return { + filename: decodeURIComponent(file.uri.substring(file.uri.lastIndexOf('/') + 1)), + description: '', + size: file.size, + mime: mime.lookup(file.uri), + path: file.uri + }; + }) as IFileToShare[]; + this.setState({ + // text, + attachments + }); + } catch { + // Do nothing } - const info = await Promise.all( - data - .filter(item => item.type === 'media') - .map(file => FileSystem.getInfoAsync(this.uriToPath(file.value), { size: true })) - ); - const attachments = info.map(file => { - if (!file.exists) { - return null; - } - - return { - filename: decodeURIComponent(file.uri.substring(file.uri.lastIndexOf('/') + 1)), - description: '', - size: file.size, - mime: mime.lookup(file.uri), - path: file.uri - }; - }) as IFileToShare[]; - const text = data.filter(item => item.type === 'text').reduce((acc, item) => `${item.value}\n${acc}`, ''); - this.setState({ - text, - attachments - }); - } catch { - // Do nothing } this.getSubscriptions(); } - componentDidUpdate(previousProps: IShareListViewProps) { - const { server } = this.props; - if (previousProps.server !== server) { + componentDidUpdate(previousProps: IShareListViewProps, previousState: IState) { + const { searching } = this.state; + const { server, connecting, isAuthenticated } = this.props; + if ( + previousProps.server !== server || + (previousProps.connecting !== connecting && !connecting) || + (previousProps.isAuthenticated !== isAuthenticated && isAuthenticated) + ) { this.getSubscriptions(); } + if (previousProps.connecting !== connecting && connecting) { + this.setState({ chats: [], searchResults: [], searching: false, searchText: '' }); + } + if (previousState.searching !== searching) { + this.setHeader(); + } } shouldComponentUpdate(nextProps: IShareListViewProps, nextState: IState) { - const { searching, needsPermission } = this.state; + const { searching } = this.state; if (nextState.searching !== searching) { return true; } - if (nextState.needsPermission !== needsPermission) { - return true; - } - - const { server, userId } = this.props; + const { server, userId, isAuthenticated, connecting } = this.props; if (server !== nextProps.server) { return true; } if (userId !== nextProps.userId) { return true; } + if (isAuthenticated !== nextProps.isAuthenticated) { + return true; + } + if (connecting !== nextProps.connecting) { + return true; + } const { searchResults } = this.state; if (nextState.searching) { @@ -174,43 +179,41 @@ class ShareListView extends React.Component { if (this.unsubscribeBlur) { this.unsubscribeBlur(); } + const { dispatch } = this.props; + dispatch(shareSetParams({})); } setHeader = () => { const { searching } = this.state; - const { navigation, theme } = this.props; + const { navigation } = this.props; - if (isIOS) { + if (searching) { navigation.setOptions({ - header: () => ( - - ) + headerTitleAlign: 'left', + headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined }, + headerRightContainerStyle: { flexGrow: 0 }, + headerLeft: () => ( + + + + ), + headerTitle: () => , + headerRight: () => null }); return; } navigation.setOptions({ - headerLeft: () => - searching ? ( - - - - ) : ( - - ), - headerTitle: () => , - headerRight: () => - searching ? null : ( - - - - ) + headerTitleAlign: undefined, + headerTitleContainerStyle: undefined, + headerRightContainerStyle: undefined, + headerLeft: () => , + headerTitle: I18n.t('Send_to'), + headerRight: () => ( + + + + ) }); }; @@ -265,11 +268,14 @@ class ShareListView extends React.Component { }; getSubscriptions = async () => { - const { server } = this.props; - const serversDB = database.servers; + const { server, connecting, isAuthenticated } = this.props; + if (connecting || !isAuthenticated) { + return; + } if (server) { const chats = await this.query(); + const serversDB = database.servers; const serversCollection = serversDB.get('servers'); const serversCount = await serversCollection.query(Q.where('rooms_updated_at', Q.notEq(null))).fetchCount(); let serverInfo = {}; @@ -289,19 +295,6 @@ class ShareListView extends React.Component { } }; - askForPermission = async (data: IDataFromShare[]) => { - const mediaIndex = data.findIndex(item => item.type === 'media'); - if (mediaIndex !== -1) { - const result = await askAndroidMediaPermissions(); - if (!result) { - this.setState({ needsPermission: true }); - return Promise.reject(); - } - } - this.setState({ needsPermission: false }); - return Promise.resolve(); - }; - uriToPath = (uri: string) => decodeURIComponent(isIOS ? uri.replace(/^file:\/\//, '') : uri); getRoomTitle = (item: TSubscriptionModel) => { @@ -349,6 +342,11 @@ class ShareListView extends React.Component { return false; }; + closeShareExtension = () => { + const { dispatch } = this.props; + dispatch(appStart({ root: RootEnum.ROOT_INSIDE })); + }; + renderSectionHeader = (header: string) => { const { searching } = this.state; const { theme } = this.props; @@ -437,37 +435,19 @@ class ShareListView extends React.Component { }; render = () => { - const { chats, loading, searchResults, searching, searchText, needsPermission } = this.state; + const { chats, loading, searchResults, searching, searchText } = this.state; const { theme } = this.props; if (loading) { return ; } - if (needsPermission) { - return ( - - - - {I18n.t('Read_External_Permission')} - - - {I18n.t('Read_External_Permission_Message')} - - - - ); - } - return ( - + { }; } -const mapStateToProps = ({ share }: IApplicationState) => ({ - userId: share.user && (share.user.id as string), - token: share.user && (share.user.token as string), - server: share.server.server as string +const mapStateToProps = ({ login, server, share }: IApplicationState) => ({ + userId: login?.user?.id as string, + token: login?.user?.token as string, + isAuthenticated: login?.isAuthenticated, + server: server?.server, + connecting: server?.connecting, + shareExtensionParams: share?.params }); export default connect(mapStateToProps)(withTheme(ShareListView)); diff --git a/app/views/ShareView/Preview.tsx b/app/views/ShareView/Preview.tsx index 4440300443..3b7cb6a091 100644 --- a/app/views/ShareView/Preview.tsx +++ b/app/views/ShareView/Preview.tsx @@ -1,17 +1,14 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Video, ResizeMode } from 'expo-av'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { ScrollView, StyleSheet, Text } from 'react-native'; +import { ScrollView, StyleSheet, Text, useWindowDimensions, View } from 'react-native'; import prettyBytes from 'pretty-bytes'; import { useHeaderHeight } from '@react-navigation/elements'; import { CustomIcon, TIconsName } from '../../containers/CustomIcon'; import { ImageViewer, types } from '../../containers/ImageViewer'; -import { useDimensions } from '../../dimensions'; import sharedStyles from '../Styles'; import I18n from '../../i18n'; -import { isAndroid } from '../../lib/methods/helpers'; -import { allowPreview } from './utils'; import { THUMBS_HEIGHT } from './constants'; import { TSupportedThemes } from '../../theme'; import { themes } from '../../lib/constants'; @@ -49,8 +46,7 @@ interface IIconPreview { const IconPreview = React.memo(({ iconName, title, description, theme, width, height, danger }: IIconPreview) => ( + contentContainerStyle={[styles.fileContainer, { width, height }]}> { const type = item?.mime; - const { width, height } = useDimensions(); + const { width, height } = useWindowDimensions(); const insets = useSafeAreaInsets(); const headerHeight = useHeaderHeight(); const thumbsHeight = length > 1 ? THUMBS_HEIGHT : 0; const calculatedHeight = height - insets.top - insets.bottom - MESSAGE_COMPOSER_HEIGHT - thumbsHeight - headerHeight; + const [wrapperDimensions, setWrapperDimensions] = useState<{ width?: number; height?: number }>({}); if (item?.canUpload) { - // Disable video preview on iOS to save memory - if (isAndroid && type?.match(/video/)) { + if (type?.match(/video/)) { return ( - + { + setWrapperDimensions({ + width: ev.nativeEvent.layout.width, + height: ev.nativeEvent.layout.height + }); + }}> + ); } // Disallow preview of images too big in order to prevent memory issues on iOS share extension if (type?.match(/image/)) { - if (allowPreview(isShareExtension, item?.size)) { - return ( - - ); - } + return ( + + ); } return ( { attachments: IShareAttachment[]; } -const ThumbContent = React.memo(({ item, theme, isShareExtension }: IThumbContent) => { +const ThumbContent = React.memo(({ item, theme }: IThumbContent) => { const type = item?.mime; if (type?.match(/image/)) { - // Disallow preview of images too big in order to prevent memory issues on iOS share extension - if (allowPreview(isShareExtension, item?.size)) { - return ; - } - return ( - - - - ); + return ; } if (type?.match(/video/)) { - if (isIOS) { - return ( - - - - ); - } - const { uri } = item; return ( - <> - - - + + + ); } - // Multiple files upload of files different than image/video is not implemented, so there's no thumb - return null; + return ( + + + + ); }); const ThumbButton: typeof React.Component = isIOS ? TouchableOpacity : TouchableNativeFeedback; @@ -123,8 +103,7 @@ const Thumb = ({ item, theme, isShareExtension, onPress, onRemove }: IThumb) => style={[styles.removeButton, { backgroundColor: themes[theme].fontDefault, borderColor: themes[theme].surfaceHover }]} activeOpacity={1} rippleColor={themes[theme].surfaceNeutral} - onPress={() => onRemove(item)} - > + onPress={() => onRemove(item)}> diff --git a/app/views/ShareView/index.tsx b/app/views/ShareView/index.tsx index 770990b8ef..3d58e816ff 100644 --- a/app/views/ShareView/index.tsx +++ b/app/views/ShareView/index.tsx @@ -1,10 +1,10 @@ import React, { Component } from 'react'; import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/native'; -import { Text, View } from 'react-native'; +import { Keyboard, Text, View } from 'react-native'; import { connect } from 'react-redux'; -import ShareExtension from 'rn-extensions-share'; import { Q } from '@nozbe/watermelondb'; +import { Dispatch } from 'redux'; import { IMessageComposerRef, MessageComposerContainer } from '../../containers/MessageComposer'; import { InsideStackParamList } from '../../stacks/types'; @@ -17,7 +17,6 @@ import { TSupportedThemes, withTheme } from '../../theme'; import { FormTextInput } from '../../containers/TextInput'; import SafeAreaView from '../../containers/SafeAreaView'; import { getUserSelector } from '../../selectors/login'; -import StatusBar from '../../containers/StatusBar'; import database from '../../lib/database'; import Thumbs from './Thumbs'; import Preview from './Preview'; @@ -28,6 +27,7 @@ import { IServer, IShareAttachment, IUser, + RootEnum, TMessageAction, TSubscriptionModel, TThreadModel @@ -35,6 +35,7 @@ import { import { sendFileMessage, sendMessage } from '../../lib/methods'; import { hasPermission, isAndroid, canUploadFile, isReadOnly, isBlocked } from '../../lib/methods/helpers'; import { RoomContext } from '../RoomView/context'; +import { appStart } from '../../actions/app'; interface IShareViewState { selected: IShareAttachment; @@ -62,6 +63,7 @@ interface IShareViewProps { server: string; FileUpload_MediaTypeWhiteList?: string; FileUpload_MaxFileSize?: number; + dispatch: Dispatch; } class ShareView extends Component { @@ -236,8 +238,10 @@ class ShareView extends Component { send = async () => { if (this.state.loading) return; + Keyboard.dismiss(); + const { attachments, room, text, thread, action, selected, selectedMessages } = this.state; - const { navigation, server, user } = this.props; + const { navigation, server, user, dispatch } = this.props; // update state await this.selectFile(selected); @@ -308,7 +312,7 @@ class ShareView extends Component { // if it's share extension this should close if (this.isShareExtension) { sendLoadingEvent({ visible: false }); - ShareExtension.close(); + dispatch(appStart({ root: RootEnum.ROOT_INSIDE })); } }; @@ -415,7 +419,7 @@ class ShareView extends Component { const { theme } = this.props; if (readOnly || isBlocked(room)) { return ( - + {isBlocked(room) ? I18n.t('This_room_is_blocked') : I18n.t('This_room_is_read_only')} @@ -423,8 +427,7 @@ class ShareView extends Component { ); } return ( - - + {this.renderContent()} ); @@ -433,7 +436,7 @@ class ShareView extends Component { const mapStateToProps = (state: IApplicationState) => ({ user: getUserSelector(state), - server: state.share.server.server || state.server.server, + server: state.server.server, FileUpload_MediaTypeWhiteList: state.settings.FileUpload_MediaTypeWhiteList as string, FileUpload_MaxFileSize: state.settings.FileUpload_MaxFileSize as number }); diff --git a/app/views/ShareView/utils.ts b/app/views/ShareView/utils.ts deleted file mode 100644 index bcc257dee3..0000000000 --- a/app/views/ShareView/utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { isAndroid } from '../../lib/methods/helpers'; - -// Limit preview to 3MB on iOS share extension -export const allowPreview = (isShareExtension: boolean, size: number): boolean => - isAndroid || !isShareExtension || size < 3000000; diff --git a/app/views/SidebarView/SidebarItem.tsx b/app/views/SidebarView/SidebarItem.tsx deleted file mode 100644 index e0b70ff131..0000000000 --- a/app/views/SidebarView/SidebarItem.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import { Text, View } from 'react-native'; - -import Touch from '../../containers/Touch'; -import { themes } from '../../lib/constants'; -import { TSupportedThemes, withTheme } from '../../theme'; -import styles from './styles'; - -interface SidebarItemProps { - left: JSX.Element; - right?: JSX.Element; - text: string; - textColor?: string; - current?: boolean; - onPress(): void; - testID: string; - theme: TSupportedThemes; -} - -const Item = React.memo(({ left, right, text, onPress, testID, current, theme, textColor }: SidebarItemProps) => ( - - {left} - - - {text} - - - {right} - -)); - -export default withTheme(Item); diff --git a/app/views/SidebarView/index.tsx b/app/views/SidebarView/index.tsx index 80feac5138..113bf0b64f 100644 --- a/app/views/SidebarView/index.tsx +++ b/app/views/SidebarView/index.tsx @@ -18,7 +18,6 @@ import { TSupportedThemes, withTheme } from '../../theme'; import { getUserSelector } from '../../selectors/login'; import SafeAreaView from '../../containers/SafeAreaView'; import Navigation from '../../lib/navigation/appNavigation'; -import SidebarItem from './SidebarItem'; import styles from './styles'; import { DrawerParamList } from '../../stacks/types'; import { IApplicationState, IUser, TSVStatus } from '../../definitions'; @@ -223,13 +222,11 @@ class Sidebar extends Component { return ( <> - } + } onPress={() => this.sidebarNavigate(routeName)} - testID='sidebar-admin' - theme={theme!} - current={this.currentItemKey === routeName} + backgroundColor={this.currentItemKey === routeName ? themes[theme!].strokeLight : undefined} /> ); @@ -239,37 +236,36 @@ class Sidebar extends Component { const { theme } = this.props; return ( <> - } + } onPress={() => this.sidebarNavigate('ChatsStackNavigator')} + backgroundColor={this.currentItemKey === 'ChatsStackNavigator' ? themes[theme!].strokeLight : undefined} testID='sidebar-chats' - theme={theme!} - current={this.currentItemKey === 'ChatsStackNavigator'} /> - } + + } onPress={() => this.sidebarNavigate('ProfileStackNavigator')} + backgroundColor={this.currentItemKey === 'ProfileStackNavigator' ? themes[theme!].strokeLight : undefined} testID='sidebar-profile' - theme={theme!} - current={this.currentItemKey === 'ProfileStackNavigator'} /> - } + + } onPress={() => this.sidebarNavigate('DisplayPrefStackNavigator')} + backgroundColor={this.currentItemKey === 'DisplayPrefStackNavigator' ? themes[theme!].strokeLight : undefined} testID='sidebar-display' - theme={theme!} - current={this.currentItemKey === 'DisplayPrefStackNavigator'} /> - } + + } onPress={() => this.sidebarNavigate('SettingsStackNavigator')} + backgroundColor={this.currentItemKey === 'SettingsStackNavigator' ? themes[theme!].strokeLight : undefined} testID='sidebar-settings' - theme={theme!} - current={this.currentItemKey === 'SettingsStackNavigator'} /> {this.renderAdmin()} @@ -284,20 +280,22 @@ class Sidebar extends Component { status = 'disabled'; } - let right: React.ReactElement | undefined = ; + let right: (() => JSX.Element | null) | undefined = () => ( + + ); if (notificationPresenceCap) { - right = ; + right = () => ; } else if (Presence_broadcast_disabled) { right = undefined; } return ( - } - theme={theme!} + } right={right} onPress={() => (Presence_broadcast_disabled ? this.onPressPresenceLearnMore() : this.sidebarNavigate('StatusView'))} + translateTitle={!user.statusText} testID={`sidebar-custom-status-${user.status}`} /> ); @@ -307,14 +305,16 @@ class Sidebar extends Component { const { theme, supportedVersionsStatus } = this.props; if (supportedVersionsStatus === 'warn') { return ( - } - theme={theme!} - onPress={() => this.onPressSupportedVersionsWarning()} - testID={`sidebar-supported-versions-warn`} - /> + <> + + } + onPress={() => this.onPressSupportedVersionsWarning()} + testID={`sidebar-supported-versions-warn`} + /> + ); } return null; @@ -327,17 +327,11 @@ class Sidebar extends Component { return null; } return ( - - + + + - + @@ -355,7 +349,6 @@ class Sidebar extends Component { - {this.renderSupportedVersionsWarn()} @@ -365,11 +358,12 @@ class Sidebar extends Component { <> {this.renderNavigation()} - ) : ( <>{this.renderAdmin()} )} + + ); diff --git a/app/views/SidebarView/styles.ts b/app/views/SidebarView/styles.ts index 63d4c290a7..e06eb5f285 100644 --- a/app/views/SidebarView/styles.ts +++ b/app/views/SidebarView/styles.ts @@ -6,30 +6,6 @@ export default StyleSheet.create({ container: { flex: 1 }, - item: { - flexDirection: 'row', - alignItems: 'center' - }, - itemCurrent: { - backgroundColor: '#E1E5E8' - }, - itemHorizontal: { - marginHorizontal: 10, - width: 30, - alignItems: 'center' - }, - itemCenter: { - flex: 1 - }, - itemText: { - marginVertical: 16, - fontSize: 14, - ...sharedStyles.textSemibold - }, - separator: { - borderBottomWidth: StyleSheet.hairlineWidth, - marginVertical: 4 - }, header: { paddingVertical: 16, flexDirection: 'row', @@ -55,15 +31,6 @@ export default StyleSheet.create({ fontSize: 14, ...sharedStyles.textSemibold }, - version: { - marginHorizontal: 10, - marginBottom: 10, - fontSize: 13, - ...sharedStyles.textSemibold - }, - inverted: { - transform: [{ scaleY: -1 }] - }, customStatusDisabled: { width: 10, height: 10, diff --git a/app/views/WithoutServersView.tsx b/app/views/WithoutServersView.tsx deleted file mode 100644 index 7a4989bef2..0000000000 --- a/app/views/WithoutServersView.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { useLayoutEffect } from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import ShareExtension from 'rn-extensions-share'; -import { useNavigation } from '@react-navigation/native'; - -import * as HeaderButton from '../containers/HeaderButton'; -import I18n from '../i18n'; -import { useTheme } from '../theme'; -import sharedStyles from './Styles'; - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - padding: 15 - }, - title: { - fontSize: 18, - ...sharedStyles.textBold - }, - content: { - fontSize: 14, - ...sharedStyles.textRegular, - ...sharedStyles.textAlignCenter - } -}); - -const WithoutServerView = (): React.ReactElement => { - const navigation = useNavigation(); - const { colors } = useTheme(); - - useLayoutEffect(() => { - navigation.setOptions({ - title: 'Rocket.Chat', - headerLeft: () => - }); - }, [navigation]); - - return ( - - {I18n.t('Without_Servers')} - - {I18n.t('You_need_to_access_at_least_one_RocketChat_server_to_share_something')} - - - ); -}; - -export default WithoutServerView; diff --git a/e2e/helpers/app.ts b/e2e/helpers/app.ts index abd2f39089..a7605a0d67 100644 --- a/e2e/helpers/app.ts +++ b/e2e/helpers/app.ts @@ -94,16 +94,20 @@ async function logout() { await expect(element(by.id('new-server-view'))).toBeVisible(); } -async function mockMessage(message: string, isThread = false) { +async function checkMessage(message: string) { const deviceType = device.getPlatform(); const { textMatcher } = platformTypes[deviceType]; - const input = isThread ? 'message-composer-input-thread' : 'message-composer-input'; - await element(by.id(input)).typeText(message); - await element(by.id('message-composer-send')).tap(); await waitFor(element(by[textMatcher](message))) .toExist() .withTimeout(60000); await element(by[textMatcher](message)).atIndex(0).tap(); +} + +async function mockMessage(message: string, isThread = false) { + const input = isThread ? 'message-composer-input-thread' : 'message-composer-input'; + await element(by.id(input)).typeText(message); + await element(by.id('message-composer-send')).tap(); + await checkMessage(message); return message; } @@ -215,6 +219,9 @@ async function checkRoomTitle(room: string) { const checkServer = async (server: string) => { const label = `Connected to ${server}`; + await waitFor(element(by.id('rooms-list-view-sidebar'))) + .toBeVisible() + .withTimeout(2000); await element(by.id('rooms-list-view-sidebar')).tap(); await waitFor(element(by.id('sidebar-view'))) .toBeVisible() @@ -264,6 +271,7 @@ export { navigateToRegister, login, logout, + checkMessage, mockMessage, tapBack, sleep, diff --git a/e2e/tests/assorted/01-e2eencryption.spec.ts b/e2e/tests/assorted/01-e2eencryption.spec.ts index 090021efe2..369a3cea6d 100644 --- a/e2e/tests/assorted/01-e2eencryption.spec.ts +++ b/e2e/tests/assorted/01-e2eencryption.spec.ts @@ -290,10 +290,9 @@ describe('E2E Encryption', () => { await waitFor(element(by[textMatcher](mockedMessageText)).atIndex(0)) .not.toExist() .withTimeout(2000); - // await waitFor(element(by.id('room-view-encrypted-room'))) - // .toBeVisible() - // .withTimeout(2000); - await expect(element(by.label('Encrypted message')).atIndex(0)).toExist(); + await waitFor(element(by.id('room-view-encrypted-room'))) + .toBeVisible() + .withTimeout(2000); }); it('should enter new e2e password and messages should be decrypted', async () => { @@ -391,9 +390,12 @@ describe('E2E Encryption', () => { // Register new user const randomUser = data.randomUser(); - await element(by.id('register-view-name')).replaceText(randomUser.username); + await element(by.id('register-view-name')).replaceText(randomUser.name); + await element(by.id('register-view-name')).tapReturnKey(); await element(by.id('register-view-username')).replaceText(randomUser.username); + await element(by.id('register-view-username')).tapReturnKey(); await element(by.id('register-view-email')).replaceText(randomUser.email); + await element(by.id('register-view-email')).tapReturnKey(); await element(by.id('register-view-password')).replaceText(randomUser.password); await element(by.id('register-view-password')).tapReturnKey(); await expectValidRegisterOrRetry(device.getPlatform()); @@ -403,11 +405,14 @@ describe('E2E Encryption', () => { }); it('should change back', async () => { + await waitFor(element(by.id('rooms-list-header-servers-list-button'))) + .toExist() + .withTimeout(2000); await element(by.id('rooms-list-header-servers-list-button')).tap(); await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await element(by.id(`rooms-list-header-server-${data.server}`)).tap(); + await element(by.id(`server-item-${data.server}`)).tap(); await waitFor(element(by.id('rooms-list-view'))) .toBeVisible() .withTimeout(10000); diff --git a/e2e/tests/assorted/06-status.spec.ts b/e2e/tests/assorted/06-status.spec.ts index b77a70895f..464c92e1ea 100644 --- a/e2e/tests/assorted/06-status.spec.ts +++ b/e2e/tests/assorted/06-status.spec.ts @@ -57,7 +57,7 @@ describe('Status screen', () => { await element(by.id('status-view-input')).replaceText('status-text-new'); await element(by.id('status-view-submit')).tap(); await sleep(3000); // Wait until the loading hide - await waitFor(element(by.id(`sidebar-custom-status-text-status-text-new`))) + await waitFor(element(by.text('status-text-new'))) .toExist() .withTimeout(5000); }); diff --git a/e2e/tests/assorted/07-changeserver.spec.ts b/e2e/tests/assorted/07-changeserver.spec.ts index 3fb0d11b64..6371186962 100644 --- a/e2e/tests/assorted/07-changeserver.spec.ts +++ b/e2e/tests/assorted/07-changeserver.spec.ts @@ -64,7 +64,7 @@ describe('Change server', () => { await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await element(by.id(`rooms-list-header-server-${data.alternateServer}`)).tap(); + await element(by.id(`server-item-${data.alternateServer}`)).tap(); await waitFor(element(by.id('workspace-view'))) .toBeVisible() .withTimeout(60000); @@ -76,8 +76,11 @@ describe('Change server', () => { // Register new user const randomUser = data.randomUser(); await element(by.id('register-view-name')).replaceText(randomUser.name); + await element(by.id('register-view-name')).tapReturnKey(); await element(by.id('register-view-username')).replaceText(randomUser.username); + await element(by.id('register-view-username')).tapReturnKey(); await element(by.id('register-view-email')).replaceText(randomUser.email); + await element(by.id('register-view-email')).tapReturnKey(); await element(by.id('register-view-password')).replaceText(randomUser.password); await element(by.id('register-view-password')).tapReturnKey(); await expectValidRegisterOrRetry(device.getPlatform()); @@ -98,7 +101,7 @@ describe('Change server', () => { await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await element(by.id(`rooms-list-header-server-${data.server}`)).tap(); + await element(by.id(`server-item-${data.server}`)).tap(); await waitFor(element(by.id('rooms-list-view'))) .toBeVisible() .withTimeout(10000); diff --git a/e2e/tests/assorted/10-deleteserver.spec.ts b/e2e/tests/assorted/10-deleteserver.spec.ts index d3ef2d7954..0b3295219b 100644 --- a/e2e/tests/assorted/10-deleteserver.spec.ts +++ b/e2e/tests/assorted/10-deleteserver.spec.ts @@ -58,8 +58,11 @@ describe('Delete server', () => { // Register new user const randomUser = data.randomUser(); await element(by.id('register-view-name')).replaceText(randomUser.name); + await element(by.id('register-view-name')).tapReturnKey(); await element(by.id('register-view-username')).replaceText(randomUser.username); + await element(by.id('register-view-username')).tapReturnKey(); await element(by.id('register-view-email')).replaceText(randomUser.email); + await element(by.id('register-view-email')).tapReturnKey(); await element(by.id('register-view-password')).replaceText(randomUser.password); await element(by.id('register-view-password')).tapReturnKey(); await expectValidRegisterOrRetry(device.getPlatform()); @@ -73,13 +76,13 @@ describe('Delete server', () => { await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await element(by.id(`rooms-list-header-server-${data.server}`)).longPress(1500); + await element(by.id(`server-item-${data.server}`)).longPress(1500); await element(by[textMatcher]('Delete').and(by.type(alertButtonType))).tap(); await element(by.id('rooms-list-header-servers-list-button')).tap(); await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await waitFor(element(by.id(`rooms-list-header-server-${data.server}`))) + await waitFor(element(by.id(`server-item-${data.server}`))) .toBeNotVisible() .withTimeout(10000); }); diff --git a/e2e/tests/assorted/11-deeplinking.spec.ts b/e2e/tests/assorted/11-deeplinking.spec.ts index bd4dcdf82a..21b3249d60 100644 --- a/e2e/tests/assorted/11-deeplinking.spec.ts +++ b/e2e/tests/assorted/11-deeplinking.spec.ts @@ -8,7 +8,10 @@ import { navigateToRegister, platformTypes, TTextMatcher, - expectValidRegisterOrRetry + expectValidRegisterOrRetry, + navigateToRoom, + checkMessage, + sleep } from '../../helpers/app'; import { IDeleteCreateUser, @@ -41,6 +44,8 @@ describe('Deep linking', () => { const deleteUsersAfterAll: IDeleteCreateUser[] = []; + const randomUserAlternateServer = data.randomUser(); + beforeAll(async () => { const user = await createRandomUser(); ({ _id: rid, name: room } = await createRandomRoom(user, 'p')); @@ -58,6 +63,25 @@ describe('Deep linking', () => { await deleteCreatedUsers(deleteUsersAfterAll); }); + const authAndNavigate = async () => { + await device.launchApp({ + permissions: { notifications: 'YES' }, + newInstance: true, + url: getDeepLink(DEEPLINK_METHODS.AUTH, data.server, `userId=${userId}${amp}token=${authToken}${amp}path=group/${room}`) + }); + await waitFor(element(by.id(`room-view-title-${room}`))) + .toExist() + .withTimeout(30000); + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))) + .toBeVisible() + .withTimeout(10000); + await checkServer(data.server); + await waitFor(element(by.id(`rooms-list-view-item-${room}`))) + .toExist() + .withTimeout(2000); + }; + describe('Authentication', () => { it('should run a deep link to an invalid account and raise error', async () => { await device.launchApp({ @@ -70,25 +94,6 @@ describe('Deep linking', () => { .withTimeout(30000); // TODO: we need to improve this message }); - const authAndNavigate = async () => { - await device.launchApp({ - permissions: { notifications: 'YES' }, - newInstance: true, - url: getDeepLink(DEEPLINK_METHODS.AUTH, data.server, `userId=${userId}${amp}token=${authToken}${amp}path=group/${room}`) - }); - await waitFor(element(by.id(`room-view-title-${room}`))) - .toExist() - .withTimeout(30000); - await tapBack(); - await waitFor(element(by.id('rooms-list-view'))) - .toBeVisible() - .withTimeout(10000); - await checkServer(data.server); - await waitFor(element(by.id(`rooms-list-view-item-${room}`))) - .toExist() - .withTimeout(2000); - }; - it('should authenticate and navigate', async () => { await authAndNavigate(); }); @@ -96,14 +101,16 @@ describe('Deep linking', () => { it('should authenticate while logged in another server', async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); await navigateToRegister(data.alternateServer); - const randomUser = data.randomUser(); - await element(by.id('register-view-name')).replaceText(randomUser.name); - await element(by.id('register-view-username')).replaceText(randomUser.username); - await element(by.id('register-view-email')).replaceText(randomUser.email); - await element(by.id('register-view-password')).replaceText(randomUser.password); + await element(by.id('register-view-name')).replaceText(randomUserAlternateServer.name); + await element(by.id('register-view-name')).tapReturnKey(); + await element(by.id('register-view-username')).replaceText(randomUserAlternateServer.username); + await element(by.id('register-view-username')).tapReturnKey(); + await element(by.id('register-view-email')).replaceText(randomUserAlternateServer.email); + await element(by.id('register-view-email')).tapReturnKey(); + await element(by.id('register-view-password')).replaceText(randomUserAlternateServer.password); await element(by.id('register-view-password')).tapReturnKey(); await expectValidRegisterOrRetry(device.getPlatform()); - deleteUsersAfterAll.push({ server: data.alternateServer, username: randomUser.username }); + deleteUsersAfterAll.push({ server: data.alternateServer, username: randomUserAlternateServer.username }); await authAndNavigate(); }); @@ -217,7 +224,7 @@ describe('Deep linking', () => { await waitFor(element(by.id('rooms-list-header-servers-list'))) .toBeVisible() .withTimeout(5000); - await element(by.id(`rooms-list-header-server-${data.alternateServer}`)).tap(); + await element(by.id(`server-item-${data.alternateServer}`)).tap(); await checkServer(data.alternateServer); await device.launchApp({ @@ -243,4 +250,87 @@ describe('Deep linking', () => { }); }); }); + + describe('Share extension', () => { + const shareTextMessage = async (message: string) => { + await waitFor(element(by.id(`share-extension-item-${room}`))) + .toBeVisible() + .withTimeout(30000); + await element(by.id(`share-extension-item-${room}`)).tap(); + await waitFor(element(by.id('share-view'))) + .toBeVisible() + .withTimeout(30000); + await waitFor(element(by.text('Send'))) + .toBeVisible() + .withTimeout(30000); + await element(by.text('Send')).tap(); + await navigateToRoom(room); + await checkMessage(message); + }; + + it('should share text', async () => { + const message = random(); + await device.launchApp({ + permissions: { notifications: 'YES' }, + newInstance: true, + url: `rocketchat://shareextension?text=${message}` + }); + await waitFor(element(by.id('share-list-view'))) + .toBeVisible() + .withTimeout(30000); + await shareTextMessage(message); + }); + + it('should change server and share text', async () => { + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))) + .toBeVisible() + .withTimeout(10000); + await element(by.id('rooms-list-header-servers-list-button')).tap(); + await waitFor(element(by.id('rooms-list-header-servers-list'))) + .toBeVisible() + .withTimeout(5000); + await element(by.id(`server-item-${data.alternateServer}`)).tap(); + await checkServer(data.alternateServer); + + // share + const message = random(); + await device.launchApp({ + permissions: { notifications: 'YES' }, + newInstance: true, + url: `rocketchat://shareextension?text=${message}` + }); + await waitFor(element(by.id('share-list-view'))) + .toBeVisible() + .withTimeout(30000); + await sleep(300); + await waitFor(element(by.id(`server-item-${data.alternateServer}`))) + .toBeVisible() + .withTimeout(2000); + await element(by.id(`server-item-${data.alternateServer}`)).tap(); + await waitFor(element(by.id('select-server-view'))) + .toBeVisible() + .withTimeout(30000); + await element(by.id(`server-item-${data.server}`)).tap(); + await waitFor(element(by.id('share-list-view'))) + .toBeVisible() + .withTimeout(30000); + await waitFor(element(by.id(`server-item-${data.server}`))) + .toBeVisible() + .withTimeout(2000); + + await shareTextMessage(message); + }); + + it('should open share without being logged in and go to onboarding', async () => { + await device.launchApp({ + permissions: { notifications: 'YES' }, + delete: true, + url: `rocketchat://shareextension?text=whatever` + }); + await waitFor(element(by.id('new-server-view'))) + .toBeVisible() + .withTimeout(30000); + }); + }); }); diff --git a/index.js b/index.js index 74f5332c5c..3007724045 100644 --- a/index.js +++ b/index.js @@ -25,7 +25,6 @@ if (!isFDroidBuild && isAndroid) { } AppRegistry.registerComponent(appName, () => require('./app/index').default); -AppRegistry.registerComponent(shareName, () => require('./app/share').default); // For storybook, comment everything above and uncomment below // import 'react-native-gesture-handler'; diff --git a/ios/Podfile b/ios/Podfile index 9e5b6a17fe..eb8c9b42f5 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -41,7 +41,6 @@ abstract_target 'defaults' do target 'RocketChatRN' # Experimental app target 'Rocket.Chat' # Official app - target 'ShareRocketChatRN' target 'NotificationService' end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 15c1065397..3b71517052 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1229,8 +1229,6 @@ PODS: - React-perflogger (= 0.73.6) - ReactNativeUiLib (3.0.4): - React - - rn-extensions-share (2.4.1): - - React - RNBootSplash (4.6.0): - React-Core - RNCAsyncStorage (1.22.3): @@ -1398,7 +1396,6 @@ DEPENDENCIES: - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - ReactNativeUiLib (from `../node_modules/react-native-ui-lib`) - - rn-extensions-share (from `../node_modules/rn-extensions-share`) - RNBootSplash (from `../node_modules/react-native-bootsplash`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" @@ -1603,8 +1600,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" ReactNativeUiLib: :path: "../node_modules/react-native-ui-lib" - rn-extensions-share: - :path: "../node_modules/rn-extensions-share" RNBootSplash: :path: "../node_modules/react-native-bootsplash" RNCAsyncStorage: @@ -1753,7 +1748,6 @@ SPEC CHECKSUMS: React-utils: d16c1d2251c088ad817996621947d0ac8167b46c ReactCommon: 2aa35648354bd4c4665b9a5084a7d37097b89c10 ReactNativeUiLib: 33521c0747ea376d292b62b6415e0f1d75bd3c10 - rn-extensions-share: 5fd84a80e6594706f0dfa1884f2d6d591b382cf5 RNBootSplash: 91e0c16bfc96703cb5b0562785b9a8cbfeb298fe RNCAsyncStorage: 10591b9e0a91eaffee14e69b3721009759235125 RNCClipboard: 60fed4b71560d7bfe40e9d35dea9762b024da86d @@ -1786,6 +1780,6 @@ SPEC CHECKSUMS: Yoga: d17d2cc8105eed528474683b42e2ea310e1daf61 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 4037481efaa1c9c86740a10ac1fa6f1f1845721c +PODFILE CHECKSUM: 23b05e7d7ba785e3452040d94d4b7ab4a920ee60 COCOAPODS: 1.14.3 diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj index 83b2385cbc..c281dc2b6b 100644 --- a/ios/RocketChatRN.xcodeproj/project.pbxproj +++ b/ios/RocketChatRN.xcodeproj/project.pbxproj @@ -26,9 +26,7 @@ 1E06561B2B7E91FB0081B01F /* ErrorActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E06561A2B7E91FB0081B01F /* ErrorActionHandler.swift */; }; 1E06561D2B7E9C1C0081B01F /* MessageActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E06561C2B7E9C1C0081B01F /* MessageActionView.swift */; }; 1E068CFE24FD2DC700A0FFC1 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E068CFD24FD2DC700A0FFC1 /* AppGroup.swift */; }; - 1E068CFF24FD2DC700A0FFC1 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E068CFD24FD2DC700A0FFC1 /* AppGroup.swift */; }; 1E068D0124FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; }; - 1E068D0224FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; }; 1E1C2F80250FCB69005DCE7D /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1C2F7F250FCB69005DCE7D /* Database.swift */; }; 1E1EA80A2326CD2200E22452 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8092326CD2200E22452 /* AVFoundation.framework */; }; 1E1EA80C2326CD2800E22452 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA80B2326CD2800E22452 /* AudioToolbox.framework */; }; @@ -39,7 +37,6 @@ 1E1EA8162326CD4500E22452 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8152326CD4500E22452 /* VideoToolbox.framework */; }; 1E1EA8182326CD4B00E22452 /* libc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8172326CD4B00E22452 /* libc.tbd */; }; 1E1EA81A2326CD5100E22452 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8192326CD5100E22452 /* libsqlite3.tbd */; }; - 1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; }; 1E29A2CC2B5857F50093C03C /* RoomListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E29A2CB2B5857F50093C03C /* RoomListView.swift */; }; 1E29A2D02B58582F0093C03C /* RoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E29A2CF2B58582F0093C03C /* RoomView.swift */; }; 1E29A2EF2B585B070093C03C /* RocketChatClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E29A2D22B585B070093C03C /* RocketChatClient.swift */; }; @@ -154,9 +151,7 @@ 1EB8EF722510F1EE00F352B7 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EB8EF712510F1EE00F352B7 /* Storage.swift */; }; 1EC687BA2BA0FF0D00C7BAAD /* MessageInfoMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC687B82BA0FECC00C7BAAD /* MessageInfoMapper.swift */; }; 1EC687BB2BA0FF0D00C7BAAD /* MessageInfoMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC687B82BA0FECC00C7BAAD /* MessageInfoMapper.swift */; }; - 1EC6ACB722CB9FC300A41C61 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6ACB522CB9FC300A41C61 /* MainInterface.storyboard */; }; 1EC6ACBB22CB9FC300A41C61 /* ShareRocketChatRN.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1EC6ACB022CB9FC300A41C61 /* ShareRocketChatRN.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 1EC6ACF622CBA01500A41C61 /* ShareRocketChatRN.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EC6ACF522CBA01500A41C61 /* ShareRocketChatRN.m */; }; 1ED00BB12513E04400A1331F /* ReplyNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED00BB02513E04400A1331F /* ReplyNotification.swift */; }; 1ED033AE2B55B1CC004F4930 /* Default.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1ED033AC2B55B1CC004F4930 /* Default.xcdatamodeld */; }; 1ED033B02B55B25A004F4930 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED033AF2B55B25A004F4930 /* Database.swift */; }; @@ -266,7 +261,6 @@ 1ED1ECE72B8699ED00F6620C /* Rocket.Chat Experimental Watch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 1ED1ECDD2B86997F00F6620C /* Rocket.Chat Experimental Watch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 1ED1ECEA2B869A4A00F6620C /* Official.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A14FCF3257FEB59005BDCD4 /* Official.xcassets */; }; 1ED1ECEC2B869B1300F6620C /* Experimental.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A14FCEC257FEB3A005BDCD4 /* Experimental.xcassets */; }; - 1ED59D4C22CBA77D00C54289 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1ED59D4B22CBA77D00C54289 /* GoogleService-Info.plist */; }; 1EDB30F22B5B453A00532C7E /* LoggedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EDB30F12B5B453A00532C7E /* LoggedInView.swift */; }; 1EDFD0FA2B589B8F002FEE5F /* MessagesLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EDFD0F92B589B8F002FEE5F /* MessagesLoader.swift */; }; 1EDFD1062B58A66E002FEE5F /* CancelBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EDFD1052B58A66E002FEE5F /* CancelBag.swift */; }; @@ -285,10 +279,10 @@ 1EFEB5982493B6640072EDC0 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EFEB5972493B6640072EDC0 /* NotificationService.swift */; }; 1EFEB59C2493B6640072EDC0 /* NotificationService.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1EFEB5952493B6640072EDC0 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 24A2AEF2383D44B586D31C01 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BB44DD4855498082A744AD /* libz.tbd */; }; - 286806D511F8AAD37A7D422C /* libPods-defaults-NotificationService.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7702E49AD9EFBD11DE2AE855 /* libPods-defaults-NotificationService.a */; }; + 39E74E20D9E02DA933B049C1 /* libPods-defaults-NotificationService.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EDAE7DFC486C8E0F5331BC7 /* libPods-defaults-NotificationService.a */; }; 4C4C8603EF082F0A33A95522 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D5C142B655F8EFD006792C /* ExpoModulesProvider.swift */; }; + 624EBD0BDE698092CB04C2FA /* libPods-defaults-RocketChatRN.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F38DDC9B729E9C3C3883E1CF /* libPods-defaults-RocketChatRN.a */; }; 65AD38372BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */; }; - 65AD38382BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */; }; 65AD38392BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */; }; 65AD383A2BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */; }; 65AD383B2BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */; }; @@ -297,11 +291,13 @@ 65B9A71B2AFC24190088956F /* ringtone.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 65B9A7192AFC24190088956F /* ringtone.mp3 */; }; 6D168AA9955DC38D82D3C051 /* libPods-defaults-Rocket.Chat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A349601A16A2DEC0EEDCB1E8 /* libPods-defaults-Rocket.Chat.a */; }; 7A006F14229C83B600803143 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A006F13229C83B600803143 /* GoogleService-Info.plist */; }; + 7A0129D42C6E8EC800F84A97 /* ShareRocketChatRN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0129D22C6E8B5900F84A97 /* ShareRocketChatRN.swift */; }; + 7A0129D62C6E8F0700F84A97 /* ShareRocketChatRN.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6AD6022CBA20C00A41C61 /* ShareRocketChatRN.entitlements */; }; + 7A0129EA2C6E921600F84A97 /* MainInterface.storyboard in Sources */ = {isa = PBXBuildFile; fileRef = 1EC6ACB522CB9FC300A41C61 /* MainInterface.storyboard */; }; 7A0D62D2242AB187006D5C06 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A0D62D1242AB187006D5C06 /* LaunchScreen.storyboard */; }; 7A14FCED257FEB3A005BDCD4 /* Experimental.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A14FCEC257FEB3A005BDCD4 /* Experimental.xcassets */; }; 7A14FCF4257FEB59005BDCD4 /* Official.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A14FCF3257FEB59005BDCD4 /* Official.xcassets */; }; 7A610CD227ECE38100B8ABDD /* custom.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7A610CD127ECE38100B8ABDD /* custom.ttf */; }; - 7A610CD327ECE38100B8ABDD /* custom.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7A610CD127ECE38100B8ABDD /* custom.ttf */; }; 7A610CD427ECE38100B8ABDD /* custom.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7A610CD127ECE38100B8ABDD /* custom.ttf */; }; 7A610CD527ECE38100B8ABDD /* custom.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7A610CD127ECE38100B8ABDD /* custom.ttf */; }; 7A8B30762BCD9D3F00146A40 /* SSLPinning.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A8B30752BCD9D3F00146A40 /* SSLPinning.mm */; }; @@ -355,12 +351,11 @@ 7AAB3E4A257E6A6E00707CF6 /* NotificationService.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1EFEB5952493B6640072EDC0 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 7ACD4897222860DE00442C55 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; }; 7AE10C0628A59530003593CB /* Inter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7AE10C0528A59530003593CB /* Inter.ttf */; }; - 7AE10C0728A59530003593CB /* Inter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7AE10C0528A59530003593CB /* Inter.ttf */; }; 7AE10C0828A59530003593CB /* Inter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7AE10C0528A59530003593CB /* Inter.ttf */; }; 85160EB6C143E0493FE5F014 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 194D9A8897F4A486C2C6F89A /* ExpoModulesProvider.swift */; }; BC404914E86821389EEB543D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 391C4F7AA7023CD41EEBD106 /* ExpoModulesProvider.swift */; }; - D94D81FB9E10756FAA03F203 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016747EF3B9FED8DE2C9DA14 /* ExpoModulesProvider.swift */; }; DD2BA30A89E64F189C2C24AC /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA7E862283664608B3894E34 /* libWatermelonDB.a */; }; + E02D91DE2C11D3BD9AC34663 /* libPods-defaults-Rocket.Chat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F08B2D270E82A48D344CB0F5 /* libPods-defaults-Rocket.Chat.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -459,8 +454,9 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 016747EF3B9FED8DE2C9DA14 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-defaults-ShareRocketChatRN/ExpoModulesProvider.swift"; sourceTree = ""; }; 06BB44DD4855498082A744AD /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + 0E80084FB76F2BA00A43C5E0 /* Pods-defaults-RocketChatRN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.debug.xcconfig"; path = "Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.debug.xcconfig"; sourceTree = ""; }; + 0FF30665E726105A87EE37A8 /* Pods-defaults-RocketChatRN.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.release.xcconfig"; path = "Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.release.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Rocket.Chat Experimental.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Rocket.Chat Experimental.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RocketChatRN/AppDelegate.h; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RocketChatRN/Images.xcassets; sourceTree = ""; }; @@ -571,7 +567,6 @@ 1EC6ACB022CB9FC300A41C61 /* ShareRocketChatRN.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareRocketChatRN.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 1EC6ACB622CB9FC300A41C61 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 1EC6ACB822CB9FC300A41C61 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1EC6ACF522CBA01500A41C61 /* ShareRocketChatRN.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareRocketChatRN.m; sourceTree = ""; }; 1EC6AD6022CBA20C00A41C61 /* ShareRocketChatRN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareRocketChatRN.entitlements; sourceTree = ""; }; 1ED00BB02513E04400A1331F /* ReplyNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyNotification.swift; sourceTree = ""; }; 1ED033AD2B55B1CC004F4930 /* Default.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Default.xcdatamodel; sourceTree = ""; }; @@ -597,7 +592,6 @@ 1ED038C92B50A58400C007D4 /* ServersLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServersLoader.swift; sourceTree = ""; }; 1ED1EC882B867E2400F6620C /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; 1ED1ECDD2B86997F00F6620C /* Rocket.Chat Experimental Watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Rocket.Chat Experimental Watch.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 1ED59D4B22CBA77D00C54289 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; 1EDB30F12B5B453A00532C7E /* LoggedInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedInView.swift; sourceTree = ""; }; 1EDFD0F92B589B8F002FEE5F /* MessagesLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesLoader.swift; sourceTree = ""; }; 1EDFD1052B58A66E002FEE5F /* CancelBag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBag.swift; sourceTree = ""; }; @@ -612,18 +606,16 @@ 1EFEB5972493B6640072EDC0 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; 1EFEB5992493B6640072EDC0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 1EFEB5A12493B67D0072EDC0 /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = ""; }; - 23D9D8F46A4AB85AAA0EB5A8 /* Pods-defaults-ShareRocketChatRN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-ShareRocketChatRN.debug.xcconfig"; path = "Target Support Files/Pods-defaults-ShareRocketChatRN/Pods-defaults-ShareRocketChatRN.debug.xcconfig"; sourceTree = ""; }; - 35DE450085CD5A850E191FBF /* Pods-defaults-Rocket.Chat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.debug.xcconfig"; path = "Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.debug.xcconfig"; sourceTree = ""; }; 391C4F7AA7023CD41EEBD106 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-defaults-Rocket.Chat/ExpoModulesProvider.swift"; sourceTree = ""; }; - 3D68C21C65AA1783CBEDE5F3 /* Pods-defaults-RocketChatRN.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.release.xcconfig"; path = "Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.release.xcconfig"; sourceTree = ""; }; + 3A4ED61C8ED0D728A146E398 /* Pods-defaults-Rocket.Chat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.debug.xcconfig"; path = "Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.debug.xcconfig"; sourceTree = ""; }; 45D5C142B655F8EFD006792C /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-defaults-RocketChatRN/ExpoModulesProvider.swift"; sourceTree = ""; }; - 48C83B3466485303788E4521 /* libPods-defaults-RocketChatRN.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-RocketChatRN.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 60B2A6A31FC4588700BD58E5 /* RocketChatRN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RocketChatRN.entitlements; path = RocketChatRN/RocketChatRN.entitlements; sourceTree = ""; }; 65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 65B9A7192AFC24190088956F /* ringtone.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = ringtone.mp3; sourceTree = ""; }; 70993AF097DB20918D5ABBDC /* Pods-defaults-Rocket.Chat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.release.xcconfig"; path = "Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.release.xcconfig"; sourceTree = ""; }; 7702E49AD9EFBD11DE2AE855 /* libPods-defaults-NotificationService.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-NotificationService.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7A006F13229C83B600803143 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 7A0129D22C6E8B5900F84A97 /* ShareRocketChatRN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareRocketChatRN.swift; sourceTree = ""; }; 7A0D62D1242AB187006D5C06 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 7A14FCEC257FEB3A005BDCD4 /* Experimental.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Experimental.xcassets; sourceTree = ""; }; 7A14FCF3257FEB59005BDCD4 /* Official.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Official.xcassets; sourceTree = ""; }; @@ -635,14 +627,14 @@ 7AAB3E52257E6A6E00707CF6 /* Rocket.Chat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rocket.Chat.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 7AE10C0528A59530003593CB /* Inter.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Inter.ttf; sourceTree = ""; }; - 825498A4D0AFA4786E98F569 /* Pods-defaults-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService.debug.xcconfig"; sourceTree = ""; }; - A349601A16A2DEC0EEDCB1E8 /* libPods-defaults-Rocket.Chat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-Rocket.Chat.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - AAE735590E45F323097F18D1 /* libPods-defaults-ShareRocketChatRN.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-ShareRocketChatRN.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B2AF8CE5DAA2B9602655ECA /* Pods-defaults-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService.debug.xcconfig"; sourceTree = ""; }; + 8F262B0EDDE35FABA5DAC31A /* Pods-defaults-Rocket.Chat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.release.xcconfig"; path = "Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.release.xcconfig"; sourceTree = ""; }; + 9EDAE7DFC486C8E0F5331BC7 /* libPods-defaults-NotificationService.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-NotificationService.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B37C79D9BD0742CE936B6982 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; BA7E862283664608B3894E34 /* libWatermelonDB.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libWatermelonDB.a; sourceTree = ""; }; - E2482220B7FDF5C4E8A955B0 /* Pods-defaults-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService.release.xcconfig"; sourceTree = ""; }; - F924993481C7F695EA66B7DC /* Pods-defaults-RocketChatRN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.debug.xcconfig"; path = "Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.debug.xcconfig"; sourceTree = ""; }; - FCE6383FF3ABD1820C92B472 /* Pods-defaults-ShareRocketChatRN.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-ShareRocketChatRN.release.xcconfig"; path = "Target Support Files/Pods-defaults-ShareRocketChatRN/Pods-defaults-ShareRocketChatRN.release.xcconfig"; sourceTree = ""; }; + C1FFA2C4EDACA0718BB71F1C /* Pods-defaults-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService.release.xcconfig"; sourceTree = ""; }; + F08B2D270E82A48D344CB0F5 /* libPods-defaults-Rocket.Chat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-Rocket.Chat.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F38DDC9B729E9C3C3883E1CF /* libPods-defaults-RocketChatRN.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-RocketChatRN.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -663,16 +655,7 @@ 7ACD4897222860DE00442C55 /* JavaScriptCore.framework in Frameworks */, 24A2AEF2383D44B586D31C01 /* libz.tbd in Frameworks */, DD2BA30A89E64F189C2C24AC /* libWatermelonDB.a in Frameworks */, - 0134A33CEB44035971D5A18E /* libPods-defaults-RocketChatRN.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1EC6ACAD22CB9FC300A41C61 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */, - 04587880D3FA9BCC2E9C7490 /* libPods-defaults-ShareRocketChatRN.a in Frameworks */, + 624EBD0BDE698092CB04C2FA /* libPods-defaults-RocketChatRN.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -694,7 +677,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 286806D511F8AAD37A7D422C /* libPods-defaults-NotificationService.a in Frameworks */, + 39E74E20D9E02DA933B049C1 /* libPods-defaults-NotificationService.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -715,7 +698,7 @@ 7AAB3E3D257E6A6E00707CF6 /* JavaScriptCore.framework in Frameworks */, 7AAB3E3E257E6A6E00707CF6 /* libz.tbd in Frameworks */, 7AAB3E3F257E6A6E00707CF6 /* libWatermelonDB.a in Frameworks */, - 6D168AA9955DC38D82D3C051 /* libPods-defaults-Rocket.Chat.a in Frameworks */, + E02D91DE2C11D3BD9AC34663 /* libPods-defaults-Rocket.Chat.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -986,11 +969,10 @@ 1EC6ACB122CB9FC300A41C61 /* ShareRocketChatRN */ = { isa = PBXGroup; children = ( - 1ED59D4B22CBA77D00C54289 /* GoogleService-Info.plist */, 1EC6AD6022CBA20C00A41C61 /* ShareRocketChatRN.entitlements */, 1EC6ACB522CB9FC300A41C61 /* MainInterface.storyboard */, 1EC6ACB822CB9FC300A41C61 /* Info.plist */, - 1EC6ACF522CBA01500A41C61 /* ShareRocketChatRN.m */, + 7A0129D22C6E8B5900F84A97 /* ShareRocketChatRN.swift */, ); path = ShareRocketChatRN; sourceTree = ""; @@ -1126,21 +1108,12 @@ path = NotificationService; sourceTree = ""; }; - 4F2FEDCF834DA36ADB5696EB /* ShareRocketChatRN */ = { - isa = PBXGroup; - children = ( - 016747EF3B9FED8DE2C9DA14 /* ExpoModulesProvider.swift */, - ); - name = ShareRocketChatRN; - sourceTree = ""; - }; 7890E71355E6C0A3288089E7 /* ExpoModulesProviders */ = { isa = PBXGroup; children = ( A19B6D9832C0496282053365 /* NotificationService */, 989BF9C58F3C91FDAA6C0452 /* Rocket.Chat */, CADEA0916086EF72D141FF5A /* RocketChatRN */, - 4F2FEDCF834DA36ADB5696EB /* ShareRocketChatRN */, ); name = ExpoModulesProviders; sourceTree = ""; @@ -1148,14 +1121,12 @@ 7AC2B09613AA7C3FEBAC9F57 /* Pods */ = { isa = PBXGroup; children = ( - 825498A4D0AFA4786E98F569 /* Pods-defaults-NotificationService.debug.xcconfig */, - E2482220B7FDF5C4E8A955B0 /* Pods-defaults-NotificationService.release.xcconfig */, - 35DE450085CD5A850E191FBF /* Pods-defaults-Rocket.Chat.debug.xcconfig */, - 70993AF097DB20918D5ABBDC /* Pods-defaults-Rocket.Chat.release.xcconfig */, - F924993481C7F695EA66B7DC /* Pods-defaults-RocketChatRN.debug.xcconfig */, - 3D68C21C65AA1783CBEDE5F3 /* Pods-defaults-RocketChatRN.release.xcconfig */, - 23D9D8F46A4AB85AAA0EB5A8 /* Pods-defaults-ShareRocketChatRN.debug.xcconfig */, - FCE6383FF3ABD1820C92B472 /* Pods-defaults-ShareRocketChatRN.release.xcconfig */, + 7B2AF8CE5DAA2B9602655ECA /* Pods-defaults-NotificationService.debug.xcconfig */, + C1FFA2C4EDACA0718BB71F1C /* Pods-defaults-NotificationService.release.xcconfig */, + 3A4ED61C8ED0D728A146E398 /* Pods-defaults-Rocket.Chat.debug.xcconfig */, + 8F262B0EDDE35FABA5DAC31A /* Pods-defaults-Rocket.Chat.release.xcconfig */, + 0E80084FB76F2BA00A43C5E0 /* Pods-defaults-RocketChatRN.debug.xcconfig */, + 0FF30665E726105A87EE37A8 /* Pods-defaults-RocketChatRN.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -1251,10 +1222,9 @@ 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */, B37C79D9BD0742CE936B6982 /* libc++.tbd */, 06BB44DD4855498082A744AD /* libz.tbd */, - 7702E49AD9EFBD11DE2AE855 /* libPods-defaults-NotificationService.a */, - A349601A16A2DEC0EEDCB1E8 /* libPods-defaults-Rocket.Chat.a */, - 48C83B3466485303788E4521 /* libPods-defaults-RocketChatRN.a */, - AAE735590E45F323097F18D1 /* libPods-defaults-ShareRocketChatRN.a */, + 9EDAE7DFC486C8E0F5331BC7 /* libPods-defaults-NotificationService.a */, + F08B2D270E82A48D344CB0F5 /* libPods-defaults-Rocket.Chat.a */, + F38DDC9B729E9C3C3883E1CF /* libPods-defaults-RocketChatRN.a */, ); name = Frameworks; sourceTree = ""; @@ -1274,7 +1244,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RocketChatRN" */; buildPhases = ( - BCA8800C060EEB85F09A442F /* [CP] Check Pods Manifest.lock */, + 39683630344A091B5F15ED5E /* [CP] Check Pods Manifest.lock */, 7AA5C63E23E30D110005C4A7 /* Start Packager */, 589729E8381BA997CD19EF19 /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, @@ -1286,8 +1256,8 @@ 1ED0389C2B507B4F00C007D4 /* Embed Watch Content */, 7AAE9EB32891A0D20024F559 /* Upload source maps to Bugsnag */, 407D3EDE3DABEE15D27BD87D /* ShellScript */, - 3AFDD31977A0B2A02090E4D1 /* [CP] Embed Pods Frameworks */, - 6112F7899A659EB5CB59A083 /* [CP] Copy Pods Resources */, + D45499F74A147D677153BC90 /* [CP] Embed Pods Frameworks */, + 9C104B12BEE385F7555E641F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1305,13 +1275,8 @@ isa = PBXNativeTarget; buildConfigurationList = 1EC6ACF322CB9FC300A41C61 /* Build configuration list for PBXNativeTarget "ShareRocketChatRN" */; buildPhases = ( - 6270E33879D02DA8B86777CB /* [CP] Check Pods Manifest.lock */, - 2C50632AB476A038AFCB1D43 /* [Expo] Configure project */, - 1EC6ACAC22CB9FC300A41C61 /* Sources */, - 1EC6ACAD22CB9FC300A41C61 /* Frameworks */, - 1EC6ACAE22CB9FC300A41C61 /* Resources */, - 1EFE4DC322CBF36300B766B7 /* ShellScript */, - A7A16EBB0002F86847D44CF0 /* [CP] Copy Pods Resources */, + A3573D86450E144A0963898E /* Sources */, + 7A0129D52C6E8EFE00F84A97 /* Resources */, ); buildRules = ( ); @@ -1360,12 +1325,12 @@ isa = PBXNativeTarget; buildConfigurationList = 1EFEB5A02493B6640072EDC0 /* Build configuration list for PBXNativeTarget "NotificationService" */; buildPhases = ( - 8272B47AB81DF99C33D2C081 /* [CP] Check Pods Manifest.lock */, + 40620FE6C682BABD00C2B4CB /* [CP] Check Pods Manifest.lock */, 86A998705576AFA7CE938617 /* [Expo] Configure project */, 1EFEB5912493B6640072EDC0 /* Sources */, 1EFEB5922493B6640072EDC0 /* Frameworks */, 1EFEB5932493B6640072EDC0 /* Resources */, - 7137CCB59B1C6DED76E1B6C8 /* [CP] Copy Pods Resources */, + 1AC60C112012F2EC4A83B6C6 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1380,7 +1345,7 @@ isa = PBXNativeTarget; buildConfigurationList = 7AAB3E4F257E6A6E00707CF6 /* Build configuration list for PBXNativeTarget "Rocket.Chat" */; buildPhases = ( - 3CCC2CBF4A94781DC1A46456 /* [CP] Check Pods Manifest.lock */, + 2A96227A2025150C0D3A4736 /* [CP] Check Pods Manifest.lock */, 7AAB3E13257E6A6E00707CF6 /* Start Packager */, 6723DBD924B66933E14E7EF7 /* [Expo] Configure project */, 7AAB3E14257E6A6E00707CF6 /* Sources */, @@ -1391,8 +1356,8 @@ 7AAB3E4B257E6A6E00707CF6 /* ShellScript */, 1ED1ECE32B8699DD00F6620C /* Embed Watch Content */, 7A10288726B1D15200E47EF8 /* Upload source maps to Bugsnag */, - 094DD573EC1232FF5E445B26 /* [CP] Embed Pods Frameworks */, - 4D18A5DB134C3977ED196A15 /* [CP] Copy Pods Resources */, + 23F41C80BD65C4C2AC2DD624 /* [CP] Embed Pods Frameworks */, + C75CF748D7A3F20A3D92419B /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1413,7 +1378,7 @@ isa = PBXProject; attributes = { DefaultBuildSystemTypeForWorkspace = Original; - LastSwiftUpdateCheck = 1500; + LastSwiftUpdateCheck = 1530; LastUpgradeCheck = 1130; ORGANIZATIONNAME = Facebook; TargetAttributes = { @@ -1508,18 +1473,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1EC6ACAE22CB9FC300A41C61 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7A610CD327ECE38100B8ABDD /* custom.ttf in Resources */, - 1EC6ACB722CB9FC300A41C61 /* MainInterface.storyboard in Resources */, - 1ED59D4C22CBA77D00C54289 /* GoogleService-Info.plist in Resources */, - 65AD38382BFBDF4A00271B39 /* PrivacyInfo.xcprivacy in Resources */, - 7AE10C0728A59530003593CB /* Inter.ttf in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1ED0388C2B507B4B00C007D4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1554,6 +1507,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7A0129D52C6E8EFE00F84A97 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A0129D62C6E8F0700F84A97 /* ShareRocketChatRN.entitlements in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7AAB3E41257E6A6E00707CF6 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1586,13 +1547,13 @@ shellPath = /bin/sh; shellScript = ". ~/.nvm/nvm.sh\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $TMPDIR/$(md5 -qs \"$CONFIGURATION_BUILD_DIR\")-main.jsbundle.map\"\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; }; - 094DD573EC1232FF5E445B26 /* [CP] Embed Pods Frameworks */ = { + 1AC60C112012F2EC4A83B6C6 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh", "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); @@ -1603,7 +1564,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 1E1EA8082326CCE300E22452 /* ShellScript */ = { @@ -1623,63 +1584,71 @@ shellPath = /bin/sh; shellScript = "echo \"Target architectures: $ARCHS\"\n\nAPP_PATH=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}\"\n\nfind \"$APP_PATH\" -name '*.framework' -type d | while read -r FRAMEWORK\ndo\nFRAMEWORK_EXECUTABLE_NAME=$(defaults read \"$FRAMEWORK/Info.plist\" CFBundleExecutable)\nFRAMEWORK_EXECUTABLE_PATH=\"$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME\"\necho \"Executable is $FRAMEWORK_EXECUTABLE_PATH\"\necho $(lipo -info \"$FRAMEWORK_EXECUTABLE_PATH\")\n\nFRAMEWORK_TMP_PATH=\"$FRAMEWORK_EXECUTABLE_PATH-tmp\"\n\n# remove simulator's archs if location is not simulator's directory\ncase \"${TARGET_BUILD_DIR}\" in\n*\"iphonesimulator\")\necho \"No need to remove archs\"\n;;\n*)\nif $(lipo \"$FRAMEWORK_EXECUTABLE_PATH\" -verify_arch \"i386\") ; then\nlipo -output \"$FRAMEWORK_TMP_PATH\" -remove \"i386\" \"$FRAMEWORK_EXECUTABLE_PATH\"\necho \"i386 architecture removed\"\nrm \"$FRAMEWORK_EXECUTABLE_PATH\"\nmv \"$FRAMEWORK_TMP_PATH\" \"$FRAMEWORK_EXECUTABLE_PATH\"\nfi\nif $(lipo \"$FRAMEWORK_EXECUTABLE_PATH\" -verify_arch \"x86_64\") ; then\nlipo -output \"$FRAMEWORK_TMP_PATH\" -remove \"x86_64\" \"$FRAMEWORK_EXECUTABLE_PATH\"\necho \"x86_64 architecture removed\"\nrm \"$FRAMEWORK_EXECUTABLE_PATH\"\nmv \"$FRAMEWORK_TMP_PATH\" \"$FRAMEWORK_EXECUTABLE_PATH\"\nfi\n;;\nesac\n\necho \"Completed for executable $FRAMEWORK_EXECUTABLE_PATH\"\necho $\n\ndone\n"; }; - 1EFE4DC322CBF36300B766B7 /* ShellScript */ = { + 23F41C80BD65C4C2AC2DD624 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); - outputFileListPaths = ( - ); + name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = ". ~/.nvm/nvm.sh\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $TMPDIR/$(md5 -qs \"$CONFIGURATION_BUILD_DIR\")-main.jsbundle.map\"\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - 2C50632AB476A038AFCB1D43 /* [Expo] Configure project */ = { + 2A96227A2025150C0D3A4736 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "[Expo] Configure project"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-defaults-Rocket.Chat-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-defaults-ShareRocketChatRN/expo-configure-project.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 3AFDD31977A0B2A02090E4D1 /* [CP] Embed Pods Frameworks */ = { + 39683630344A091B5F15ED5E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", + "$(DERIVED_FILE_DIR)/Pods-defaults-Rocket.Chat-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 3CCC2CBF4A94781DC1A46456 /* [CP] Check Pods Manifest.lock */ = { + 40620FE6C682BABD00C2B4CB /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1694,7 +1663,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-defaults-Rocket.Chat-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-defaults-NotificationService-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1719,82 +1688,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 4D18A5DB134C3977ED196A15 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCrashlytics/FirebaseCrashlytics_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCrashlytics_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 589729E8381BA997CD19EF19 /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -1814,104 +1707,6 @@ shellPath = /bin/sh; shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-defaults-RocketChatRN/expo-configure-project.sh\"\n"; }; - 6112F7899A659EB5CB59A083 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCrashlytics/FirebaseCrashlytics_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCrashlytics_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 6270E33879D02DA8B86777CB /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-defaults-ShareRocketChatRN-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 6723DBD924B66933E14E7EF7 /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -1931,82 +1726,6 @@ shellPath = /bin/sh; shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-defaults-Rocket.Chat/expo-configure-project.sh\"\n"; }; - 7137CCB59B1C6DED76E1B6C8 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCrashlytics/FirebaseCrashlytics_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf", - "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCrashlytics_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 7A10288726B1D15200E47EF8 /* Upload source maps to Bugsnag */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2015,7 +1734,7 @@ inputFileListPaths = ( ); inputPaths = ( - "$TARGET_BUILD_DIR/$INFOPLIST_PATH", + $TARGET_BUILD_DIR/$INFOPLIST_PATH, ); name = "Upload source maps to Bugsnag"; outputFileListPaths = ( @@ -2101,7 +1820,7 @@ inputFileListPaths = ( ); inputPaths = ( - "$TARGET_BUILD_DIR/$INFOPLIST_PATH", + $TARGET_BUILD_DIR/$INFOPLIST_PATH, ); name = "Upload source maps to Bugsnag"; outputFileListPaths = ( @@ -2112,29 +1831,26 @@ shellPath = /bin/sh; shellScript = "SOURCE_MAP=\"$TMPDIR/$(md5 -qs \"$CONFIGURATION_BUILD_DIR\")-main.jsbundle.map\" ../node_modules/@bugsnag/react-native/bugsnag-react-native-xcode.sh\n"; }; - 8272B47AB81DF99C33D2C081 /* [CP] Check Pods Manifest.lock */ = { + 86A998705576AFA7CE938617 /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; + name = "[Expo] Configure project"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-defaults-NotificationService-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-defaults-NotificationService/expo-configure-project.sh\"\n"; }; - 86A998705576AFA7CE938617 /* [Expo] Configure project */ = { + 9C104B12BEE385F7555E641F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -2153,13 +1869,13 @@ shellPath = /bin/sh; shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-defaults-NotificationService/expo-configure-project.sh\"\n"; }; - A7A16EBB0002F86847D44CF0 /* [CP] Copy Pods Resources */ = { + C75CF748D7A3F20A3D92419B /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-defaults-ShareRocketChatRN/Pods-defaults-ShareRocketChatRN-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", @@ -2226,29 +1942,27 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-ShareRocketChatRN/Pods-defaults-ShareRocketChatRN-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-resources.sh\"\n"; showEnvVarsInLog = 0; }; - BCA8800C060EEB85F09A442F /* [CP] Check Pods Manifest.lock */ = { + D45499F74A147D677153BC90 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); + name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-defaults-RocketChatRN-checkManifestLockResult.txt", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -2302,17 +2016,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1EC6ACAC22CB9FC300A41C61 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1EC6ACF622CBA01500A41C61 /* ShareRocketChatRN.m in Sources */, - 1E068CFF24FD2DC700A0FFC1 /* AppGroup.swift in Sources */, - 1E068D0224FD2E0500A0FFC1 /* AppGroup.m in Sources */, - D94D81FB9E10756FAA03F203 /* ExpoModulesProvider.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1ED0388A2B507B4B00C007D4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2579,6 +2282,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A3573D86450E144A0963898E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A0129EA2C6E921600F84A97 /* MainInterface.storyboard in Sources */, + 7A0129D42C6E8EC800F84A97 /* ShareRocketChatRN.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2628,7 +2340,7 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F924993481C7F695EA66B7DC /* Pods-defaults-RocketChatRN.debug.xcconfig */; + baseConfigurationReference = 0E80084FB76F2BA00A43C5E0 /* Pods-defaults-RocketChatRN.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -2689,7 +2401,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3D68C21C65AA1783CBEDE5F3 /* Pods-defaults-RocketChatRN.release.xcconfig */; + baseConfigurationReference = 0FF30665E726105A87EE37A8 /* Pods-defaults-RocketChatRN.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -2750,7 +2462,6 @@ }; 1EC6ACBC22CB9FC300A41C61 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 23D9D8F46A4AB85AAA0EB5A8 /* Pods-defaults-ShareRocketChatRN.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)"; APPLICATION_EXTENSION_API_ONLY = YES; @@ -2775,6 +2486,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = S6UPZG7ZR3; ENABLE_BITCODE = NO; ENABLE_TESTABILITY = YES; @@ -2793,7 +2505,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$PODS_CONFIGURATION_BUILD_DIR/Firebase", + $PODS_CONFIGURATION_BUILD_DIR/Firebase, "$(SRCROOT)/../node_modules/react-native-mmkv-storage/ios/**", ); INFOPLIST_FILE = ShareRocketChatRN/Info.plist; @@ -2826,7 +2538,6 @@ }; 1EC6ACBD22CB9FC300A41C61 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FCE6383FF3ABD1820C92B472 /* Pods-defaults-ShareRocketChatRN.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)"; APPLICATION_EXTENSION_API_ONLY = YES; @@ -2852,6 +2563,7 @@ CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = S6UPZG7ZR3; ENABLE_BITCODE = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -2869,7 +2581,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$PODS_CONFIGURATION_BUILD_DIR/Firebase", + $PODS_CONFIGURATION_BUILD_DIR/Firebase, "$(SRCROOT)/../node_modules/react-native-mmkv-storage/ios/**", ); INFOPLIST_FILE = ShareRocketChatRN/Info.plist; @@ -3110,7 +2822,7 @@ }; 1EFEB59D2493B6640072EDC0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 825498A4D0AFA4786E98F569 /* Pods-defaults-NotificationService.debug.xcconfig */; + baseConfigurationReference = 7B2AF8CE5DAA2B9602655ECA /* Pods-defaults-NotificationService.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)"; CLANG_ANALYZER_NONNULL = YES; @@ -3135,7 +2847,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.51.0; + MARKETING_VERSION = 4.52.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; @@ -3152,7 +2864,7 @@ }; 1EFEB59E2493B6640072EDC0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E2482220B7FDF5C4E8A955B0 /* Pods-defaults-NotificationService.release.xcconfig */; + baseConfigurationReference = C1FFA2C4EDACA0718BB71F1C /* Pods-defaults-NotificationService.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)"; CLANG_ANALYZER_NONNULL = YES; @@ -3179,7 +2891,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.51.0; + MARKETING_VERSION = 4.52.0; MTL_FAST_MATH = YES; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; @@ -3195,7 +2907,7 @@ }; 7AAB3E50257E6A6E00707CF6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 35DE450085CD5A850E191FBF /* Pods-defaults-Rocket.Chat.debug.xcconfig */; + baseConfigurationReference = 3A4ED61C8ED0D728A146E398 /* Pods-defaults-Rocket.Chat.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -3255,7 +2967,7 @@ }; 7AAB3E51257E6A6E00707CF6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 70993AF097DB20918D5ABBDC /* Pods-defaults-Rocket.Chat.release.xcconfig */; + baseConfigurationReference = 8F262B0EDDE35FABA5DAC31A /* Pods-defaults-Rocket.Chat.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -3376,10 +3088,7 @@ ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)"; - OTHER_LDFLAGS = ( - "$(inherited)", - " ", - ); + OTHER_LDFLAGS = "$(inherited) "; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -3442,10 +3151,7 @@ MTL_ENABLE_DEBUG_INFO = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)"; - OTHER_LDFLAGS = ( - "$(inherited)", - " ", - ); + OTHER_LDFLAGS = "$(inherited) "; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/ios/RocketChatRN/Info.plist b/ios/RocketChatRN/Info.plist index b7325a93c5..64e5d24cd4 100644 --- a/ios/RocketChatRN/Info.plist +++ b/ios/RocketChatRN/Info.plist @@ -28,7 +28,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 4.51.0 + 4.52.0 CFBundleSignature ???? CFBundleURLTypes diff --git a/ios/ShareRocketChatRN/Base.lproj/MainInterface.storyboard b/ios/ShareRocketChatRN/Base.lproj/MainInterface.storyboard index b822a68217..04f6af80f7 100644 --- a/ios/ShareRocketChatRN/Base.lproj/MainInterface.storyboard +++ b/ios/ShareRocketChatRN/Base.lproj/MainInterface.storyboard @@ -1,28 +1,27 @@ - - - - + + - + - + - + - + + diff --git a/ios/ShareRocketChatRN/Info.plist b/ios/ShareRocketChatRN/Info.plist index 66c3277239..6c60a7052e 100644 --- a/ios/ShareRocketChatRN/Info.plist +++ b/ios/ShareRocketChatRN/Info.plist @@ -26,7 +26,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 4.51.0 + 4.52.0 CFBundleVersion 1 KeychainGroup diff --git a/ios/ShareRocketChatRN/ShareRocketChatRN.m b/ios/ShareRocketChatRN/ShareRocketChatRN.m deleted file mode 100644 index f4a53b1b6c..0000000000 --- a/ios/ShareRocketChatRN/ShareRocketChatRN.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// ShareRocketChatRN.m -// ShareRocketChatRN -// -// Created by Djorkaeff Alexandre Vilela Pereira on 16/05/19. -// Copyright © 2019 Facebook. All rights reserved. -// - -#import -#import "ReactNativeShareExtension.h" -#import -#import -#import - -#import -#import -#import - -@interface ShareRocketChatRN : ReactNativeShareExtension -@end; - -@implementation ShareRocketChatRN - -RCT_EXPORT_MODULE(); - -- (UIView*) shareView { - NSURL *jsCodeLocation; - - if(![FIRApp defaultApp]){ - [FIRApp configure]; - } - [Bugsnag start]; - - jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; - - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge - moduleName:@"ShareRocketChatRN" - initialProperties:nil]; - rootView.backgroundColor = nil; - - // Uncomment for console output in Xcode console for release mode on device: - // RCTSetLogThreshold(RCTLogLevelInfo - 1); - - // AppGroup MMKV - NSString *groupDir = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"]].path; - [MMKV initializeMMKV:nil groupDir:groupDir logLevel:MMKVLogInfo]; - - return rootView; -} - -- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge -{ - #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; - #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; - #endif -} - -@end diff --git a/ios/ShareRocketChatRN/ShareRocketChatRN.swift b/ios/ShareRocketChatRN/ShareRocketChatRN.swift new file mode 100644 index 0000000000..e31eeca3b3 --- /dev/null +++ b/ios/ShareRocketChatRN/ShareRocketChatRN.swift @@ -0,0 +1,218 @@ +// +// ShareRocketChatRN.swift +// ShareRocketChatRN +// +// Created by Diego Mello on 8/15/24. +// Copyright © 2024 Facebook. All rights reserved. +// + +import UIKit +import MobileCoreServices + +class ShareRocketChatRN: UIViewController { + let appScheme = "rocketchat" + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem, + let attachments = extensionItem.attachments else { + self.completeRequest() + return + } + + // Handle URL or Text using the first attachment only + if let firstAttachment = attachments.first { + if firstAttachment.hasItemConformingToTypeIdentifier("public.url") { + firstAttachment.loadItem(forTypeIdentifier: "public.url", options: nil) { (data, error) in + if let url = data as? URL { + if url.isFileURL { + // Handle all file URLs + self.handleAllFileURLs(items: attachments) + } else { + // Handle as a web URL + self.handleUrl(item: firstAttachment) + } + } + } + return + } else if firstAttachment.hasItemConformingToTypeIdentifier("public.text") { + self.handleText(item: firstAttachment) + return + } + } + + // Handle Media (Images, Videos) and Data (PDFs, etc.) for all attachments + self.handleMultipleMediaAndData(items: attachments) + } + + private func handleText(item: NSItemProvider) { + item.loadItem(forTypeIdentifier: "public.text", options: nil) { (data, error) in + if let text = data as? String { + if let encoded = text.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://shareextension?text=\(encoded)") { + _ = self.openURL(url) + } + } + self.completeRequest() + } + } + + private func handleUrl(item: NSItemProvider) { + item.loadItem(forTypeIdentifier: "public.url", options: nil) { (data, error) in + if let url = data as? URL { + if let encoded = url.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let finalUrl = URL(string: "\(self.appScheme)://shareextension?url=\(encoded)") { + _ = self.openURL(finalUrl) + } + } + self.completeRequest() + } + } + + private func handleAllFileURLs(items: [NSItemProvider]) { + var fileUris = [String]() + let dispatchGroup = DispatchGroup() + + for item in items { + dispatchGroup.enter() + item.loadItem(forTypeIdentifier: "public.data", options: nil) { (data, error) in + if let fileUrl = data as? URL, fileUrl.isFileURL { + do { + let fileData = try Data(contentsOf: fileUrl) + let originalFilename = fileUrl.lastPathComponent + let savedUrl = self.saveDataToSharedContainer(data: fileData, filename: originalFilename) + if let finalUrl = savedUrl?.absoluteString { + fileUris.append(finalUrl) + } + } catch { + // Handle error + } + } + dispatchGroup.leave() + } + } + + dispatchGroup.notify(queue: .main) { + let combinedFileUris = fileUris.joined(separator: ",") + if let encoded = combinedFileUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://shareextension?mediaUris=\(encoded)") { + _ = self.openURL(url) + } + self.completeRequest() + } + } + + + private func handleMultipleMediaAndData(items: [NSItemProvider]) { + var mediaUris = [String]() + let dispatchGroup = DispatchGroup() + + for (_, item) in items.enumerated() { + dispatchGroup.enter() + + if item.hasItemConformingToTypeIdentifier("public.image") { + self.loadAndSaveItem(item: item, type: "public.image", dispatchGroup: dispatchGroup) { mediaUriInfo in + if let mediaUriInfo = mediaUriInfo { + mediaUris.append(mediaUriInfo) + } + } + } else if item.hasItemConformingToTypeIdentifier("public.movie") { + self.loadAndSaveItem(item: item, type: "public.movie", dispatchGroup: dispatchGroup) { mediaUriInfo in + if let mediaUriInfo = mediaUriInfo { + mediaUris.append(mediaUriInfo) + } + } + } else if item.hasItemConformingToTypeIdentifier("public.data") { + self.loadAndSaveItem(item: item, type: "public.data", dispatchGroup: dispatchGroup) { mediaUriInfo in + if let mediaUriInfo = mediaUriInfo { + mediaUris.append(mediaUriInfo) + } + } + } else { + dispatchGroup.leave() + } + } + + dispatchGroup.notify(queue: .main) { + let combinedMediaUris = mediaUris.joined(separator: ",") + if let encoded = combinedMediaUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://shareextension?mediaUris=\(encoded)") { + _ = self.openURL(url) + } + self.completeRequest() + } + } + + private func loadAndSaveItem(item: NSItemProvider, type: String, dispatchGroup: DispatchGroup, completion: @escaping (String?) -> Void) { + item.loadItem(forTypeIdentifier: type, options: nil) { (data, error) in + var mediaUriInfo: String? + + if let dataUri = data as? URL { + do { + let data = try Data(contentsOf: dataUri) + let originalFilename = dataUri.lastPathComponent + let savedUrl = self.saveDataToSharedContainer(data: data, filename: originalFilename) + mediaUriInfo = savedUrl?.absoluteString + } catch { + mediaUriInfo = nil + } + } else if let data = data as? Data { + if let fileExtension = self.inferFileExtension(from: item) { + let filename = UUID().uuidString + "." + fileExtension + let savedUrl = self.saveDataToSharedContainer(data: data, filename: filename) + mediaUriInfo = savedUrl?.absoluteString + } + } + + completion(mediaUriInfo) + dispatchGroup.leave() + } + } + + private func saveDataToSharedContainer(data: Data, filename: String) -> URL? { + guard let appGroup = Bundle.main.object(forInfoDictionaryKey: "AppGroup") as? String else { + return nil + } + guard let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else { + return nil + } + let fileURL = groupURL.appendingPathComponent(filename) + do { + try data.write(to: fileURL) + return fileURL + } catch { + return nil + } + } + + private func inferFileExtension(from item: NSItemProvider) -> String? { + if item.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { + return "jpeg" + } else if item.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { + return "mp4" + } else if let typeIdentifier = item.registeredTypeIdentifiers.first as CFString? { + if let utType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, typeIdentifier, nil)?.takeRetainedValue() { + if let preferredExtension = UTTypeCopyPreferredTagWithClass(utType, kUTTagClassFilenameExtension)?.takeRetainedValue() { + return preferredExtension as String + } + } + } + return nil + } + + @objc private func openURL(_ url: URL) -> Bool { + var responder: UIResponder? = self + while responder != nil { + if let application = responder as? UIApplication { + return application.perform(#selector(openURL(_:)), with: url) != nil + } + responder = responder?.next + } + return false + } + + private func completeRequest() { + self.extensionContext?.completeRequest(returningItems: nil) + } +} diff --git a/package.json b/package.json index 11ccf05f69..b01a323d8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rocket-chat-reactnative", - "version": "4.51.0", + "version": "4.52.0", "private": true, "scripts": { "start": "react-native start", @@ -76,7 +76,7 @@ "i18n-js": "3.9.2", "js-base64": "3.6.1", "js-sha256": "0.9.0", - "jsrsasign": "10.8.6", + "jsrsasign": "11.0.0", "lint-staged": "11.1.0", "lodash": "4.17.21", "mitt": "3.0.1", @@ -135,12 +135,11 @@ "redux-saga": "1.1.3", "remove-markdown": "0.3.0", "reselect": "4.0.0", - "rn-extensions-share": "RocketChat/rn-extensions-share", "rn-root-view": "RocketChat/rn-root-view", - "semver": "7.3.8", + "semver": "7.5.2", "transliteration": "2.3.5", "typed-redux-saga": "1.5.0", - "ua-parser-js": "1.0.32", + "ua-parser-js": "1.0.33", "uri-js": "4.4.1", "url-parse": "1.5.10", "use-debounce": "9.0.4", @@ -175,7 +174,7 @@ "@types/bytebuffer": "^5.0.44", "@types/ejson": "^2.1.3", "@types/i18n-js": "^3.8.3", - "@types/invariant": "^2.2.37", + "@types/invariant": "2.2.37", "@types/jest": "^29.5.12", "@types/jsrsasign": "^10.5.8", "@types/lodash": "^4.14.188", @@ -191,7 +190,7 @@ "@types/url-parse": "^1.4.8", "@typescript-eslint/eslint-plugin": "^7.4.0", "@typescript-eslint/parser": "^7.4.0", - "axios": "0.27.2", + "axios": "0.28.0", "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "babel-plugin-transform-remove-console": "^6.9.4", diff --git a/patches/@discord+bottom-sheet+4.6.1.patch b/patches/@discord+bottom-sheet+4.6.1.patch index 66621ae989..3a2e2e3c01 100644 --- a/patches/@discord+bottom-sheet+4.6.1.patch +++ b/patches/@discord+bottom-sheet+4.6.1.patch @@ -1,3 +1,17 @@ +diff --git a/node_modules/@discord/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@discord/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx +index 2897fef..9a8505e 100644 +--- a/node_modules/@discord/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx ++++ b/node_modules/@discord/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx +@@ -1382,7 +1382,8 @@ const BottomSheetComponent = forwardRef( + if (containerHeight !== _previousContainerHeight) { + animationSource = ANIMATION_SOURCE.CONTAINER_RESIZE; + animationConfig = { +- duration: 0, ++ // https://github.com/gorhom/react-native-bottom-sheet/pull/1497 ++ duration: 1, + }; + } + } diff --git a/node_modules/@discord/bottom-sheet/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx b/node_modules/@discord/bottom-sheet/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx index 2219e0f..59f90ba 100644 --- a/node_modules/@discord/bottom-sheet/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx diff --git a/yarn.lock b/yarn.lock index e43f3bb4a2..e6bcf75602 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4317,7 +4317,7 @@ resolved "https://registry.yarnpkg.com/@types/i18n-js/-/i18n-js-3.8.9.tgz#074d1389539d2db992e6afd7eb379aa02929ef93" integrity sha512-bSxgya4x5O+x+QhfCGckiDDE+17XGPp1TNBgBA/vfF5EwdiZC70F4cKG5QK2v44+v62oY7/t/InreRhxskulcA== -"@types/invariant@^2.2.37": +"@types/invariant@2.2.37": version "2.2.37" resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.37.tgz#1709741e534364d653c87dff22fc76fa94aa7bc0" integrity sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A== @@ -5300,13 +5300,14 @@ axe-core@=4.7.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== -axios@0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== +axios@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.28.0.tgz#801a4d991d0404961bccef46800e1170f8278c89" + integrity sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q== dependencies: - follow-redirects "^1.14.9" + follow-redirects "^1.15.0" form-data "^4.0.0" + proxy-from-env "^1.1.0" axios@^1.6.2: version "1.6.8" @@ -5659,12 +5660,12 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" browser-process-hrtime@^1.0.0: version "1.0.0" @@ -7823,9 +7824,9 @@ fast-url-parser@^1.1.3: punycode "^1.3.2" fast-xml-parser@^4.0.12, fast-xml-parser@^4.2.4: - version "4.3.5" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.5.tgz#e2f2a2ae8377e9c3dc321b151e58f420ca7e5ccc" - integrity sha512-sWvP1Pl8H03B8oFJpFR3HE31HUfwtX7Rlf9BNsvdpujD4n7WMhfmu8h9wOV2u+c1k0ZilTADhPqypzx2J690ZQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f" + integrity sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw== dependencies: strnum "^1.0.5" @@ -7908,10 +7909,10 @@ file-system-cache@2.3.0: fs-extra "11.1.1" ramda "0.29.0" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -8046,7 +8047,7 @@ flow-parser@^0.206.0: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== -follow-redirects@^1.14.9, follow-redirects@^1.15.6: +follow-redirects@^1.15.0, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -9935,10 +9936,10 @@ jsonify@^0.0.1: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== -jsrsasign@10.8.6: - version "10.8.6" - resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-10.8.6.tgz#ebf7f3c812c6517af84f0d8a10115e0dbfabe145" - integrity sha512-bQmbVtsfbgaKBTWCKiDCPlUPbdlRIK/FzSwT3BzIgZl/cU6TqXu6pZJsCI/dJVrZ9Gir5GC4woqw9shH/v7MBw== +jsrsasign@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-11.0.0.tgz#766570c21f87d68075a142f5188f7e583cee9d70" + integrity sha512-BtRwVKS+5dsgPpAtzJcpo5OoWjSs1/zllSBG0+8o8/aV0Ki76m6iZwHnwnsqoTdhfFZDN1XIdcaZr5ZkP+H2gg== "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.3.0" @@ -10616,11 +10617,11 @@ mhchemparser@^4.1.0: integrity sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ== micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": @@ -12725,10 +12726,6 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" -rn-extensions-share@RocketChat/rn-extensions-share: - version "2.4.1" - resolved "https://codeload.github.com/RocketChat/rn-extensions-share/tar.gz/4d7c0e4c2f300e4fb116af7b7cc0dbbc8169150c" - rn-host-detect@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0" @@ -12849,10 +12846,10 @@ semver@7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -semver@7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@7.5.2: + version "7.5.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" + integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== dependencies: lru-cache "^6.0.0" @@ -12868,34 +12865,13 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.0.0, semver@^7.5.2, semver@^7.5.4: +semver@^7.0.0, semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.3: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - send@0.18.0, send@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -13721,9 +13697,9 @@ tar-stream@^3.1.5: streamx "^2.15.0" tar@^6.0.2, tar@^6.0.5: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -14221,10 +14197,10 @@ ua-parser-js@1.0.2, ua-parser-js@^0.7.30, ua-parser-js@^1.0.35: resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.2.tgz#e2976c34dbfb30b15d2c300b2a53eac87c57a775" integrity sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg== -ua-parser-js@1.0.32: - version "1.0.32" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.32.tgz#786bf17df97de159d5b1c9d5e8e9e89806f8a030" - integrity sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA== +ua-parser-js@1.0.33: + version "1.0.33" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.33.tgz#f21f01233e90e7ed0f059ceab46eb190ff17f8f4" + integrity sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ== uglify-js@^3.1.4: version "3.17.4"