Chat Folders: Add "Read all messages" and "Edit" for the "All chats" folder (#5793)
Co-authored-by: zubiden <19638254+zubiden@users.noreply.github.com>
This commit is contained in:
parent
7d84defd09
commit
3167a36d84
@ -11,7 +11,7 @@
|
|||||||
"Month11" = "November";
|
"Month11" = "November";
|
||||||
"Month12" = "December";
|
"Month12" = "December";
|
||||||
"GroupLeaveGroup" = "Leave Group";
|
"GroupLeaveGroup" = "Leave Group";
|
||||||
"DeleteChatUser" = "Delete chat";
|
"DeleteChat" = "Delete Chat";
|
||||||
"AccDescrGroup" = "Group";
|
"AccDescrGroup" = "Group";
|
||||||
"AccDescrChannel" = "Channel";
|
"AccDescrChannel" = "Channel";
|
||||||
"Nothing" = "Nothing";
|
"Nothing" = "Nothing";
|
||||||
@ -85,6 +85,9 @@
|
|||||||
"ProfileCopyPhone" = "Copy Phone Number";
|
"ProfileCopyPhone" = "Copy Phone Number";
|
||||||
"ContextCopySelected" = "Copy Selected Text";
|
"ContextCopySelected" = "Copy Selected Text";
|
||||||
"ContextCopyText" = "Copy Text";
|
"ContextCopyText" = "Copy Text";
|
||||||
|
"ContextArchiveCollapse" = "Collapse";
|
||||||
|
"ContextArchiveExpand" = "Collapse";
|
||||||
|
"ContextArchiveToMenu" = "Move to Main Menu";
|
||||||
"CallMessageVideoIncomingDeclined" = "Declined Video Call";
|
"CallMessageVideoIncomingDeclined" = "Declined Video Call";
|
||||||
"CallMessageVideoOutgoingMissed" = "Canceled Video Call";
|
"CallMessageVideoOutgoingMissed" = "Canceled Video Call";
|
||||||
"CallMessageVideoIncomingMissed" = "Missed Video Call";
|
"CallMessageVideoIncomingMissed" = "Missed Video Call";
|
||||||
@ -478,8 +481,9 @@
|
|||||||
"PasscodeControllerDisableTitle" = "Disable Passcode";
|
"PasscodeControllerDisableTitle" = "Disable Passcode";
|
||||||
"PasscodeControllerChangeTitle" = "Change Passcode";
|
"PasscodeControllerChangeTitle" = "Change Passcode";
|
||||||
"FilterNew" = "New Folder";
|
"FilterNew" = "New Folder";
|
||||||
"FilterEdit" = "Edit folder";
|
"EditFolder" = "Edit Folder";
|
||||||
"FilterDelete" = "Delete folder";
|
"FilterEditFolders" = "Edit Folders";
|
||||||
|
"FilterMenuDelete" = "Delete Folder";
|
||||||
"FilterShare" = "Share";
|
"FilterShare" = "Share";
|
||||||
"AutoDeleteConfirm" = "Confirm";
|
"AutoDeleteConfirm" = "Confirm";
|
||||||
"LogOutTitle" = "Log Out";
|
"LogOutTitle" = "Log Out";
|
||||||
@ -827,7 +831,7 @@
|
|||||||
"EmptyGroupInfoLine3" = "• Public links such as t.me/title";
|
"EmptyGroupInfoLine3" = "• Public links such as t.me/title";
|
||||||
"EmptyGroupInfoLine4" = "• Admins with different rights";
|
"EmptyGroupInfoLine4" = "• Admins with different rights";
|
||||||
"Reactions" = "Reactions";
|
"Reactions" = "Reactions";
|
||||||
"MarkAllAsRead" = "Mark all as read";
|
"ChatListMarkAllAsRead" = "Mark All as Read";
|
||||||
"PaymentCardNumber" = "Card Number";
|
"PaymentCardNumber" = "Card Number";
|
||||||
"PaymentCheckoutAcceptRecurrent" = "I accept the *Terms of Service* of {bot}.";
|
"PaymentCheckoutAcceptRecurrent" = "I accept the *Terms of Service* of {bot}.";
|
||||||
"CheckoutTotalAmount" = "Total";
|
"CheckoutTotalAmount" = "Total";
|
||||||
@ -881,7 +885,7 @@
|
|||||||
"ChannelSubscribers" = "Subscribers";
|
"ChannelSubscribers" = "Subscribers";
|
||||||
"ChannelBlockedUsers" = "Removed users";
|
"ChannelBlockedUsers" = "Removed users";
|
||||||
"ChannelDelete" = "Delete Channel";
|
"ChannelDelete" = "Delete Channel";
|
||||||
"LeaveChannel" = "Leave channel";
|
"ChannelLeave" = "Leave Channel";
|
||||||
"ChannelDeleteAlert" = "Deleting this channel will remove all subscribers and all posts will be lost. Delete the channel anyway?";
|
"ChannelDeleteAlert" = "Deleting this channel will remove all subscribers and all posts will be lost. Delete the channel anyway?";
|
||||||
"ChannelLeaveAlert" = "Are you sure you want to leave this channel?";
|
"ChannelLeaveAlert" = "Are you sure you want to leave this channel?";
|
||||||
"ChannelCreator" = "Owner";
|
"ChannelCreator" = "Owner";
|
||||||
@ -1178,10 +1182,13 @@
|
|||||||
"ConversationViewChannel" = "VIEW CHANNEL";
|
"ConversationViewChannel" = "VIEW CHANNEL";
|
||||||
"Telegram" = "Telegram";
|
"Telegram" = "Telegram";
|
||||||
"ChatListFilterAddToFolder" = "Add to folder...";
|
"ChatListFilterAddToFolder" = "Add to folder...";
|
||||||
"UnpinFromTop" = "Unpin from top";
|
"ChatListUnpinFromTop" = "Unpin from Top";
|
||||||
"PinToTop" = "Pin to top";
|
"ChatListPinToTop" = "Pin to Top";
|
||||||
"MarkAsRead" = "Mark as read";
|
"ChatListOpenInNewWindow" = "Open in New Window";
|
||||||
"MarkAsUnread" = "Mark as unread";
|
"ChatListOpenInNewTab" = "Open in New Tab";
|
||||||
|
"ChatListContextMaskAsRead" = "Mark as Read";
|
||||||
|
"ChatListContextMaskAsUnread" = "Mark as Unread";
|
||||||
|
"ChatListContextAddToFolder" = "Add to Folder";
|
||||||
"Unarchive" = "Unarchive";
|
"Unarchive" = "Unarchive";
|
||||||
"Archive" = "Archive";
|
"Archive" = "Archive";
|
||||||
"WaitingForNetwork" = "Waiting for network...";
|
"WaitingForNetwork" = "Waiting for network...";
|
||||||
|
|||||||
@ -109,7 +109,7 @@ const GiftMenuItems = ({
|
|||||||
<>
|
<>
|
||||||
{hasPinOptions && (
|
{hasPinOptions && (
|
||||||
<MenuItem icon={savedGift.isPinned ? 'unpin' : 'pin'} onClick={handleTogglePin}>
|
<MenuItem icon={savedGift.isPinned ? 'unpin' : 'pin'} onClick={handleTogglePin}>
|
||||||
{lang(savedGift.isPinned ? 'UnpinFromTop' : 'PinToTop')}
|
{lang(savedGift.isPinned ? 'ChatListUnpinFromTop' : 'ChatListPinToTop')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
<MenuItem icon="link-badge" onClick={handleCopyLink}>
|
<MenuItem icon="link-badge" onClick={handleCopyLink}>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { formatIntegerCompact } from '../../../util/textFormat';
|
|||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
|
|
||||||
import { useFolderManagerForOrderedIds, useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
|
import { useFolderManagerForOrderedIds, useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
import Avatar from '../../common/Avatar';
|
import Avatar from '../../common/Avatar';
|
||||||
import Icon from '../../common/icons/Icon';
|
import Icon from '../../common/icons/Icon';
|
||||||
@ -42,7 +42,7 @@ const Archive: FC<OwnProps> = ({
|
|||||||
onClick,
|
onClick,
|
||||||
}) => {
|
}) => {
|
||||||
const { updateArchiveSettings } = getActions();
|
const { updateArchiveSettings } = getActions();
|
||||||
const lang = useOldLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const orderedChatIds = useFolderManagerForOrderedIds(ARCHIVED_FOLDER_ID);
|
const orderedChatIds = useFolderManagerForOrderedIds(ARCHIVED_FOLDER_ID);
|
||||||
const unreadCounters = useFolderManagerForUnreadCounters();
|
const unreadCounters = useFolderManagerForUnreadCounters();
|
||||||
@ -75,7 +75,7 @@ const Archive: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const contextActions = useMemo(() => {
|
const contextActions = useMemo(() => {
|
||||||
const actionMinimize = !archiveSettings.isMinimized && {
|
const actionMinimize = !archiveSettings.isMinimized && {
|
||||||
title: lang('lng_context_archive_collapse'),
|
title: lang('ContextArchiveCollapse'),
|
||||||
icon: 'collapse',
|
icon: 'collapse',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
updateArchiveSettings({ isMinimized: true });
|
updateArchiveSettings({ isMinimized: true });
|
||||||
@ -83,7 +83,7 @@ const Archive: FC<OwnProps> = ({
|
|||||||
} satisfies MenuItemContextAction;
|
} satisfies MenuItemContextAction;
|
||||||
|
|
||||||
const actionExpand = archiveSettings.isMinimized && {
|
const actionExpand = archiveSettings.isMinimized && {
|
||||||
title: lang('lng_context_archive_expand'),
|
title: lang('ContextArchiveExpand'),
|
||||||
icon: 'expand',
|
icon: 'expand',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
updateArchiveSettings({ isMinimized: false });
|
updateArchiveSettings({ isMinimized: false });
|
||||||
@ -91,7 +91,7 @@ const Archive: FC<OwnProps> = ({
|
|||||||
} satisfies MenuItemContextAction;
|
} satisfies MenuItemContextAction;
|
||||||
|
|
||||||
const actionHide = {
|
const actionHide = {
|
||||||
title: lang('lng_context_archive_to_menu'),
|
title: lang('ContextArchiveToMenu'),
|
||||||
icon: 'archive-to-main',
|
icon: 'archive-to-main',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
updateArchiveSettings({ isHidden: true });
|
updateArchiveSettings({ isHidden: true });
|
||||||
|
|||||||
@ -7,9 +7,10 @@ import { getActions, getGlobal, withGlobal } from '../../../global';
|
|||||||
import type { ApiChatFolder, ApiChatlistExportedInvite, ApiSession } from '../../../api/types';
|
import type { ApiChatFolder, ApiChatlistExportedInvite, ApiSession } from '../../../api/types';
|
||||||
import type { GlobalState } from '../../../global/types';
|
import type { GlobalState } from '../../../global/types';
|
||||||
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
|
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
|
||||||
import type { LeftColumnContent, SettingsScreens } from '../../../types';
|
import type { LeftColumnContent } from '../../../types';
|
||||||
import type { MenuItemContextAction } from '../../ui/ListItem';
|
import type { MenuItemContextAction } from '../../ui/ListItem';
|
||||||
import type { TabWithProperties } from '../../ui/TabList';
|
import type { TabWithProperties } from '../../ui/TabList';
|
||||||
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { ALL_FOLDER_ID } from '../../../config';
|
import { ALL_FOLDER_ID } from '../../../config';
|
||||||
import { selectCanShareFolder, selectTabState } from '../../../global/selectors';
|
import { selectCanShareFolder, selectTabState } from '../../../global/selectors';
|
||||||
@ -22,7 +23,10 @@ import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
|||||||
import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntities';
|
import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntities';
|
||||||
|
|
||||||
import useDerivedState from '../../../hooks/useDerivedState';
|
import useDerivedState from '../../../hooks/useDerivedState';
|
||||||
import { useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
|
import {
|
||||||
|
useFolderManagerForUnreadChatsByFolder,
|
||||||
|
useFolderManagerForUnreadCounters,
|
||||||
|
} from '../../../hooks/useFolderManager';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
@ -90,6 +94,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
openDeleteChatFolderModal,
|
openDeleteChatFolderModal,
|
||||||
openEditChatFolder,
|
openEditChatFolder,
|
||||||
openLimitReachedModal,
|
openLimitReachedModal,
|
||||||
|
markChatMessagesRead,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -112,6 +117,14 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
const isStoryRibbonClosing = useDerivedState(getIsStoryRibbonClosing);
|
const isStoryRibbonClosing = useDerivedState(getIsStoryRibbonClosing);
|
||||||
|
|
||||||
|
const scrollToTop = useLastCallback(() => {
|
||||||
|
const activeList = ref.current?.querySelector<HTMLElement>('.chat-list.Transition_slide-active');
|
||||||
|
activeList?.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const allChatsFolder: ApiChatFolder = useMemo(() => {
|
const allChatsFolder: ApiChatFolder = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
id: ALL_FOLDER_ID,
|
id: ALL_FOLDER_ID,
|
||||||
@ -137,6 +150,16 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
const isInAllChatsFolder = allChatsFolderIndex === activeChatFolder;
|
const isInAllChatsFolder = allChatsFolderIndex === activeChatFolder;
|
||||||
const isInFirstFolder = FIRST_FOLDER_INDEX === activeChatFolder;
|
const isInFirstFolder = FIRST_FOLDER_INDEX === activeChatFolder;
|
||||||
|
|
||||||
|
const folderUnreadChatsCountersById = useFolderManagerForUnreadChatsByFolder();
|
||||||
|
const handleReadAllChats = useLastCallback((folderId: number) => {
|
||||||
|
const unreadChatIds = folderUnreadChatsCountersById[folderId];
|
||||||
|
if (!unreadChatIds?.length) return;
|
||||||
|
|
||||||
|
unreadChatIds.forEach((chatId) => {
|
||||||
|
markChatMessagesRead({ id: chatId });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const folderCountersById = useFolderManagerForUnreadCounters();
|
const folderCountersById = useFolderManagerForUnreadCounters();
|
||||||
const folderTabs = useMemo(() => {
|
const folderTabs = useMemo(() => {
|
||||||
if (!displayedFolders || !displayedFolders.length) {
|
if (!displayedFolders || !displayedFolders.length) {
|
||||||
@ -177,17 +200,41 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id !== ALL_FOLDER_ID) {
|
if (id === ALL_FOLDER_ID) {
|
||||||
contextActions.push({
|
contextActions.push({
|
||||||
title: lang('FilterEdit'),
|
title: lang('FilterEditFolders'),
|
||||||
|
icon: 'edit',
|
||||||
|
handler: () => {
|
||||||
|
onSettingsScreenSelect(SettingsScreens.Folders);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (folderUnreadChatsCountersById[id]?.length) {
|
||||||
|
contextActions.push({
|
||||||
|
title: lang('ChatListMarkAllAsRead'),
|
||||||
|
icon: 'readchats',
|
||||||
|
handler: () => handleReadAllChats(folder.id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
contextActions.push({
|
||||||
|
title: lang('EditFolder'),
|
||||||
icon: 'edit',
|
icon: 'edit',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
openEditChatFolder({ folderId: id });
|
openEditChatFolder({ folderId: id });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (folderUnreadChatsCountersById[id]?.length) {
|
||||||
|
contextActions.push({
|
||||||
|
title: lang('ChatListMarkAllAsRead'),
|
||||||
|
icon: 'readchats',
|
||||||
|
handler: () => handleReadAllChats(folder.id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
contextActions.push({
|
contextActions.push({
|
||||||
title: lang('FilterDelete'),
|
title: lang('FilterMenuDelete'),
|
||||||
icon: 'delete',
|
icon: 'delete',
|
||||||
destructive: true,
|
destructive: true,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
@ -211,11 +258,14 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
displayedFolders, maxFolders, folderCountersById, lang, chatFoldersById, maxChatLists, folderInvitesById,
|
displayedFolders, maxFolders, folderCountersById, lang, chatFoldersById, maxChatLists, folderInvitesById,
|
||||||
maxFolderInvites,
|
maxFolderInvites, folderUnreadChatsCountersById, onSettingsScreenSelect,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleSwitchTab = useLastCallback((index: number) => {
|
const handleSwitchTab = useLastCallback((index: number) => {
|
||||||
setActiveChatFolder({ activeChatFolder: index }, { forceOnHeavyAnimation: true });
|
setActiveChatFolder({ activeChatFolder: index }, { forceOnHeavyAnimation: true });
|
||||||
|
if (activeChatFolder === index) {
|
||||||
|
scrollToTop();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent `activeTab` pointing at non-existing folder after update
|
// Prevent `activeTab` pointing at non-existing folder after update
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
.badge {
|
.badge {
|
||||||
min-width: 1.25rem;
|
min-width: 1.25rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
margin-inline-start: 0.5rem;
|
margin-inline-start: 0.3125rem;
|
||||||
background: var(--color-gray);
|
background: var(--color-gray);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
padding: 0 0.3125rem;
|
padding: 0 0.3125rem;
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
} from '../global/helpers';
|
} from '../global/helpers';
|
||||||
import { IS_ELECTRON, IS_OPEN_IN_NEW_TAB_SUPPORTED } from '../util/browser/windowEnvironment';
|
import { IS_ELECTRON, IS_OPEN_IN_NEW_TAB_SUPPORTED } from '../util/browser/windowEnvironment';
|
||||||
import { compact } from '../util/iteratees';
|
import { compact } from '../util/iteratees';
|
||||||
import useOldLang from './useOldLang';
|
import useLang from './useLang';
|
||||||
|
|
||||||
const useChatContextActions = ({
|
const useChatContextActions = ({
|
||||||
chat,
|
chat,
|
||||||
@ -44,7 +44,7 @@ const useChatContextActions = ({
|
|||||||
handleChatFolderChange: NoneToVoidFunction;
|
handleChatFolderChange: NoneToVoidFunction;
|
||||||
handleReport?: NoneToVoidFunction;
|
handleReport?: NoneToVoidFunction;
|
||||||
}, isInSearch = false) => {
|
}, isInSearch = false) => {
|
||||||
const lang = useOldLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const { isSelf } = user || {};
|
const { isSelf } = user || {};
|
||||||
const isServiceNotifications = user?.id === SERVICE_NOTIFICATIONS_USER_ID;
|
const isServiceNotifications = user?.id === SERVICE_NOTIFICATIONS_USER_ID;
|
||||||
@ -57,7 +57,7 @@ const useChatContextActions = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUserId(chat.id)) {
|
if (isUserId(chat.id)) {
|
||||||
return lang('DeleteChatUser');
|
return lang('DeleteChat');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCanDeleteChat(chat)) {
|
if (getCanDeleteChat(chat)) {
|
||||||
@ -65,10 +65,10 @@ const useChatContextActions = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isChatChannel(chat)) {
|
if (isChatChannel(chat)) {
|
||||||
return lang('LeaveChannel');
|
return lang('ChannelLeave');
|
||||||
}
|
}
|
||||||
|
|
||||||
return lang('Group.LeaveGroup');
|
return lang('GroupLeaveGroup');
|
||||||
}, [chat, isSavedDialog, lang]);
|
}, [chat, isSavedDialog, lang]);
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
@ -87,7 +87,7 @@ const useChatContextActions = ({
|
|||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
const actionOpenInNewTab = IS_OPEN_IN_NEW_TAB_SUPPORTED && {
|
const actionOpenInNewTab = IS_OPEN_IN_NEW_TAB_SUPPORTED && {
|
||||||
title: IS_ELECTRON ? 'Open in new window' : 'Open in new tab',
|
title: IS_ELECTRON ? lang('ChatListOpenInNewWindow') : lang('ChatListOpenInNewTab'),
|
||||||
icon: 'open-in-new-tab',
|
icon: 'open-in-new-tab',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
if (isSavedDialog) {
|
if (isSavedDialog) {
|
||||||
@ -108,12 +108,12 @@ const useChatContextActions = ({
|
|||||||
|
|
||||||
const actionPin = isPinned
|
const actionPin = isPinned
|
||||||
? {
|
? {
|
||||||
title: lang('UnpinFromTop'),
|
title: lang('ChatListUnpinFromTop'),
|
||||||
icon: 'unpin',
|
icon: 'unpin',
|
||||||
handler: togglePinned,
|
handler: togglePinned,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
title: lang('PinToTop'),
|
title: lang('ChatListPinToTop'),
|
||||||
icon: 'pin',
|
icon: 'pin',
|
||||||
handler: togglePinned,
|
handler: togglePinned,
|
||||||
};
|
};
|
||||||
@ -130,19 +130,19 @@ const useChatContextActions = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actionAddToFolder = canChangeFolder ? {
|
const actionAddToFolder = canChangeFolder ? {
|
||||||
title: lang('ChatList.Filter.AddToFolder'),
|
title: lang('ChatListContextAddToFolder'),
|
||||||
icon: 'folder',
|
icon: 'folder',
|
||||||
handler: handleChatFolderChange,
|
handler: handleChatFolderChange,
|
||||||
} : undefined;
|
} : undefined;
|
||||||
|
|
||||||
const actionMute = isMuted
|
const actionMute = isMuted
|
||||||
? {
|
? {
|
||||||
title: lang('ChatList.Unmute'),
|
title: lang('ChatsUnmute'),
|
||||||
icon: 'unmute',
|
icon: 'unmute',
|
||||||
handler: () => updateChatMutedState({ chatId: chat.id, isMuted: false }),
|
handler: () => updateChatMutedState({ chatId: chat.id, isMuted: false }),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
title: `${lang('ChatList.Mute')}...`,
|
title: `${lang('ChatsMute')}...`,
|
||||||
icon: 'mute',
|
icon: 'mute',
|
||||||
handler: handleMute,
|
handler: handleMute,
|
||||||
};
|
};
|
||||||
@ -153,10 +153,13 @@ const useChatContextActions = ({
|
|||||||
|
|
||||||
const actionMaskAsRead = (
|
const actionMaskAsRead = (
|
||||||
chat.unreadCount || chat.hasUnreadMark || Object.values(topics || {}).some(({ unreadCount }) => unreadCount)
|
chat.unreadCount || chat.hasUnreadMark || Object.values(topics || {}).some(({ unreadCount }) => unreadCount)
|
||||||
) ? { title: lang('MarkAsRead'), icon: 'readchats', handler: () => markChatMessagesRead({ id: chat.id }) }
|
) ? {
|
||||||
: undefined;
|
title: lang('ChatListContextMaskAsRead'),
|
||||||
|
icon: 'readchats',
|
||||||
|
handler: () => markChatMessagesRead({ id: chat.id }),
|
||||||
|
} : undefined;
|
||||||
const actionMarkAsUnread = !(chat.unreadCount || chat.hasUnreadMark) && !chat.isForum
|
const actionMarkAsUnread = !(chat.unreadCount || chat.hasUnreadMark) && !chat.isForum
|
||||||
? { title: lang('MarkAsUnread'), icon: 'unread', handler: () => markChatUnread({ id: chat.id }) }
|
? { title: lang('ChatListContextMaskAsUnread'), icon: 'unread', handler: () => markChatUnread({ id: chat.id }) }
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const actionArchive = isChatArchived(chat)
|
const actionArchive = isChatArchived(chat)
|
||||||
@ -165,7 +168,7 @@ const useChatContextActions = ({
|
|||||||
|
|
||||||
const canReport = handleReport && !user && (isChatChannel(chat) || isChatGroup(chat));
|
const canReport = handleReport && !user && (isChatChannel(chat) || isChatGroup(chat));
|
||||||
const actionReport = canReport
|
const actionReport = canReport
|
||||||
? { title: lang('ReportPeer.Report'), icon: 'flag', handler: handleReport }
|
? { title: lang('ReportPeerReport'), icon: 'flag', handler: handleReport }
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const isInFolder = folderId !== undefined;
|
const isInFolder = folderId !== undefined;
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { useEffect } from '../lib/teact/teact';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
addChatsCountCallback,
|
addChatsCountCallback,
|
||||||
addOrderedIdsCallback,
|
addOrderedIdsCallback, addUnreadChatsByFolderIdCallback,
|
||||||
addUnreadCountersCallback,
|
addUnreadCountersCallback,
|
||||||
getChatsCount,
|
getChatsCount,
|
||||||
getOrderedIds,
|
getOrderedIds, getUnreadChatsByFolderId,
|
||||||
getUnreadCounters,
|
getUnreadCounters,
|
||||||
} from '../util/folderManager';
|
} from '../util/folderManager';
|
||||||
import useForceUpdate from './useForceUpdate';
|
import useForceUpdate from './useForceUpdate';
|
||||||
@ -33,3 +33,11 @@ export function useFolderManagerForChatsCount() {
|
|||||||
|
|
||||||
return getChatsCount();
|
return getChatsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useFolderManagerForUnreadChatsByFolder() {
|
||||||
|
const forceUpdate = useForceUpdate();
|
||||||
|
|
||||||
|
useEffect(() => addUnreadChatsByFolderIdCallback(forceUpdate), [forceUpdate]);
|
||||||
|
|
||||||
|
return getUnreadChatsByFolderId();
|
||||||
|
}
|
||||||
|
|||||||
26
src/types/language.d.ts
vendored
26
src/types/language.d.ts
vendored
@ -14,7 +14,7 @@ export interface LangPair {
|
|||||||
'Month11': undefined;
|
'Month11': undefined;
|
||||||
'Month12': undefined;
|
'Month12': undefined;
|
||||||
'GroupLeaveGroup': undefined;
|
'GroupLeaveGroup': undefined;
|
||||||
'DeleteChatUser': undefined;
|
'DeleteChat': undefined;
|
||||||
'AccDescrGroup': undefined;
|
'AccDescrGroup': undefined;
|
||||||
'AccDescrChannel': undefined;
|
'AccDescrChannel': undefined;
|
||||||
'Nothing': undefined;
|
'Nothing': undefined;
|
||||||
@ -67,6 +67,9 @@ export interface LangPair {
|
|||||||
'ProfileCopyPhone': undefined;
|
'ProfileCopyPhone': undefined;
|
||||||
'ContextCopySelected': undefined;
|
'ContextCopySelected': undefined;
|
||||||
'ContextCopyText': undefined;
|
'ContextCopyText': undefined;
|
||||||
|
'ContextArchiveCollapse': undefined;
|
||||||
|
'ContextArchiveExpand': undefined;
|
||||||
|
'ContextArchiveToMenu': undefined;
|
||||||
'CallMessageVideoIncomingDeclined': undefined;
|
'CallMessageVideoIncomingDeclined': undefined;
|
||||||
'CallMessageVideoOutgoingMissed': undefined;
|
'CallMessageVideoOutgoingMissed': undefined;
|
||||||
'CallMessageVideoIncomingMissed': undefined;
|
'CallMessageVideoIncomingMissed': undefined;
|
||||||
@ -428,8 +431,9 @@ export interface LangPair {
|
|||||||
'PasscodeControllerDisableTitle': undefined;
|
'PasscodeControllerDisableTitle': undefined;
|
||||||
'PasscodeControllerChangeTitle': undefined;
|
'PasscodeControllerChangeTitle': undefined;
|
||||||
'FilterNew': undefined;
|
'FilterNew': undefined;
|
||||||
'FilterEdit': undefined;
|
'EditFolder': undefined;
|
||||||
'FilterDelete': undefined;
|
'FilterEditFolders': undefined;
|
||||||
|
'FilterMenuDelete': undefined;
|
||||||
'FilterShare': undefined;
|
'FilterShare': undefined;
|
||||||
'AutoDeleteConfirm': undefined;
|
'AutoDeleteConfirm': undefined;
|
||||||
'LogOutTitle': undefined;
|
'LogOutTitle': undefined;
|
||||||
@ -710,7 +714,7 @@ export interface LangPair {
|
|||||||
'EmptyGroupInfoLine3': undefined;
|
'EmptyGroupInfoLine3': undefined;
|
||||||
'EmptyGroupInfoLine4': undefined;
|
'EmptyGroupInfoLine4': undefined;
|
||||||
'Reactions': undefined;
|
'Reactions': undefined;
|
||||||
'MarkAllAsRead': undefined;
|
'ChatListMarkAllAsRead': undefined;
|
||||||
'PaymentCardNumber': undefined;
|
'PaymentCardNumber': undefined;
|
||||||
'CheckoutTotalAmount': undefined;
|
'CheckoutTotalAmount': undefined;
|
||||||
'PaymentCheckoutMethod': undefined;
|
'PaymentCheckoutMethod': undefined;
|
||||||
@ -761,7 +765,7 @@ export interface LangPair {
|
|||||||
'ChannelSubscribers': undefined;
|
'ChannelSubscribers': undefined;
|
||||||
'ChannelBlockedUsers': undefined;
|
'ChannelBlockedUsers': undefined;
|
||||||
'ChannelDelete': undefined;
|
'ChannelDelete': undefined;
|
||||||
'LeaveChannel': undefined;
|
'ChannelLeave': undefined;
|
||||||
'ChannelDeleteAlert': undefined;
|
'ChannelDeleteAlert': undefined;
|
||||||
'ChannelLeaveAlert': undefined;
|
'ChannelLeaveAlert': undefined;
|
||||||
'ChannelCreator': undefined;
|
'ChannelCreator': undefined;
|
||||||
@ -976,6 +980,7 @@ export interface LangPair {
|
|||||||
'ChatListFilterErrorEmpty': undefined;
|
'ChatListFilterErrorEmpty': undefined;
|
||||||
'ChatListFilterErrorTitleEmpty': undefined;
|
'ChatListFilterErrorTitleEmpty': undefined;
|
||||||
'FilterMuted': undefined;
|
'FilterMuted': undefined;
|
||||||
|
'ReadFolder': undefined;
|
||||||
'FilterRead': undefined;
|
'FilterRead': undefined;
|
||||||
'FilterArchived': undefined;
|
'FilterArchived': undefined;
|
||||||
'GroupsAndChannelsLimitTitle': undefined;
|
'GroupsAndChannelsLimitTitle': undefined;
|
||||||
@ -1008,10 +1013,13 @@ export interface LangPair {
|
|||||||
'ConversationViewChannel': undefined;
|
'ConversationViewChannel': undefined;
|
||||||
'Telegram': undefined;
|
'Telegram': undefined;
|
||||||
'ChatListFilterAddToFolder': undefined;
|
'ChatListFilterAddToFolder': undefined;
|
||||||
'UnpinFromTop': undefined;
|
'ChatListUnpinFromTop': undefined;
|
||||||
'PinToTop': undefined;
|
'ChatListPinToTop': undefined;
|
||||||
'MarkAsRead': undefined;
|
'ChatListOpenInNewWindow': undefined;
|
||||||
'MarkAsUnread': undefined;
|
'ChatListOpenInNewTab': undefined;
|
||||||
|
'ChatListContextMaskAsRead': undefined;
|
||||||
|
'ChatListContextMaskAsUnread': undefined;
|
||||||
|
'ChatListContextAddToFolder': undefined;
|
||||||
'Unarchive': undefined;
|
'Unarchive': undefined;
|
||||||
'Archive': undefined;
|
'Archive': undefined;
|
||||||
'WaitingForNetwork': undefined;
|
'WaitingForNetwork': undefined;
|
||||||
|
|||||||
@ -97,12 +97,14 @@ let results: {
|
|||||||
chatsCount: number;
|
chatsCount: number;
|
||||||
notificationsCount: number;
|
notificationsCount: number;
|
||||||
} | undefined>;
|
} | undefined>;
|
||||||
|
unreadChatIdsByFolderId: Record<string, string[] | undefined>;
|
||||||
} = initials.results;
|
} = initials.results;
|
||||||
|
|
||||||
let callbacks: {
|
let callbacks: {
|
||||||
orderedIdsByFolderId: Record<number, CallbackManager>;
|
orderedIdsByFolderId: Record<number, CallbackManager>;
|
||||||
chatsCountByFolderId: CallbackManager;
|
chatsCountByFolderId: CallbackManager;
|
||||||
unreadCountersByFolderId: CallbackManager;
|
unreadCountersByFolderId: CallbackManager;
|
||||||
|
unreadChatIdsByFolderId: CallbackManager;
|
||||||
} = initials.callbacks;
|
} = initials.callbacks;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -159,6 +161,12 @@ export function getUnreadCounters() {
|
|||||||
return results.unreadCountersByFolderId;
|
return results.unreadCountersByFolderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUnreadChatsByFolderId() {
|
||||||
|
if (!inited) init();
|
||||||
|
|
||||||
|
return results.unreadChatIdsByFolderId;
|
||||||
|
}
|
||||||
|
|
||||||
export function getAllNotificationsCount() {
|
export function getAllNotificationsCount() {
|
||||||
return getUnreadCounters()[ALL_FOLDER_ID]?.notificationsCount || 0;
|
return getUnreadCounters()[ALL_FOLDER_ID]?.notificationsCount || 0;
|
||||||
}
|
}
|
||||||
@ -182,6 +190,12 @@ export function addChatsCountCallback(callback: (chatsCount: typeof results.chat
|
|||||||
return callbacks.chatsCountByFolderId.addCallback(callback);
|
return callbacks.chatsCountByFolderId.addCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addUnreadChatsByFolderIdCallback(
|
||||||
|
callback: (unreadChats: typeof results.unreadChatIdsByFolderId) => void,
|
||||||
|
) {
|
||||||
|
return callbacks.unreadChatIdsByFolderId.addCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
export function addUnreadCountersCallback(callback: (unreadCounters: typeof results.unreadCountersByFolderId) => void) {
|
export function addUnreadCountersCallback(callback: (unreadCounters: typeof results.unreadCountersByFolderId) => void) {
|
||||||
return callbacks.unreadCountersByFolderId.addCallback(callback);
|
return callbacks.unreadCountersByFolderId.addCallback(callback);
|
||||||
}
|
}
|
||||||
@ -677,6 +691,7 @@ function updateListsForChat(chatId: string, currentFolderIds: number[], newFolde
|
|||||||
function updateResults(affectedFolderIds: number[]) {
|
function updateResults(affectedFolderIds: number[]) {
|
||||||
let wasUnreadCountersChanged = false;
|
let wasUnreadCountersChanged = false;
|
||||||
let wasChatsCountChanged = false;
|
let wasChatsCountChanged = false;
|
||||||
|
let wasUnreadChatsChanged = false;
|
||||||
|
|
||||||
Array.from(affectedFolderIds).forEach((folderId) => {
|
Array.from(affectedFolderIds).forEach((folderId) => {
|
||||||
const { pinnedCount: newPinnedCount, orderedIds: newOrderedIds } = buildFolderOrderedIds(folderId);
|
const { pinnedCount: newPinnedCount, orderedIds: newOrderedIds } = buildFolderOrderedIds(folderId);
|
||||||
@ -715,6 +730,15 @@ function updateResults(affectedFolderIds: number[]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
results.unreadCountersByFolderId[folderId] = newUnreadCounters;
|
results.unreadCountersByFolderId[folderId] = newUnreadCounters;
|
||||||
|
|
||||||
|
const currentUnreadChats = results.unreadChatIdsByFolderId[folderId];
|
||||||
|
const newUnreadChats = buildFolderByUnreadChats(folderId);
|
||||||
|
if (!wasUnreadChatsChanged) {
|
||||||
|
wasUnreadChatsChanged = (
|
||||||
|
!currentUnreadChats || !areSortedArraysEqual(newUnreadChats, currentUnreadChats)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
results.unreadChatIdsByFolderId[folderId] = newUnreadChats;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (wasChatsCountChanged) {
|
if (wasChatsCountChanged) {
|
||||||
@ -730,6 +754,10 @@ function updateResults(affectedFolderIds: number[]) {
|
|||||||
results.unreadCountersByFolderId = newValue;
|
results.unreadCountersByFolderId = newValue;
|
||||||
callbacks.unreadCountersByFolderId.runCallbacks(newValue);
|
callbacks.unreadCountersByFolderId.runCallbacks(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wasUnreadChatsChanged) {
|
||||||
|
callbacks.unreadChatIdsByFolderId.runCallbacks(results.unreadChatIdsByFolderId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFolderOrderedIds(folderId: number) {
|
function buildFolderOrderedIds(folderId: number) {
|
||||||
@ -801,6 +829,16 @@ function buildFolderUnreadCounters(folderId: number) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildFolderByUnreadChats(folderId: number) {
|
||||||
|
const { chatSummariesById } = prepared;
|
||||||
|
const { orderedIdsByFolderId: { [folderId]: orderedIds } } = results;
|
||||||
|
|
||||||
|
return orderedIds!.filter((chatId) => {
|
||||||
|
const chatSummary = chatSummariesById.get(chatId);
|
||||||
|
return chatSummary?.isUnread;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function buildInitials() {
|
function buildInitials() {
|
||||||
return {
|
return {
|
||||||
prevGlobal: {
|
prevGlobal: {
|
||||||
@ -823,12 +861,14 @@ function buildInitials() {
|
|||||||
pinnedCountByFolderId: {},
|
pinnedCountByFolderId: {},
|
||||||
chatsCountByFolderId: {},
|
chatsCountByFolderId: {},
|
||||||
unreadCountersByFolderId: {},
|
unreadCountersByFolderId: {},
|
||||||
|
unreadChatIdsByFolderId: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
callbacks: {
|
callbacks: {
|
||||||
orderedIdsByFolderId: {},
|
orderedIdsByFolderId: {},
|
||||||
chatsCountByFolderId: createCallbackManager(),
|
chatsCountByFolderId: createCallbackManager(),
|
||||||
unreadCountersByFolderId: createCallbackManager(),
|
unreadCountersByFolderId: createCallbackManager(),
|
||||||
|
unreadChatIdsByFolderId: createCallbackManager(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user