Fix Timeline to not peek group call for direct calls
This commit is contained in:
parent
9ebdf6e399
commit
b359d28771
4 changed files with 52 additions and 21 deletions
|
@ -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,
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue