diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index c6603343a..cffe7f233 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -460,6 +460,8 @@ "PasscodeControllerChangeTitle" = "Change Passcode"; "FilterNew" = "New Folder"; "FilterEdit" = "Edit folder"; +"FilterDelete" = "Delete folder"; +"FilterShare" = "Share"; "AutoDeleteConfirm" = "Confirm"; "LogOutTitle" = "Log Out"; "AccDescrGoBack" = "Go back"; @@ -1414,3 +1416,29 @@ "FolderLinkTitleDescription" = "Anyone with this link can add {folder} folder and {chats} selected below."; "FolderLinkTitleDescriptionChats_one" = "the chat"; "FolderLinkTitleDescriptionChats_other" = "the {count} chats"; +"SearchTabChats" = "Chats"; +"SearchTabChannels" = "Channels"; +"SearchTabApps" = "Apps"; +"SearchTabMedia" = "Media"; +"SearchTabLinks" = "Links"; +"SearchTabFiles" = "Files"; +"SearchTabMusic" = "Music"; +"SearchTabVoice" = "Voice"; +"SearchTabMessages" = "Messages"; +"StarsTransactionsAll" = "All Transactions"; +"StarsTransactionsIncoming" = "Incoming"; +"StarsTransactionsOutgoing" = "Outgoing"; +"ProfileTabSavedDialogs" = "Chats"; +"ProfileTabStories" = "Posts"; +"ProfileTabStoriesArchive" = "Story Archive"; +"ProfileTabGifts" = "Gifts"; +"ProfileTabSubscribers" = "Subscribers"; +"ProfileTabMembers" = "Members"; +"ProfileTabBotPreview" = "Preview"; +"ProfileTabMedia" = "Media"; +"ProfileTabFiles" = "Files"; +"ProfileTabLinks" = "Links"; +"ProfileTabMusic" = "Music"; +"ProfileTabVoice" = "Voice"; +"ProfileTabSharedGroups" = "Groups"; +"ProfileTabSimilarChannels" = "Similar Channels"; diff --git a/src/components/left/main/ChatFolders.tsx b/src/components/left/main/ChatFolders.tsx index 3501fb022..431e2ef27 100644 --- a/src/components/left/main/ChatFolders.tsx +++ b/src/components/left/main/ChatFolders.tsx @@ -24,8 +24,8 @@ import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntit import useDerivedState from '../../../hooks/useDerivedState'; import { useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager'; import useHistoryBack from '../../../hooks/useHistoryBack'; +import useLang from '../../../hooks/useLang'; import useLastCallback from '../../../hooks/useLastCallback'; -import useOldLang from '../../../hooks/useOldLang'; import useShowTransition from '../../../hooks/useShowTransition'; import StoryRibbon from '../../story/StoryRibbon'; @@ -95,7 +95,7 @@ const ChatFolders: FC = ({ // eslint-disable-next-line no-null/no-null const transitionRef = useRef(null); - const lang = useOldLang(); + const lang = useLang(); useEffect(() => { loadChatFolders(); @@ -151,7 +151,7 @@ const ChatFolders: FC = ({ if (canShareFolder) { contextActions.push({ - title: lang('ChatList.ContextMenuShare'), + title: lang('FilterShare'), icon: 'link', handler: () => { const chatListCount = Object.values(chatFoldersById).reduce((acc, el) => acc + (el.isChatList ? 1 : 0), 0); @@ -187,7 +187,7 @@ const ChatFolders: FC = ({ }); contextActions.push({ - title: lang('FilterDeleteItem'), + title: lang('FilterDelete'), icon: 'delete', destructive: true, handler: () => { diff --git a/src/components/left/search/LeftSearch.tsx b/src/components/left/search/LeftSearch.tsx index 0c7a208cf..ce6c803f7 100644 --- a/src/components/left/search/LeftSearch.tsx +++ b/src/components/left/search/LeftSearch.tsx @@ -7,6 +7,7 @@ import React, { } from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; +import type { RegularLangKey } from '../../../types/language'; import { GlobalSearchContent } from '../../../types'; import { selectTabState } from '../../../global/selectors'; @@ -14,8 +15,8 @@ import { parseDateString } from '../../../util/dates/dateFormat'; import useHistoryBack from '../../../hooks/useHistoryBack'; import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'; +import useLang from '../../../hooks/useLang'; import useLastCallback from '../../../hooks/useLastCallback'; -import useOldLang from '../../../hooks/useOldLang'; import TabList from '../../ui/TabList'; import Transition from '../../ui/Transition'; @@ -41,19 +42,24 @@ type StateProps = { chatId?: string; }; -const TABS = [ - { type: GlobalSearchContent.ChatList, title: 'SearchAllChatsShort' }, - { type: GlobalSearchContent.ChannelList, title: 'ChannelsTab' }, - { type: GlobalSearchContent.BotApps, title: 'AppsTab' }, - { type: GlobalSearchContent.Media, title: 'SharedMediaTab2' }, - { type: GlobalSearchContent.Links, title: 'SharedLinksTab2' }, - { type: GlobalSearchContent.Files, title: 'SharedFilesTab2' }, - { type: GlobalSearchContent.Music, title: 'SharedMusicTab2' }, - { type: GlobalSearchContent.Voice, title: 'SharedVoiceTab2' }, +type TabInfo = { + type: GlobalSearchContent; + key: RegularLangKey; +}; + +const TABS: TabInfo[] = [ + { type: GlobalSearchContent.ChatList, key: 'SearchTabChats' }, + { type: GlobalSearchContent.ChannelList, key: 'SearchTabChannels' }, + { type: GlobalSearchContent.BotApps, key: 'SearchTabApps' }, + { type: GlobalSearchContent.Media, key: 'SearchTabMedia' }, + { type: GlobalSearchContent.Links, key: 'SearchTabLinks' }, + { type: GlobalSearchContent.Files, key: 'SearchTabFiles' }, + { type: GlobalSearchContent.Music, key: 'SearchTabMusic' }, + { type: GlobalSearchContent.Voice, key: 'SearchTabVoice' }, ]; -const CHAT_TABS = [ - { type: GlobalSearchContent.ChatList, title: 'All Messages' }, +const CHAT_TABS: TabInfo[] = [ + { type: GlobalSearchContent.ChatList, key: 'SearchTabMessages' }, ...TABS.slice(3), // Skip ChatList, ChannelList and BotApps, replaced with All Messages ]; @@ -70,11 +76,17 @@ const LeftSearch: FC = ({ setGlobalSearchDate, } = getActions(); - const lang = useOldLang(); + const lang = useLang(); const [activeTab, setActiveTab] = useState(currentContent); const dateSearchQuery = useMemo(() => parseDateString(searchQuery), [searchQuery]); - const tabs = chatId ? CHAT_TABS : TABS; + const tabs = useMemo(() => { + const arr = chatId ? CHAT_TABS : TABS; + return arr.map((tab) => ({ + ...tab, + title: lang(tab.key), + })); + }, [chatId, lang]); const handleSwitchTab = useLastCallback((index: number) => { const tab = tabs[index]; diff --git a/src/components/modals/stars/StarsBalanceModal.tsx b/src/components/modals/stars/StarsBalanceModal.tsx index 346583944..1273bf97c 100644 --- a/src/components/modals/stars/StarsBalanceModal.tsx +++ b/src/components/modals/stars/StarsBalanceModal.tsx @@ -5,6 +5,7 @@ import { getActions, getGlobal, withGlobal } from '../../../global'; import type { ApiStarTopupOption } from '../../../api/types'; import type { GlobalState, TabState } from '../../../global/types'; +import type { RegularLangKey } from '../../../types/language'; import { getChatTitle, getUserFullName } from '../../../global/helpers'; import { selectChat, selectIsPremiumPurchaseBlocked, selectUser } from '../../../global/selectors'; @@ -35,10 +36,10 @@ import StarLogo from '../../../assets/icons/StarLogo.svg'; import StarsBackground from '../../../assets/stars-bg.png'; const TRANSACTION_TYPES = ['all', 'inbound', 'outbound'] as const; -const TRANSACTION_TABS: TabWithProperties[] = [ - { title: 'StarsTransactionsAll' }, - { title: 'StarsTransactionsIncoming' }, - { title: 'StarsTransactionsOutgoing' }, +const TRANSACTION_TABS_KEYS: RegularLangKey[] = [ + 'StarsTransactionsAll', + 'StarsTransactionsIncoming', + 'StarsTransactionsOutgoing', ]; const TRANSACTION_ITEM_CLASS = 'StarsTransactionItem'; const SUBSCRIPTION_PURPOSE = 'subs'; @@ -113,6 +114,12 @@ const StarsBalanceModal = ({ const shouldShowItems = Boolean(history?.all?.transactions.length && !shouldOpenOnBuy); const shouldSuggestGifting = !shouldOpenOnBuy; + const transactionTabs: TabWithProperties[] = useMemo(() => { + return TRANSACTION_TABS_KEYS.map((key) => ({ + title: lang(key), + })); + }, [lang]); + useEffect(() => { if (!isOpen) { setHeaderHidden(true); @@ -266,7 +273,7 @@ const StarsBalanceModal = ({ @@ -292,7 +299,7 @@ const StarsBalanceModal = ({ className={styles.tabs} tabClassName={styles.tab} activeTab={selectedTabIndex} - tabs={TRANSACTION_TABS} + tabs={transactionTabs} onSwitchTab={setSelectedTabIndex} /> diff --git a/src/components/right/Profile.tsx b/src/components/right/Profile.tsx index f4776cd14..81a4f3c72 100644 --- a/src/components/right/Profile.tsx +++ b/src/components/right/Profile.tsx @@ -19,6 +19,7 @@ import type { TabState } from '../../global/types'; import type { ISettings, ProfileState, ProfileTabType, SharedMediaType, ThreadId, } from '../../types'; +import type { RegularLangKey } from '../../types/language'; import { MAIN_THREAD_ID } from '../../api/types'; import { AudioOrigin, MediaViewerOrigin, NewChatMembersProgress } from '../../types'; @@ -68,6 +69,7 @@ import useCacheBuster from '../../hooks/useCacheBuster'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useFlag from '../../hooks/useFlag'; import { useIntersectionObserver } from '../../hooks/useIntersectionObserver'; +import useLang from '../../hooks/useLang'; import useLastCallback from '../../hooks/useLastCallback'; import useOldLang from '../../hooks/useOldLang'; import useAsyncRendering from './hooks/useAsyncRendering'; @@ -151,14 +153,14 @@ type StateProps = { type TabProps = { type: ProfileTabType; - title: string; + key: RegularLangKey; }; const TABS: TabProps[] = [ - { type: 'media', title: 'SharedMediaTab2' }, - { type: 'documents', title: 'SharedFilesTab2' }, - { type: 'links', title: 'SharedLinksTab2' }, - { type: 'audio', title: 'SharedMusicTab2' }, + { type: 'media', key: 'ProfileTabMedia' }, + { type: 'documents', key: 'ProfileTabFiles' }, + { type: 'links', key: 'ProfileTabLinks' }, + { type: 'audio', key: 'ProfileTabMusic' }, ]; const HIDDEN_RENDER_DELAY = 1000; @@ -231,42 +233,63 @@ const Profile: FC = ({ const containerRef = useRef(null); // eslint-disable-next-line no-null/no-null const transitionRef = useRef(null); - const lang = useOldLang(); + + const oldLang = useOldLang(); + const lang = useLang(); + const [deletingUserId, setDeletingUserId] = useState(); const profileId = isSavedDialog ? String(threadId) : chatId; const isSavedMessages = profileId === currentUserId && !isSavedDialog; - const tabs = useMemo(() => ([ - ...(isSavedMessages && !isSavedDialog ? [{ type: 'dialogs' as const, title: 'SavedDialogsTab' }] : []), - ...(hasStoriesTab ? [{ type: 'stories' as const, title: 'ProfileStories' }] : []), - ...(hasStoriesTab && isSavedMessages ? [{ type: 'storiesArchive' as const, title: 'ProfileStoriesArchive' }] : []), - ...(hasGiftsTab ? [{ type: 'gifts' as const, title: 'ProfileGifts' }] : []), - ...(hasMembersTab ? [{ - type: 'members' as const, title: isChannel ? 'ChannelSubscribers' : 'GroupMembers', - }] : []), - ...(hasPreviewMediaTab ? [{ - type: 'previewMedia' as const, title: 'ProfileBotPreviewTab', - }] : []), - ...TABS, - // TODO The filter for voice messages currently does not work - // in forum topics. Return it when it's fixed on the server side. - ...(!isTopicInfo ? [{ type: 'voice' as const, title: 'SharedVoiceTab2' }] : []), - ...(hasCommonChatsTab ? [{ type: 'commonChats' as const, title: 'SharedGroupsTab2' }] : []), - ...(isChannel && similarChannels?.length - ? [{ type: 'similarChannels' as const, title: 'SimilarChannelsTab' }] - : []), - ]), [ - hasCommonChatsTab, - hasMembersTab, - hasPreviewMediaTab, - hasStoriesTab, - hasGiftsTab, - isChannel, - isTopicInfo, - similarChannels, - isSavedMessages, - isSavedDialog, + const tabs = useMemo(() => { + const arr: TabProps[] = []; + if (isSavedMessages && !isSavedDialog) { + arr.push({ type: 'dialogs', key: 'ProfileTabSavedDialogs' }); + } + + if (hasStoriesTab) { + arr.push({ type: 'stories', key: 'ProfileTabStories' }); + } + + if (hasStoriesTab && isSavedMessages) { + arr.push({ type: 'storiesArchive', key: 'ProfileTabStoriesArchive' }); + } + + if (hasGiftsTab) { + arr.push({ type: 'gifts', key: 'ProfileTabGifts' }); + } + + if (hasMembersTab) { + arr.push({ type: 'members', key: isChannel ? 'ProfileTabSubscribers' : 'ProfileTabMembers' }); + } + + if (hasPreviewMediaTab) { + arr.push({ type: 'previewMedia', key: 'ProfileTabBotPreview' }); + } + + arr.push(...TABS); + + // Voice messages filter currently does not work in forum topics. Return it when it's fixed on the server side. + if (!isTopicInfo) { + arr.push({ type: 'voice', key: 'ProfileTabVoice' }); + } + + if (hasCommonChatsTab) { + arr.push({ type: 'commonChats', key: 'ProfileTabSharedGroups' }); + } + + if (isChannel && similarChannels?.length) { + arr.push({ type: 'similarChannels', key: 'ProfileTabSimilarChannels' }); + } + + return arr.map((tab) => ({ + type: tab.type, + title: lang(tab.key), + })); + }, [ + isSavedMessages, isSavedDialog, hasStoriesTab, hasGiftsTab, hasMembersTab, hasPreviewMediaTab, isTopicInfo, + hasCommonChatsTab, isChannel, similarChannels?.length, lang, ]); const initialTab = useMemo(() => { @@ -471,7 +494,7 @@ const Profile: FC = ({ function getMemberContextAction(memberId: string): MenuItemContextAction[] | undefined { return memberId === currentUserId || !canDeleteMembers ? undefined : [{ - title: lang('lng_context_remove_from_group'), + title: oldLang('lng_context_remove_from_group'), icon: 'stop', handler: () => { setDeletingUserId(memberId); @@ -506,28 +529,28 @@ const Profile: FC = ({ text = areMembersHidden ? 'You have no access to group members list.' : 'No members found'; break; case 'commonChats': - text = lang('NoGroupsInCommon'); + text = oldLang('NoGroupsInCommon'); break; case 'documents': - text = lang('lng_media_file_empty'); + text = oldLang('lng_media_file_empty'); break; case 'links': - text = lang('lng_media_link_empty'); + text = oldLang('lng_media_link_empty'); break; case 'audio': - text = lang('lng_media_song_empty'); + text = oldLang('lng_media_song_empty'); break; case 'voice': - text = lang('lng_media_audio_empty'); + text = oldLang('lng_media_audio_empty'); break; case 'stories': - text = lang('StoryList.SavedEmptyState.Title'); + text = oldLang('StoryList.SavedEmptyState.Title'); break; case 'storiesArchive': - text = lang('StoryList.ArchivedEmptyState.Title'); + text = oldLang('StoryList.ArchivedEmptyState.Title'); break; default: - text = lang('SharedMedia.EmptyTitle'); + text = oldLang('SharedMedia.EmptyTitle'); } return ( @@ -540,7 +563,7 @@ const Profile: FC = ({ return (
{resultType === 'media' ? ( @@ -612,7 +635,7 @@ const Profile: FC = ({ key={id} theme={theme} message={messagesById[id]} - senderTitle={getSenderName(lang, messagesById[id], chatsById, usersById)} + senderTitle={getSenderName(oldLang, messagesById[id], chatsById, usersById)} origin={AudioOrigin.SharedMedia} date={messagesById[id].date} className="scroll-item" @@ -679,11 +702,11 @@ const Profile: FC = ({ <> {/* eslint-disable-next-line react/jsx-no-bind */}
- {renderText(lang('MoreSimilarText', limitSimilarChannels), ['simple_markdown'])} + {renderText(oldLang('MoreSimilarText', limitSimilarChannels), ['simple_markdown'])}
)} @@ -721,7 +744,7 @@ const Profile: FC = ({ > = ({ diff --git a/src/types/language.d.ts b/src/types/language.d.ts index a3a4190b5..865b3d96b 100644 --- a/src/types/language.d.ts +++ b/src/types/language.d.ts @@ -408,6 +408,8 @@ export interface LangPair { 'PasscodeControllerChangeTitle': undefined; 'FilterNew': undefined; 'FilterEdit': undefined; + 'FilterDelete': undefined; + 'FilterShare': undefined; 'AutoDeleteConfirm': undefined; 'LogOutTitle': undefined; 'AccDescrGoBack': undefined; @@ -1172,6 +1174,32 @@ export interface LangPair { 'PrivateChatsSearchContext': undefined; 'GroupChatsSearchContext': undefined; 'ChannelsSearchContext': undefined; + 'SearchTabChats': undefined; + 'SearchTabChannels': undefined; + 'SearchTabApps': undefined; + 'SearchTabMedia': undefined; + 'SearchTabLinks': undefined; + 'SearchTabFiles': undefined; + 'SearchTabMusic': undefined; + 'SearchTabVoice': undefined; + 'SearchTabMessages': undefined; + 'StarsTransactionsAll': undefined; + 'StarsTransactionsIncoming': undefined; + 'StarsTransactionsOutgoing': undefined; + 'ProfileTabSavedDialogs': undefined; + 'ProfileTabStories': undefined; + 'ProfileTabStoriesArchive': undefined; + 'ProfileTabGifts': undefined; + 'ProfileTabSubscribers': undefined; + 'ProfileTabMembers': undefined; + 'ProfileTabBotPreview': undefined; + 'ProfileTabMedia': undefined; + 'ProfileTabFiles': undefined; + 'ProfileTabLinks': undefined; + 'ProfileTabMusic': undefined; + 'ProfileTabVoice': undefined; + 'ProfileTabSharedGroups': undefined; + 'ProfileTabSimilarChannels': undefined; } export interface LangPairWithVariables {