diff --git a/native/chat/chat.react.js b/native/chat/chat.react.js
--- a/native/chat/chat.react.js
+++ b/native/chat/chat.react.js
@@ -72,6 +72,7 @@
ChangeRolesScreenRouteName,
} from '../navigation/route-names.js';
import ChangeRolesHeaderLeftButton from '../roles/change-roles-header-left-button.react.js';
+import ChangeRolesHeaderRightButton from '../roles/change-roles-header-right-button.react.js';
import ChangeRolesScreen from '../roles/change-roles-screen.react.js';
import MessageSearch from '../search/message-search.react.js';
import SearchHeader from '../search/search-header.react.js';
@@ -302,6 +303,8 @@
),
headerTitle: 'Change Role',
+ // eslint-disable-next-line react/display-name
+ headerRight: () => ,
presentation: 'modal',
});
diff --git a/native/roles/change-roles-header-right-button.react.js b/native/roles/change-roles-header-right-button.react.js
new file mode 100644
--- /dev/null
+++ b/native/roles/change-roles-header-right-button.react.js
@@ -0,0 +1,72 @@
+// @flow
+
+import { useNavigation } from '@react-navigation/native';
+import invariant from 'invariant';
+import * as React from 'react';
+import { Text } from 'react-native';
+import { TouchableOpacity } from 'react-native-gesture-handler';
+
+import {
+ changeThreadMemberRoles,
+ changeThreadMemberRolesActionTypes,
+} from 'lib/actions/thread-actions.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from 'lib/utils/action-utils.js';
+
+import type { NavigationRoute } from '../navigation/route-names';
+import { useColors } from '../themes/colors.js';
+
+type Props = {
+ +route: NavigationRoute<'ChangeRolesScreen'>,
+};
+
+function ChangeRolesHeaderRightButton(props: Props): React.Node {
+ const { threadInfo, memberInfo, role: selectedRole } = props.route.params;
+ const { role: initialRole } = memberInfo;
+ invariant(selectedRole, 'Expected selected role to be defined');
+ const navigation = useNavigation();
+
+ const callChangeThreadMemberRoles = useServerCall(changeThreadMemberRoles);
+ const dispatchActionPromise = useDispatchActionPromise();
+
+ const { purpleLink } = useColors();
+ const textStyle = React.useMemo(
+ () => ({
+ color: purpleLink,
+ marginRight: 10,
+ }),
+ [purpleLink],
+ );
+
+ const handleSave = React.useCallback(() => {
+ if (selectedRole === initialRole) {
+ navigation.goBack();
+ return;
+ }
+
+ dispatchActionPromise(
+ changeThreadMemberRolesActionTypes,
+ callChangeThreadMemberRoles(threadInfo.id, [memberInfo.id], selectedRole),
+ );
+
+ navigation.goBack();
+ }, [
+ callChangeThreadMemberRoles,
+ dispatchActionPromise,
+ initialRole,
+ memberInfo.id,
+ navigation,
+ selectedRole,
+ threadInfo.id,
+ ]);
+
+ return (
+
+ Save
+
+ );
+}
+
+export default ChangeRolesHeaderRightButton;