Fix Timeline to not peek group call for direct calls

This commit is contained in:
ayumi-signal 2024-03-18 12:47:22 -07:00 committed by GitHub
parent 9ebdf6e399
commit b359d28771
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 21 deletions

View file

@ -463,6 +463,7 @@ const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
overrideProps.invitedContactsForNewlyCreatedGroup || [], overrideProps.invitedContactsForNewlyCreatedGroup || [],
warning: overrideProps.warning, warning: overrideProps.warning,
hasContactSpoofingReview: false, hasContactSpoofingReview: false,
conversationType: 'direct',
id: uuid(), id: uuid(),
renderItem, renderItem,

View file

@ -88,6 +88,7 @@ type PropsHousekeepingType = {
isSomeoneTyping: boolean; isSomeoneTyping: boolean;
unreadCount?: number; unreadCount?: number;
unreadMentionsCount?: number; unreadMentionsCount?: number;
conversationType: 'direct' | 'group';
targetedMessageId?: string; targetedMessageId?: string;
invitedContactsForNewlyCreatedGroup: Array<ConversationType>; invitedContactsForNewlyCreatedGroup: Array<ConversationType>;
@ -497,21 +498,8 @@ export class Timeline extends React.Component<
} }
}, 500); }, 500);
public override componentDidMount(): void { private setupGroupCallPeekTimeouts(): void {
const containerEl = this.containerRef.current; this.cleanupGroupCallPeekTimeouts();
const messagesEl = this.messagesRef.current;
const { isConversationSelected } = this.props;
strictAssert(
// We don't render anything unless the conversation is selected
(containerEl && messagesEl) || !isConversationSelected,
'<Timeline> mounted without some refs'
);
this.updateIntersectionObserver();
window.SignalContext.activeWindowService.registerForActive(
this.markNewestBottomVisibleMessageRead
);
this.delayedPeekTimeout = setTimeout(() => { this.delayedPeekTimeout = setTimeout(() => {
const { id, peekGroupCallForTheFirstTime } = this.props; const { id, peekGroupCallForTheFirstTime } = this.props;
@ -525,19 +513,46 @@ export class Timeline extends React.Component<
}, MINUTE); }, MINUTE);
} }
public override componentWillUnmount(): void { private cleanupGroupCallPeekTimeouts(): void {
const { delayedPeekTimeout, peekInterval } = this; const { delayedPeekTimeout, peekInterval } = this;
clearTimeoutIfNecessary(delayedPeekTimeout);
this.delayedPeekTimeout = undefined;
if (peekInterval) {
clearInterval(peekInterval);
this.peekInterval = undefined;
}
}
public override componentDidMount(): void {
const containerEl = this.containerRef.current;
const messagesEl = this.messagesRef.current;
const { conversationType, isConversationSelected } = this.props;
strictAssert(
// We don't render anything unless the conversation is selected
(containerEl && messagesEl) || !isConversationSelected,
'<Timeline> mounted without some refs'
);
this.updateIntersectionObserver();
window.SignalContext.activeWindowService.registerForActive(
this.markNewestBottomVisibleMessageRead
);
if (conversationType === 'group') {
this.setupGroupCallPeekTimeouts();
}
}
public override componentWillUnmount(): void {
window.SignalContext.activeWindowService.unregisterForActive( window.SignalContext.activeWindowService.unregisterForActive(
this.markNewestBottomVisibleMessageRead this.markNewestBottomVisibleMessageRead
); );
this.intersectionObserver?.disconnect(); this.intersectionObserver?.disconnect();
this.cleanupGroupCallPeekTimeouts();
clearTimeoutIfNecessary(delayedPeekTimeout);
if (peekInterval) {
clearInterval(peekInterval);
}
} }
public override getSnapshotBeforeUpdate( public override getSnapshotBeforeUpdate(
@ -588,11 +603,13 @@ export class Timeline extends React.Component<
snapshot: Readonly<SnapshotType> snapshot: Readonly<SnapshotType>
): void { ): void {
const { const {
conversationType: previousConversationType,
items: oldItems, items: oldItems,
messageChangeCounter: previousMessageChangeCounter, messageChangeCounter: previousMessageChangeCounter,
messageLoadingState: previousMessageLoadingState, messageLoadingState: previousMessageLoadingState,
} = prevProps; } = prevProps;
const { const {
conversationType,
discardMessages, discardMessages,
id, id,
items: newItems, items: newItems,
@ -666,6 +683,13 @@ export class Timeline extends React.Component<
if (previousMessageChangeCounter !== messageChangeCounter) { if (previousMessageChangeCounter !== messageChangeCounter) {
this.markNewestBottomVisibleMessageRead(); this.markNewestBottomVisibleMessageRead();
} }
if (previousConversationType !== conversationType) {
this.cleanupGroupCallPeekTimeouts();
if (conversationType === 'group') {
this.setupGroupCallPeekTimeouts();
}
}
} }
private handleBlur = (event: React.FocusEvent): void => { private handleBlur = (event: React.FocusEvent): void => {

View file

@ -210,6 +210,7 @@ export const SmartTimeline = memo(function SmartTimeline({
typingContactIdTimestamps = {}, typingContactIdTimestamps = {},
unreadCount, unreadCount,
unreadMentionsCount, unreadMentionsCount,
type: conversationType,
} = conversation ?? {}; } = conversation ?? {};
const { const {
haveNewest, haveNewest,
@ -240,6 +241,7 @@ export const SmartTimeline = memo(function SmartTimeline({
} }
clearTargetedMessage={clearTargetedMessage} clearTargetedMessage={clearTargetedMessage}
closeContactSpoofingReview={closeContactSpoofingReview} closeContactSpoofingReview={closeContactSpoofingReview}
conversationType={conversationType}
discardMessages={discardMessages} discardMessages={discardMessages}
getPreferredBadge={getPreferredBadge} getPreferredBadge={getPreferredBadge}
getTimestampForMessage={getTimestampForMessage} getTimestampForMessage={getTimestampForMessage}

View file

@ -1,6 +1,10 @@
// Copyright 2022 Signal Messenger, LLC // Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
/**
* Calls clearTimeout on a timeout if it is defined.
* Note: Do not use with intervals (e.g. setInterval). Results may be unexpected.
* */
export function clearTimeoutIfNecessary( export function clearTimeoutIfNecessary(
timeout: undefined | null | ReturnType<typeof setTimeout> timeout: undefined | null | ReturnType<typeof setTimeout>
): void { ): void {