Message List: Do not mark messages read when in background (another attempt)

This commit is contained in:
Alexander Zinchuk 2021-06-19 00:25:33 +03:00
parent 7355100770
commit 5f6010bbd0
5 changed files with 27 additions and 34 deletions

View File

@ -54,6 +54,7 @@ import fastSmoothScroll, { isAnimatingScroll } from '../../util/fastSmoothScroll
import renderText from '../common/helpers/renderText'; import renderText from '../common/helpers/renderText';
import useLang, { LangFn } from '../../hooks/useLang'; import useLang, { LangFn } from '../../hooks/useLang';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/useWindowSize';
import useBackgroundMode from '../../hooks/useBackgroundMode';
import Loading from '../ui/Loading'; import Loading from '../ui/Loading';
import MessageScroll from './MessageScroll'; import MessageScroll from './MessageScroll';
@ -227,6 +228,8 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
} }
}); });
useBackgroundMode(freezeForReading, unfreezeForReading);
useOnChange(() => { useOnChange(() => {
memoFocusingIdRef.current = focusingId; memoFocusingIdRef.current = focusingId;

View File

@ -1,7 +1,5 @@
import { MutableRefObject } from 'react'; import { MutableRefObject } from 'react';
import React, { import React, { FC, useCallback, useRef } from '../../lib/teact/teact';
FC, useCallback, useEffect, useRef,
} from '../../lib/teact/teact';
import { MESSAGE_LIST_SENSITIVE_AREA } from '../../config'; import { MESSAGE_LIST_SENSITIVE_AREA } from '../../config';
import resetScroll from '../../util/resetScroll'; import resetScroll from '../../util/resetScroll';
@ -25,9 +23,6 @@ type OwnProps = {
const FAB_THRESHOLD = 50; const FAB_THRESHOLD = 50;
const TOOLS_FREEZE_TIMEOUT = 100; const TOOLS_FREEZE_TIMEOUT = 100;
// Local flag is used because `freeze/unfreeze` methods are controlled by heavy animation
let areToolsFrozen = false;
const MessageScroll: FC<OwnProps> = ({ const MessageScroll: FC<OwnProps> = ({
containerRef, containerRef,
className, className,
@ -49,10 +44,6 @@ const MessageScroll: FC<OwnProps> = ({
const fabTriggerRef = useRef<HTMLDivElement>(null); const fabTriggerRef = useRef<HTMLDivElement>(null);
const toggleScrollTools = useCallback(() => { const toggleScrollTools = useCallback(() => {
if (areToolsFrozen) {
return;
}
if (!messageIds || !messageIds.length) { if (!messageIds || !messageIds.length) {
onFabToggle(false); onFabToggle(false);
onNotchToggle(false); onNotchToggle(false);
@ -118,35 +109,34 @@ const MessageScroll: FC<OwnProps> = ({
const { const {
observe: observeIntersectionForNotch, observe: observeIntersectionForNotch,
freeze: freezeForNotch,
unfreeze: unfreezeForNotch,
} = useIntersectionObserver({ } = useIntersectionObserver({
rootRef: containerRef, rootRef: containerRef,
}, toggleScrollTools); }, toggleScrollTools);
useOnIntersect(fabTriggerRef, observeIntersectionForNotch); useOnIntersect(fabTriggerRef, observeIntersectionForNotch);
// Do not load more and show FAB when focusing const isFocusing = Boolean(focusingId);
useOnChange(() => { useOnChange(() => {
if (focusingId) { if (isFocusing) {
freezeForLoadMore(); freezeForLoadMore();
freezeForFab();
} else { } else {
unfreezeForFab();
unfreezeForLoadMore(); unfreezeForLoadMore();
} }
}, [focusingId]); }, [isFocusing]);
// Workaround for FAB and notch flickering with tall incoming message // Workaround for FAB and notch flickering with tall incoming message
useOnChange(() => { useOnChange(() => {
areToolsFrozen = true; freezeForFab();
freezeForNotch();
setTimeout(() => { setTimeout(() => {
areToolsFrozen = false; unfreezeForNotch();
unfreezeForFab();
}, TOOLS_FREEZE_TIMEOUT); }, TOOLS_FREEZE_TIMEOUT);
}, [messageIds]); }, [messageIds]);
// Workaround for stuck FAB when many unread messages
useEffect(toggleScrollTools, [firstUnreadId]);
return ( return (
<div className={className} teactFastList> <div className={className} teactFastList>
<div ref={backwardsTriggerRef} key="backwards-trigger" className="backwards-trigger" /> <div ref={backwardsTriggerRef} key="backwards-trigger" className="backwards-trigger" />

View File

@ -1,11 +1,10 @@
import React, { FC, useCallback, useEffect } from '../../../lib/teact/teact'; import React, { FC, useCallback } from '../../../lib/teact/teact';
import { ApiMessage } from '../../../api/types'; import { ApiMessage } from '../../../api/types';
import { IAnchorPosition } from '../../../types'; import { IAnchorPosition } from '../../../types';
import { getMessageCopyOptions } from './helpers/copyOptions'; import { getMessageCopyOptions } from './helpers/copyOptions';
import useContextMenuPosition from '../../../hooks/useContextMenuPosition'; import useContextMenuPosition from '../../../hooks/useContextMenuPosition';
import { dispatchHeavyAnimationEvent } from '../../../hooks/useHeavyAnimationCheck';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import Menu from '../../ui/Menu'; import Menu from '../../ui/Menu';
@ -46,7 +45,6 @@ type OwnProps = {
onCopyLink?: () => void; onCopyLink?: () => void;
}; };
const ANIMATION_DURATION = 200;
const SCROLLBAR_WIDTH = 10; const SCROLLBAR_WIDTH = 10;
const MessageContextMenu: FC<OwnProps> = ({ const MessageContextMenu: FC<OwnProps> = ({
@ -81,10 +79,6 @@ const MessageContextMenu: FC<OwnProps> = ({
onCloseAnimationEnd, onCloseAnimationEnd,
onCopyLink, onCopyLink,
}) => { }) => {
useEffect(() => {
dispatchHeavyAnimationEvent(ANIMATION_DURATION);
}, [isOpen]);
const copyOptions = getMessageCopyOptions(message, onClose, canCopyLink ? onCopyLink : undefined); const copyOptions = getMessageCopyOptions(message, onClose, canCopyLink ? onCopyLink : undefined);
const getTriggerElement = useCallback(() => { const getTriggerElement = useCallback(() => {

View File

@ -7,8 +7,10 @@ let timeout: number | undefined;
let isAnimating = false; let isAnimating = false;
export const dispatchHeavyAnimationEvent = (duration: number) => { export const dispatchHeavyAnimationEvent = (duration: number) => {
document.dispatchEvent(new Event(ANIMATION_START_EVENT)); if (!isAnimating) {
isAnimating = true; isAnimating = true;
document.dispatchEvent(new Event(ANIMATION_START_EVENT));
}
if (timeout) { if (timeout) {
clearTimeout(timeout); clearTimeout(timeout);

View File

@ -41,19 +41,23 @@ export function useIntersectionObserver({
}, rootCallback?: RootCallback): Response { }, rootCallback?: RootCallback): Response {
const controllerRef = useRef<IntersectionController>(); const controllerRef = useRef<IntersectionController>();
const rootCallbackRef = useRef<RootCallback>(); const rootCallbackRef = useRef<RootCallback>();
const isFrozenRef = useRef<boolean>(); const freezeFlagsRef = useRef(0);
const onUnfreezeRef = useRef<NoneToVoidFunction>(); const onUnfreezeRef = useRef<NoneToVoidFunction>();
rootCallbackRef.current = rootCallback; rootCallbackRef.current = rootCallback;
const freeze = useCallback(() => { const freeze = useCallback(() => {
isFrozenRef.current = true; freezeFlagsRef.current++;
}, []); }, []);
const unfreeze = useCallback(() => { const unfreeze = useCallback(() => {
isFrozenRef.current = false; if (!freezeFlagsRef.current) {
return;
}
if (onUnfreezeRef.current) { freezeFlagsRef.current--;
if (!freezeFlagsRef.current && onUnfreezeRef.current) {
onUnfreezeRef.current(); onUnfreezeRef.current();
onUnfreezeRef.current = undefined; onUnfreezeRef.current = undefined;
} }
@ -104,7 +108,7 @@ export function useIntersectionObserver({
entriesAccumulator.set(entry.target, entry); entriesAccumulator.set(entry.target, entry);
}); });
if (isFrozenRef.current) { if (freezeFlagsRef.current) {
onUnfreezeRef.current = () => { onUnfreezeRef.current = () => {
observerCallback(); observerCallback();
}; };