Message List: Do not mark messages read when in background (another attempt)
This commit is contained in:
parent
7355100770
commit
5f6010bbd0
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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" />
|
||||||
|
|||||||
@ -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(() => {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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();
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user