diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx
index 9d7df5cf4..dfda5aa32 100644
--- a/src/components/common/Avatar.tsx
+++ b/src/components/common/Avatar.tsx
@@ -135,7 +135,7 @@ const Avatar = ({
const isAnonymousForwards = realPeer && isAnonymousForwardsChat(realPeer.id);
const isForum = chat?.isForum;
- const peerColorKey = getPeerColorKey(peer);
+ const peerColorKey = getPeerColorKey(peer, true);
const peerColorClass = peerColorKey !== undefined ? getPeerColorClass(peerColorKey) : undefined;
const isStoryClickable = withStory && storyViewerMode !== 'disabled' && realPeer?.hasStories;
diff --git a/src/components/left/main/ChatBadge.tsx b/src/components/left/main/ChatBadge.tsx
index 7b0ae62d1..3efae178a 100644
--- a/src/components/left/main/ChatBadge.tsx
+++ b/src/components/left/main/ChatBadge.tsx
@@ -93,6 +93,7 @@ const ChatBadge = ({
}, [isForum, isMuted, topicsWithUnread, topic?.notifySettings.mutedUntil]);
const hasUnreadMark = topic ? false : chat.hasUnreadMark;
+ const isUnread = Boolean((unreadCount || hasUnreadMark) && !isSavedDialog);
const resolvedForceHidden = useDerivedState(
() => (isSignal(forceHidden) ? forceHidden() : forceHidden),
@@ -133,8 +134,8 @@ const ChatBadge = ({
+ const unreadCountElement = isUnread ? (
+
) : undefined;
diff --git a/src/components/right/Profile.tsx b/src/components/right/Profile.tsx
index c11d3dd00..c51b9f4f5 100644
--- a/src/components/right/Profile.tsx
+++ b/src/components/right/Profile.tsx
@@ -4,6 +4,7 @@ import { getActions, getGlobal, withGlobal } from '../../global';
import type {
ApiBotPreviewMedia,
ApiChat,
+ ApiChatFullInfo,
ApiChatMember,
ApiMessage,
ApiProfileTab,
@@ -12,6 +13,7 @@ import type {
ApiStoryAlbum,
ApiTypeStory,
ApiUser,
+ ApiUserFullInfo,
ApiUserStatus,
} from '../../api/types';
import type { ProfileCollectionKey } from '../../global/selectors/payments';
@@ -183,7 +185,7 @@ type StateProps = {
isSavedMessages?: boolean;
isSynced?: boolean;
hasAvatar?: boolean;
- mainTab?: ApiProfileTab;
+ peerFullInfo?: ApiUserFullInfo | ApiChatFullInfo;
canUpdateMainTab?: boolean;
canAutoPlayGifs?: boolean;
};
@@ -272,7 +274,7 @@ const Profile = ({
isSavedMessages,
isSynced,
hasAvatar,
- mainTab,
+ peerFullInfo,
canUpdateMainTab,
canAutoPlayGifs,
onProfileStateChange,
@@ -324,6 +326,7 @@ const Profile = ({
const isUser = isUserId(chatId);
const validMainTabTypes = isUser ? VALID_USER_MAIN_TAB_TYPES : VALID_CHANNEL_MAIN_TAB_TYPES;
+ const mainTab = peerFullInfo?.mainTab;
const tabs = useMemo(() => {
const arr: LocalTabProps[] = [];
@@ -428,10 +431,10 @@ const Profile = ({
setActiveTab(tabs[0].type); // Set default tab
}, [isClosed, profileTab, tabs]);
- useEffectWithPrevDeps(([prevMainTab]) => {
- if (prevMainTab || !mainTab) return;
- setActiveTab(mainTab); // Only focus when loading full info
- }, [mainTab]);
+ useEffectWithPrevDeps(([prevPeerFullInfo]) => {
+ if (prevPeerFullInfo || !peerFullInfo?.mainTab) return;
+ setActiveTab(peerFullInfo.mainTab); // Only focus when loading full info
+ }, [peerFullInfo]);
const handleSwitchTab = useCallback((index: number) => {
startAutoScrollToTabsIfNeeded();
@@ -1364,7 +1367,7 @@ export default memo(withGlobal
(
commonChatIds: commonChats?.ids,
monoforumChannel,
hasAvatar,
- mainTab: peerFullInfo?.mainTab,
+ peerFullInfo,
canUpdateMainTab: selectCanUpdateMainTab(global, chatId),
canAutoPlayGifs,
};
diff --git a/src/global/helpers/chats.ts b/src/global/helpers/chats.ts
index 9661ea624..d49c57af1 100644
--- a/src/global/helpers/chats.ts
+++ b/src/global/helpers/chats.ts
@@ -364,7 +364,7 @@ export function getOrderedTopics(
}
}
-export function getPeerColorKey(peer: ApiPeer | CustomPeer | undefined) {
+export function getPeerColorKey(peer: ApiPeer | CustomPeer | undefined, isForAvatar?: boolean) {
if (!peer) return 0;
if ('isCustomPeer' in peer) {
@@ -372,8 +372,8 @@ export function getPeerColorKey(peer: ApiPeer | CustomPeer | undefined) {
}
if (peer.color) {
- if (peer.color.type === 'collectible') return undefined; // Custom colors
- if (peer.color.color !== undefined) return peer.color.color;
+ if (peer.color.type === 'regular' && peer.color.color !== undefined) return peer.color.color;
+ if (peer.color.type === 'collectible' && !isForAvatar) return undefined; // Custom colors
}
return getPeerIdDividend(peer.id) % 7;
diff --git a/src/hooks/useHeavyAnimation.ts b/src/hooks/useHeavyAnimation.ts
index 8945acd7b..54dcb1306 100644
--- a/src/hooks/useHeavyAnimation.ts
+++ b/src/hooks/useHeavyAnimation.ts
@@ -1,6 +1,6 @@
import {
getIsHeavyAnimating,
- useCallback, useEffect, useMemo, useRef,
+ useCallback, useEffect, useRef,
} from '../lib/teact/teact';
import { createCallbackManager } from '../util/callbacks';
@@ -48,25 +48,32 @@ export default function useHeavyAnimation(
export function useThrottleForHeavyAnimation(afterHeavyAnimation: T, deps: unknown[]) {
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
const fnMemo = useCallback(afterHeavyAnimation, deps);
+ const pendingCallRef = useRef();
- const isScheduledRef = useRef(false);
-
- return useMemo(() => {
- return (...args: Parameters) => {
- if (!isScheduledRef.current) {
- if (!getIsHeavyAnimating()) {
- fnMemo(...args);
- return;
- }
-
- isScheduledRef.current = true;
-
- const removeCallback = endCallbacks.addCallback(() => {
- fnMemo(...args);
- removeCallback();
- isScheduledRef.current = false;
- });
+ useEffect(() => {
+ return () => {
+ if (pendingCallRef.current) {
+ endCallbacks.removeCallback(pendingCallRef.current);
+ pendingCallRef.current = undefined;
}
};
}, [fnMemo]);
+
+ return useCallback((...args: Parameters) => {
+ if (pendingCallRef.current) {
+ endCallbacks.removeCallback(pendingCallRef.current);
+ }
+
+ const wrappedCallback = () => {
+ pendingCallRef.current = undefined;
+ fnMemo(...args);
+ };
+
+ if (getIsHeavyAnimating()) {
+ pendingCallRef.current = wrappedCallback;
+ endCallbacks.addCallback(wrappedCallback);
+ } else {
+ wrappedCallback();
+ }
+ }, [fnMemo]) as T;
}