diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt
index e4ab65ceba1..da574e2767d 100644
--- a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt
+++ b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt
@@ -1,24 +1,28 @@
package chat.rocket.reactnative
-
+
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import android.os.Bundle
+import android.os.Build
+import android.os.PersistableBundle
import com.zoontek.rnbootsplash.RNBootSplash
import android.content.Intent
import android.content.res.Configuration
import chat.rocket.reactnative.notification.NotificationIntentHandler
-
+import androidx.core.net.toUri
+import java.util.Locale
+
class MainActivity : ReactActivity() {
-
+
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
override fun getMainComponentName(): String = "RocketChatRN"
-
+
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
@@ -27,17 +31,30 @@ class MainActivity : ReactActivity() {
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
override fun onCreate(savedInstanceState: Bundle?) {
+ // quick actions handling
+ intent?.let {
+ embedQuickActionIntoLinking(it)
+ }
+
RNBootSplash.init(this, R.style.BootTheme)
super.onCreate(null)
-
+
// Handle notification intents
intent?.let { NotificationIntentHandler.handleIntent(this, it) }
}
-
+
public override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
-
+
+ /* Keep this after super:
+ - onNewIntent is required for background quick actions
+ - Expo handles background shortcuts via JS listeners
+ - Normalizing before super breaks that flow
+ */
+ // quick actions handling
+ embedQuickActionIntoLinking(intent)
+
// Handle notification intents when activity is already running
NotificationIntentHandler.handleIntent(this, intent)
}
@@ -45,4 +62,82 @@ class MainActivity : ReactActivity() {
override fun invokeDefaultOnBackPressed() {
moveTaskToBack(true)
}
+
+ private fun embedQuickActionIntoLinking(intent: Intent) {
+ val action = intent.action ?: return
+
+ if (BuildConfig.DEBUG){
+ android.util.Log.d("RocketChat.QuickAction", "Original action: $action")
+ }
+
+ // Handle Expo quick actions
+ if (action == "expo.modules.quickactions.SHORTCUT") {
+ // Get the PersistableBundle
+ val shortcutData: PersistableBundle? =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableExtra(
+ "shortcut_data",
+ PersistableBundle::class.java
+ )
+ } else {
+ @Suppress("DEPRECATION")
+ intent.getParcelableExtra("shortcut_data")
+ }
+
+ if (shortcutData != null) {
+
+ // Try to get the shortcut ID from various possible keys
+ val shortcutId = shortcutData.getString("id")
+ ?: shortcutData.getString("shortcutId")
+ ?: shortcutData.getString("android.intent.extra.shortcut.ID")
+
+ if (shortcutId != null) {
+ val uri = "rocketchat://quick-action/$shortcutId".toUri()
+
+ if (BuildConfig.DEBUG) {
+ android.util.Log.d("RocketChat.QuickAction", "Converted to: $uri")
+ }
+
+ intent.action = Intent.ACTION_VIEW
+ intent.data = uri
+ setIntent(intent)
+
+ if (BuildConfig.DEBUG) {
+ android.util.Log.d(
+ "RocketChat.QuickAction",
+ "Intent set with data: ${getIntent().data}"
+ )
+ }
+ }
+ } else {
+ if (BuildConfig.DEBUG){
+ android.util.Log.d("RocketChat.QuickAction", "No shortcut_data bundle found")
+ }
+ }
+ return
+ }
+
+ // skip for non-Expo quick actions (app launches)
+ if (!action.startsWith("chat.rocket.reactnative.")) {
+ if (BuildConfig.DEBUG) {
+ android.util.Log.d("RocketChat.QuickAction", "Not a quick action, skipping")
+ }
+ return
+ }
+
+ val quickAction = action
+ .removePrefix("chat.rocket.reactnative.")
+ .lowercase(Locale.ROOT)
+ .replace('_', '-')
+
+ val uri = "rocketchat://quick-action/$quickAction".toUri()
+
+ intent.action = Intent.ACTION_VIEW
+ intent.data = uri
+ setIntent(intent)
+
+ if (BuildConfig.DEBUG){
+ android.util.Log.d("RocketChat.QuickAction", "Intent set with data: ${getIntent().data}")
+ }
+ }
}
\ No newline at end of file
diff --git a/android/app/src/main/res/drawable/ic_quickaction_add.xml b/android/app/src/main/res/drawable/ic_quickaction_add.xml
new file mode 100644
index 00000000000..ab03689d18d
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_quickaction_add.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_quickaction_contact.xml b/android/app/src/main/res/drawable/ic_quickaction_contact.xml
new file mode 100644
index 00000000000..2e92649f3bc
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_quickaction_contact.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_quickaction_find.xml b/android/app/src/main/res/drawable/ic_quickaction_find.xml
new file mode 100644
index 00000000000..a0e11aa0f02
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_quickaction_find.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_quickaction_recent.xml b/android/app/src/main/res/drawable/ic_quickaction_recent.xml
new file mode 100644
index 00000000000..f18f24197e2
--- /dev/null
+++ b/android/app/src/main/res/drawable/ic_quickaction_recent.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx
index 001b9d33a0d..8eaabb90f8d 100644
--- a/app/AppContainer.tsx
+++ b/app/AppContainer.tsx
@@ -1,12 +1,13 @@
import React, { useContext, memo, useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import { connect } from 'react-redux';
+import { connect, useDispatch } from 'react-redux';
+import { registerQuickActions, unregisterQuickActions, updateQuickActions } from './lib/quickActions';
import type { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes';
import Navigation from './lib/navigation/appNavigation';
import { defaultHeader, getActiveRouteName, navigationTheme } from './lib/methods/helpers/navigation';
-import { RootEnum } from './definitions';
+import { type IApplicationState, RootEnum } from './definitions';
// Stacks
import AuthLoadingView from './views/AuthLoadingView';
// SetUsername Stack
@@ -19,6 +20,8 @@ import { ThemeContext } from './theme';
import { setCurrentScreen } from './lib/methods/helpers/log';
import { themes } from './lib/constants/colors';
import { emitter } from './lib/methods/helpers';
+import { useAppSelector } from './lib/hooks/useAppSelector';
+import { NAVIGATION } from './actions/actionsTypes';
const createStackNavigator = createNativeStackNavigator;
@@ -34,6 +37,17 @@ const SetUsernameStack = () => (
const Stack = createStackNavigator();
const App = memo(({ root, isMasterDetail }: { root: string; isMasterDetail: boolean }) => {
const { theme } = useContext(ThemeContext);
+ const dispatch = useDispatch();
+ const recentRooms = useAppSelector((state: IApplicationState) => state.rooms.recentRooms);
+
+ useEffect(() => {
+ registerQuickActions();
+
+ return () => {
+ unregisterQuickActions();
+ };
+ }, []);
+
useEffect(() => {
if (root) {
const state = Navigation.navigationRef.current?.getRootState();
@@ -43,6 +57,10 @@ const App = memo(({ root, isMasterDetail }: { root: string; isMasterDetail: bool
}
}, [root]);
+ useEffect(() => {
+ updateQuickActions({ recentRooms });
+ }, [recentRooms]);
+
if (!root) {
return null;
}
@@ -55,6 +73,7 @@ const App = memo(({ root, isMasterDetail }: { root: string; isMasterDetail: bool
ref={Navigation.navigationRef}
onReady={() => {
emitter.emit('navigationReady');
+ dispatch({ type: NAVIGATION.NAVIGATION_READY });
}}
onStateChange={state => {
const previousRouteName = Navigation.routeNameRef.current;
diff --git a/app/actions/actionsTypes.ts b/app/actions/actionsTypes.ts
index 938ff7b9d5d..3b7bb7acac1 100644
--- a/app/actions/actionsTypes.ts
+++ b/app/actions/actionsTypes.ts
@@ -12,7 +12,7 @@ function createRequestTypes(base = {}, types = defaultTypes): Record;
+}
+export function quickActionHandle(params: Partial): IQuickAction {
+ return {
+ type: QUICK_ACTIONS.QUICK_ACTION_HANDLE,
+ params
+ };
+}
diff --git a/app/actions/rooms.ts b/app/actions/rooms.ts
index b2034080cc0..ac1fa60d416 100644
--- a/app/actions/rooms.ts
+++ b/app/actions/rooms.ts
@@ -1,6 +1,7 @@
import { type Action } from 'redux';
import { ROOMS } from './actionsTypes';
+import { type IRecentRoomsStore } from '../reducers/rooms';
export interface IRoomsRequest extends Action {
params: any;
@@ -14,7 +15,16 @@ export interface IRoomsFailure extends Action {
err: Record | string;
}
-export type IRoomsAction = IRoomsRequest & ISetSearch & IRoomsFailure;
+export interface IRoomsLastVisited extends Action {
+ lastVisitedRoomId: string;
+ lastVisitedRoomName: string;
+}
+
+export interface IRecentRooms extends Action {
+ recentRooms: IRecentRoomsStore[];
+}
+
+export type IRoomsAction = IRoomsRequest & ISetSearch & IRoomsFailure & IRoomsLastVisited & IRecentRooms;
export function roomsRequest(
params: {
@@ -45,3 +55,18 @@ export function roomsRefresh(): Action {
type: ROOMS.REFRESH
};
}
+
+export function roomsStoreLastVisited(rid: string, name: string): IRoomsLastVisited {
+ return {
+ type: ROOMS.STORE_LAST_VISITED,
+ lastVisitedRoomId: rid,
+ lastVisitedRoomName: name
+ };
+}
+
+export function roomsStoreRecentRooms(recentRooms: IRecentRoomsStore[]): IRecentRooms {
+ return {
+ type: ROOMS.STORE_RECENT_ROOMS,
+ recentRooms
+ };
+}
diff --git a/app/containers/Avatar/__snapshots__/Avatar.test.tsx.snap b/app/containers/Avatar/__snapshots__/Avatar.test.tsx.snap
index 97d9de5ea35..2e201a58eb5 100644
--- a/app/containers/Avatar/__snapshots__/Avatar.test.tsx.snap
+++ b/app/containers/Avatar/__snapshots__/Avatar.test.tsx.snap
@@ -37,7 +37,9 @@ exports[`Story Snapshots: AvatarExternalProviderUrl should match snapshot 1`] =
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://hips.hearstapps.com/hmg-prod/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg?crop=0.752xw:1.00xh;0.175xw,0&resize=1200:*&format=png&size=112",
},
]
@@ -92,7 +94,9 @@ exports[`Story Snapshots: AvatarPath should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=112",
},
]
@@ -147,7 +151,9 @@ exports[`Story Snapshots: AvatarRoomId should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/room/devWBbYr7inwupPqK?format=png&size=112",
},
]
@@ -202,7 +208,9 @@ exports[`Story Snapshots: AvatarText should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/Avatar?format=png&size=112",
},
]
@@ -257,7 +265,9 @@ exports[`Story Snapshots: AvatarUrl should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg",
},
]
@@ -312,7 +322,9 @@ exports[`Story Snapshots: Channel should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/@general?format=png&size=112",
},
]
@@ -367,7 +379,9 @@ exports[`Story Snapshots: Children should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/Avatar?format=png&size=112",
},
]
@@ -462,7 +476,9 @@ exports[`Story Snapshots: CustomBorderRadius should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/Avatar?format=png&size=112",
},
]
@@ -519,7 +535,9 @@ exports[`Story Snapshots: CustomStyle should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/Avatar?format=png&size=112",
},
]
@@ -574,7 +592,9 @@ exports[`Story Snapshots: Direct should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=112",
},
]
@@ -696,7 +716,9 @@ exports[`Story Snapshots: RoomAvatarExternalProviderUrl should match snapshot 1`
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://cdn.pensador.com/img/authors/ho/me/homer-simpson-l.jpg?format=png&size=112",
},
]
@@ -751,7 +773,9 @@ exports[`Story Snapshots: Static should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg",
},
]
@@ -840,7 +864,9 @@ exports[`Story Snapshots: Touchable should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/Avatar?format=png&size=112",
},
]
@@ -896,7 +922,9 @@ exports[`Story Snapshots: WithETag should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=112&etag=5ag8KffJcZj9m5rCv",
},
]
@@ -951,7 +979,9 @@ exports[`Story Snapshots: WithoutETag should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=112",
},
]
@@ -1006,7 +1036,9 @@ exports[`Story Snapshots: WrongServer should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://google.com/avatar/Avatar?format=png&size=112",
},
]
diff --git a/app/containers/Chip/__snapshots__/Chip.test.tsx.snap b/app/containers/Chip/__snapshots__/Chip.test.tsx.snap
index 58de1a6452d..8a26f96352e 100644
--- a/app/containers/Chip/__snapshots__/Chip.test.tsx.snap
+++ b/app/containers/Chip/__snapshots__/Chip.test.tsx.snap
@@ -207,7 +207,9 @@ exports[`Story Snapshots: ChipText should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/rocket.cat?format=png&size=56",
},
]
@@ -389,7 +391,9 @@ exports[`Story Snapshots: ChipWithShortText should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/rocket.cat?format=png&size=56",
},
]
@@ -799,7 +803,9 @@ exports[`Story Snapshots: ChipWithoutIcon should match snapshot 1`] = `
source={
[
{
- "headers": undefined,
+ "headers": {
+ "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)",
+ },
"uri": "https://open.rocket.chat/avatar/rocket.cat?format=png&size=56",
},
]
diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts
index f32d7041e69..002699268a2 100644
--- a/app/definitions/redux/index.ts
+++ b/app/definitions/redux/index.ts
@@ -48,6 +48,7 @@ import { type IRooms } from '../../reducers/rooms';
import { type IPreferences } from '../IPreferences';
import { type ICustomEmojis } from '../IEmoji';
import { type IUsersTyping } from '../../reducers/usersTyping';
+import { type IUIState } from '../../reducers/ui';
export interface IApplicationState {
settings: TSettingsState;
@@ -76,6 +77,7 @@ export interface IApplicationState {
troubleshootingNotification: ITroubleshootingNotification;
supportedVersions: ISupportedVersionsState;
inAppFeedback: IInAppFeedbackState;
+ ui: IUIState;
}
export type TApplicationActions = TActionActiveUsers &
diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json
index 20adc12eb90..772163ce9f2 100644
--- a/app/i18n/locales/en.json
+++ b/app/i18n/locales/en.json
@@ -328,6 +328,7 @@
"Enter_manually": "Enter manually",
"Enter_the_code": "Enter the code we just emailed you.",
"Error_Download_file": "Error while downloading file",
+ "Error_finding_room": "Error finding room in this server\ntry switching server",
"Error_incorrect_password": "Incorrect password",
"Error_play_video": "There was an error while playing this video",
"Error_prefix": "Error: {{message}}",
@@ -453,6 +454,7 @@
"Last_updated": "Last updated",
"Last_updated_at": "Last updated at",
"Last_updated_on": "Last updated on",
+ "Last_visited_room": "Last visited",
"last-owner-can-not-be-removed": "Last owner cannot be removed",
"Leader": "Leader",
"Learn_more": "Learn more",
@@ -693,6 +695,7 @@
"Receive_Group_Mentions_Info": "Receive @all and @here mentions",
"Receive_Notification": "Receive notification",
"Receive_notifications_from": "Receive notifications from {{name}}",
+ "Recent_Rooms": "Recent Rooms",
"Recently_used": "Recently used",
"Record_audio_message": "Record audio message",
"Recording_audio_in_progress": "Recording audio message",
@@ -840,6 +843,7 @@
"Slash_Topic_Description": "Set topic",
"Slash_Topic_Params": "Topic message",
"Smileys_and_people": "Smileys and people",
+ "Something_Wrong?": "Something Wrong?",
"Sort_by": "Sort by",
"Sound": "Sound",
"Star": "Star",
@@ -977,6 +981,7 @@
"Waiting_for_answer": "Waiting for answer",
"Waiting_for_network": "Waiting for network...",
"Waiting_for_server_connection": "Waiting for server connection",
+ "We_are_here_to_help": "We're here to help",
"Websocket_disabled": "Websocket is disabled for this workspace.\n{{contact}}",
"What_are_you_doing_right_now": "What are you doing right now?",
"Whats_the_password_for_your_certificate": "What's the password for your certificate?",
diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json
index cbd4dfb4eae..b1a16ba5cb5 100644
--- a/app/i18n/locales/pt-BR.json
+++ b/app/i18n/locales/pt-BR.json
@@ -319,6 +319,7 @@
"Enter_manually": "Inserir manualmente",
"Enter_the_code": "Insira o código que acabamos de enviar por e-mail.",
"Error_Download_file": "Erro ao baixar o arquivo",
+ "Error_finding_room": "Erro ao encontrar uma sala neste servidor\ntente mudar de servidor.",
"Error_incorrect_password": "Senha incorreta",
"Error_play_video": "Houve um erro ao reproduzir esse vídeo",
"Error_prefix": "Erro: {{message}}",
@@ -443,6 +444,7 @@
"Last_updated": "Última atualização",
"Last_updated_at": "Última atualização em",
"Last_updated_on": "Última atualização em",
+ "Last_visited_room": "Última visita",
"last-owner-can-not-be-removed": "O último dono não pode ser removido",
"Leader": "Líder",
"Learn_more": "Saiba mais",
@@ -681,6 +683,7 @@
"Receive_Group_Mentions_Info": "Receber menções @all e @here",
"Receive_Notification": "Receber notificação",
"Receive_notifications_from": "Receber notificação de {{name}}",
+ "Recent_Rooms": "Quartos recentes",
"Recently_used": "Usados recentemente",
"Record_audio_message": "Gravar mensagem de áudio",
"Register": "Registrar",
@@ -821,6 +824,7 @@
"Slash_Topic_Description": "Definir tópico",
"Slash_Topic_Params": "Mensagem do tópico",
"Smileys_and_people": "Carinhas e pessoas",
+ "Something_Wrong?": "Algo errado?",
"Sort_by": "Ordenar por",
"Sound": "Som da notificação",
"Star": "Favorito",
@@ -959,6 +963,7 @@
"Waiting_for_answer": "Esperando por resposta",
"Waiting_for_network": "Aguardando rede...",
"Waiting_for_server_connection": "Aguardando conexão com o servidor",
+ "We_are_here_to_help": "Estamos aqui para ajudar.",
"Websocket_disabled": "Websocket está desativado para essa workspace.\n{{contact}}",
"What_are_you_doing_right_now": "O que você está fazendo agora?",
"Whats_the_password_for_your_certificate": "Qual é a senha para o seu certificado?",
diff --git a/app/index.tsx b/app/index.tsx
index 88f8347445f..20eed013ddb 100644
--- a/app/index.tsx
+++ b/app/index.tsx
@@ -9,7 +9,9 @@ import { KeyboardProvider } from 'react-native-keyboard-controller';
import ResponsiveLayoutProvider from './lib/hooks/useResponsiveLayout/useResponsiveLayout';
import AppContainer from './AppContainer';
import { appInit, appInitLocalSettings, setMasterDetail as setMasterDetailAction } from './actions/app';
+import { getRecentQuickAction } from './lib/quickActions/getRecentQuickAction';
import { deepLinkingOpen } from './actions/deepLinking';
+import { quickActionHandle } from './actions/quickActions';
import { ActionSheetProvider } from './containers/ActionSheet';
import InAppNotification from './containers/InAppNotification';
import Loading from './containers/Loading';
@@ -61,6 +63,18 @@ interface IState {
const parseDeepLinking = (url: string) => {
if (url) {
+ /**
+ * android only
+ * restores quick action from intent / Linking
+ */
+ if (url.startsWith('rocketchat://quick-action/')) {
+ const action = url.replace('rocketchat://quick-action/', '');
+ return {
+ type: 'quick-action',
+ action
+ };
+ }
+
url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, '');
const regex = /^(room|auth|invite|shareextension)\?/;
const match = url.match(regex);
@@ -151,6 +165,24 @@ export default class Root extends React.Component<{}, IState> {
// Open app from deep linking
const deepLinking = await Linking.getInitialURL();
const parsedDeepLinkingURL = parseDeepLinking(deepLinking!);
+
+ /**
+ * ios only
+ * fetched recent quick action stored on native side
+ * automatically cleared after we call to `getRecentQuickAction()`
+ */
+ const quickAction = await getRecentQuickAction();
+ if (quickAction) {
+ store.dispatch(quickActionHandle({ action: quickAction }));
+ return;
+ }
+
+ // android quick action handling via intent
+ if (parsedDeepLinkingURL?.type === 'quick-action') {
+ store.dispatch(quickActionHandle({ action: parsedDeepLinkingURL.action }));
+ return;
+ }
+
if (parsedDeepLinkingURL) {
store.dispatch(deepLinkingOpen(parsedDeepLinkingURL));
return;
diff --git a/app/lib/constants/keys.ts b/app/lib/constants/keys.ts
index 8c6dc1da7d2..e0c73d356d1 100644
--- a/app/lib/constants/keys.ts
+++ b/app/lib/constants/keys.ts
@@ -25,3 +25,6 @@ export const ANALYTICS_EVENTS_KEY = 'RC_ANALYTICS_EVENTS_KEY';
export const TOKEN_KEY = 'reactnativemeteor_usertoken';
export const CURRENT_SERVER = 'currentServer';
export const CERTIFICATE_KEY = 'RC_CERTIFICATE_KEY';
+export const LAST_VISITED_ROOM_ID_KEY = 'RC_LAST_VISITED_ROOM_ID_KEY';
+export const LAST_VISITED_ROOM_NAME_KEY = 'RC_LAST_VISITED_ROOM_NAME_KEY';
+export const RECENT_VISITED_ROOMS_KEY = 'RC_RECENT_VISITED_ROOMS_KEY';
diff --git a/app/lib/methods/getServerList.ts b/app/lib/methods/getServerList.ts
new file mode 100644
index 00000000000..de053a8f90e
--- /dev/null
+++ b/app/lib/methods/getServerList.ts
@@ -0,0 +1,10 @@
+import { type TServerModel } from '../../definitions';
+import database from '../database';
+
+export const getServersList = async (): Promise => {
+ const serversDB = database.servers;
+
+ const servers: TServerModel[] = await serversDB.get('servers').query().fetch();
+
+ return servers;
+};
diff --git a/app/lib/methods/helpers/emitter.ts b/app/lib/methods/helpers/emitter.ts
index 268ca8f0a96..6516246c6f2 100644
--- a/app/lib/methods/helpers/emitter.ts
+++ b/app/lib/methods/helpers/emitter.ts
@@ -17,6 +17,10 @@ export type TEmitterEvents = TDynamicMediaDownloadEvents & {
setComposerHeightThread: number;
audioFocused: string;
navigationReady: undefined;
+ roomVisited: {
+ rid: string;
+ name: string;
+ };
};
export type TKeyEmitterEvent = keyof TEmitterEvents;
diff --git a/app/lib/methods/helpers/goRoom.ts b/app/lib/methods/helpers/goRoom.ts
index 6119420898f..ae83ee335bc 100644
--- a/app/lib/methods/helpers/goRoom.ts
+++ b/app/lib/methods/helpers/goRoom.ts
@@ -12,6 +12,8 @@ import {
import { getRoomTitle, getUidDirectMessage } from './helpers';
import { createDirectMessage } from '../../services/restApi';
import { emitErrorCreateDirectMessage } from './emitErrorCreateDirectMessage';
+import { getRoom } from '../getRoom';
+import { emitter } from './emitter';
interface IGoRoomItem {
search?: boolean; // comes from spotlight
@@ -98,6 +100,22 @@ export const goRoom = async ({
const { username } = item;
const result = await createDirectMessage(username as string);
if (result.success && result?.room?._id) {
+ try {
+ // storing last visited room
+ const room = await getRoom(result?.room?.rid || '');
+
+ /**
+ * store.dispatch causing dependency cycle error here
+ * using emitter based flow to prevent it
+ */
+ emitter.emit('roomVisited', {
+ rid: result.room._id,
+ name: room.name
+ });
+ } catch {
+ // do nothing
+ }
+
return navigate({
item: {
rid: result.room._id,
@@ -120,6 +138,18 @@ export const goRoom = async ({
*/
let _item = item;
if (item.rid) {
+ try {
+ const room = await getRoom(item.rid);
+
+ // storing last visited room
+ emitter.emit('roomVisited', {
+ rid: room.rid,
+ name: room.name
+ });
+ } catch {
+ // do nothing
+ }
+
const sub = await getSubscriptionByRoomId(item.rid);
if (sub) {
_item = sub;
diff --git a/app/lib/methods/logout.ts b/app/lib/methods/logout.ts
index 69a9643ec2d..080d038549e 100644
--- a/app/lib/methods/logout.ts
+++ b/app/lib/methods/logout.ts
@@ -2,7 +2,7 @@ import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
import type Model from '@nozbe/watermelondb/Model';
import { getDeviceToken } from '../notifications';
-import { isSsl } from './helpers';
+import { emitter, isSsl } from './helpers';
import { BASIC_AUTH_KEY } from './helpers/fetch';
import database, { getDatabase } from '../database';
import log from './helpers/log';
@@ -24,6 +24,14 @@ function removeServerKeys({ server, userId }: { server: string; userId?: string
UserPreferences.removeItem(`${server}-${E2E_RANDOM_PASSWORD_KEY}`);
}
+function removeLastVisitedRoomKeys() {
+ // clearing the state
+ emitter.emit('roomVisited', {
+ rid: '',
+ name: ''
+ });
+}
+
export async function removeServerData({ server }: { server: string }): Promise {
try {
const batch: Model[] = [];
@@ -117,4 +125,5 @@ export async function logout({ server }: { server: string }): Promise {
await removeServerData({ server });
await removeCurrentServer();
await removeServerDatabase({ server });
+ removeLastVisitedRoomKeys();
}
diff --git a/app/lib/quickActions/getRecentQuickAction.ts b/app/lib/quickActions/getRecentQuickAction.ts
new file mode 100644
index 00000000000..90a194bec32
--- /dev/null
+++ b/app/lib/quickActions/getRecentQuickAction.ts
@@ -0,0 +1,20 @@
+import { NativeModules } from 'react-native';
+
+const { QuickActionsConnector } = NativeModules;
+
+/**
+ * Reads the initial iOS quick action (cold / background launch).
+ * Returns the action type once, then clears it on native side.
+ */
+export async function getRecentQuickAction(): Promise {
+ if (!QuickActionsConnector?.getInitialQuickAction) {
+ return null;
+ }
+
+ try {
+ const action = await QuickActionsConnector.getInitialQuickAction();
+ return action ?? null;
+ } catch {
+ return null;
+ }
+}
diff --git a/app/lib/quickActions/index.ts b/app/lib/quickActions/index.ts
new file mode 100644
index 00000000000..6abab0275b6
--- /dev/null
+++ b/app/lib/quickActions/index.ts
@@ -0,0 +1,93 @@
+import * as QuickActions from 'expo-quick-actions';
+import { InteractionManager, AppState, Platform } from 'react-native';
+
+import store from '../store';
+import { getRecentQuickAction } from './getRecentQuickAction';
+import { quickActionHandle } from '../../actions/quickActions';
+import { type IRecentRoomsStore } from '../../reducers/rooms';
+import { getServersList } from '../methods/getServerList';
+import I18n from '../../i18n';
+
+let registered = false;
+
+let quickActionSubscription: { remove(): void } | null = null;
+let appStateSubscription: { remove(): void } | null = null;
+
+export async function updateQuickActions({ recentRooms }: { recentRooms: IRecentRoomsStore[] } = { recentRooms: [] }) {
+ const serverList = (await getServersList()).map(server => server._raw.id);
+ const recentRoomQuickActions: QuickActions.Action[] = recentRooms
+ .map(room => {
+ if (!room.server) return null;
+ if (!serverList.includes(room.server)) return null;
+
+ return {
+ id: `recent/${encodeURIComponent(room.server)}/${room.rid}`,
+ title: room.name,
+ subtitle: room.server,
+ icon: Platform.select({
+ ios: 'symbol:clock.arrow.trianglehead.counterclockwise.rotate.90',
+ android: 'ic_quickaction_recent',
+ default: undefined
+ })
+ } as QuickActions.Action;
+ })
+ .filter(item => item !== null)
+ .reverse();
+
+ const quickActionItems = [
+ ...recentRoomQuickActions,
+ {
+ id: 'contact',
+ title: Platform.select({ android: I18n.t('Contact_us'), ios: I18n.t('Something_Wrong?') }) ?? I18n.t('Contact_us'),
+ subtitle: I18n.t('We_are_here_to_help'),
+ icon: Platform.select({
+ ios: 'symbol:envelope',
+ android: 'ic_quickaction_contact'
+ })
+ }
+ ];
+
+ await QuickActions.setItems(quickActionItems);
+}
+
+export async function registerQuickActions() {
+ if (registered) {
+ return;
+ }
+ registered = true;
+
+ await updateQuickActions();
+
+ quickActionSubscription = QuickActions.addListener(action => {
+ if (!action?.id) {
+ return;
+ }
+ handleQuickAction(action.id);
+ });
+
+ appStateSubscription = AppState.addEventListener('change', async nextState => {
+ if (nextState === 'active') {
+ const nativeAction = await getRecentQuickAction();
+ if (nativeAction) {
+ InteractionManager.runAfterInteractions(() => {
+ handleQuickAction(nativeAction);
+ });
+ }
+ }
+ });
+}
+
+export function unregisterQuickActions() {
+ quickActionSubscription?.remove();
+ appStateSubscription?.remove();
+ quickActionSubscription = null;
+ registered = false;
+}
+
+function handleQuickAction(id: string) {
+ store.dispatch(
+ quickActionHandle({
+ action: id
+ })
+ );
+}
diff --git a/app/lib/store/index.ts b/app/lib/store/index.ts
index 3ae917484ac..cfbc18a12e1 100644
--- a/app/lib/store/index.ts
+++ b/app/lib/store/index.ts
@@ -27,6 +27,7 @@ if (__DEV__) {
}
const store = createStore(reducers, enhancers);
+export type AppDispatch = typeof store.dispatch;
sagaMiddleware.run(sagas);
export default store;
diff --git a/app/reducers/index.js b/app/reducers/index.js
index 4258685f94f..3653d31f0b1 100644
--- a/app/reducers/index.js
+++ b/app/reducers/index.js
@@ -26,6 +26,8 @@ import usersRoles from './usersRoles';
import troubleshootingNotification from './troubleshootingNotification';
import supportedVersions from './supportedVersions';
import inAppFeedback from './inAppFeedback';
+import quickActions from './quickActions';
+import ui from './ui';
export default combineReducers({
settings,
@@ -35,8 +37,10 @@ export default combineReducers({
selectedUsers,
createChannel,
app,
+ ui,
room,
rooms,
+ quickActions,
sortPreferences,
share,
customEmojis,
diff --git a/app/reducers/quickActions.ts b/app/reducers/quickActions.ts
new file mode 100644
index 00000000000..74a839fb02f
--- /dev/null
+++ b/app/reducers/quickActions.ts
@@ -0,0 +1,44 @@
+import { type Action } from 'redux';
+
+import { QUICK_ACTIONS } from '../actions/actionsTypes';
+
+interface IQuickActionsState {
+ lastAction: string | null;
+ handled: boolean;
+}
+
+export const initialState: IQuickActionsState = {
+ lastAction: null,
+ handled: false
+};
+
+interface IQuickActionPayloadAction extends Action {
+ payload: {
+ action: string;
+ };
+}
+
+type QuickActionsAction = IQuickActionPayloadAction | Action;
+
+export default function quickActions(state = initialState, action: QuickActionsAction): IQuickActionsState {
+ switch (action.type) {
+ case QUICK_ACTIONS.QUICK_ACTION_HANDLE:
+ if (!('payload' in action) || !action.payload?.action) {
+ return state;
+ }
+ return {
+ ...state,
+ lastAction: (action as IQuickActionPayloadAction).payload.action,
+ handled: false
+ };
+
+ case QUICK_ACTIONS.QUICK_ACTION_HANDLED:
+ return {
+ ...state,
+ handled: true
+ };
+
+ default:
+ return state;
+ }
+}
diff --git a/app/reducers/quickactions.test.ts b/app/reducers/quickactions.test.ts
new file mode 100644
index 00000000000..f004dcb3b42
--- /dev/null
+++ b/app/reducers/quickactions.test.ts
@@ -0,0 +1,67 @@
+import { mockedStore } from './mockedStore';
+import { initialState } from './quickActions';
+import { QUICK_ACTIONS } from '../actions/actionsTypes';
+
+describe('test quickActions reducer', () => {
+ it('should return initial state', () => {
+ const state = mockedStore.getState().quickActions;
+ expect(state).toEqual(initialState);
+ });
+
+ it('should set lastAction and handled=false on QUICK_ACTION_HANDLE', () => {
+ mockedStore.dispatch({
+ type: QUICK_ACTIONS.QUICK_ACTION_HANDLE,
+ payload: {
+ action: 'NEW_MESSAGE'
+ }
+ });
+
+ const state = mockedStore.getState().quickActions;
+
+ expect(state.lastAction).toEqual('NEW_MESSAGE');
+ expect(state.handled).toEqual(false);
+ });
+
+ it('should not modify state if QUICK_ACTION_HANDLE has no payload', () => {
+ const prevState = mockedStore.getState().quickActions;
+
+ mockedStore.dispatch({
+ type: QUICK_ACTIONS.QUICK_ACTION_HANDLE
+ });
+
+ const state = mockedStore.getState().quickActions;
+ expect(state).toEqual(prevState);
+ });
+
+ it('should not modify state if QUICK_ACTION_HANDLE payload has no action', () => {
+ const prevState = mockedStore.getState().quickActions;
+
+ mockedStore.dispatch({
+ type: QUICK_ACTIONS.QUICK_ACTION_HANDLE,
+ payload: {}
+ });
+
+ const state = mockedStore.getState().quickActions;
+ expect(state).toEqual(prevState);
+ });
+
+ it('should set handled=true on QUICK_ACTION_HANDLED', () => {
+ mockedStore.dispatch({
+ type: QUICK_ACTIONS.QUICK_ACTION_HANDLED
+ });
+
+ const state = mockedStore.getState().quickActions;
+ expect(state.handled).toEqual(true);
+ });
+
+ it('should return same state for unknown action', () => {
+ const prevState = mockedStore.getState().quickActions;
+
+ mockedStore.dispatch({
+ type: 'UNKNOWN_ACTION'
+ });
+
+ const state = mockedStore.getState().quickActions;
+ expect(state).toEqual(prevState);
+ });
+});
diff --git a/app/reducers/rooms.test.ts b/app/reducers/rooms.test.ts
index 1f84137c701..a1d0718adc8 100644
--- a/app/reducers/rooms.test.ts
+++ b/app/reducers/rooms.test.ts
@@ -1,4 +1,4 @@
-import { roomsFailure, roomsRefresh, roomsRequest, roomsSuccess } from '../actions/rooms';
+import { roomsFailure, roomsRefresh, roomsRequest, roomsStoreLastVisited, roomsSuccess } from '../actions/rooms';
import { mockedStore } from './mockedStore';
import { initialState } from './rooms';
@@ -34,4 +34,13 @@ describe('test selectedUsers reducer', () => {
const state = mockedStore.getState().rooms;
expect(state.errorMessage).toEqual('error');
});
+
+ it('should handle storeLastVisited', () => {
+ mockedStore.dispatch(roomsStoreLastVisited('room-id-123', 'general'));
+
+ const state = mockedStore.getState().rooms;
+
+ expect(state.lastVisitedRid).toEqual('room-id-123');
+ expect(state.lastVisitedName).toEqual('general');
+ });
});
diff --git a/app/reducers/rooms.ts b/app/reducers/rooms.ts
index de2ef250c35..17dcb8e23bf 100644
--- a/app/reducers/rooms.ts
+++ b/app/reducers/rooms.ts
@@ -1,18 +1,32 @@
import { type IRoomsAction } from '../actions/rooms';
import { ROOMS } from '../actions/actionsTypes';
+import UserPreferences from '../lib/methods/userPreferences';
+import { CURRENT_SERVER } from '../lib/constants/keys';
+
+export interface IRecentRoomsStore {
+ rid: string;
+ name: string;
+ server: string | null;
+}
export interface IRooms {
isFetching: boolean;
refreshing: boolean;
failure: boolean;
errorMessage: Record | string;
+ lastVisitedRid: string;
+ lastVisitedName: string;
+ recentRooms: IRecentRoomsStore[];
}
export const initialState: IRooms = {
isFetching: false,
refreshing: false,
failure: false,
- errorMessage: {}
+ errorMessage: {},
+ lastVisitedRid: '',
+ lastVisitedName: '',
+ recentRooms: []
};
export default function rooms(state = initialState, action: IRoomsAction): IRooms {
@@ -44,6 +58,41 @@ export default function rooms(state = initialState, action: IRoomsAction): IRoom
isFetching: true,
refreshing: true
};
+ case ROOMS.STORE_LAST_VISITED:
+ const server = UserPreferences.getString(CURRENT_SERVER);
+ const newRoom = { rid: action.lastVisitedRoomId, name: action.lastVisitedRoomName, server };
+
+ const existingIndex = state.recentRooms.findIndex(room => room.rid === newRoom.rid && room.server === newRoom.server);
+ let updatedRecentRooms: IRecentRoomsStore[];
+
+ if (existingIndex !== -1) {
+ // Move existing room to end
+ updatedRecentRooms = [
+ ...state.recentRooms.slice(0, existingIndex),
+ ...state.recentRooms.slice(existingIndex + 1),
+ newRoom
+ ];
+ } else {
+ // Add new room
+ updatedRecentRooms = [...state.recentRooms, newRoom];
+ }
+
+ if (updatedRecentRooms.length > 3) {
+ updatedRecentRooms = updatedRecentRooms.slice(-3);
+ }
+
+ return {
+ ...state,
+ lastVisitedRid: action.lastVisitedRoomId,
+ lastVisitedName: action.lastVisitedRoomName,
+ recentRooms: updatedRecentRooms
+ };
+ case ROOMS.STORE_RECENT_ROOMS:
+ return {
+ ...state,
+ recentRooms: action.recentRooms
+ };
+
default:
return state;
}
diff --git a/app/reducers/ui.ts b/app/reducers/ui.ts
new file mode 100644
index 00000000000..b305accfee7
--- /dev/null
+++ b/app/reducers/ui.ts
@@ -0,0 +1,28 @@
+import { type Action } from 'redux';
+
+import { UI } from '../actions/actionsTypes';
+
+export interface IUIState {
+ triggerSearch: boolean;
+}
+
+export const initialState: IUIState = {
+ triggerSearch: false
+};
+
+export default function ui(state = initialState, action: Action): IUIState {
+ switch (action.type) {
+ case UI.TRIGGER_SEARCH:
+ return {
+ ...state,
+ triggerSearch: true
+ };
+ case UI.CLEAR_TRIGGERED_SEARCH:
+ return {
+ ...state,
+ triggerSearch: false
+ };
+ default:
+ return state;
+ }
+}
diff --git a/app/sagas/index.js b/app/sagas/index.js
index b60cc211837..ebdbbe175ff 100644
--- a/app/sagas/index.js
+++ b/app/sagas/index.js
@@ -15,10 +15,14 @@ import createDiscussion from './createDiscussion';
import encryption from './encryption';
import videoConf from './videoConf';
import troubleshootingNotification from './troubleshootingNotification';
+import quickActions from './quickActions';
+import roomVisited from './roomVisited';
const root = function* root() {
yield all([
init(),
+ quickActions(),
+ roomVisited(),
createChannel(),
rooms(),
room(),
diff --git a/app/sagas/init.js b/app/sagas/init.js
index d9d6024abe8..8f587531355 100644
--- a/app/sagas/init.js
+++ b/app/sagas/init.js
@@ -2,7 +2,13 @@ import { call, put, select, takeLatest } from 'redux-saga/effects';
import RNBootSplash from 'react-native-bootsplash';
import AsyncStorage from '@react-native-async-storage/async-storage';
-import { CURRENT_SERVER, TOKEN_KEY } from '../lib/constants/keys';
+import {
+ CURRENT_SERVER,
+ LAST_VISITED_ROOM_ID_KEY,
+ LAST_VISITED_ROOM_NAME_KEY,
+ RECENT_VISITED_ROOMS_KEY,
+ TOKEN_KEY
+} from '../lib/constants/keys';
import UserPreferences from '../lib/methods/userPreferences';
import { selectServerRequest } from '../actions/server';
import { setAllPreferences } from '../actions/sortPreferences';
@@ -15,6 +21,7 @@ import { RootEnum } from '../definitions';
import { getSortPreferences } from '../lib/methods/userPreferencesMethods';
import { deepLinkingClickCallPush } from '../actions/deepLinking';
import { getServerById } from '../lib/database/services/Server';
+import { roomsStoreLastVisited, roomsStoreRecentRooms } from '../actions/rooms';
export const initLocalSettings = function* initLocalSettings() {
const sortPreferences = getSortPreferences();
@@ -51,6 +58,17 @@ const restore = function* restore() {
return;
}
yield put(selectServerRequest(server, serverRecord.version));
+ const lastVisitedRid = UserPreferences.getString(LAST_VISITED_ROOM_ID_KEY);
+ const lastVisitedRoomName = UserPreferences.getString(LAST_VISITED_ROOM_NAME_KEY);
+ const recentRooms = JSON.parse(UserPreferences.getString(RECENT_VISITED_ROOMS_KEY));
+
+ if (recentRooms) {
+ yield put(roomsStoreRecentRooms(recentRooms));
+ }
+
+ if (lastVisitedRid && lastVisitedRoomName) {
+ yield put(roomsStoreLastVisited(lastVisitedRid, lastVisitedRoomName));
+ }
}
yield put(appReady({}));
diff --git a/app/sagas/quickActions.ts b/app/sagas/quickActions.ts
new file mode 100644
index 00000000000..91955aa08a8
--- /dev/null
+++ b/app/sagas/quickActions.ts
@@ -0,0 +1,142 @@
+import { select, takeEvery, put, take, type Effect, call, race, delay } from 'redux-saga/effects';
+import { Alert } from 'react-native';
+import { type Action } from 'redux';
+
+import { QUICK_ACTIONS, APP, UI, NAVIGATION } from '../actions/actionsTypes';
+import { appStart, appInit } from '../actions/app';
+import { selectServerRequest, serverInitAdd } from '../actions/server';
+import { type IApplicationState, RootEnum, type TServerModel, type TSubscriptionModel } from '../definitions';
+import UserPreferences from '../lib/methods/userPreferences';
+import { CURRENT_SERVER } from '../lib/constants/keys';
+import Navigation from '../lib/navigation/appNavigation';
+import { sendEmail } from '../views/SettingsView';
+import { goRoom } from '../lib/methods/helpers/goRoom';
+import { getRoom } from '../lib/methods/getRoom';
+import I18n from '../i18n';
+import { getServerById } from '../lib/database/services/Server';
+
+interface IQuickActionOpen extends Action {
+ params?: {
+ action?: string;
+ };
+ payload?: {
+ action?: string;
+ };
+}
+
+function* waitForAppReady(): Generator {
+ const isReady: boolean = yield select((state: IApplicationState) => state.app.ready);
+
+ if (!isReady) {
+ yield put(appInit());
+ yield take(APP.READY);
+ }
+}
+
+function* waitForRoomInDB(rid: string): Generator {
+ try {
+ const room = (yield call(getRoom, rid)) as TSubscriptionModel;
+ return room;
+ } catch {
+ // Wait for APP.START OR timeout
+ const { timeout } = (yield race({
+ started: take(APP.START),
+ timeout: delay(3000)
+ })) as { started?: unknown; timeout?: true };
+
+ if (timeout) {
+ throw new Error('Timed out waiting for APP.START');
+ }
+ }
+
+ return yield call(getRoom, rid);
+}
+
+function* waitForNavigationReady(): Generator {
+ if (Navigation.navigationRef.current) {
+ return;
+ }
+
+ yield take(NAVIGATION.NAVIGATION_READY);
+}
+
+function* switchServer(targetServer: string): Generator {
+ const server = (yield call(getServerById, targetServer)) as TServerModel;
+ yield put(selectServerRequest(server._raw.id, server.version, true, true));
+}
+
+function* handleQuickActionOpen(action: IQuickActionOpen): Generator {
+ const quickActionFromParams = action.params?.action ?? action.payload?.action;
+
+ if (!quickActionFromParams) {
+ return;
+ }
+
+ const actionWithId = quickActionFromParams.split('/');
+
+ const quickAction = actionWithId[0];
+
+ switch (quickAction) {
+ case 'add-server': {
+ const server = UserPreferences.getString(CURRENT_SERVER);
+
+ yield put(appStart({ root: RootEnum.ROOT_OUTSIDE }));
+ yield put(serverInitAdd(server || ''));
+ break;
+ }
+ case 'search': {
+ yield waitForAppReady();
+ const currentRoute = Navigation.getCurrentRoute();
+
+ if (currentRoute?.name !== 'RoomsListView') {
+ Navigation.navigate('RoomsListView');
+ }
+ yield put({ type: UI.TRIGGER_SEARCH });
+ break;
+ }
+ case 'contact': {
+ yield call(sendEmail);
+ yield waitForAppReady(); // if user navigates back to app just init it
+ break;
+ }
+ case 'recent': {
+ yield waitForAppReady();
+
+ const targetServer = decodeURIComponent(actionWithId[1]);
+ const currentServer: string = yield select((state: IApplicationState) => state.server.server);
+
+ const rid = actionWithId[2];
+
+ if (!rid) {
+ showRoomNotFoundError();
+ break;
+ }
+
+ if (currentServer !== targetServer) {
+ yield call(switchServer, targetServer);
+ }
+
+ try {
+ const room = (yield call(waitForRoomInDB, rid)) as TSubscriptionModel;
+ yield waitForNavigationReady();
+ const isMasterDetail = yield select((state: IApplicationState) => state.app.isMasterDetail);
+ yield call(goRoom, { item: { rid: room.rid }, isMasterDetail });
+ } catch (e) {
+ console.log(e);
+ showRoomNotFoundError();
+ }
+
+ break;
+ }
+ }
+
+ yield put({ type: QUICK_ACTIONS.QUICK_ACTION_HANDLED });
+}
+
+const showRoomNotFoundError = () => {
+ Alert.alert(I18n.t('Room_not_found'), I18n.t('Error_finding_room'));
+};
+
+export default function* root(): Generator {
+ yield takeEvery(QUICK_ACTIONS.QUICK_ACTION_HANDLE, handleQuickActionOpen);
+}
diff --git a/app/sagas/roomVisited.ts b/app/sagas/roomVisited.ts
new file mode 100644
index 00000000000..fcb772c3da7
--- /dev/null
+++ b/app/sagas/roomVisited.ts
@@ -0,0 +1,43 @@
+import { eventChannel } from 'redux-saga';
+import { call, put, take, fork, select } from 'redux-saga/effects';
+import type { SagaIterator } from 'redux-saga';
+
+import { emitter } from '../lib/methods/helpers';
+import { roomsStoreLastVisited } from '../actions/rooms';
+import UserPreferences from '../lib/methods/userPreferences';
+import { LAST_VISITED_ROOM_ID_KEY, LAST_VISITED_ROOM_NAME_KEY, RECENT_VISITED_ROOMS_KEY } from '../lib/constants/keys';
+import { type IApplicationState } from '../definitions';
+import { type IRooms } from '../reducers/rooms';
+
+const getRecentRooms = (state: IApplicationState) => state.rooms.recentRooms;
+
+function createRoomVisitedChannel() {
+ return eventChannel<{ rid: string; name: string }>(emit => {
+ const handler = ({ rid, name }: { rid: string; name: string }) => {
+ emit({ rid, name });
+ };
+
+ emitter.on('roomVisited', handler);
+ return () => emitter.off('roomVisited', handler);
+ });
+}
+
+function* watchRoomVisited(): SagaIterator {
+ const channel = yield call(createRoomVisitedChannel);
+
+ while (true) {
+ const { rid, name } = yield take(channel);
+ yield put(roomsStoreLastVisited(rid, name));
+
+ const recentRooms: IRooms['recentRooms'] = yield select(getRecentRooms);
+
+ UserPreferences.setString(RECENT_VISITED_ROOMS_KEY, JSON.stringify(recentRooms));
+
+ UserPreferences.setString(LAST_VISITED_ROOM_ID_KEY, rid);
+ UserPreferences.setString(LAST_VISITED_ROOM_NAME_KEY, name);
+ }
+}
+
+export default function* roomVisited(): SagaIterator {
+ yield fork(watchRoomVisited);
+}
diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js
index 39058a03228..174325121f7 100644
--- a/app/sagas/rooms.js
+++ b/app/sagas/rooms.js
@@ -18,7 +18,7 @@ const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) {
const serverRecord = yield serversCollection.find(server);
return serversDB.write(async () => {
- await serverRecord.update((record) => {
+ await serverRecord.update(record => {
record.roomsUpdatedAt = newRoomsUpdatedAt;
});
});
@@ -75,12 +75,12 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
const allRecords = [
...subsToCreate.map(subscription =>
- subCollection.prepareCreate((s) => {
+ subCollection.prepareCreate(s => {
s._raw = sanitizedRaw({ id: subscription.rid }, subCollection.schema);
return Object.assign(s, subscription);
})
),
- ...subsToUpdate.map((subscription) => {
+ ...subsToUpdate.map(subscription => {
try {
const newSub = subscriptions.find(s => s._id === subscription._id);
if (!newSub) {
@@ -99,7 +99,7 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
return null;
}
}),
- ...subsToDelete.map((subscription) => {
+ ...subsToDelete.map(subscription => {
try {
return subscription.prepareDestroyPermanently();
} catch (e) {
@@ -108,13 +108,13 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
}
}),
...messagesToCreate.map(message =>
- messagesCollection.prepareCreate((m) => {
+ messagesCollection.prepareCreate(m => {
m._raw = sanitizedRaw({ id: message._id }, messagesCollection.schema);
m.subscription.id = message.rid;
return Object.assign(m, message);
})
),
- ...messagesToUpdate.map((message) => {
+ ...messagesToUpdate.map(message => {
const newMessage = lastMessages.find(m => m._id === message.id);
return message.prepareUpdate(() => {
try {
diff --git a/app/views/RoomsListView/hooks/useSearch.ts b/app/views/RoomsListView/hooks/useSearch.ts
index 97c7a0d2a12..5f239121ada 100644
--- a/app/views/RoomsListView/hooks/useSearch.ts
+++ b/app/views/RoomsListView/hooks/useSearch.ts
@@ -1,10 +1,13 @@
-import { useCallback, useReducer } from 'react';
+import { useCallback, useEffect, useReducer } from 'react';
import { AccessibilityInfo } from 'react-native';
+import { useDispatch } from 'react-redux';
import { type IRoomItem } from '../../../containers/RoomItem/interfaces';
import { search as searchLib } from '../../../lib/methods/search';
import { useDebounce } from '../../../lib/methods/helpers/debounce';
import i18n from '../../../i18n';
+import { useAppSelector } from '../../../lib/hooks/useAppSelector';
+import { UI } from '../../../actions/actionsTypes';
interface SearchState {
searchEnabled: boolean;
@@ -59,7 +62,8 @@ export const useSearch = () => {
'use memo';
const [state, dispatch] = useReducer(searchReducer, initialState);
-
+ const triggerSearch = useAppSelector(state => state.ui?.triggerSearch);
+ const storeDispatch = useDispatch();
const announceSearchResultsForAccessibility = (count: number) => {
if (count < 1) {
AccessibilityInfo.announceForAccessibility(i18n.t('No_results_found'));
@@ -87,6 +91,13 @@ export const useSearch = () => {
dispatch({ type: 'STOP_SEARCH' });
}, []);
+ useEffect(() => {
+ if (triggerSearch) {
+ startSearch();
+ storeDispatch({ type: UI.CLEAR_TRIGGERED_SEARCH });
+ }
+ }, [startSearch, storeDispatch, triggerSearch]);
+
return {
searching: state.searching,
searchEnabled: state.searchEnabled,
diff --git a/app/views/SettingsView/index.tsx b/app/views/SettingsView/index.tsx
index 169f7d6da02..5abc1b957a7 100644
--- a/app/views/SettingsView/index.tsx
+++ b/app/views/SettingsView/index.tsx
@@ -33,6 +33,22 @@ import SidebarView from '../SidebarView';
type TLogScreenName = 'SE_GO_LANGUAGE' | 'SE_GO_DEFAULTBROWSER' | 'SE_GO_THEME' | 'SE_GO_PROFILE' | 'SE_GO_SECURITYPRIVACY';
+export const sendEmail = async () => {
+ logEvent(events.SE_CONTACT_US);
+ const subject = encodeURI('Rocket.Chat Mobile App Support');
+ const email = encodeURI('support@rocket.chat');
+ const description = encodeURI(`
+ version: ${getReadableVersion}
+ device: ${getDeviceModel}
+ `);
+ try {
+ await Linking.openURL(`mailto:${email}?subject=${subject}&body=${description}`);
+ } catch (e) {
+ logEvent(events.SE_CONTACT_US_F);
+ showErrorAlert(I18n.t('error-email-send-failed', { message: 'support@rocket.chat' }));
+ }
+};
+
const SettingsView = (): React.ReactElement => {
'use memo';
@@ -86,22 +102,6 @@ const SettingsView = (): React.ReactElement => {
navigation.navigate(screen);
};
- const sendEmail = async () => {
- logEvent(events.SE_CONTACT_US);
- const subject = encodeURI('Rocket.Chat Mobile App Support');
- const email = encodeURI('support@rocket.chat');
- const description = encodeURI(`
- version: ${getReadableVersion}
- device: ${getDeviceModel}
- `);
- try {
- await Linking.openURL(`mailto:${email}?subject=${subject}&body=${description}`);
- } catch (e) {
- logEvent(events.SE_CONTACT_US_F);
- showErrorAlert(I18n.t('error-email-send-failed', { message: 'support@rocket.chat' }));
- }
- };
-
const shareApp = () => {
let message;
if (isAndroid) {
diff --git a/ios/AppDelegate.swift b/ios/AppDelegate.swift
index b0aa0e2851f..c683dcdbb4f 100644
--- a/ios/AppDelegate.swift
+++ b/ios/AppDelegate.swift
@@ -4,6 +4,7 @@ import ReactAppDependencyProvider
import Firebase
import Bugsnag
import WatchConnectivity
+import Foundation
@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
@@ -42,6 +43,15 @@ public class AppDelegate: ExpoAppDelegate {
launchOptions: launchOptions)
#endif
+ if let shortcutItem =
+ launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
+
+ RCSetPendingQuickActionType(shortcutItem.type)
+
+ // Return false so iOS does NOT call performActionFor again
+ return false
+ }
+
let result = super.application(application, didFinishLaunchingWithOptions: launchOptions)
// Initialize boot splash
@@ -76,6 +86,15 @@ public class AppDelegate: ExpoAppDelegate {
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
}
+
+ public override func application(
+ _ application: UIApplication,
+ performActionFor shortcutItem: UIApplicationShortcutItem,
+ completionHandler: @escaping (Bool) -> Void
+ ) {
+ RCSetPendingQuickActionType(shortcutItem.type)
+ completionHandler(true)
+ }
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
diff --git a/ios/Podfile b/ios/Podfile
index 4d852a82cd3..61ffa429e1d 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -9,6 +9,7 @@ prepare_react_native_project!
def all_pods
pod 'simdjson', path: '../node_modules/@nozbe/simdjson', modular_headers: true
pod 'react-native-mmkv', path: '../node_modules/react-native-mmkv', modular_headers: true
+ pod 'ExpoQuickActions', path: '../node_modules/expo-quick-actions/ios'
$RNFirebaseAnalyticsWithoutAdIdSupport = true
use_expo_modules!
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 99a6053f60c..c94a12a53a7 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -117,6 +117,8 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
+ - ExpoQuickActions (5.0.0):
+ - ExpoModulesCore
- ExpoSystemUI (5.0.7):
- ExpoModulesCore
- ExpoVideoThumbnails (9.1.2):
@@ -2652,6 +2654,7 @@ DEPENDENCIES:
- ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- ExpoLocalAuthentication (from `../node_modules/expo-local-authentication/ios`)
- ExpoModulesCore (from `../node_modules/expo-modules-core`)
+ - ExpoQuickActions (from `../node_modules/expo-quick-actions/ios`)
- ExpoSystemUI (from `../node_modules/expo-system-ui/ios`)
- ExpoVideoThumbnails (from `../node_modules/expo-video-thumbnails/ios`)
- ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`)
@@ -2829,6 +2832,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-local-authentication/ios"
ExpoModulesCore:
:path: "../node_modules/expo-modules-core"
+ ExpoQuickActions:
+ :path: "../node_modules/expo-quick-actions/ios"
ExpoSystemUI:
:path: "../node_modules/expo-system-ui/ios"
ExpoVideoThumbnails:
@@ -3059,6 +3064,7 @@ SPEC CHECKSUMS:
ExpoKeepAwake: 213acedecafb6fda8c0ffedad22ee9e2903400c5
ExpoLocalAuthentication: f69863a1822e42db67a311ce839ecbac70e7fa65
ExpoModulesCore: b4fdeaceca6a4360d4a75fbae335907427c1df6b
+ ExpoQuickActions: fdbda7f5874aed3dd2b1d891ec00ab3300dc7541
ExpoSystemUI: 82c970cf8495449698e7343b4f78a0d04bcec9ee
ExpoVideoThumbnails: 2a448a23eb4eeb860d92ded372fec6e6a7a0cdcb
ExpoWebBrowser: d81a92137919312afc5628d47951dc7a35554f90
@@ -3185,9 +3191,9 @@ SPEC CHECKSUMS:
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
WatermelonDB: 4c846c8cb94eef3cba90fa034d15310163226703
- Yoga: dfabf1234ccd5ac41d1b1d43179f024366ae9831
+ Yoga: 2a3a4c38a8441b6359d5e5914d35db7b2b67aebd
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
-PODFILE CHECKSUM: 199f6fbbe6fb415c822cca992e6152000ac55b3e
+PODFILE CHECKSUM: dd876c3ef913a49cdfbdb46236ad1b6a54b56724
COCOAPODS: 1.15.2
diff --git a/ios/QuickActionsConnector.h b/ios/QuickActionsConnector.h
new file mode 100644
index 00000000000..9f6bc2446ad
--- /dev/null
+++ b/ios/QuickActionsConnector.h
@@ -0,0 +1,4 @@
+#import
+
+@interface QuickActionsConnector : NSObject
+@end
diff --git a/ios/QuickActionsConnector.mm b/ios/QuickActionsConnector.mm
new file mode 100644
index 00000000000..085aff3f34a
--- /dev/null
+++ b/ios/QuickActionsConnector.mm
@@ -0,0 +1,17 @@
+#import "QuickActionsConnector.h"
+#import "QuickActionsStore.h"
+
+@implementation QuickActionsConnector
+
+RCT_EXPORT_MODULE();
+
+RCT_EXPORT_METHOD(
+ getInitialQuickAction:
+ (RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject
+) {
+ NSString *action = RCConsumePendingQuickActionType();
+ resolve(action);
+}
+
+@end
diff --git a/ios/QuickActionsStore.h b/ios/QuickActionsStore.h
new file mode 100644
index 00000000000..34764e99c73
--- /dev/null
+++ b/ios/QuickActionsStore.h
@@ -0,0 +1,8 @@
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+FOUNDATION_EXPORT void RCSetPendingQuickActionType(NSString * _Nullable type);
+FOUNDATION_EXPORT NSString * _Nullable RCConsumePendingQuickActionType(void);
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/QuickActionsStore.mm b/ios/QuickActionsStore.mm
new file mode 100644
index 00000000000..c3183db1858
--- /dev/null
+++ b/ios/QuickActionsStore.mm
@@ -0,0 +1,27 @@
+#import "QuickActionsStore.h"
+
+static NSString * _Nullable RCPendingQuickActionType = nil;
+static dispatch_queue_t rcQuickActionQueue;
+
+__attribute__((constructor))
+static void RCInitQuickActionQueue(void) {
+ rcQuickActionQueue = dispatch_queue_create(
+ "chat.rocket.quickactions.queue",
+ DISPATCH_QUEUE_SERIAL
+ );
+}
+
+void RCSetPendingQuickActionType(NSString * _Nullable type) {
+ dispatch_sync(rcQuickActionQueue, ^{
+ RCPendingQuickActionType = type;
+ });
+}
+
+NSString * _Nullable RCConsumePendingQuickActionType(void) {
+ __block NSString *type = nil;
+ dispatch_sync(rcQuickActionQueue, ^{
+ type = RCPendingQuickActionType;
+ RCPendingQuickActionType = nil;
+ });
+ return type;
+}
diff --git a/ios/RocketChatRN-Bridging-Header.h b/ios/RocketChatRN-Bridging-Header.h
index 40e9146f471..20a4b23ff93 100644
--- a/ios/RocketChatRN-Bridging-Header.h
+++ b/ios/RocketChatRN-Bridging-Header.h
@@ -10,3 +10,4 @@
#import
#import
#import
+#import "QuickActionsStore.h"
diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj
index 29cc9563241..a0b2806e2a1 100644
--- a/ios/RocketChatRN.xcodeproj/project.pbxproj
+++ b/ios/RocketChatRN.xcodeproj/project.pbxproj
@@ -7,10 +7,13 @@
objects = {
/* Begin PBXBuildFile section */
- 020BAAEF21339D1538B55D15 /* Pods_defaults_NotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537F37501C643FE86F92916E /* Pods_defaults_NotificationService.framework */; };
- 05F9D701BF644C25192B8E79 /* Pods_defaults_RocketChatRN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A46AABC73B7E9703E69AF850 /* Pods_defaults_RocketChatRN.framework */; };
+ 059517F8FF85756835127879 /* Pods_defaults_Rocket_Chat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BABABB66676C60622674D15E /* Pods_defaults_Rocket_Chat.framework */; };
0C6E2DE448364EA896869ADF /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B37C79D9BD0742CE936B6982 /* libc++.tbd */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
+ 167D56822F104B7D00880439 /* QuickActionsConnector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 167D56812F104B7D00880439 /* QuickActionsConnector.mm */; };
+ 167D56832F104B7D00880439 /* QuickActionsConnector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 167D56812F104B7D00880439 /* QuickActionsConnector.mm */; };
+ 16A6D54E2F0D95FC000FCD09 /* QuickActionsStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16A6D54D2F0D95FC000FCD09 /* QuickActionsStore.mm */; };
+ 16A6D54F2F0D95FC000FCD09 /* QuickActionsStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16A6D54D2F0D95FC000FCD09 /* QuickActionsStore.mm */; };
1E01C81C2511208400FEF824 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E01C81B2511208400FEF824 /* URL+Extensions.swift */; };
1E01C8212511301400FEF824 /* PushResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E01C8202511301400FEF824 /* PushResponse.swift */; };
1E01C8252511303100FEF824 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E01C8242511303100FEF824 /* Notification.swift */; };
@@ -364,9 +367,10 @@
A2C6E2DD38F8BEE19BFB2E1D /* SecureStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B215A42CFB843397273C7EA /* SecureStorage.m */; };
A48B46D92D3FFBD200945489 /* A11yFlowModule.m in Sources */ = {isa = PBXBuildFile; fileRef = A48B46D82D3FFBD200945489 /* A11yFlowModule.m */; };
A48B46DA2D3FFBD200945489 /* A11yFlowModule.m in Sources */ = {isa = PBXBuildFile; fileRef = A48B46D82D3FFBD200945489 /* A11yFlowModule.m */; };
- ACCF5C382F186B5D43B2C952 /* Pods_defaults_Rocket_Chat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85094D3182EA9331CC444733 /* Pods_defaults_Rocket_Chat.framework */; };
+ AFE1A0329E79D5FDE4B09ECF /* Pods_defaults_RocketChatRN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C409D947C9DBB25E0204FD /* Pods_defaults_RocketChatRN.framework */; };
BC404914E86821389EEB543D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 391C4F7AA7023CD41EEBD106 /* ExpoModulesProvider.swift */; };
DD2BA30A89E64F189C2C24AC /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA7E862283664608B3894E34 /* libWatermelonDB.a */; };
+ FF53AD18205526A976C47AA5 /* Pods_defaults_NotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A10597851D3193C3E990372A /* Pods_defaults_NotificationService.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -465,10 +469,15 @@
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; };
+ 0547DC0CF78D9F082A8B0BB5 /* 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 = ""; };
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; };
13B07F961A680F5B00A75B9A /* Rocket.Chat Experimental.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Rocket.Chat Experimental.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RocketChatRN/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RocketChatRN/Info.plist; sourceTree = ""; };
+ 167D56812F104B7D00880439 /* QuickActionsConnector.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickActionsConnector.mm; sourceTree = ""; };
+ 16A6D54C2F0D95E3000FCD09 /* QuickActionsStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QuickActionsStore.h; sourceTree = ""; };
+ 16A6D54D2F0D95FC000FCD09 /* QuickActionsStore.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickActionsStore.mm; sourceTree = ""; };
+ 16A6D5502F0D9674000FCD09 /* QuickActionsConnector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QuickActionsConnector.h; sourceTree = ""; };
194D9A8897F4A486C2C6F89A /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-defaults-NotificationService/ExpoModulesProvider.swift"; sourceTree = ""; };
1E01C81B2511208400FEF824 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = ""; };
1E01C8202511301400FEF824 /* PushResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushResponse.swift; sourceTree = ""; };
@@ -612,11 +621,10 @@
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 = ""; };
+ 25B6129FD3765EC5B5D0F3F3 /* 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 = ""; };
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 = ""; };
- 44A0BDC6158008BF9FF04F0A /* 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 = ""; };
+ 42C409D947C9DBB25E0204FD /* Pods_defaults_RocketChatRN.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_RocketChatRN.framework; sourceTree = BUILT_PRODUCTS_DIR; };
45D5C142B655F8EFD006792C /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-defaults-RocketChatRN/ExpoModulesProvider.swift"; sourceTree = ""; };
- 482E711ACFA5E2C4281835BF /* 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 = ""; };
- 537F37501C643FE86F92916E /* Pods_defaults_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_NotificationService.framework; 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 = ""; };
@@ -624,7 +632,7 @@
66C2701A2EBBCB570062725F /* MMKVKeyManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMKVKeyManager.mm; sourceTree = ""; };
66C2701E2EBBCB780062725F /* SecureStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecureStorage.h; sourceTree = ""; };
66C2701F2EBBCB780062725F /* SecureStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecureStorage.m; sourceTree = ""; };
- 6CE8C7A54627937DB698E839 /* 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 = ""; };
+ 6B6D45FCB4C3A2DAC625E0C5 /* 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 = ""; };
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 = ""; };
@@ -640,18 +648,18 @@
7ACD4853222860DE00442C55 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
7ACFE7D82DDE48760090D9BC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7AE10C0528A59530003593CB /* Inter.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Inter.ttf; sourceTree = ""; };
- 85094D3182EA9331CC444733 /* Pods_defaults_Rocket_Chat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_Rocket_Chat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 92B416D2ADF070E0E0C782A0 /* 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 = ""; };
9B215A42CFB843397273C7EA /* SecureStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = SecureStorage.m; sourceTree = ""; };
9B215A44CFB843397273C7EC /* MMKVBridge.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MMKVBridge.mm; path = Shared/RocketChat/MMKVBridge.mm; sourceTree = ""; };
- A46AABC73B7E9703E69AF850 /* Pods_defaults_RocketChatRN.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_RocketChatRN.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A10597851D3193C3E990372A /* Pods_defaults_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_NotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A48B46D72D3FFBD200945489 /* A11yFlowModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = A11yFlowModule.h; sourceTree = ""; };
A48B46D82D3FFBD200945489 /* A11yFlowModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = A11yFlowModule.m; sourceTree = ""; };
+ A775A4A535C3A4DF9E009CB5 /* 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 = ""; };
B179038FDD7AAF285047814B /* SecureStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = SecureStorage.h; sourceTree = ""; };
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 = ""; };
- CD1F8BBE6FE382D33AB37935 /* 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 = ""; };
- F6BFACDCE2AB06F4936B3E03 /* 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 = ""; };
+ BABABB66676C60622674D15E /* Pods_defaults_Rocket_Chat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_defaults_Rocket_Chat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ D37FD1CB4DF877266A49B72B /* 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 = ""; };
+ D97BDAB3F63F70EF45D2FD6B /* 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 = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -672,7 +680,7 @@
7ACD4897222860DE00442C55 /* JavaScriptCore.framework in Frameworks */,
24A2AEF2383D44B586D31C01 /* libz.tbd in Frameworks */,
DD2BA30A89E64F189C2C24AC /* libWatermelonDB.a in Frameworks */,
- 05F9D701BF644C25192B8E79 /* Pods_defaults_RocketChatRN.framework in Frameworks */,
+ AFE1A0329E79D5FDE4B09ECF /* Pods_defaults_RocketChatRN.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -694,7 +702,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 020BAAEF21339D1538B55D15 /* Pods_defaults_NotificationService.framework in Frameworks */,
+ FF53AD18205526A976C47AA5 /* Pods_defaults_NotificationService.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -715,7 +723,7 @@
7AAB3E3D257E6A6E00707CF6 /* JavaScriptCore.framework in Frameworks */,
7AAB3E3E257E6A6E00707CF6 /* libz.tbd in Frameworks */,
7AAB3E3F257E6A6E00707CF6 /* libWatermelonDB.a in Frameworks */,
- ACCF5C382F186B5D43B2C952 /* Pods_defaults_Rocket_Chat.framework in Frameworks */,
+ 059517F8FF85756835127879 /* Pods_defaults_Rocket_Chat.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -728,6 +736,9 @@
66C2701E2EBBCB780062725F /* SecureStorage.h */,
66C2701F2EBBCB780062725F /* SecureStorage.m */,
7ACFE7D82DDE48760090D9BC /* AppDelegate.swift */,
+ 16A6D54C2F0D95E3000FCD09 /* QuickActionsStore.h */,
+ 16A6D54D2F0D95FC000FCD09 /* QuickActionsStore.mm */,
+ 16A6D5502F0D9674000FCD09 /* QuickActionsConnector.h */,
A48B46D72D3FFBD200945489 /* A11yFlowModule.h */,
A48B46D82D3FFBD200945489 /* A11yFlowModule.m */,
7A8B30742BCD9D3F00146A40 /* SSLPinning.h */,
@@ -746,6 +757,7 @@
65AD38362BFBDF4A00271B39 /* PrivacyInfo.xcprivacy */,
66C270192EBBCB570062725F /* MMKVKeyManager.h */,
66C2701A2EBBCB570062725F /* MMKVKeyManager.mm */,
+ 167D56812F104B7D00880439 /* QuickActionsConnector.mm */,
);
name = RocketChatRN;
sourceTree = "";
@@ -1143,12 +1155,12 @@
7AC2B09613AA7C3FEBAC9F57 /* Pods */ = {
isa = PBXGroup;
children = (
- 6CE8C7A54627937DB698E839 /* Pods-defaults-NotificationService.debug.xcconfig */,
- 44A0BDC6158008BF9FF04F0A /* Pods-defaults-NotificationService.release.xcconfig */,
- 92B416D2ADF070E0E0C782A0 /* Pods-defaults-Rocket.Chat.debug.xcconfig */,
- CD1F8BBE6FE382D33AB37935 /* Pods-defaults-Rocket.Chat.release.xcconfig */,
- 482E711ACFA5E2C4281835BF /* Pods-defaults-RocketChatRN.debug.xcconfig */,
- F6BFACDCE2AB06F4936B3E03 /* Pods-defaults-RocketChatRN.release.xcconfig */,
+ A775A4A535C3A4DF9E009CB5 /* Pods-defaults-NotificationService.debug.xcconfig */,
+ D97BDAB3F63F70EF45D2FD6B /* Pods-defaults-NotificationService.release.xcconfig */,
+ 0547DC0CF78D9F082A8B0BB5 /* Pods-defaults-Rocket.Chat.debug.xcconfig */,
+ 6B6D45FCB4C3A2DAC625E0C5 /* Pods-defaults-Rocket.Chat.release.xcconfig */,
+ 25B6129FD3765EC5B5D0F3F3 /* Pods-defaults-RocketChatRN.debug.xcconfig */,
+ D37FD1CB4DF877266A49B72B /* Pods-defaults-RocketChatRN.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -1247,9 +1259,9 @@
7ACD4853222860DE00442C55 /* JavaScriptCore.framework */,
B37C79D9BD0742CE936B6982 /* libc++.tbd */,
06BB44DD4855498082A744AD /* libz.tbd */,
- 537F37501C643FE86F92916E /* Pods_defaults_NotificationService.framework */,
- 85094D3182EA9331CC444733 /* Pods_defaults_Rocket_Chat.framework */,
- A46AABC73B7E9703E69AF850 /* Pods_defaults_RocketChatRN.framework */,
+ A10597851D3193C3E990372A /* Pods_defaults_NotificationService.framework */,
+ BABABB66676C60622674D15E /* Pods_defaults_Rocket_Chat.framework */,
+ 42C409D947C9DBB25E0204FD /* Pods_defaults_RocketChatRN.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -1269,8 +1281,8 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RocketChatRN" */;
buildPhases = (
- 8A4915EBB9B9EA919C35752B /* [CP] Check Pods Manifest.lock */,
- 06C10D4F29CD7532492AD29E /* [Expo] Configure project */,
+ D17D219AF77F48D35A0D7171 /* [CP] Check Pods Manifest.lock */,
+ 589729E8381BA997CD19EF19 /* [Expo] Configure project */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -1279,8 +1291,10 @@
1E1EA8082326CCE300E22452 /* ShellScript */,
1ED0389C2B507B4F00C007D4 /* Embed Watch Content */,
7AAE9EB32891A0D20024F559 /* Upload source maps to Bugsnag */,
- BCA373A96A91C30B09231381 /* [CP] Embed Pods Frameworks */,
- E57DE3ACCEF8E313DFF4D411 /* [CP] Copy Pods Resources */,
+ 407D3EDE3DABEE15D27BD87D /* ShellScript */,
+ 9C104B12BEE385F7555E641F /* [Expo] Configure project */,
+ 4CCE5B7235CA003F286BD050 /* [CP] Embed Pods Frameworks */,
+ 69520DF942793F987B1AA05B /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1348,12 +1362,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 1EFEB5A02493B6640072EDC0 /* Build configuration list for PBXNativeTarget "NotificationService" */;
buildPhases = (
- 664B079CA244E1ABB144A1C9 /* [CP] Check Pods Manifest.lock */,
+ 23A5F6CB83957B93A7EA1C97 /* [CP] Check Pods Manifest.lock */,
86A998705576AFA7CE938617 /* [Expo] Configure project */,
1EFEB5912493B6640072EDC0 /* Sources */,
1EFEB5922493B6640072EDC0 /* Frameworks */,
1EFEB5932493B6640072EDC0 /* Resources */,
- 6BC31F4F1CF6E74A7683D2D4 /* [CP] Copy Pods Resources */,
+ B4801301A00C50FA3AD72CF9 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1368,18 +1382,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 7AAB3E4F257E6A6E00707CF6 /* Build configuration list for PBXNativeTarget "Rocket.Chat" */;
buildPhases = (
- 7E2F5D729E377A4A5D1E96B4 /* [CP] Check Pods Manifest.lock */,
- 6319FBDD06EF0030B48AD389 /* [Expo] Configure project */,
+ AEF2010F70C9B50729A6B50C /* [CP] Check Pods Manifest.lock */,
+ 84028E94C77DEBDD5200728D /* [Expo] Configure project */,
7AAB3E14257E6A6E00707CF6 /* Sources */,
7AAB3E32257E6A6E00707CF6 /* Frameworks */,
7AAB3E41257E6A6E00707CF6 /* Resources */,
- 7A55BE3B2F11316900D8744D /* Bundle React Native code and images */,
7AAB3E48257E6A6E00707CF6 /* Embed App Extensions */,
- 7A55BE3C2F1131C000D8744D /* ShellScript */,
1ED1ECE32B8699DD00F6620C /* Embed Watch Content */,
- 7A55BE3D2F11320C00D8744D /* Upload source maps to Bugsnag */,
- F1B660D44BA706C4AA9FC60C /* [CP] Embed Pods Frameworks */,
- 441DA981C582EB474E37526F /* [CP] Copy Pods Resources */,
+ 6E2B7753E1396AE4448B35AE /* [CP] Embed Pods Frameworks */,
+ 6931B3875D0CA69F22785138 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -1553,9 +1564,8 @@
shellPath = /bin/sh;
shellScript = "export 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";
};
- 06C10D4F29CD7532492AD29E /* [Expo] Configure project */ = {
+ 1E1EA8082326CCE300E22452 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@@ -1563,16 +1573,15 @@
);
inputPaths = (
);
- name = "[Expo] Configure project";
outputFileListPaths = (
);
outputPaths = (
);
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-RocketChatRN/expo-configure-project.sh\"\n";
+ 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";
};
- 1E1EA8082326CCE300E22452 /* ShellScript */ = {
+ 23A5F6CB83957B93A7EA1C97 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1580,16 +1589,76 @@
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-NotificationService-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
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";
+ 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;
+ };
+ 407D3EDE3DABEE15D27BD87D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ 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",
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-defaults-NotificationService-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 4CCE5B7235CA003F286BD050 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 589729E8381BA997CD19EF19 /* [Expo] Configure project */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "[Expo] Configure project";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ 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-RocketChatRN/expo-configure-project.sh\"\n";
};
- 441DA981C582EB474E37526F /* [CP] Copy Pods Resources */ = {
+ 6931B3875D0CA69F22785138 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1665,54 +1734,13 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 6319FBDD06EF0030B48AD389 /* [Expo] Configure project */ = {
- isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- );
- name = "[Expo] Configure project";
- outputFileListPaths = (
- );
- outputPaths = (
- );
- 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-Rocket.Chat/expo-configure-project.sh\"\n";
- };
- 664B079CA244E1ABB144A1C9 /* [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-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;
- };
- 6BC31F4F1CF6E74A7683D2D4 /* [CP] Copy Pods Resources */ = {
+ 69520DF942793F987B1AA05B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh",
+ "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative/Bugsnag.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
@@ -1779,45 +1807,28 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 7A55BE3B2F11316900D8744D /* Bundle React Native code and images */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- );
- name = "Bundle React Native code and images";
- outputFileListPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "export 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";
- };
- 7A55BE3C2F1131C000D8744D /* ShellScript */ = {
+ 6E2B7753E1396AE4448B35AE /* [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}/hermes-engine/Pre-built/hermes.framework/hermes",
);
- outputFileListPaths = (
- );
+ name = "[CP] Embed Pods Frameworks";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
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";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
};
- 7A55BE3D2F11320C00D8744D /* Upload source maps to Bugsnag */ = {
+ 7AAE9EB32891A0D20024F559 /* Upload source maps to Bugsnag */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1825,7 +1836,7 @@
inputFileListPaths = (
);
inputPaths = (
- "$TARGET_BUILD_DIR/$INFOPLIST_PATH",
+ $TARGET_BUILD_DIR/$INFOPLIST_PATH,
);
name = "Upload source maps to Bugsnag";
outputFileListPaths = (
@@ -1837,49 +1848,45 @@
shellScript = "SOURCE_MAP=\"$TMPDIR/$(md5 -qs \"$CONFIGURATION_BUILD_DIR\")-main.jsbundle.map\" ../node_modules/@bugsnag/react-native/bugsnag-react-native-xcode.sh\n";
showEnvVarsInLog = 0;
};
- 7AAE9EB32891A0D20024F559 /* Upload source maps to Bugsnag */ = {
+ 84028E94C77DEBDD5200728D /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
- "$TARGET_BUILD_DIR/$INFOPLIST_PATH",
);
- name = "Upload source maps to Bugsnag";
+ name = "[Expo] Configure project";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
- showEnvVarsInLog = 0;
+ 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";
};
- 7E2F5D729E377A4A5D1E96B4 /* [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-Rocket.Chat-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 /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
@@ -1898,7 +1905,7 @@
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";
};
- 8A4915EBB9B9EA919C35752B /* [CP] Check Pods Manifest.lock */ = {
+ AEF2010F70C9B50729A6B50C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1913,38 +1920,20 @@
outputFileListPaths = (
);
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-defaults-RocketChatRN-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-defaults-Rocket.Chat-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;
};
- BCA373A96A91C30B09231381 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- E57DE3ACCEF8E313DFF4D411 /* [CP] Copy Pods Resources */ = {
+ B4801301A00C50FA3AD72CF9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh",
+ "${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative/Bugsnag.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
@@ -2011,25 +2000,29 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-NotificationService/Pods-defaults-NotificationService-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- F1B660D44BA706C4AA9FC60C /* [CP] Embed Pods Frameworks */ = {
+ D17D219AF77F48D35A0D7171 /* [CP] Check Pods Manifest.lock */ = {
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}/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}/hermes.framework",
+ "$(DERIVED_FILE_DIR)/Pods-defaults-RocketChatRN-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat-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;
};
/* End PBXShellScriptBuildPhase section */
@@ -2047,6 +2040,7 @@
66C2701B2EBBCB570062725F /* MMKVKeyManager.mm in Sources */,
1ED00BB12513E04400A1331F /* ReplyNotification.swift in Sources */,
1E76CBC2251529560067298C /* Storage.swift in Sources */,
+ 16A6D54F2F0D95FC000FCD09 /* QuickActionsStore.mm in Sources */,
1E76CBD925152C8C0067298C /* Push.swift in Sources */,
1E0426E6251A5467008F022C /* RoomType.swift in Sources */,
1E76CBCD25152C2C0067298C /* MessageType.swift in Sources */,
@@ -2066,6 +2060,7 @@
1ED038A52B50900800C007D4 /* Bundle+Extensions.swift in Sources */,
1E76CBC325152A460067298C /* String+Extensions.swift in Sources */,
1ED038BA2B50A1B800C007D4 /* WatchConnection.swift in Sources */,
+ 167D56822F104B7D00880439 /* QuickActionsConnector.mm in Sources */,
7AACF8A82C94AB8B0082844E /* EncryptedContent.swift in Sources */,
1ED038A12B508FE700C007D4 /* FileManager+Extensions.swift in Sources */,
1E76CBCA25152C220067298C /* Notification.swift in Sources */,
@@ -2322,6 +2317,7 @@
66C2701C2EBBCB570062725F /* MMKVKeyManager.mm in Sources */,
7AAB3E17257E6A6E00707CF6 /* ReplyNotification.swift in Sources */,
7AAB3E18257E6A6E00707CF6 /* Storage.swift in Sources */,
+ 16A6D54E2F0D95FC000FCD09 /* QuickActionsStore.mm in Sources */,
7AAB3E19257E6A6E00707CF6 /* Push.swift in Sources */,
7AAB3E1A257E6A6E00707CF6 /* RoomType.swift in Sources */,
7AAB3E1B257E6A6E00707CF6 /* MessageType.swift in Sources */,
@@ -2341,6 +2337,7 @@
1ED038A72B50900800C007D4 /* Bundle+Extensions.swift in Sources */,
7AAB3E26257E6A6E00707CF6 /* String+Extensions.swift in Sources */,
1ED038BB2B50A1B800C007D4 /* WatchConnection.swift in Sources */,
+ 167D56832F104B7D00880439 /* QuickActionsConnector.mm in Sources */,
7AACF8AA2C94AB8B0082844E /* EncryptedContent.swift in Sources */,
1ED038A32B508FE700C007D4 /* FileManager+Extensions.swift in Sources */,
7AAB3E27257E6A6E00707CF6 /* Notification.swift in Sources */,
@@ -2421,7 +2418,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 482E711ACFA5E2C4281835BF /* Pods-defaults-RocketChatRN.debug.xcconfig */;
+ baseConfigurationReference = 25B6129FD3765EC5B5D0F3F3 /* Pods-defaults-RocketChatRN.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
@@ -2486,7 +2483,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = F6BFACDCE2AB06F4936B3E03 /* Pods-defaults-RocketChatRN.release.xcconfig */;
+ baseConfigurationReference = D37FD1CB4DF877266A49B72B /* Pods-defaults-RocketChatRN.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
@@ -2593,7 +2590,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,
);
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -2669,7 +2666,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,
);
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -2901,7 +2898,7 @@
};
1EFEB59D2493B6640072EDC0 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 6CE8C7A54627937DB698E839 /* Pods-defaults-NotificationService.debug.xcconfig */;
+ baseConfigurationReference = A775A4A535C3A4DF9E009CB5 /* Pods-defaults-NotificationService.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)";
CLANG_ANALYZER_NONNULL = YES;
@@ -2953,7 +2950,7 @@
};
1EFEB59E2493B6640072EDC0 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 44A0BDC6158008BF9FF04F0A /* Pods-defaults-NotificationService.release.xcconfig */;
+ baseConfigurationReference = D97BDAB3F63F70EF45D2FD6B /* Pods-defaults-NotificationService.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(EMBEDDED_CONTENT_CONTAINS_SWIFT)";
CLANG_ANALYZER_NONNULL = YES;
@@ -3004,7 +3001,7 @@
};
7AAB3E50257E6A6E00707CF6 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 92B416D2ADF070E0E0C782A0 /* Pods-defaults-Rocket.Chat.debug.xcconfig */;
+ baseConfigurationReference = 0547DC0CF78D9F082A8B0BB5 /* Pods-defaults-Rocket.Chat.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
@@ -3019,7 +3016,7 @@
DEVELOPMENT_TEAM = S6UPZG7ZR3;
ENABLE_BITCODE = NO;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
- EXCLUDED_ARCHS = "";
+ "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
@@ -3069,7 +3066,7 @@
};
7AAB3E51257E6A6E00707CF6 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = CD1F8BBE6FE382D33AB37935 /* Pods-defaults-Rocket.Chat.release.xcconfig */;
+ baseConfigurationReference = 6B6D45FCB4C3A2DAC625E0C5 /* Pods-defaults-Rocket.Chat.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
diff --git a/ios/RocketChatRN/Info.plist b/ios/RocketChatRN/Info.plist
index b2d1a400cba..57d83fd56d1 100644
--- a/ios/RocketChatRN/Info.plist
+++ b/ios/RocketChatRN/Info.plist
@@ -11,8 +11,8 @@
apiKey
apiKeyValue
- CADisableMinimumFrameDurationOnPhone
-
+ CADisableMinimumFrameDurationOnPhone
+
CFBundleDevelopmentRegion
en
CFBundleDisplayName
@@ -60,13 +60,13 @@
LSRequiresIPhoneOS
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
- NSAllowsLocalNetworking
-
-
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ NSAllowsLocalNetworking
+
+
NSCameraUsageDescription
Take photos to share with other users
NSFaceIDUsageDescription
diff --git a/package.json b/package.json
index 45c7b5e50e1..9d3f1465ebb 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"expo-local-authentication": "16.0.3",
"expo-navigation-bar": "^4.2.4",
"expo-notifications": "0.32.11",
+ "expo-quick-actions": "^5.0.0",
"expo-status-bar": "^2.2.3",
"expo-system-ui": "^5.0.7",
"expo-video-thumbnails": "9.1.2",
diff --git a/yarn.lock b/yarn.lock
index 5f334cbad37..2afa4b1d100 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2934,6 +2934,21 @@
temp-dir "~2.0.0"
unique-string "~2.0.0"
+"@expo/image-utils@~0.7.4":
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.7.6.tgz#b8442bef770e1c7b39997d57f666bffeeced0a7a"
+ integrity sha512-GKnMqC79+mo/1AFrmAcUcGfbsXXTRqOMNS1umebuevl3aaw+ztsYEFEiuNhHZW7PQ3Xs3URNT513ZxKhznDscw==
+ dependencies:
+ "@expo/spawn-async" "^1.7.2"
+ chalk "^4.0.0"
+ getenv "^2.0.0"
+ jimp-compact "0.16.1"
+ parse-png "^2.1.0"
+ resolve-from "^5.0.0"
+ semver "^7.6.0"
+ temp-dir "~2.0.0"
+ unique-string "~2.0.0"
+
"@expo/json-file@^10.0.8", "@expo/json-file@~10.0.7":
version "10.0.8"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-10.0.8.tgz#05e524d1ecc0011db0a6d66b525ea2f58cfe6d43"
@@ -8578,6 +8593,15 @@ expo-notifications@0.32.11:
expo-application "~7.0.7"
expo-constants "~18.0.8"
+expo-quick-actions@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/expo-quick-actions/-/expo-quick-actions-5.0.0.tgz#6b3c5c21190607f779be1588ebaf119577a3c120"
+ integrity sha512-NSsDhfbal11gXsHkJbvYVw7x0QUCKrEth2kBBKZUv03dX4J7ZPADSV89LyEpOVYXCkrw6LuanlEtKavg/BFaRA==
+ dependencies:
+ "@expo/image-utils" "~0.7.4"
+ schema-utils "^4.2.0"
+ sf-symbols-typescript "^2.1.0"
+
expo-status-bar@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-2.2.3.tgz#09385a866732328e0af3b4588c4f349a15fd7cd0"
@@ -13505,6 +13529,16 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1"
ajv-keywords "^5.1.0"
+schema-utils@^4.2.0:
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46"
+ integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ ajv "^8.9.0"
+ ajv-formats "^2.1.1"
+ ajv-keywords "^5.1.0"
+
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
@@ -13668,6 +13702,11 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+sf-symbols-typescript@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz#926d6e0715e3d8784cadf7658431e36581254208"
+ integrity sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==
+
shallow-clone@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"