diff --git a/app/lib/methods/helpers/isReadOnly.ts b/app/lib/methods/helpers/isReadOnly.ts index 226cd5350e9..28087a19c1f 100644 --- a/app/lib/methods/helpers/isReadOnly.ts +++ b/app/lib/methods/helpers/isReadOnly.ts @@ -2,19 +2,24 @@ import { store as reduxStore } from '../../store/auxStore'; import { type ISubscription } from '../../../definitions'; import { hasPermission } from './helpers'; -const canPostReadOnly = async (room: Partial, username: string) => { +const canPostReadOnly = async (room: Partial, username: string, postReadOnlyPermission?: string[]) => { // RC 6.4.0 const isUnmuted = !!room?.unmuted?.find(m => m === username); - // TODO: this is not reactive. If this permission changes, the component won't be updated - const postReadOnlyPermission = reduxStore.getState().permissions['post-readonly']; - const permission = await hasPermission([postReadOnlyPermission], room.rid); - return permission[0] || isUnmuted; + // Use provided permission or fallback to static snapshot for backward compatibility + const permissionToCheck = postReadOnlyPermission ?? reduxStore.getState().permissions['post-readonly']; + const permissions = (await hasPermission([permissionToCheck], room.rid)) ?? [false]; + const canPost = !!permissions[0]; + return canPost || isUnmuted; }; const isMuted = (room: Partial, username: string) => room && room.muted && room.muted.find && !!room.muted.find(m => m === username); -export const isReadOnly = async (room: Partial, username: string): Promise => { +export const isReadOnly = async ( + room: Partial, + username: string, + postReadOnlyPermission?: string[] +): Promise => { if (room.archived) { return true; } @@ -22,7 +27,7 @@ export const isReadOnly = async (room: Partial, username: string) return true; } if (room?.ro) { - const allowPost = await canPostReadOnly(room, username); + const allowPost = await canPostReadOnly(room, username, postReadOnlyPermission); if (allowPost) { return false; } diff --git a/app/views/RoomView/definitions.ts b/app/views/RoomView/definitions.ts index 7301dfaa0f7..bce655ec2c7 100644 --- a/app/views/RoomView/definitions.ts +++ b/app/views/RoomView/definitions.ts @@ -28,6 +28,7 @@ export interface IRoomViewProps extends IActionSheetProvider, IBaseScreen { shouldComponentUpdate(nextProps: IRoomViewProps, nextState: IRoomViewState) { const { state } = this; const { roomUpdate, member, isOnHold, isAutocompleteVisible } = state; - const { theme, insets, route, encryptionEnabled, airGappedRestrictionRemainingDays } = this.props; + const { theme, insets, route, encryptionEnabled, airGappedRestrictionRemainingDays, postReadOnlyPermission } = this.props; if (theme !== nextProps.theme) { return true; } @@ -258,6 +258,9 @@ class RoomView extends React.Component { if (airGappedRestrictionRemainingDays !== nextProps.airGappedRestrictionRemainingDays) { return true; } + if (!dequal(postReadOnlyPermission, nextProps.postReadOnlyPermission)) { + return true; + } if (member.statusText !== nextState.member.statusText) { return true; } @@ -310,6 +313,8 @@ class RoomView extends React.Component { if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) { this.setHeader(); } + // Update readOnly when permission changes or room updates + // Always call setReadOnly to ensure it's up to date (it will only update state if value changed) this.setReadOnly(); } @@ -568,8 +573,8 @@ class RoomView extends React.Component { setReadOnly = async () => { const { room } = this.state; - const { user } = this.props; - const readOnly = await isReadOnly(room as ISubscription, user.username as string); + const { user, postReadOnlyPermission } = this.props; + const readOnly = await isReadOnly(room as ISubscription, user.username as string, postReadOnlyPermission); this.setState({ readOnly }); }; @@ -1576,6 +1581,7 @@ const mapStateToProps = (state: IApplicationState) => ({ Hide_System_Messages: state.settings.Hide_System_Messages as string[], transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'], viewCannedResponsesPermission: state.permissions['view-canned-responses'], + postReadOnlyPermission: state.permissions['post-readonly'], livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean, airGappedRestrictionRemainingDays: state.settings.Cloud_Workspace_AirGapped_Restrictions_Remaining_Days, inAppFeedback: state.inAppFeedback,