Save source of selectedMessage changes to prevent unnecessary scrolls

This commit is contained in:
Scott Nonnenberg 2022-11-09 12:18:03 -08:00 committed by GitHub
parent d00898fdfc
commit 4fa614e1d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 3 deletions

View file

@ -81,6 +81,7 @@ export const App = ({
requestVerification, requestVerification,
selectedConversationId, selectedConversationId,
selectedMessage, selectedMessage,
selectedMessageSource,
showConversation, showConversation,
showWhatsNewModal, showWhatsNewModal,
theme, theme,
@ -117,6 +118,7 @@ export const App = ({
renderLeftPane={renderLeftPane} renderLeftPane={renderLeftPane}
selectedConversationId={selectedConversationId} selectedConversationId={selectedConversationId}
selectedMessage={selectedMessage} selectedMessage={selectedMessage}
selectedMessageSource={selectedMessageSource}
showConversation={showConversation} showConversation={showConversation}
showWhatsNewModal={showWhatsNewModal} showWhatsNewModal={showWhatsNewModal}
/> />

View file

@ -15,6 +15,7 @@ import { ToastStickerPackInstallFailed } from './ToastStickerPackInstallFailed';
import { WhatsNewLink } from './WhatsNewLink'; import { WhatsNewLink } from './WhatsNewLink';
import { showToast } from '../util/showToast'; import { showToast } from '../util/showToast';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
import { SelectedMessageSource } from '../state/ducks/conversationsEnums';
export type PropsType = { export type PropsType = {
hasInitialLoadCompleted: boolean; hasInitialLoadCompleted: boolean;
@ -24,6 +25,7 @@ export type PropsType = {
renderLeftPane: () => JSX.Element; renderLeftPane: () => JSX.Element;
selectedConversationId?: string; selectedConversationId?: string;
selectedMessage?: string; selectedMessage?: string;
selectedMessageSource?: SelectedMessageSource;
showConversation: ShowConversationType; showConversation: ShowConversationType;
showWhatsNewModal: () => unknown; showWhatsNewModal: () => unknown;
}; };
@ -36,6 +38,7 @@ export const Inbox = ({
renderLeftPane, renderLeftPane,
selectedConversationId, selectedConversationId,
selectedMessage, selectedMessage,
selectedMessageSource,
showConversation, showConversation,
showWhatsNewModal, showWhatsNewModal,
}: PropsType): JSX.Element => { }: PropsType): JSX.Element => {
@ -86,13 +89,21 @@ export const Inbox = ({
setPrevConversation(conversation); setPrevConversation(conversation);
conversation.trigger('opened', selectedMessage); conversation.trigger('opened', selectedMessage);
} else if (selectedMessage) { } else if (
selectedMessage &&
selectedMessageSource !== SelectedMessageSource.Focus
) {
conversation.trigger('scroll-to-message', selectedMessage); conversation.trigger('scroll-to-message', selectedMessage);
} }
// Make sure poppers are positioned properly // Make sure poppers are positioned properly
window.dispatchEvent(new Event('resize')); window.dispatchEvent(new Event('resize'));
}, [prevConversation, selectedConversationId, selectedMessage]); }, [
prevConversation,
selectedConversationId,
selectedMessage,
selectedMessageSource,
]);
// Whenever the selectedConversationId is cleared we should also ensure // Whenever the selectedConversationId is cleared we should also ensure
// that prevConversation is cleared too. // that prevConversation is cleared too.

View file

@ -72,6 +72,7 @@ import {
ComposerStep, ComposerStep,
ConversationVerificationState, ConversationVerificationState,
OneTimeModalState, OneTimeModalState,
SelectedMessageSource,
} from './conversationsEnums'; } from './conversationsEnums';
import { markViewed as messageUpdaterMarkViewed } from '../../services/MessageUpdater'; import { markViewed as messageUpdaterMarkViewed } from '../../services/MessageUpdater';
import { useBoundActions } from '../../hooks/useBoundActions'; import { useBoundActions } from '../../hooks/useBoundActions';
@ -341,8 +342,9 @@ export type ConversationsStateType = {
conversationsByGroupId: ConversationLookupType; conversationsByGroupId: ConversationLookupType;
conversationsByUsername: ConversationLookupType; conversationsByUsername: ConversationLookupType;
selectedConversationId?: string; selectedConversationId?: string;
selectedMessage?: string; selectedMessage: string | undefined;
selectedMessageCounter: number; selectedMessageCounter: number;
selectedMessageSource: SelectedMessageSource | undefined;
selectedConversationTitle?: string; selectedConversationTitle?: string;
selectedConversationPanelDepth: number; selectedConversationPanelDepth: number;
showArchived: boolean; showArchived: boolean;
@ -2118,7 +2120,9 @@ export function getEmptyState(): ConversationsStateType {
verificationDataByConversation: {}, verificationDataByConversation: {},
messagesByConversation: {}, messagesByConversation: {},
messagesLookup: {}, messagesLookup: {},
selectedMessage: undefined,
selectedMessageCounter: 0, selectedMessageCounter: 0,
selectedMessageSource: undefined,
showArchived: false, showArchived: false,
selectedConversationTitle: '', selectedConversationTitle: '',
selectedConversationPanelDepth: 0, selectedConversationPanelDepth: 0,
@ -2605,6 +2609,7 @@ export function reducer(
...state, ...state,
selectedMessage: messageId, selectedMessage: messageId,
selectedMessageCounter: state.selectedMessageCounter + 1, selectedMessageCounter: state.selectedMessageCounter + 1,
selectedMessageSource: SelectedMessageSource.Focus,
}; };
} }
if (action.type === CONVERSATION_STOPPED_BY_MISSING_VERIFICATION) { if (action.type === CONVERSATION_STOPPED_BY_MISSING_VERIFICATION) {
@ -2750,6 +2755,7 @@ export function reducer(
? { ? {
selectedMessage: scrollToMessageId, selectedMessage: scrollToMessageId,
selectedMessageCounter: state.selectedMessageCounter + 1, selectedMessageCounter: state.selectedMessageCounter + 1,
selectedMessageSource: SelectedMessageSource.Reset,
} }
: {}), : {}),
messagesLookup: { messagesLookup: {
@ -2842,6 +2848,7 @@ export function reducer(
...state, ...state,
selectedMessage: messageId, selectedMessage: messageId,
selectedMessageCounter: state.selectedMessageCounter + 1, selectedMessageCounter: state.selectedMessageCounter + 1,
selectedMessageSource: SelectedMessageSource.NavigateToMessage,
messagesByConversation: { messagesByConversation: {
...messagesByConversation, ...messagesByConversation,
[conversationId]: { [conversationId]: {
@ -3127,6 +3134,8 @@ export function reducer(
return { return {
...state, ...state,
selectedMessage: undefined, selectedMessage: undefined,
selectedMessageCounter: 0,
selectedMessageSource: undefined,
}; };
} }
if (action.type === 'CLEAR_UNREAD_METRICS') { if (action.type === 'CLEAR_UNREAD_METRICS') {
@ -3161,6 +3170,7 @@ export function reducer(
...omit(state, 'contactSpoofingReview'), ...omit(state, 'contactSpoofingReview'),
selectedConversationId: id, selectedConversationId: id,
selectedMessage: messageId, selectedMessage: messageId,
selectedMessageSource: SelectedMessageSource.NavigateToMessage,
}; };
if (switchToAssociatedView && id) { if (switchToAssociatedView && id) {

View file

@ -23,3 +23,9 @@ export enum ConversationVerificationState {
PendingVerification = 'PendingVerification', PendingVerification = 'PendingVerification',
VerificationCancelled = 'VerificationCancelled', VerificationCancelled = 'VerificationCancelled',
} }
export enum SelectedMessageSource {
Reset = 'Reset',
NavigateToMessage = 'NavigateToMessage',
Focus = 'Focus',
}

View file

@ -85,6 +85,7 @@ const mapStateToProps = (state: StateType) => {
}, },
selectedConversationId: state.conversations.selectedConversationId, selectedConversationId: state.conversations.selectedConversationId,
selectedMessage: state.conversations.selectedMessage, selectedMessage: state.conversations.selectedMessage,
selectedMessageSource: state.conversations.selectedMessageSource,
theme: getTheme(state), theme: getTheme(state),
executeMenuRole: (role: MenuItemConstructorOptions['role']): void => { executeMenuRole: (role: MenuItemConstructorOptions['role']): void => {