Floating Actions Buttons: Fix animations (#3575)
Co-authored-by: zubiden <19638254+zubiden@users.noreply.github.com>
This commit is contained in:
parent
2688cd768a
commit
11cbab7d39
1
src/@types/global.d.ts
vendored
1
src/@types/global.d.ts
vendored
@ -38,6 +38,7 @@ type AnyLiteral = Record<string, any>;
|
|||||||
type AnyClass = new (...args: any[]) => any;
|
type AnyClass = new (...args: any[]) => any;
|
||||||
type AnyFunction = (...args: any[]) => any;
|
type AnyFunction = (...args: any[]) => any;
|
||||||
type AnyToVoidFunction = (...args: any[]) => void;
|
type AnyToVoidFunction = (...args: any[]) => void;
|
||||||
|
type BooleanToVoidFunction = (value: boolean) => void;
|
||||||
type NoneToVoidFunction = () => void;
|
type NoneToVoidFunction = () => void;
|
||||||
|
|
||||||
type EmojiCategory = {
|
type EmojiCategory = {
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.only-reactions {
|
&.hide-scroll-down {
|
||||||
transform: translateY(4rem);
|
transform: translateY(4rem);
|
||||||
|
|
||||||
.unread {
|
.unread {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import ScrollDownButton from './ScrollDownButton';
|
|||||||
import styles from './FloatingActionButtons.module.scss';
|
import styles from './FloatingActionButtons.module.scss';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
isShown: boolean;
|
withScrollDown: boolean;
|
||||||
canPost?: boolean;
|
canPost?: boolean;
|
||||||
withExtraShift?: boolean;
|
withExtraShift?: boolean;
|
||||||
};
|
};
|
||||||
@ -32,7 +32,7 @@ type StateProps = {
|
|||||||
const FOCUS_MARGIN = 20;
|
const FOCUS_MARGIN = 20;
|
||||||
|
|
||||||
const FloatingActionButtons: FC<OwnProps & StateProps> = ({
|
const FloatingActionButtons: FC<OwnProps & StateProps> = ({
|
||||||
isShown,
|
withScrollDown,
|
||||||
canPost,
|
canPost,
|
||||||
messageListType,
|
messageListType,
|
||||||
chatId,
|
chatId,
|
||||||
@ -64,15 +64,17 @@ const FloatingActionButtons: FC<OwnProps & StateProps> = ({
|
|||||||
}
|
}
|
||||||
}, [chatId, fetchUnreadMentions, hasUnreadMentions]);
|
}, [chatId, fetchUnreadMentions, hasUnreadMentions]);
|
||||||
|
|
||||||
const handleClick = useLastCallback(() => {
|
const handleScrollDownClick = useLastCallback(() => {
|
||||||
if (!isShown) {
|
if (!withScrollDown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageListType === 'thread') {
|
if (messageListType === 'thread') {
|
||||||
focusNextReply();
|
focusNextReply();
|
||||||
} else {
|
} else {
|
||||||
const messagesContainer = elementRef.current!.parentElement!.querySelector<HTMLDivElement>('.MessageList')!;
|
const messagesContainer = elementRef.current!.parentElement!.querySelector<HTMLDivElement>(
|
||||||
|
'.Transition_slide-active > .MessageList',
|
||||||
|
)!;
|
||||||
const messageElements = messagesContainer.querySelectorAll<HTMLDivElement>('.message-list-item');
|
const messageElements = messagesContainer.querySelectorAll<HTMLDivElement>('.message-list-item');
|
||||||
const lastMessageElement = messageElements[messageElements.length - 1];
|
const lastMessageElement = messageElements[messageElements.length - 1];
|
||||||
if (!lastMessageElement) {
|
if (!lastMessageElement) {
|
||||||
@ -85,8 +87,8 @@ const FloatingActionButtons: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const fabClassName = buildClassName(
|
const fabClassName = buildClassName(
|
||||||
styles.root,
|
styles.root,
|
||||||
(isShown || Boolean(reactionsCount) || Boolean(mentionsCount)) && styles.revealed,
|
(withScrollDown || Boolean(reactionsCount) || Boolean(mentionsCount)) && styles.revealed,
|
||||||
(Boolean(reactionsCount) || Boolean(mentionsCount)) && !isShown && styles.onlyReactions,
|
(Boolean(reactionsCount) || Boolean(mentionsCount)) && !withScrollDown && styles.hideScrollDown,
|
||||||
!canPost && styles.noComposer,
|
!canPost && styles.noComposer,
|
||||||
!withExtraShift && styles.noExtraShift,
|
!withExtraShift && styles.noExtraShift,
|
||||||
);
|
);
|
||||||
@ -118,7 +120,7 @@ const FloatingActionButtons: FC<OwnProps & StateProps> = ({
|
|||||||
<ScrollDownButton
|
<ScrollDownButton
|
||||||
icon="arrow-down"
|
icon="arrow-down"
|
||||||
ariaLabelLang="AccDescrPageDown"
|
ariaLabelLang="AccDescrPageDown"
|
||||||
onClick={handleClick}
|
onClick={handleScrollDownClick}
|
||||||
unreadCount={unreadCount}
|
unreadCount={unreadCount}
|
||||||
className={styles.unread}
|
className={styles.unread}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -90,8 +90,8 @@ type OwnProps = {
|
|||||||
isComments?: boolean;
|
isComments?: boolean;
|
||||||
canPost: boolean;
|
canPost: boolean;
|
||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
onFabToggle: (shouldShow: boolean) => void;
|
onScrollDownToggle: BooleanToVoidFunction;
|
||||||
onNotchToggle: (shouldShow: boolean) => void;
|
onNotchToggle: BooleanToVoidFunction;
|
||||||
hasTools?: boolean;
|
hasTools?: boolean;
|
||||||
withBottomShift?: boolean;
|
withBottomShift?: boolean;
|
||||||
withDefaultBg: boolean;
|
withDefaultBg: boolean;
|
||||||
@ -148,7 +148,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
threadId,
|
threadId,
|
||||||
type,
|
type,
|
||||||
hasTools,
|
hasTools,
|
||||||
onFabToggle,
|
onScrollDownToggle,
|
||||||
onNotchToggle,
|
onNotchToggle,
|
||||||
isCurrentUserPremium,
|
isCurrentUserPremium,
|
||||||
isChatLoaded,
|
isChatLoaded,
|
||||||
@ -597,6 +597,12 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const hasMessages = (messageIds && messageGroups) || lastMessage;
|
const hasMessages = (messageIds && messageGroups) || lastMessage;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hasMessages) return;
|
||||||
|
|
||||||
|
onScrollDownToggle(false);
|
||||||
|
}, [hasMessages, onScrollDownToggle]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
@ -650,7 +656,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
isSchedule={messageGroups ? type === 'scheduled' : false}
|
isSchedule={messageGroups ? type === 'scheduled' : false}
|
||||||
shouldRenderBotInfo={isBot}
|
shouldRenderBotInfo={isBot}
|
||||||
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
||||||
onFabToggle={onFabToggle}
|
onScrollDownToggle={onScrollDownToggle}
|
||||||
onNotchToggle={onNotchToggle}
|
onNotchToggle={onNotchToggle}
|
||||||
onPinnedIntersectionChange={onPinnedIntersectionChange}
|
onPinnedIntersectionChange={onPinnedIntersectionChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -56,7 +56,7 @@ interface OwnProps {
|
|||||||
shouldRenderBotInfo?: boolean;
|
shouldRenderBotInfo?: boolean;
|
||||||
noAppearanceAnimation: boolean;
|
noAppearanceAnimation: boolean;
|
||||||
isSavedDialog?: boolean;
|
isSavedDialog?: boolean;
|
||||||
onFabToggle: AnyToVoidFunction;
|
onScrollDownToggle: BooleanToVoidFunction;
|
||||||
onNotchToggle: AnyToVoidFunction;
|
onNotchToggle: AnyToVoidFunction;
|
||||||
onPinnedIntersectionChange: PinnedIntersectionChangedCallback;
|
onPinnedIntersectionChange: PinnedIntersectionChangedCallback;
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
shouldRenderBotInfo,
|
shouldRenderBotInfo,
|
||||||
noAppearanceAnimation,
|
noAppearanceAnimation,
|
||||||
isSavedDialog,
|
isSavedDialog,
|
||||||
onFabToggle,
|
onScrollDownToggle,
|
||||||
onNotchToggle,
|
onNotchToggle,
|
||||||
onPinnedIntersectionChange,
|
onPinnedIntersectionChange,
|
||||||
}) => {
|
}) => {
|
||||||
@ -115,7 +115,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
getContainerHeight,
|
getContainerHeight,
|
||||||
isViewportNewest,
|
isViewportNewest,
|
||||||
isUnread,
|
isUnread,
|
||||||
onFabToggle,
|
onScrollDownToggle,
|
||||||
onNotchToggle,
|
onNotchToggle,
|
||||||
isReady,
|
isReady,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -238,7 +238,7 @@ function MiddleColumn({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [dropAreaState, setDropAreaState] = useState(DropAreaState.None);
|
const [dropAreaState, setDropAreaState] = useState(DropAreaState.None);
|
||||||
const [isFabShown, setIsFabShown] = useState<boolean | undefined>();
|
const [isScrollDownShown, setIsScrollDownShown] = useState(false);
|
||||||
const [isNotchShown, setIsNotchShown] = useState<boolean | undefined>();
|
const [isNotchShown, setIsNotchShown] = useState<boolean | undefined>();
|
||||||
const [isUnpinModalOpen, setIsUnpinModalOpen] = useState(false);
|
const [isUnpinModalOpen, setIsUnpinModalOpen] = useState(false);
|
||||||
|
|
||||||
@ -273,7 +273,9 @@ function MiddleColumn({
|
|||||||
&& !renderingCanRestartBot && !renderingCanStartBot && !renderingCanSubscribe && !renderingCanUnblock
|
&& !renderingCanRestartBot && !renderingCanStartBot && !renderingCanSubscribe && !renderingCanUnblock
|
||||||
&& chatId !== TMP_CHAT_ID && !isContactRequirePremium;
|
&& chatId !== TMP_CHAT_ID && !isContactRequirePremium;
|
||||||
const renderingHasTools = usePrevDuringAnimation(hasTools, closeAnimationDuration);
|
const renderingHasTools = usePrevDuringAnimation(hasTools, closeAnimationDuration);
|
||||||
const renderingIsFabShown = usePrevDuringAnimation(isFabShown, closeAnimationDuration) && chatId !== TMP_CHAT_ID;
|
const renderingIsScrollDownShown = usePrevDuringAnimation(
|
||||||
|
isScrollDownShown, closeAnimationDuration,
|
||||||
|
) && chatId !== TMP_CHAT_ID;
|
||||||
const renderingIsChannel = usePrevDuringAnimation(isChannel, closeAnimationDuration);
|
const renderingIsChannel = usePrevDuringAnimation(isChannel, closeAnimationDuration);
|
||||||
const renderingShouldJoinToSend = usePrevDuringAnimation(shouldJoinToSend, closeAnimationDuration);
|
const renderingShouldJoinToSend = usePrevDuringAnimation(shouldJoinToSend, closeAnimationDuration);
|
||||||
const renderingShouldSendJoinRequest = usePrevDuringAnimation(shouldSendJoinRequest, closeAnimationDuration);
|
const renderingShouldSendJoinRequest = usePrevDuringAnimation(shouldSendJoinRequest, closeAnimationDuration);
|
||||||
@ -489,9 +491,9 @@ function MiddleColumn({
|
|||||||
);
|
);
|
||||||
const withMessageListBottomShift = Boolean(
|
const withMessageListBottomShift = Boolean(
|
||||||
renderingCanRestartBot || renderingCanSubscribe || renderingShouldSendJoinRequest || renderingCanStartBot
|
renderingCanRestartBot || renderingCanSubscribe || renderingShouldSendJoinRequest || renderingCanStartBot
|
||||||
|| isPinnedMessageList || canShowOpenChatButton || renderingCanUnblock,
|
|| (isPinnedMessageList && canUnpin) || canShowOpenChatButton || renderingCanUnblock,
|
||||||
);
|
);
|
||||||
const withExtraShift = Boolean(isMessagingDisabled || isSelectModeActive || isPinnedMessageList);
|
const withExtraShift = Boolean(isMessagingDisabled || isSelectModeActive);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -552,7 +554,7 @@ function MiddleColumn({
|
|||||||
isComments={isComments}
|
isComments={isComments}
|
||||||
canPost={renderingCanPost!}
|
canPost={renderingCanPost!}
|
||||||
hasTools={renderingHasTools}
|
hasTools={renderingHasTools}
|
||||||
onFabToggle={setIsFabShown}
|
onScrollDownToggle={setIsScrollDownShown}
|
||||||
onNotchToggle={setIsNotchShown}
|
onNotchToggle={setIsNotchShown}
|
||||||
isReady={isReady}
|
isReady={isReady}
|
||||||
isContactRequirePremium={isContactRequirePremium}
|
isContactRequirePremium={isContactRequirePremium}
|
||||||
@ -693,7 +695,7 @@ function MiddleColumn({
|
|||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<FloatingActionButtons
|
<FloatingActionButtons
|
||||||
isShown={renderingIsFabShown!}
|
withScrollDown={renderingIsScrollDownShown}
|
||||||
canPost={renderingCanPost}
|
canPost={renderingCanPost}
|
||||||
withExtraShift={withExtraShift}
|
withExtraShift={withExtraShift}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -64,7 +64,8 @@
|
|||||||
top: -0.3125rem;
|
top: -0.3125rem;
|
||||||
right: -0.3125rem;
|
right: -0.3125rem;
|
||||||
|
|
||||||
background: var(--color-green);
|
background-color: var(--color-green);
|
||||||
|
border: 1px solid var(--color-background);
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|||||||
@ -28,8 +28,8 @@ export default function useScrollHooks(
|
|||||||
getContainerHeight: Signal<number | undefined>,
|
getContainerHeight: Signal<number | undefined>,
|
||||||
isViewportNewest: boolean,
|
isViewportNewest: boolean,
|
||||||
isUnread: boolean,
|
isUnread: boolean,
|
||||||
onFabToggle: AnyToVoidFunction,
|
onScrollDownToggle: BooleanToVoidFunction,
|
||||||
onNotchToggle: AnyToVoidFunction,
|
onNotchToggle: BooleanToVoidFunction,
|
||||||
isReady: boolean,
|
isReady: boolean,
|
||||||
) {
|
) {
|
||||||
const { loadViewportMessages } = getActions();
|
const { loadViewportMessages } = getActions();
|
||||||
@ -54,13 +54,13 @@ export default function useScrollHooks(
|
|||||||
if (!isReady) return;
|
if (!isReady) return;
|
||||||
|
|
||||||
if (!messageIds?.length) {
|
if (!messageIds?.length) {
|
||||||
onFabToggle(false);
|
onScrollDownToggle(false);
|
||||||
onNotchToggle(false);
|
onNotchToggle(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isViewportNewest) {
|
if (!isViewportNewest) {
|
||||||
onFabToggle(true);
|
onScrollDownToggle(true);
|
||||||
onNotchToggle(true);
|
onNotchToggle(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ export default function useScrollHooks(
|
|||||||
|
|
||||||
if (scrollHeight === 0) return;
|
if (scrollHeight === 0) return;
|
||||||
|
|
||||||
onFabToggle(isUnread ? !isAtBottom : !isNearBottom);
|
onScrollDownToggle(isUnread ? !isAtBottom : !isNearBottom);
|
||||||
onNotchToggle(!isAtBottom);
|
onNotchToggle(!isAtBottom);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -410,6 +410,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
disableContextMenuHint,
|
disableContextMenuHint,
|
||||||
animateUnreadReaction,
|
animateUnreadReaction,
|
||||||
focusLastMessage,
|
focusLastMessage,
|
||||||
|
markMentionsRead,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -795,10 +796,16 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const bottomMarker = bottomMarkerRef.current;
|
const bottomMarker = bottomMarkerRef.current;
|
||||||
if (hasUnreadReaction && bottomMarker && isElementInViewport(bottomMarker)) {
|
if (!bottomMarker || !isElementInViewport(bottomMarker)) return;
|
||||||
|
|
||||||
|
if (hasUnreadReaction) {
|
||||||
animateUnreadReaction({ messageIds: [messageId] });
|
animateUnreadReaction({ messageIds: [messageId] });
|
||||||
}
|
}
|
||||||
}, [hasUnreadReaction, messageId, animateUnreadReaction]);
|
|
||||||
|
if (message.hasUnreadMention) {
|
||||||
|
markMentionsRead({ messageIds: [messageId] });
|
||||||
|
}
|
||||||
|
}, [hasUnreadReaction, messageId, animateUnreadReaction, message.hasUnreadMention]);
|
||||||
|
|
||||||
const albumLayout = useMemo(() => {
|
const albumLayout = useMemo(() => {
|
||||||
return isAlbum
|
return isAlbum
|
||||||
|
|||||||
@ -1550,6 +1550,10 @@ addActionHandler('clickSponsoredMessage', (global, actions, payload): ActionRetu
|
|||||||
|
|
||||||
addActionHandler('fetchUnreadMentions', async (global, actions, payload): Promise<void> => {
|
addActionHandler('fetchUnreadMentions', async (global, actions, payload): Promise<void> => {
|
||||||
const { chatId, offsetId } = payload;
|
const { chatId, offsetId } = payload;
|
||||||
|
await fetchUnreadMentions(global, chatId, offsetId);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchUnreadMentions<T extends GlobalState>(global: T, chatId: string, offsetId?: number) {
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
if (!chat) return;
|
if (!chat) return;
|
||||||
|
|
||||||
@ -1571,7 +1575,7 @@ addActionHandler('fetchUnreadMentions', async (global, actions, payload): Promis
|
|||||||
});
|
});
|
||||||
|
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
});
|
}
|
||||||
|
|
||||||
addActionHandler('markMentionsRead', (global, actions, payload): ActionReturnType => {
|
addActionHandler('markMentionsRead', (global, actions, payload): ActionReturnType => {
|
||||||
const { messageIds, tabId = getCurrentTabId() } = payload;
|
const { messageIds, tabId = getCurrentTabId() } = payload;
|
||||||
@ -1579,8 +1583,15 @@ addActionHandler('markMentionsRead', (global, actions, payload): ActionReturnTyp
|
|||||||
const chat = selectCurrentChat(global, tabId);
|
const chat = selectCurrentChat(global, tabId);
|
||||||
if (!chat) return;
|
if (!chat) return;
|
||||||
|
|
||||||
const unreadMentions = (chat.unreadMentions || []).filter((id) => !messageIds.includes(id));
|
const currentUnreadMentions = chat.unreadMentions || [];
|
||||||
|
|
||||||
|
const unreadMentions = currentUnreadMentions.filter((id) => !messageIds.includes(id));
|
||||||
|
const removedCount = currentUnreadMentions.length - unreadMentions.length;
|
||||||
|
|
||||||
global = updateChat(global, chat.id, {
|
global = updateChat(global, chat.id, {
|
||||||
|
...(chat.unreadMentionsCount && {
|
||||||
|
unreadMentionsCount: Math.max(chat.unreadMentionsCount - removedCount, 0) || undefined,
|
||||||
|
}),
|
||||||
unreadMentions,
|
unreadMentions,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1589,12 +1600,20 @@ addActionHandler('markMentionsRead', (global, actions, payload): ActionReturnTyp
|
|||||||
actions.markMessagesRead({ messageIds, tabId });
|
actions.markMessagesRead({ messageIds, tabId });
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('focusNextMention', (global, actions, payload): ActionReturnType => {
|
addActionHandler('focusNextMention', async (global, actions, payload): Promise<void> => {
|
||||||
const { tabId = getCurrentTabId() } = payload || {};
|
const { tabId = getCurrentTabId() } = payload || {};
|
||||||
|
|
||||||
const chat = selectCurrentChat(global, tabId);
|
let chat = selectCurrentChat(global, tabId);
|
||||||
|
|
||||||
if (!chat?.unreadMentions) return;
|
if (!chat) return;
|
||||||
|
|
||||||
|
if (!chat.unreadMentions) {
|
||||||
|
await fetchUnreadMentions(global, chat.id);
|
||||||
|
global = getGlobal();
|
||||||
|
const previousChatId = chat.id;
|
||||||
|
chat = selectCurrentChat(global, tabId);
|
||||||
|
if (!chat?.unreadMentions || previousChatId !== chat.id) return;
|
||||||
|
}
|
||||||
|
|
||||||
actions.focusMessage({ chatId: chat.id, messageId: chat.unreadMentions[0], tabId });
|
actions.focusMessage({ chatId: chat.id, messageId: chat.unreadMentions[0], tabId });
|
||||||
});
|
});
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import {
|
|||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||||
import {
|
import {
|
||||||
addChatMessagesById, addChats, addUsers, updateChatMessage,
|
addChatMessagesById, addChats, addUsers, updateChat, updateChatMessage,
|
||||||
} from '../../reducers';
|
} from '../../reducers';
|
||||||
import { addMessageReaction, subtractXForEmojiInteraction, updateUnreadReactions } from '../../reducers/reactions';
|
import { addMessageReaction, subtractXForEmojiInteraction, updateUnreadReactions } from '../../reducers/reactions';
|
||||||
import { updateTabState } from '../../reducers/tabs';
|
import { updateTabState } from '../../reducers/tabs';
|
||||||
@ -437,9 +437,17 @@ addActionHandler('focusNextReaction', (global, actions, payload): ActionReturnTy
|
|||||||
const { tabId = getCurrentTabId() } = payload || {};
|
const { tabId = getCurrentTabId() } = payload || {};
|
||||||
const chat = selectCurrentChat(global, tabId);
|
const chat = selectCurrentChat(global, tabId);
|
||||||
|
|
||||||
if (!chat?.unreadReactions) return;
|
if (!chat?.unreadReactions) {
|
||||||
|
if (chat?.unreadReactionsCount) {
|
||||||
|
return updateChat(global, chat.id, {
|
||||||
|
unreadReactionsCount: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
actions.focusMessage({ chatId: chat.id, messageId: chat.unreadReactions[0], tabId });
|
actions.focusMessage({ chatId: chat.id, messageId: chat.unreadReactions[0], tabId });
|
||||||
|
return undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('readAllReactions', (global, actions, payload): ActionReturnType => {
|
addActionHandler('readAllReactions', (global, actions, payload): ActionReturnType => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
|||||||
import { isLocalMessageId } from '../../../util/messageKey';
|
import { isLocalMessageId } from '../../../util/messageKey';
|
||||||
import { closeMessageNotifications, notifyAboutMessage } from '../../../util/notifications';
|
import { closeMessageNotifications, notifyAboutMessage } from '../../../util/notifications';
|
||||||
import { buildLocalMessage } from '../../../api/gramjs/apiBuilders/messages';
|
import { buildLocalMessage } from '../../../api/gramjs/apiBuilders/messages';
|
||||||
import { isChatChannel } from '../../helpers';
|
import { checkIfHasUnreadReactions, isChatChannel } from '../../helpers';
|
||||||
import {
|
import {
|
||||||
addActionHandler, getGlobal, setGlobal,
|
addActionHandler, getGlobal, setGlobal,
|
||||||
} from '../../index';
|
} from '../../index';
|
||||||
@ -206,24 +206,22 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
case 'updateCommonBoxMessages':
|
case 'updateCommonBoxMessages':
|
||||||
case 'updateChannelMessages': {
|
case 'updateChannelMessages': {
|
||||||
const { ids, messageUpdate } = update;
|
const { ids, messageUpdate } = update;
|
||||||
if (messageUpdate.hasUnreadMention !== false) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
ids.forEach((id) => {
|
ids.forEach((id) => {
|
||||||
const chatId = ('channelId' in update ? update.channelId : selectCommonBoxChatId(global, id))!;
|
const chatId = ('channelId' in update ? update.channelId : selectCommonBoxChatId(global, id))!;
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
|
|
||||||
if (chat?.unreadReactionsCount) {
|
if (messageUpdate.reactions && chat?.unreadReactionsCount
|
||||||
|
&& !checkIfHasUnreadReactions(global, messageUpdate.reactions)) {
|
||||||
global = updateUnreadReactions(global, chatId, {
|
global = updateUnreadReactions(global, chatId, {
|
||||||
unreadReactionsCount: (chat.unreadReactionsCount - 1) || undefined,
|
unreadReactionsCount: Math.max(chat.unreadReactionsCount - 1, 0) || undefined,
|
||||||
unreadReactions: chat.unreadReactions?.filter((i) => i !== id),
|
unreadReactions: chat.unreadReactions?.filter((i) => i !== id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chat?.unreadMentionsCount) {
|
if (!messageUpdate.hasUnreadMention && chat?.unreadMentionsCount) {
|
||||||
global = updateChat(global, chatId, {
|
global = updateChat(global, chatId, {
|
||||||
unreadMentionsCount: (chat.unreadMentionsCount - 1) || undefined,
|
unreadMentionsCount: Math.max(chat.unreadMentionsCount - 1, 0) || undefined,
|
||||||
unreadMentions: chat.unreadMentions?.filter((i) => i !== id),
|
unreadMentions: chat.unreadMentions?.filter((i) => i !== id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import useForceUpdate from './useForceUpdate';
|
|||||||
import usePrevious from './usePrevious';
|
import usePrevious from './usePrevious';
|
||||||
import useSyncEffect from './useSyncEffect';
|
import useSyncEffect from './useSyncEffect';
|
||||||
|
|
||||||
export default function usePrevDuringAnimation<T>(current: T, duration?: number) {
|
export default function usePrevDuringAnimation<T>(current: T, duration?: number): T {
|
||||||
const prev = usePrevious(current, true);
|
const prev = usePrevious(current, true);
|
||||||
const timeoutRef = useRef<number>();
|
const timeoutRef = useRef<number>();
|
||||||
const forceUpdate = useForceUpdate();
|
const forceUpdate = useForceUpdate();
|
||||||
@ -28,5 +28,5 @@ export default function usePrevDuringAnimation<T>(current: T, duration?: number)
|
|||||||
}
|
}
|
||||||
}, [duration, forceUpdate, isCurrentPresent, isPrevPresent]);
|
}, [duration, forceUpdate, isCurrentPresent, isPrevPresent]);
|
||||||
|
|
||||||
return !timeoutRef.current || !duration || isCurrentPresent ? current : prev;
|
return (!timeoutRef.current || !duration || isCurrentPresent ? current : prev)!;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user