Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 34 additions & 37 deletions app/views/RoomView/components/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,43 @@ interface IBannerProps {
closeBanner: () => void;
}

const Banner = memo(
({ text, title, bannerClosed, closeBanner }: IBannerProps) => {
const [showModal, openModal] = useState(false);
const { colors } = useTheme();
const Banner = memo(({ text, title, bannerClosed, closeBanner }: IBannerProps) => {
const [showModal, openModal] = useState(false);
const { colors } = useTheme();

const toggleModal = () => openModal(prevState => !prevState);
const toggleModal = () => openModal(prevState => !prevState);

if (text && !bannerClosed) {
return (
<>
<BorderlessButton
style={[styles.bannerContainer, { backgroundColor: colors.surfaceNeutral }]}
testID='room-view-banner'
onPress={toggleModal}>
<MarkdownPreview msg={text} style={styles.bannerText} />
<BorderlessButton onPress={closeBanner} hitSlop={10}>
<CustomIcon color={colors.fontSecondaryInfo} name='close' size={20} />
</BorderlessButton>
if (text && !bannerClosed) {
return (
<>
<BorderlessButton
style={[styles.bannerContainer, { backgroundColor: colors.surfaceNeutral }]}
testID='room-view-banner'
onPress={toggleModal}>
<MarkdownPreview msg={text} style={styles.bannerText} />
<BorderlessButton onPress={closeBanner} hitSlop={10}>
<CustomIcon color={colors.fontSecondaryInfo} name='close' size={20} />
</BorderlessButton>
<Modal
onBackdropPress={toggleModal}
onBackButtonPress={toggleModal}
useNativeDriver
isVisible={showModal}
animationIn='fadeIn'
animationOut='fadeOut'>
<GestureHandlerRootView style={[styles.modalView, { backgroundColor: colors.surfaceNeutral }]}>
<Text style={[styles.bannerModalTitle, { color: colors.fontSecondaryInfo }]}>{title}</Text>
<ScrollView style={styles.modalScrollView}>
<Markdown msg={text} />
</ScrollView>
</GestureHandlerRootView>
</Modal>
</>
);
}
</BorderlessButton>
<Modal
onBackdropPress={toggleModal}
onBackButtonPress={toggleModal}
useNativeDriver
isVisible={showModal}
animationIn='fadeIn'
animationOut='fadeOut'>
<GestureHandlerRootView style={[styles.modalView, { backgroundColor: colors.surfaceNeutral }]}>
<Text style={[styles.bannerModalTitle, { color: colors.fontSecondaryInfo }]}>{title}</Text>
<ScrollView style={styles.modalScrollView}>
<Markdown msg={text} />
</ScrollView>
</GestureHandlerRootView>
</Modal>
</>
);
}

return null;
},
(prevProps, nextProps) => prevProps.text === nextProps.text && prevProps.bannerClosed === nextProps.bannerClosed
);
return null;
});

export default Banner;
13 changes: 3 additions & 10 deletions app/views/RoomView/components/InvitedRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ type InvitedRoomProps = {
title: string;
description: string;
inviter: IInviteSubscription['inviter'];
loading?: boolean;
onAccept: () => Promise<void>;
onReject: () => Promise<void>;
};

