fix unread banner position when first unread is visible
This commit is contained in:
parent
c2b5ac68d6
commit
c8f0150aaf
|
@ -341,11 +341,15 @@
|
|||
window.setMediaPermissions(!value);
|
||||
};
|
||||
|
||||
Whisper.Notifications.on('click', (id, messageId) => {
|
||||
Whisper.Notifications.on('click', async (id, messageId) => {
|
||||
window.showWindow();
|
||||
if (id) {
|
||||
const firstUnreadIdOnOpen = await window.Signal.Data.getFirstUnreadMessageIdInConversation(
|
||||
id
|
||||
);
|
||||
|
||||
window.inboxStore.dispatch(
|
||||
window.actionsCreators.openConversationExternal({ id, messageId })
|
||||
window.actionsCreators.openConversationExternal({ id, messageId, firstUnreadIdOnOpen })
|
||||
);
|
||||
} else {
|
||||
appView.openInbox({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { contextMenu } from 'react-contexify';
|
||||
|
@ -26,6 +26,7 @@ import { SessionIcon, SessionIconSize, SessionIconType } from './session/icon';
|
|||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { SectionType } from '../state/ducks/section';
|
||||
import { getFocusedSection } from '../state/selectors/section';
|
||||
import { getFirstUnreadMessageIdInConversation } from '../data/data';
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface ConversationListItemProps extends ReduxConversationType {}
|
||||
|
@ -240,13 +241,16 @@ const ConversationListItem = (props: Props) => {
|
|||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const openConvo = useCallback(async () => {
|
||||
const firstUnreadIdOnOpen = await getFirstUnreadMessageIdInConversation(conversationId);
|
||||
dispatch(openConversationExternal({ id: conversationId, firstUnreadIdOnOpen }));
|
||||
}, [conversationId]);
|
||||
|
||||
return (
|
||||
<div key={key}>
|
||||
<div
|
||||
role="button"
|
||||
onClick={() => {
|
||||
dispatch(openConversationExternal({ id: conversationId }));
|
||||
}}
|
||||
onClick={openConvo}
|
||||
onContextMenu={(e: any) => {
|
||||
contextMenu.show({
|
||||
id: triggerId,
|
||||
|
|
|
@ -94,7 +94,13 @@ export const MessageSearchResult = (props: Props) => {
|
|||
<div
|
||||
role="button"
|
||||
onClick={() => {
|
||||
dispatch(openConversationExternal({ id: conversationId, messageId }));
|
||||
dispatch(
|
||||
openConversationExternal({
|
||||
id: conversationId,
|
||||
messageId,
|
||||
firstUnreadIdOnOpen: undefined,
|
||||
})
|
||||
);
|
||||
}}
|
||||
className={classNames(
|
||||
'module-message-search-result',
|
||||
|
|
|
@ -11,6 +11,7 @@ import { updateUserDetailsModal } from '../state/ducks/modalDialog';
|
|||
import { openConversationExternal } from '../state/ducks/conversations';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import useKey from 'react-use/lib/useKey';
|
||||
import { getFirstUnreadMessageIdInConversation } from '../data/data';
|
||||
type Props = {
|
||||
conversationId: string;
|
||||
authorAvatarPath?: string;
|
||||
|
@ -33,8 +34,11 @@ export const UserDetailsDialog = (props: Props) => {
|
|||
convo.id,
|
||||
ConversationTypeEnum.PRIVATE
|
||||
);
|
||||
const firstUnreadIdOnOpen = await getFirstUnreadMessageIdInConversation(conversation.id);
|
||||
|
||||
window.inboxStore?.dispatch(openConversationExternal({ id: conversation.id }));
|
||||
window.inboxStore?.dispatch(
|
||||
openConversationExternal({ id: conversation.id, firstUnreadIdOnOpen })
|
||||
);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
|
|
|
@ -39,7 +39,10 @@ import { ClickToTrustSender } from './message/ClickToTrustSender';
|
|||
import { getMessageById } from '../../data/data';
|
||||
import { connect } from 'react-redux';
|
||||
import { StateType } from '../../state/reducer';
|
||||
import { getSelectedMessageIds } from '../../state/selectors/conversations';
|
||||
import {
|
||||
getQuotedMessageToAnimate,
|
||||
getSelectedMessageIds,
|
||||
} from '../../state/selectors/conversations';
|
||||
import {
|
||||
messageExpired,
|
||||
showLightBox,
|
||||
|
@ -64,7 +67,10 @@ interface State {
|
|||
const EXPIRATION_CHECK_MINIMUM = 2000;
|
||||
const EXPIRED_DELAY = 600;
|
||||
|
||||
type Props = MessageRegularProps & { selectedMessages: Array<string> };
|
||||
type Props = MessageRegularProps & {
|
||||
selectedMessages: Array<string>;
|
||||
quotedMessageToAnimate: string | undefined;
|
||||
};
|
||||
|
||||
const onClickAttachment = async (onClickProps: {
|
||||
attachment: AttachmentTypeWithPath;
|
||||
|
@ -570,14 +576,7 @@ class MessageInner extends React.PureComponent<Props, State> {
|
|||
|
||||
// tslint:disable-next-line: cyclomatic-complexity
|
||||
public render() {
|
||||
const {
|
||||
direction,
|
||||
id,
|
||||
multiSelectMode,
|
||||
conversationType,
|
||||
isUnread,
|
||||
selectedMessages,
|
||||
} = this.props;
|
||||
const { direction, id, conversationType, isUnread, selectedMessages } = this.props;
|
||||
const { expired, expiring } = this.state;
|
||||
|
||||
if (expired) {
|
||||
|
@ -601,7 +600,7 @@ class MessageInner extends React.PureComponent<Props, State> {
|
|||
divClasses.push('public-chat-message-wrapper');
|
||||
}
|
||||
|
||||
if (this.props.isQuotedMessageToAnimate) {
|
||||
if (this.props.quotedMessageToAnimate === this.props.id) {
|
||||
divClasses.push('flash-green-once');
|
||||
}
|
||||
|
||||
|
@ -851,6 +850,7 @@ class MessageInner extends React.PureComponent<Props, State> {
|
|||
const mapStateToProps = (state: StateType) => {
|
||||
return {
|
||||
selectedMessages: getSelectedMessageIds(state),
|
||||
quotedMessageToAnimate: getQuotedMessageToAnimate(state),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
|
|||
useFocus(onChange);
|
||||
|
||||
return (
|
||||
<InView {...props} as="div" threshold={1} delay={200} triggerOnce={false}>
|
||||
<InView {...props} as="div" threshold={0.5} delay={20} triggerOnce={false}>
|
||||
{props.children}
|
||||
</InView>
|
||||
);
|
||||
|
|
|
@ -26,6 +26,7 @@ import autoBind from 'auto-bind';
|
|||
import { onsNameRegex } from '../../session/snode_api/SNodeAPI';
|
||||
import { SNodeAPI } from '../../session/snode_api';
|
||||
import { clearSearch, search, updateSearchTerm } from '../../state/ducks/search';
|
||||
import { getFirstUnreadMessageIdInConversation } from '../../data/data';
|
||||
|
||||
export interface Props {
|
||||
searchTerm: string;
|
||||
|
@ -319,7 +320,11 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
|
|||
pubkeyorOns,
|
||||
ConversationTypeEnum.PRIVATE
|
||||
);
|
||||
window.inboxStore?.dispatch(openConversationExternal({ id: pubkeyorOns }));
|
||||
const firstUnreadIdOnOpen = await getFirstUnreadMessageIdInConversation(pubkeyorOns);
|
||||
|
||||
window.inboxStore?.dispatch(
|
||||
openConversationExternal({ id: pubkeyorOns, firstUnreadIdOnOpen })
|
||||
);
|
||||
this.handleToggleOverlay(undefined);
|
||||
} else {
|
||||
// this might be an ONS, validate the regex first
|
||||
|
@ -339,7 +344,12 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
|
|||
resolvedSessionID,
|
||||
ConversationTypeEnum.PRIVATE
|
||||
);
|
||||
window.inboxStore?.dispatch(openConversationExternal({ id: resolvedSessionID }));
|
||||
|
||||
const firstUnreadIdOnOpen = await getFirstUnreadMessageIdInConversation(resolvedSessionID);
|
||||
|
||||
window.inboxStore?.dispatch(
|
||||
openConversationExternal({ id: resolvedSessionID, firstUnreadIdOnOpen })
|
||||
);
|
||||
this.handleToggleOverlay(undefined);
|
||||
} catch (e) {
|
||||
window?.log?.warn('failed to resolve ons name', pubkeyorOns, e);
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
PropsForDataExtractionNotification,
|
||||
QuoteClickOptions,
|
||||
} from '../../../models/messageType';
|
||||
import { getFirstUnreadMessageIdInConversation, getMessagesBySentAt } from '../../../data/data';
|
||||
import { getMessagesBySentAt } from '../../../data/data';
|
||||
import autoBind from 'auto-bind';
|
||||
import { ConversationTypeEnum } from '../../../models/conversation';
|
||||
import { DataExtractionNotification } from '../../conversation/DataExtractionNotification';
|
||||
|
@ -44,9 +44,9 @@ import {
|
|||
getSelectedConversationKey,
|
||||
getShowScrollButton,
|
||||
isMessageSelectionMode,
|
||||
getFirstUnreadMessageIndex,
|
||||
areMoreMessagesBeingFetched,
|
||||
isFirstUnreadMessageIdAbove,
|
||||
getFirstUnreadMessageId,
|
||||
} from '../../../state/selectors/conversations';
|
||||
import { isElectronWindowFocused } from '../../../session/utils/WindowUtils';
|
||||
import useInterval from 'react-use/lib/useInterval';
|
||||
|
@ -65,8 +65,9 @@ type Props = SessionMessageListProps & {
|
|||
areMoreMessagesBeingFetched: boolean;
|
||||
};
|
||||
|
||||
const UnreadIndicator = (props: { messageId: string; show: boolean }) => {
|
||||
if (!props.show) {
|
||||
const UnreadIndicator = (props: { messageId: string }) => {
|
||||
const isFirstUnreadOnOpen = useSelector(getFirstUnreadMessageId);
|
||||
if (!isFirstUnreadOnOpen || isFirstUnreadOnOpen !== props.messageId) {
|
||||
return null;
|
||||
}
|
||||
return <SessionLastSeenIndicator key={`unread-indicator-${props.messageId}`} />;
|
||||
|
@ -75,12 +76,11 @@ const UnreadIndicator = (props: { messageId: string; show: boolean }) => {
|
|||
const GroupUpdateItem = (props: {
|
||||
messageId: string;
|
||||
groupNotificationProps: PropsForGroupUpdate;
|
||||
showUnreadIndicator: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<React.Fragment key={props.messageId}>
|
||||
<GroupNotification key={props.messageId} {...props.groupNotificationProps} />
|
||||
<UnreadIndicator messageId={props.messageId} show={props.showUnreadIndicator} />
|
||||
<UnreadIndicator messageId={props.messageId} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -88,13 +88,12 @@ const GroupUpdateItem = (props: {
|
|||
const GroupInvitationItem = (props: {
|
||||
messageId: string;
|
||||
propsForGroupInvitation: PropsForGroupInvitation;
|
||||
showUnreadIndicator: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<React.Fragment key={props.messageId}>
|
||||
<GroupInvitation key={props.messageId} {...props.propsForGroupInvitation} />
|
||||
|
||||
<UnreadIndicator messageId={props.messageId} show={props.showUnreadIndicator} />
|
||||
<UnreadIndicator messageId={props.messageId} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -102,7 +101,6 @@ const GroupInvitationItem = (props: {
|
|||
const DataExtractionNotificationItem = (props: {
|
||||
messageId: string;
|
||||
propsForDataExtractionNotification: PropsForDataExtractionNotification;
|
||||
showUnreadIndicator: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<React.Fragment key={props.messageId}>
|
||||
|
@ -111,7 +109,7 @@ const DataExtractionNotificationItem = (props: {
|
|||
{...props.propsForDataExtractionNotification}
|
||||
/>
|
||||
|
||||
<UnreadIndicator messageId={props.messageId} show={props.showUnreadIndicator} />
|
||||
<UnreadIndicator messageId={props.messageId} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -119,13 +117,12 @@ const DataExtractionNotificationItem = (props: {
|
|||
const TimerNotificationItem = (props: {
|
||||
messageId: string;
|
||||
timerProps: PropsForExpirationTimer;
|
||||
showUnreadIndicator: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<React.Fragment key={props.messageId}>
|
||||
<TimerNotification key={props.messageId} {...props.timerProps} />
|
||||
|
||||
<UnreadIndicator messageId={props.messageId} show={props.showUnreadIndicator} />
|
||||
<UnreadIndicator messageId={props.messageId} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -134,12 +131,10 @@ const GenericMessageItem = (props: {
|
|||
messageId: string;
|
||||
messageProps: SortedMessageModelProps;
|
||||
playableMessageIndex?: number;
|
||||
showUnreadIndicator: boolean;
|
||||
scrollToQuoteMessage: (options: QuoteClickOptions) => Promise<void>;
|
||||
playNextMessage?: (value: number) => void;
|
||||
}) => {
|
||||
const multiSelectMode = useSelector(isMessageSelectionMode);
|
||||
const quotedMessageToAnimate = useSelector(getQuotedMessageToAnimate);
|
||||
const nextMessageToPlay = useSelector(getNextMessageToPlayIndex);
|
||||
|
||||
const messageId = props.messageId;
|
||||
|
@ -152,7 +147,6 @@ const GenericMessageItem = (props: {
|
|||
...props.messageProps.propsForMessage,
|
||||
firstMessageOfSeries: props.messageProps.firstMessageOfSeries,
|
||||
multiSelectMode,
|
||||
isQuotedMessageToAnimate: messageId === quotedMessageToAnimate,
|
||||
nextMessageToPlay,
|
||||
playNextMessage: props.playNextMessage,
|
||||
onQuoteClick,
|
||||
|
@ -166,7 +160,7 @@ const GenericMessageItem = (props: {
|
|||
multiSelectMode={multiSelectMode}
|
||||
key={messageId}
|
||||
/>
|
||||
<UnreadIndicator messageId={props.messageId} show={props.showUnreadIndicator} />
|
||||
<UnreadIndicator messageId={props.messageId} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -176,7 +170,6 @@ const MessageList = (props: {
|
|||
playNextMessage?: (value: number) => void;
|
||||
}) => {
|
||||
const messagesProps = useSelector(getSortedMessagesOfSelectedConversation);
|
||||
const firstUnreadMessageIndex = useSelector(getFirstUnreadMessageIndex);
|
||||
const isAbove = useSelector(isFirstUnreadMessageIdAbove);
|
||||
|
||||
console.warn('isAbove', isAbove);
|
||||
|
@ -191,19 +184,12 @@ const MessageList = (props: {
|
|||
|
||||
const groupNotificationProps = messageProps.propsForGroupNotification;
|
||||
|
||||
// IF we found the first unread message
|
||||
// AND we are not scrolled all the way to the bottom
|
||||
// THEN, show the unread banner for the current message
|
||||
const showUnreadIndicator =
|
||||
Boolean(firstUnreadMessageIndex) && firstUnreadMessageIndex === index;
|
||||
|
||||
if (groupNotificationProps) {
|
||||
return (
|
||||
<GroupUpdateItem
|
||||
key={messageProps.propsForMessage.id}
|
||||
groupNotificationProps={groupNotificationProps}
|
||||
messageId={messageProps.propsForMessage.id}
|
||||
showUnreadIndicator={showUnreadIndicator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -214,7 +200,6 @@ const MessageList = (props: {
|
|||
key={messageProps.propsForMessage.id}
|
||||
propsForGroupInvitation={propsForGroupInvitation}
|
||||
messageId={messageProps.propsForMessage.id}
|
||||
showUnreadIndicator={showUnreadIndicator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -225,7 +210,6 @@ const MessageList = (props: {
|
|||
key={messageProps.propsForMessage.id}
|
||||
propsForDataExtractionNotification={propsForDataExtractionNotification}
|
||||
messageId={messageProps.propsForMessage.id}
|
||||
showUnreadIndicator={showUnreadIndicator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -236,7 +220,6 @@ const MessageList = (props: {
|
|||
key={messageProps.propsForMessage.id}
|
||||
timerProps={timerProps}
|
||||
messageId={messageProps.propsForMessage.id}
|
||||
showUnreadIndicator={showUnreadIndicator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -255,7 +238,6 @@ const MessageList = (props: {
|
|||
playableMessageIndex={playableMessageIndex}
|
||||
messageId={messageProps.propsForMessage.id}
|
||||
messageProps={messageProps}
|
||||
showUnreadIndicator={showUnreadIndicator}
|
||||
scrollToQuoteMessage={props.scrollToQuoteMessage}
|
||||
playNextMessage={props.playNextMessage}
|
||||
/>
|
||||
|
@ -266,7 +248,6 @@ const MessageList = (props: {
|
|||
};
|
||||
|
||||
class SessionMessagesListInner extends React.Component<Props> {
|
||||
private scrollOffsetBottomPx: number = Number.MAX_VALUE;
|
||||
private ignoreScrollEvents: boolean;
|
||||
private timeoutResetQuotedScroll: NodeJS.Timeout | null = null;
|
||||
|
||||
|
@ -301,7 +282,7 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
) {
|
||||
// displayed conversation changed. We have a bit of cleaning to do here
|
||||
this.ignoreScrollEvents = true;
|
||||
this.setupTimeoutResetQuotedHighlightedMessage(true);
|
||||
this.setupTimeoutResetQuotedHighlightedMessage(this.props.animateQuotedMessageId);
|
||||
this.initialMessageLoadingPosition();
|
||||
} else {
|
||||
// if we got new message for this convo, and we are scrolled to bottom
|
||||
|
@ -355,7 +336,7 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~ MESSAGE HANDLING ~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
private updateReadMessages() {
|
||||
private updateReadMessages(forceIsOnBottom = false) {
|
||||
const { messagesProps, conversationKey } = this.props;
|
||||
|
||||
if (!messagesProps || messagesProps.length === 0 || !conversationKey) {
|
||||
|
@ -372,7 +353,7 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.getScrollOffsetBottomPx() === 0 && isElectronWindowFocused()) {
|
||||
if ((forceIsOnBottom || this.getScrollOffsetBottomPx() === 0) && isElectronWindowFocused()) {
|
||||
void conversation.markRead(messagesProps[0].propsForMessage.receivedAt || 0);
|
||||
}
|
||||
}
|
||||
|
@ -450,10 +431,10 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
window.inboxStore?.dispatch(showScrollToBottomButton(showScrollButton));
|
||||
|
||||
// trigger markRead if we hit the bottom
|
||||
const isScrolledToBottom = bottomOfBottomMessage >= containerBottom - 5;
|
||||
const isScrolledToBottom = bottomOfBottomMessage <= containerBottom - 5;
|
||||
if (isScrolledToBottom) {
|
||||
// Mark messages read
|
||||
this.updateReadMessages();
|
||||
this.updateReadMessages(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -522,19 +503,15 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
* So we need to reset the state of of the highlighted message so when the users clicks again,
|
||||
* the highlight is shown once again
|
||||
*/
|
||||
private setupTimeoutResetQuotedHighlightedMessage(clearOnly = false) {
|
||||
private setupTimeoutResetQuotedHighlightedMessage(messageId: string | undefined) {
|
||||
if (this.timeoutResetQuotedScroll) {
|
||||
clearTimeout(this.timeoutResetQuotedScroll);
|
||||
}
|
||||
// only clear the timeout, do not schedule once again
|
||||
if (clearOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.props.animateQuotedMessageId !== undefined) {
|
||||
if (messageId !== undefined) {
|
||||
this.timeoutResetQuotedScroll = global.setTimeout(() => {
|
||||
window.inboxStore?.dispatch(quotedMessageToAnimate(undefined));
|
||||
}, 3000);
|
||||
}, 2000); // should match .flash-green-once
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +525,7 @@ class SessionMessagesListInner extends React.Component<Props> {
|
|||
// we consider that a `smooth` set to true, means it's a quoted message, so highlight this message on the UI
|
||||
if (smooth) {
|
||||
window.inboxStore?.dispatch(quotedMessageToAnimate(messageId));
|
||||
this.setupTimeoutResetQuotedHighlightedMessage();
|
||||
this.setupTimeoutResetQuotedHighlightedMessage(messageId);
|
||||
}
|
||||
|
||||
const messageContainer = this.props.messageContainerRef.current;
|
||||
|
|
|
@ -1087,8 +1087,17 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
|
||||
public async markRead(readAt: number) {
|
||||
this.markReadNoCommit(readAt);
|
||||
|
||||
await this.commit();
|
||||
|
||||
const convo = this.getConversation();
|
||||
if (convo) {
|
||||
const beforeUnread = convo.get('unreadCount');
|
||||
const unreadCount = await convo.getUnreadCount();
|
||||
if (beforeUnread !== unreadCount) {
|
||||
convo.set({ unreadCount });
|
||||
await convo.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public markReadNoCommit(readAt: number) {
|
||||
|
|
|
@ -244,7 +244,6 @@ export interface MessageRegularProps {
|
|||
multiSelectMode: boolean;
|
||||
firstMessageOfSeries: boolean;
|
||||
isUnread: boolean;
|
||||
isQuotedMessageToAnimate?: boolean;
|
||||
isTrustedForAttachmentDownload: boolean;
|
||||
onQuoteClick?: (options: QuoteClickOptions) => Promise<void>;
|
||||
|
||||
|
|
|
@ -31,10 +31,7 @@ import { forceSyncConfigurationNowIfNeeded } from '../session/utils/syncUtils';
|
|||
import { getMessageController } from '../session/messages';
|
||||
import { ClosedGroupEncryptionPairReplyMessage } from '../session/messages/outgoing/controlMessage/group/ClosedGroupEncryptionPairReplyMessage';
|
||||
import { queueAllCachedFromSource } from './receiver';
|
||||
import {
|
||||
actions as conversationActions,
|
||||
openConversationExternal,
|
||||
} from '../state/ducks/conversations';
|
||||
import { openConversationExternal } from '../state/ducks/conversations';
|
||||
import { getSwarmPollingInstance } from '../session/snode_api';
|
||||
import { MessageModel } from '../models/message';
|
||||
|
||||
|
@ -955,7 +952,9 @@ export async function createClosedGroup(groupName: string, members: Array<string
|
|||
|
||||
await forceSyncConfigurationNowIfNeeded();
|
||||
|
||||
window.inboxStore?.dispatch(openConversationExternal({ id: groupPublicKey }));
|
||||
window.inboxStore?.dispatch(
|
||||
openConversationExternal({ id: groupPublicKey, firstUnreadIdOnOpen: undefined })
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -292,7 +292,6 @@ export type SortedMessageModelProps = MessageModelProps & {
|
|||
type FetchedMessageResults = {
|
||||
conversationKey: string;
|
||||
messagesProps: Array<MessageModelProps>;
|
||||
firstUnreadMessageId: string | undefined;
|
||||
};
|
||||
|
||||
export const fetchMessagesForConversation = createAsyncThunk(
|
||||
|
@ -307,8 +306,6 @@ export const fetchMessagesForConversation = createAsyncThunk(
|
|||
const beforeTimestamp = Date.now();
|
||||
console.time('fetchMessagesForConversation');
|
||||
const messagesProps = await getMessages(conversationKey, count);
|
||||
|
||||
const firstUnreadMessageId = await getFirstUnreadMessageIdInConversation(conversationKey);
|
||||
const afterTimestamp = Date.now();
|
||||
console.timeEnd('fetchMessagesForConversation');
|
||||
|
||||
|
@ -318,7 +315,6 @@ export const fetchMessagesForConversation = createAsyncThunk(
|
|||
return {
|
||||
conversationKey,
|
||||
messagesProps,
|
||||
firstUnreadMessageId,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
@ -594,12 +590,14 @@ const conversationsSlice = createSlice({
|
|||
state: ConversationsStateType,
|
||||
action: PayloadAction<{
|
||||
id: string;
|
||||
firstUnreadIdOnOpen: string | undefined;
|
||||
messageId?: string;
|
||||
}>
|
||||
) {
|
||||
if (state.selectedConversation === action.payload.id) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return {
|
||||
conversationLookup: state.conversationLookup,
|
||||
selectedConversation: action.payload.id,
|
||||
|
@ -615,7 +613,7 @@ const conversationsSlice = createSlice({
|
|||
showScrollButton: false,
|
||||
animateQuotedMessageId: undefined,
|
||||
mentionMembers: [],
|
||||
firstUnreadMessageId: undefined,
|
||||
firstUnreadMessageId: action.payload.firstUnreadIdOnOpen,
|
||||
};
|
||||
},
|
||||
showLightBox(
|
||||
|
@ -662,14 +660,13 @@ const conversationsSlice = createSlice({
|
|||
fetchMessagesForConversation.fulfilled,
|
||||
(state: ConversationsStateType, action: PayloadAction<FetchedMessageResults>) => {
|
||||
// this is called once the messages are loaded from the db for the currently selected conversation
|
||||
const { messagesProps, conversationKey, firstUnreadMessageId } = action.payload;
|
||||
const { messagesProps, conversationKey } = action.payload;
|
||||
// double check that this update is for the shown convo
|
||||
if (conversationKey === state.selectedConversation) {
|
||||
return {
|
||||
...state,
|
||||
messages: messagesProps,
|
||||
areMoreMessagesBeingFetched: false,
|
||||
firstUnreadMessageId,
|
||||
};
|
||||
}
|
||||
return state;
|
||||
|
|
|
@ -5,11 +5,7 @@ import { cleanSearchTerm } from '../../util/cleanSearchTerm';
|
|||
import { searchConversations, searchMessages } from '../../../ts/data/data';
|
||||
import { makeLookup } from '../../util/makeLookup';
|
||||
|
||||
import {
|
||||
openConversationExternal,
|
||||
PropsForSearchResults,
|
||||
ReduxConversationType,
|
||||
} from './conversations';
|
||||
import { PropsForSearchResults, ReduxConversationType } from './conversations';
|
||||
import { PubKey } from '../../session/types';
|
||||
import { MessageModel } from '../../models/message';
|
||||
import { MessageModelType } from '../../models/messageType';
|
||||
|
|
|
@ -402,14 +402,6 @@ function sortMessages(
|
|||
return messagesSorted;
|
||||
}
|
||||
|
||||
export const getFirstUnreadMessageIndex = createSelector(
|
||||
getSortedMessagesOfSelectedConversation,
|
||||
(messageModelsProps: Array<MessageModelProps>): number | undefined => {
|
||||
const firstUnreadIndex = getFirstMessageUnreadIndex(messageModelsProps);
|
||||
return firstUnreadIndex;
|
||||
}
|
||||
);
|
||||
|
||||
function getFirstMessageUnreadIndex(messages: Array<MessageModelProps>) {
|
||||
if (!messages || messages.length === 0) {
|
||||
return -1;
|
||||
|
@ -442,7 +434,6 @@ function getFirstMessageUnreadIndex(messages: Array<MessageModelProps>) {
|
|||
export const getFirstUnreadMessageId = createSelector(
|
||||
getConversations,
|
||||
(state: ConversationsStateType): string | undefined => {
|
||||
console.warn('getFirstUnreadMessageId', state.firstUnreadMessageId);
|
||||
return state.firstUnreadMessageId;
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue