Skip to content

Commit 4b2bee8

Browse files
zubidenAjaxy
authored andcommitted
Chat: Fix muted state (#5752)
1 parent e494152 commit 4b2bee8

File tree

8 files changed

+57
-23
lines changed

8 files changed

+57
-23
lines changed

src/components/common/Composer.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,18 +1923,20 @@ const Composer: FC<OwnProps & StateProps> = ({
19231923
{!hasText && (
19241924
<>
19251925
{isChannel && (
1926-
<Button
1927-
round
1928-
faded
1929-
className="composer-action-button"
1930-
color="translucent"
1931-
onClick={handleToggleSilentPosting}
1932-
ariaLabel={lang(
1933-
isSilentPosting ? 'AriaComposerSilentPostingDisable' : 'AriaComposerSilentPostingEnable',
1934-
)}
1935-
>
1936-
<Icon name={isSilentPosting ? 'mute' : 'unmute'} />
1937-
</Button>
1926+
<Transition className="composer-action-button" name="reveal" activeKey={Number(isSilentPosting)}>
1927+
<Button
1928+
round
1929+
faded
1930+
className="composer-action-button"
1931+
color="translucent"
1932+
onClick={handleToggleSilentPosting}
1933+
ariaLabel={lang(
1934+
isSilentPosting ? 'AriaComposerSilentPostingDisable' : 'AriaComposerSilentPostingEnable',
1935+
)}
1936+
>
1937+
<Icon name={isSilentPosting ? 'mute' : 'unmute'} />
1938+
</Button>
1939+
</Transition>
19381940
)}
19391941
{withScheduledButton && (
19401942
<Button

src/components/left/main/Chat.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ const Chat: FC<OwnProps & StateProps> = ({
281281
isSavedDialog,
282282
currentUserId,
283283
isPreview,
284+
topics,
284285
});
285286

286287
const isIntersecting = useIsIntersecting(ref, chat ? observeIntersection : undefined);

src/global/actions/api/chats.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import {
7575
replaceChatListIds,
7676
replaceChatListLoadingParameters,
7777
replaceMessages,
78+
replaceNotifyExceptions,
7879
replaceSimilarChannels,
7980
replaceThreadParam,
8081
replaceUserStatuses,
@@ -2928,6 +2929,7 @@ async function loadChats(
29282929
const offsetId = params.nextOffsetId;
29292930

29302931
const isFirstBatch = !shouldIgnorePagination && !offsetPeer && !offsetDate && !offsetId;
2932+
const shouldReplaceStaleState = listType === 'active' && isFirstBatch;
29312933

29322934
const result = listType === 'saved' ? await callApi('fetchSavedChats', {
29332935
limit: CHAT_LIST_LOAD_SLICE,
@@ -2960,16 +2962,21 @@ async function loadChats(
29602962
global = updateChats(global, newChats);
29612963
if (isFirstBatch) {
29622964
global = replaceChatListIds(global, listType, chatIds);
2963-
global = replaceUserStatuses(global, result.userStatusesById);
29642965
} else {
29652966
global = addChatListIds(global, listType, chatIds);
2967+
}
2968+
2969+
if (shouldReplaceStaleState) {
2970+
global = replaceUserStatuses(global, result.userStatusesById);
2971+
global = replaceNotifyExceptions(global, result.notifyExceptionById);
2972+
} else {
29662973
global = addUserStatuses(global, result.userStatusesById);
2974+
global = addNotifyExceptions(global, result.notifyExceptionById);
29672975
}
29682976

29692977
global = updateChatListSecondaryInfo(global, listType, result);
29702978
global = replaceMessages(global, result.messages);
29712979
global = updateChatsLastMessageId(global, result.lastMessageByChatId, listType);
2972-
global = addNotifyExceptions(global, result.notifyExceptionById);
29732980

29742981
if (!shouldIgnorePagination) {
29752982
global = replaceChatListLoadingParameters(

src/global/actions/apiUpdaters/messages.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,15 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
544544

545545
const chat = selectChat(global, chatId);
546546
const currentThreadInfo = selectThreadInfo(global, chatId, threadId);
547-
if (chat?.isForum && threadInfo.lastReadInboxMessageId !== currentThreadInfo?.lastReadInboxMessageId) {
548-
actions.loadTopicById({ chatId, topicId: Number(threadId) });
547+
const topic = selectTopic(global, chatId, threadId);
548+
if (chat?.isForum) {
549+
if (!topic || topic.lastMessageId !== currentThreadInfo?.lastReadInboxMessageId) {
550+
actions.loadTopicById({ chatId, topicId: Number(threadId) });
551+
} else {
552+
global = updateTopic(global, chatId, Number(threadId), {
553+
unreadCount: 0,
554+
});
555+
}
549556
}
550557

551558
// Update reply thread last read message id if already read in main thread

src/global/cache.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ function reduceChats<T extends GlobalState>(global: T): GlobalState['chats'] {
498498
similarChannelsById: {},
499499
similarBotsById: {},
500500
isFullyLoaded: {},
501-
notifyExceptionById: {},
501+
notifyExceptionById: pickTruthy(global.chats.notifyExceptionById, idsToSave),
502502
loadingParameters: INITIAL_GLOBAL_STATE.chats.loadingParameters,
503503
byId: pickTruthy(global.chats.byId, idsToSave),
504504
fullInfoById: pickTruthy(global.chats.fullInfoById, idsToSave),
@@ -659,7 +659,7 @@ function omitLocalMedia(message: ApiMessage): ApiMessage {
659659

660660
function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings'] {
661661
const {
662-
byKey, themes, performance, botVerificationShownPeerIds, miniAppsCachedPosition, miniAppsCachedSize,
662+
byKey, themes, performance, botVerificationShownPeerIds, miniAppsCachedPosition, miniAppsCachedSize, notifyDefaults,
663663
} = global.settings;
664664

665665
return {
@@ -670,6 +670,7 @@ function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings
670670
botVerificationShownPeerIds,
671671
miniAppsCachedPosition,
672672
miniAppsCachedSize,
673+
notifyDefaults,
673674
};
674675
}
675676

src/global/reducers/settings.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ export function addNotifyExceptions<T extends GlobalState>(
5353
};
5454
}
5555

56+
export function replaceNotifyExceptions<T extends GlobalState>(
57+
global: T, notifyExceptionById: Record<string, ApiPeerNotifySettings>,
58+
): T {
59+
return {
60+
...global,
61+
chats: {
62+
...global.chats,
63+
notifyExceptionById,
64+
},
65+
};
66+
}
67+
5668
export function addNotifyException<T extends GlobalState>(
5769
global: T, id: string, notifyException: ApiPeerNotifySettings,
5870
): T {

src/hooks/useChatContextActions.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useMemo } from '../lib/teact/teact';
22
import { getActions } from '../global';
33

4+
import type { ApiChat, ApiTopic, ApiUser } from '../api/types';
45
import type { MenuItemContextAction } from '../components/ui/ListItem';
5-
import { type ApiChat, type ApiUser } from '../api/types';
66

77
import { SERVICE_NOTIFICATIONS_USER_ID } from '../config';
88
import {
@@ -23,6 +23,7 @@ const useChatContextActions = ({
2323
isSavedDialog,
2424
currentUserId,
2525
isPreview,
26+
topics,
2627
handleDelete,
2728
handleMute,
2829
handleChatFolderChange,
@@ -37,6 +38,7 @@ const useChatContextActions = ({
3738
isSavedDialog?: boolean;
3839
currentUserId?: string;
3940
isPreview?: boolean;
41+
topics?: Record<number, ApiTopic>;
4042
handleDelete?: NoneToVoidFunction;
4143
handleMute?: NoneToVoidFunction;
4244
handleChatFolderChange: NoneToVoidFunction;
@@ -149,8 +151,9 @@ const useChatContextActions = ({
149151
return compact([actionOpenInNewTab, actionPin, actionAddToFolder, actionMute]) as MenuItemContextAction[];
150152
}
151153

152-
const actionMaskAsRead = (chat.unreadCount || chat.hasUnreadMark)
153-
? { title: lang('MarkAsRead'), icon: 'readchats', handler: () => markChatMessagesRead({ id: chat.id }) }
154+
const actionMaskAsRead = (
155+
chat.unreadCount || chat.hasUnreadMark || Object.values(topics || {}).some(({ unreadCount }) => unreadCount)
156+
) ? { title: lang('MarkAsRead'), icon: 'readchats', handler: () => markChatMessagesRead({ id: chat.id }) }
154157
: undefined;
155158
const actionMarkAsUnread = !(chat.unreadCount || chat.hasUnreadMark) && !chat.isForum
156159
? { title: lang('MarkAsUnread'), icon: 'unread', handler: () => markChatUnread({ id: chat.id }) }
@@ -181,7 +184,7 @@ const useChatContextActions = ({
181184
}, [
182185
chat, user, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted, currentUserId,
183186
handleDelete, handleMute, handleReport, folderId, isSelf, isServiceNotifications, isSavedDialog, deleteTitle,
184-
isPreview,
187+
isPreview, topics,
185188
]);
186189
};
187190

src/util/notifications.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,10 @@ function checkIfShouldNotify(chat: ApiChat, message: Partial<ApiMessage>) {
278278
const topic = selectTopicFromMessage(global, message as ApiMessage);
279279
const topicMutedUntil = topic?.notifySettings.mutedUntil;
280280
const isMuted = topicMutedUntil === undefined ? isChatMuted : topicMutedUntil > getServerTime();
281+
const shouldIgnoreMute = message.isMentioned;
281282

282283
const shouldNotifyAboutMessage = message.content?.action?.type !== 'phoneCall';
283-
if (isMuted || !shouldNotifyAboutMessage
284+
if ((isMuted && !shouldIgnoreMute) || !shouldNotifyAboutMessage
284285
|| chat.isNotJoined || !chat.isListed || selectIsChatWithSelf(global, chat.id)) {
285286
return false;
286287
}

0 commit comments

Comments
 (0)