export const InvitedRoom = ({ title, description, inviter, loading, onAccept, onReject }: InvitedRoomProps): ReactElement => {
export const InvitedRoom = ({ title, description, inviter, onAccept, onReject }: InvitedRoomProps): ReactElement => {
const { colors } = useTheme();

return (
Expand All @@ -25,14 +24,8 @@ export const InvitedRoom = ({ title, description, inviter, loading, onAccept, on
title={title}
description={description}
detail={<Chip avatar={inviter.username} text={inviter.name || inviter.username} fullWidth />}>
<Button title={I18n.t('accept')} loading={loading} onPress={onAccept} />
<Button
title={I18n.t('reject')}
type='secondary'
loading={loading}
backgroundColor={colors.surfaceTint}
onPress={onReject}
/>
<Button title={I18n.t('accept')} onPress={onAccept} />
<Button title={I18n.t('reject')} type='secondary' backgroundColor={colors.surfaceTint} onPress={onReject} />
</RoomPlaceholder>
);
};
42 changes: 15 additions & 27 deletions app/views/RoomView/components/MessageRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { type RoomType, type TAnyMessageModel } from '../../../definitions';
import { useThreadBadgeColor } from '../hooks/useThreadBadgeColor';
import { type IRoomViewState, type TMessageRowProps } from '../definitions';

// The room model mutates in place (same ref per emit), and the React Compiler caches derived
// values on that stable ref. Deriving the boolean inside the selector keeps it fresh per emit
// and only re-renders the caller when the derived value actually changes.
const useIsIgnored = (authorId?: string): boolean =>
useRoomStore(s => (authorId && 'id' in s.room ? (s.room.ignored?.includes(authorId) ?? false) : false));

Expand Down Expand Up @@ -42,40 +39,31 @@ export const MessageRow = ({ item, previousItem, highlightedMessage, onLongPress
const { lastSeen } = useRoomScreen();
const { dateSeparator, showUnreadSeparator } = getMessageSeparators(item, previousItem, lastSeen);

let content = null;
if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t as MessageTypeLoad)) {
const runOnRender = () => {
if (item.t === MessageTypeLoad.MORE) {
if (!previousItem) return true;
if (previousItem?.tmid) return true;
}
return false;
};
content = (
const runOnRender = item.t === MessageTypeLoad.MORE && (!previousItem || !!previousItem.tmid);
return (
<LoadMore
rid={room.rid}
t={room.t as RoomType}
loaderId={item.id}
type={item.t}
runOnRender={runOnRender()}
dateSeparator={dateSeparator}
showUnreadSeparator={showUnreadSeparator}
/>
);
} else {
content = (
<Message
item={item}
isIgnored={isIgnored}
previousItem={previousItem}
onLongPress={onLongPress}
threadBadgeColor={threadBadgeColor}
highlighted={highlightedMessage === item.id}
runOnRender={runOnRender}
dateSeparator={dateSeparator}
showUnreadSeparator={showUnreadSeparator}
/>
);
}

return content;
return (
<Message
item={item}
isIgnored={isIgnored}
previousItem={previousItem}
onLongPress={onLongPress}
threadBadgeColor={threadBadgeColor}
highlighted={highlightedMessage === item.id}
dateSeparator={dateSeparator}
showUnreadSeparator={showUnreadSeparator}
/>
);
};
22 changes: 9 additions & 13 deletions app/views/RoomView/components/RightButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { closeLivechat as closeLivechatService } from '../../../lib/methods/help
import { events, logEvent } from '../../../lib/methods/helpers/log';
import getRoomAccessibilityLabel from '../../../lib/helpers/getRoomAccessibilityLabel';
import { useAppSelector } from '../../../lib/hooks/useAppSelector';
import { useSetting } from '../../../lib/hooks/useSetting';
import { useCanReturnQueue } from '../../../ee/omnichannel/hooks/useCanReturnQueue';
import { useMasterDetail } from '../../../lib/hooks/useMasterDetail';
import { usePermissions } from '../../../lib/hooks/usePermissions';
Expand Down Expand Up @@ -128,10 +129,8 @@ const RightButtons = ({ rid, tmid }: IRightButtonsProps): ReactElement | null =>
const { showActionSheet } = useActionSheet();

const userId = useAppSelector(state => getUserSelector(state).id);
const threadsEnabled = useAppSelector(state => state.settings.Threads_enabled as boolean);
const livechatRequestComment = useAppSelector(
state => state.settings.Livechat_request_comment_when_closing_conversation as boolean
);
const threadsEnabled = useSetting('Threads_enabled') as boolean;
const livechatRequestComment = useSetting('Livechat_request_comment_when_closing_conversation') as boolean;
const issuesWithNotifications = useAppSelector(state => state.troubleshootingNotification.issuesWithNotifications);

const room = useRoomStoreByRid(rid, s => s.room);
Expand Down Expand Up @@ -235,15 +234,12 @@ const RightButtons = ({ rid, tmid }: IRightButtonsProps): ReactElement | null =>
if (!rid) {
return;
}
if (isMasterDetail) {
// @ts-ignore TODO: find a way to make this work
navigation.navigate('ModalStackNavigator', {
screen: 'SearchMessagesView',
params: { rid, showCloseModal: true, encrypted }
});
} else {
navigation.navigate('SearchMessagesView', { rid, t, encrypted });
}
navigateToScreen({
navigation,
isMasterDetail,
screen: 'SearchMessagesView',
params: isMasterDetail ? { rid, t, encrypted, showCloseModal: true } : { rid, t, encrypted }
});
};

const goE2EEToggleRoomView = () => {
Expand Down
1 change: 0 additions & 1 deletion app/views/RoomView/components/RoomFooter/TakeOrJoin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const TakeOrJoin = ({ joinCodeRef }: ITakeOrJoinProps): ReactElement => {
const room = useRoomWithUpdate();
const joinRoom = useRoomStore(s => s.joinRoom);

// The join-code modal lives on this screen, so the trigger is handed to joinRoom per call.
const onPressJoin = (): Promise<void> => joinRoom(() => joinCodeRef.current?.show());

return (
Expand Down
7 changes: 4 additions & 3 deletions app/views/RoomView/components/RoomFooter/useFooterMessage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import I18n from '../../../../i18n';
import { useAppSelector } from '../../../../lib/hooks/useAppSelector';
import { useSetting } from '../../../../lib/hooks/useSetting';
import { isBlocked } from '../../../../lib/methods/helpers/room';
import { type IRoomFederated, isRoomFederated, isRoomNativeFederated } from '../../../../lib/methods/isRoomFederated';
import { useReadOnly } from '../../hooks/useReadOnly';
Expand All @@ -25,9 +26,9 @@ const getFederatedFooterDescription = (
export const useFooterMessage = (): string | null => {
const room = useRoomWithUpdate();
const readOnly = useReadOnly();
const isFederationEnabled = useAppSelector(
state => (state.settings.Federation_Matrix_enabled || state.settings.Federation_Service_Enabled) as boolean
);
const federationMatrixEnabled = useSetting('Federation_Matrix_enabled');
const federationServiceEnabled = useSetting('Federation_Service_Enabled');
const isFederationEnabled = !!(federationMatrixEnabled || federationServiceEnabled);
const isFederationModuleEnabled = useAppSelector(state => state.enterpriseModules.includes('federation'));

if (readOnly) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useAppSelector } from '../../../../lib/hooks/useAppSelector';
import { useSetting } from '../../../../lib/hooks/useSetting';
import { useRoomStore, useRoomWithUpdate } from '../../stores/RoomStoreContext';
import { useFooterMessage } from './useFooterMessage';

Expand All @@ -12,9 +12,9 @@ export type TRoomFooterState =
export const useRoomFooterState = (): TRoomFooterState => {
const room = useRoomWithUpdate();
const joined = useRoomStore(s => s.joined);
const airGappedRestrictionRemainingDays = useAppSelector(
state => state.settings.Cloud_Workspace_AirGapped_Restrictions_Remaining_Days as number | undefined
);
const airGappedRestrictionRemainingDays = useSetting('Cloud_Workspace_AirGapped_Restrictions_Remaining_Days') as
| number
| undefined;
const footerMessage = useFooterMessage();

if ('onHold' in room && room.onHold) {
Expand Down
34 changes: 31 additions & 3 deletions app/views/RoomView/components/RoomMessageProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,40 @@ export const RoomMessageProvider = ({
onThreadPress,
onReactionPress,
sendMessage,
...state
rid,
tmid,
isThreadRoom,
archived,
broadcast,
isReadReceiptEnabled,
Message_GroupingPeriod,
timeFormat,
autoTranslateRoom,
autoTranslateLanguage,
jumpToMessage,
closeEmojiAndAction,
reactionInit,
errorActionsShow
}: IRoomMessageProviderProps): ReactElement => {
const handlers = useRoomMessageHandlers({ tmid: state.tmid, onThreadPress, onReactionPress, sendMessage });
const handlers = useRoomMessageHandlers({ tmid, onThreadPress, onReactionPress, sendMessage });

return (
<MessageRoomProvider {...state} handlers={handlers}>
<MessageRoomProvider
handlers={handlers}
rid={rid}
tmid={tmid}
isThreadRoom={isThreadRoom}
archived={archived}
broadcast={broadcast}
isReadReceiptEnabled={isReadReceiptEnabled}
Message_GroupingPeriod={Message_GroupingPeriod}
timeFormat={timeFormat}
autoTranslateRoom={autoTranslateRoom}
autoTranslateLanguage={autoTranslateLanguage}
jumpToMessage={jumpToMessage}
closeEmojiAndAction={closeEmojiAndAction}
reactionInit={reactionInit}
errorActionsShow={errorActionsShow}>
{children}
</MessageRoomProvider>
);
Expand Down
Loading
Loading