From d6d98bdae18a43c97b6732d1874d49c68bfe343d Mon Sep 17 00:00:00 2001 From: zubiden <19638254+zubiden@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:53:01 +0200 Subject: [PATCH] Various padding fixes (#4924) --- src/components/common/ChatExtra.module.scss | 38 ----- src/components/common/RecipientPicker.tsx | 1 + .../common/pickers/ChatOrUserPicker.scss | 25 +-- .../common/pickers/ChatOrUserPicker.tsx | 150 ++++++++++++------ .../common/pickers/PickerItem.module.scss | 2 +- src/components/common/pickers/PickerItem.tsx | 3 + .../common/profile/ChatExtra.module.scss | 4 + src/components/left/main/Chat.tsx | 1 + src/components/left/search/LeftSearch.scss | 6 +- .../left/search/RecentContacts.scss | 2 +- src/components/ui/Checkbox.scss | 2 + src/components/ui/Tab.scss | 4 +- src/config.ts | 1 + src/styles/_common.scss | 4 +- 14 files changed, 128 insertions(+), 115 deletions(-) delete mode 100644 src/components/common/ChatExtra.module.scss diff --git a/src/components/common/ChatExtra.module.scss b/src/components/common/ChatExtra.module.scss deleted file mode 100644 index fbb856757..000000000 --- a/src/components/common/ChatExtra.module.scss +++ /dev/null @@ -1,38 +0,0 @@ -.businessLocation { - width: 4rem; - height: 4rem; - object-fit: cover; - border-radius: 0.25rem; - flex-shrink: 0; - margin-inline-start: 0.25rem; -} - -.personalChannel { - display: grid; - grid-template-columns: 1fr auto; - grid-template-rows: auto auto; - column-gap: 0.5rem; - margin-bottom: 0.5rem; -} - -.personalChannelTitle { - grid-column: 1; - grid-row: 1; - color: var(--color-text-secondary); - font-size: 0.875rem; - margin-inline-start: 0.5rem; - margin-bottom: 0; -} - -.personalChannelSubscribers { - grid-column: 2; - grid-row: 1; - color: var(--color-text-secondary); - font-size: 0.875rem; - margin-inline-end: 0.5rem; -} - -.personalChannelItem { - grid-column: 1 / span 2; - grid-row: 2; -} diff --git a/src/components/common/RecipientPicker.tsx b/src/components/common/RecipientPicker.tsx index 300e83c5d..0953ceecb 100644 --- a/src/components/common/RecipientPicker.tsx +++ b/src/components/common/RecipientPicker.tsx @@ -104,6 +104,7 @@ const RecipientPicker: FC = ({ isOpen={isOpen} className={className} chatOrUserIds={renderingIds} + currentUserId={currentUserId} searchPlaceholder={searchPlaceholder} search={search} onSearchChange={setSearch} diff --git a/src/components/common/pickers/ChatOrUserPicker.scss b/src/components/common/pickers/ChatOrUserPicker.scss index 43ff499a2..c39b3496a 100644 --- a/src/components/common/pickers/ChatOrUserPicker.scss +++ b/src/components/common/pickers/ChatOrUserPicker.scss @@ -1,3 +1,5 @@ +@use "../../../styles/mixins"; + .ChatOrUserPicker { .modal-dialog { height: 70%; @@ -54,7 +56,9 @@ height: 100%; overflow-x: hidden; overflow-y: auto; - padding: 0 0.5rem; + padding-inline: 0.5rem; + + @include mixins.adapt-padding-to-scrollbar(0.5rem); body.is-ios &, body.is-android & { @@ -81,25 +85,12 @@ position: relative; } - .ListItem { + .ChatOrUserPicker-item { position: absolute; width: 100%; - body.is-ios &:not(:last-of-type)::after, - body.is-android &:not(:last-of-type)::after { - right: -0.5rem; - } - } - - .ListItem.chat-item-clickable { - &:not(.force-rounded-corners) { - @media (max-width: 600px) { - margin: 0; - - .ListItem-button { - border-radius: 0; - } - } + .online { + color: var(--color-primary); } } diff --git a/src/components/common/pickers/ChatOrUserPicker.tsx b/src/components/common/pickers/ChatOrUserPicker.tsx index 1be70ba6d..a8d0fff86 100644 --- a/src/components/common/pickers/ChatOrUserPicker.tsx +++ b/src/components/common/pickers/ChatOrUserPicker.tsx @@ -1,18 +1,24 @@ import type { FC } from '../../../lib/teact/teact'; import React, { - memo, useMemo, useRef, useState, + memo, useCallback, useMemo, useRef, useState, } from '../../../lib/teact/teact'; import { getActions, getGlobal } from '../../../global'; import type { ApiTopic } from '../../../api/types'; +import type { GlobalState } from '../../../global/types'; import type { ThreadId } from '../../../types'; -import { CHAT_HEIGHT_PX } from '../../../config'; -import { getCanPostInChat, isUserId } from '../../../global/helpers'; +import { PEER_PICKER_ITEM_HEIGHT_PX } from '../../../config'; +import { + getCanPostInChat, getGroupStatus, getUserStatus, isUserOnline, +} from '../../../global/helpers'; +import { isApiPeerChat } from '../../../global/helpers/peers'; +import { selectChat, selectPeer, selectUserStatus } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { REM } from '../helpers/mediaDimensions'; import renderText from '../helpers/renderText'; +import useSelector from '../../../hooks/data/useSelector'; import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; import useInputFocusOnOpen from '../../../hooks/useInputFocusOnOpen'; import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'; @@ -22,13 +28,13 @@ import useOldLang from '../../../hooks/useOldLang'; import Button from '../../ui/Button'; import InfiniteScroll from '../../ui/InfiniteScroll'; import InputText from '../../ui/InputText'; -import ListItem from '../../ui/ListItem'; import Loading from '../../ui/Loading'; import Modal from '../../ui/Modal'; import Transition from '../../ui/Transition'; -import GroupChatInfo from '../GroupChatInfo'; -import PrivateChatInfo from '../PrivateChatInfo'; +import Avatar from '../Avatar'; +import FullNameTitle from '../FullNameTitle'; import TopicIcon from '../TopicIcon'; +import PickerItem from './PickerItem'; import './ChatOrUserPicker.scss'; @@ -49,6 +55,8 @@ export type OwnProps = { const CHAT_LIST_SLIDE = 0; const TOPIC_LIST_SLIDE = 1; const TOPIC_ICON_SIZE = 2.75 * REM; +const ITEM_CLASS_NAME = 'ChatOrUserPicker-item'; +const TOPIC_ITEM_HEIGHT_PX = 56; const ChatOrUserPicker: FC = ({ isOpen, @@ -86,22 +94,33 @@ const ChatOrUserPicker: FC = ({ useInputFocusOnOpen(searchRef, isOpen && activeKey === CHAT_LIST_SLIDE, resetSearch); useInputFocusOnOpen(topicSearchRef, isOpen && activeKey === TOPIC_LIST_SLIDE); + const selectTopics = useLastCallback((global: GlobalState) => { + if (!forumId) { + return undefined; + } + + return selectChat(global, forumId)?.topics; + }); + + const forumTopics = useSelector(selectTopics); + const [topicIds, topics] = useMemo(() => { const global = getGlobal(); const chatsById = global.chats.byId; const chatFullInfoById = global.chats.fullInfoById; - const topicsResult = forumId ? chatsById[forumId].topics : undefined; - if (!topicsResult) { + const chat = chatsById[forumId!]; + + if (!chat || !forumTopics) { return [undefined, undefined]; } const searchTitle = topicSearch.toLowerCase(); - const result = topicsResult - ? Object.values(topicsResult).reduce((acc, topic) => { + const result = forumTopics + ? Object.values(forumTopics).reduce((acc, topic) => { if ( - getCanPostInChat(chatsById[forumId!], topic.id, undefined, chatFullInfoById[forumId!]) + getCanPostInChat(chat, topic.id, undefined, chatFullInfoById[forumId!]) && (!searchTitle || topic.title.toLowerCase().includes(searchTitle)) ) { acc[topic.id] = topic; @@ -109,10 +128,10 @@ const ChatOrUserPicker: FC = ({ return acc; }, {} as Record) - : topicsResult; + : forumTopics; return [Object.keys(result).map(Number), result]; - }, [forumId, topicSearch]); + }, [forumId, topicSearch, forumTopics]); const handleHeaderBackClick = useLastCallback(() => { setForumId(undefined); @@ -140,15 +159,15 @@ const ChatOrUserPicker: FC = ({ onSelectChatOrUser(chatId); } } - }, '.ListItem-button', true); + }, `.${ITEM_CLASS_NAME}`, true); const handleTopicKeyDown = useKeyboardListNavigation(topicContainerRef, isOpen, (index) => { if (topicIds?.length) { onSelectChatOrUser(forumId!, topicIds[index === -1 ? 0 : index]); } - }, '.ListItem-button', true); + }, `.${ITEM_CLASS_NAME}`, true); - const handleClick = useLastCallback((e: React.MouseEvent, chatId: string) => { + const handleClick = useLastCallback((chatId: string) => { const chatsById = getGlobal().chats.byId; const chat = chatsById?.[chatId]; if (chat?.isForum) { @@ -160,9 +179,52 @@ const ChatOrUserPicker: FC = ({ } }); - const handleTopicClick = useLastCallback((e: React.MouseEvent, topicId: number) => { - onSelectChatOrUser(forumId!, topicId); - }); + const renderChatItem = useCallback((id: string, index: number) => { + const global = getGlobal(); + const peer = selectPeer(global, id); + if (!peer) { + return undefined; + } + + const isSelf = peer && !isApiPeerChat(peer) ? peer.isSelf : undefined; + + function getSubtitle() { + if (!peer) return undefined; + if (peer.id === currentUserId) return [lang('SavedMessagesInfo')]; + if (isApiPeerChat(peer)) { + return [getGroupStatus(lang, peer)]; + } + + const userStatus = selectUserStatus(global, peer.id); + return [ + getUserStatus(lang, peer, userStatus), + buildClassName(isUserOnline(peer, userStatus, true) && 'online'), + ]; + } + + const [subtitle, subtitleClassName] = getSubtitle() || []; + + return ( + } + avatarElement={( + + )} + subtitle={subtitle} + subtitleClassName={subtitleClassName} + ripple + style={`top: ${(viewportOffset + index) * PEER_PICKER_ITEM_HEIGHT_PX}px;`} + // eslint-disable-next-line react/jsx-no-bind + onClick={() => handleClick(id)} + /> + ); + }, [currentUserId, lang, viewportOffset]); function renderTopicList() { return ( @@ -184,28 +246,28 @@ const ChatOrUserPicker: FC = ({ className="picker-list custom-scroll" items={topicIds} withAbsolutePositioning - maxHeight={!topicIds ? 0 : topicIds.length * CHAT_HEIGHT_PX} + maxHeight={(topicIds?.length || 0) * TOPIC_ITEM_HEIGHT_PX} onKeyDown={handleTopicKeyDown} > - {topicIds - ? topicIds.map((topicId, i) => ( - + {!topicIds && } + {topicIds?.map((topicId, i) => ( + onSelectChatOrUser(forumId!, topicId)} + style={`top: ${(viewportOffset + i) * TOPIC_ITEM_HEIGHT_PX}px;`} + avatarElement={( -
{renderText(topics[topicId].title)}
-
- )) - : } + )} + title={renderText(topics[topicId].title)} + /> + ))} ); @@ -237,29 +299,13 @@ const ChatOrUserPicker: FC = ({ ref={containerRef} className="picker-list custom-scroll" items={viewportIds} + itemSelector={`.${ITEM_CLASS_NAME}`} onLoadMore={getMore} withAbsolutePositioning - maxHeight={chatOrUserIds!.length * CHAT_HEIGHT_PX} + maxHeight={chatOrUserIds!.length * PEER_PICKER_ITEM_HEIGHT_PX} onKeyDown={handleKeyDown} > - {viewportIds.map((id, i) => ( - - {isUserId(id) ? ( - - ) : ( - - )} - - ))} + {viewportIds.map(renderChatItem)} ) : viewportIds && !viewportIds.length ? (

{lang('lng_blocked_list_not_found')}

diff --git a/src/components/common/pickers/PickerItem.module.scss b/src/components/common/pickers/PickerItem.module.scss index b0179e4c5..00c54ad85 100644 --- a/src/components/common/pickers/PickerItem.module.scss +++ b/src/components/common/pickers/PickerItem.module.scss @@ -60,7 +60,6 @@ color: var(--color-text-secondary); grid-row: 2; grid-column: 3; - align-self: start; } .title, .subtitle { @@ -76,6 +75,7 @@ .multiline { .title { grid-row: 1; + align-self: end; } } diff --git a/src/components/common/pickers/PickerItem.tsx b/src/components/common/pickers/PickerItem.tsx index 4aa3c084a..607eace28 100644 --- a/src/components/common/pickers/PickerItem.tsx +++ b/src/components/common/pickers/PickerItem.tsx @@ -22,6 +22,7 @@ type OwnProps = { className?: string; titleClassName?: string; subtitleClassName?: string; + style?: string; onClick?: NoneToVoidFunction; onDisabledClick?: NoneToVoidFunction; }; @@ -38,6 +39,7 @@ const PickerItem = ({ className, titleClassName, subtitleClassName, + style, onClick, onDisabledClick, }: OwnProps) => { @@ -66,6 +68,7 @@ const PickerItem = ({ className, )} onClick={handleClick} + style={style} dir={lang.isRtl ? 'rtl' : undefined} role={isClickable ? 'button' : undefined} // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex diff --git a/src/components/common/profile/ChatExtra.module.scss b/src/components/common/profile/ChatExtra.module.scss index 11e360459..f5ec1cf55 100644 --- a/src/components/common/profile/ChatExtra.module.scss +++ b/src/components/common/profile/ChatExtra.module.scss @@ -40,6 +40,10 @@ .personalChannelItem { grid-column: 1 / span 2; grid-row: 2; + + :global(.Avatar) { + margin-right: 0.9375rem !important; + } } .openAppButton { diff --git a/src/components/left/main/Chat.tsx b/src/components/left/main/Chat.tsx index 1682eded5..df36834f7 100644 --- a/src/components/left/main/Chat.tsx +++ b/src/components/left/main/Chat.tsx @@ -335,6 +335,7 @@ const Chat: FC = ({ peer={peer} isSavedMessages={user?.isSelf} isSavedDialog={isSavedDialog} + size={isPreview ? 'medium' : 'large'} withStory={!user?.isSelf} withStoryGap={isAvatarOnlineShown} storyViewerOrigin={StoryViewerOrigin.ChatList} diff --git a/src/components/left/search/LeftSearch.scss b/src/components/left/search/LeftSearch.scss index 766995b43..d639599ee 100644 --- a/src/components/left/search/LeftSearch.scss +++ b/src/components/left/search/LeftSearch.scss @@ -86,7 +86,7 @@ } .RecentContacts .search-section { - padding-left: 0.25rem; + padding-inline: 0.5rem; } .WebLink { @@ -193,7 +193,9 @@ } .search-section { - padding: 0 0.125rem 0 0.75rem; + padding-inline: 0.5rem; + + @include mixins.adapt-padding-to-scrollbar(0.5rem); .section-heading { color: var(--color-text-secondary); diff --git a/src/components/left/search/RecentContacts.scss b/src/components/left/search/RecentContacts.scss index f860c0a05..15ef24bbe 100644 --- a/src/components/left/search/RecentContacts.scss +++ b/src/components/left/search/RecentContacts.scss @@ -81,6 +81,6 @@ .clear-recent-chats { position: absolute; - inset-inline-end: 0.5rem; + inset-inline-end: 0; } } diff --git a/src/components/ui/Checkbox.scss b/src/components/ui/Checkbox.scss index 98f2d7b60..ce3110fe8 100644 --- a/src/components/ui/Checkbox.scss +++ b/src/components/ui/Checkbox.scss @@ -224,12 +224,14 @@ &.onlyInput { padding-inline-start: 1.125rem; + margin-block: 0 1.25rem; .Checkbox-main { &::before, &::after { left: 0; right: 0; + top: 0; } } } diff --git a/src/components/ui/Tab.scss b/src/components/ui/Tab.scss index d4138884f..8d3396991 100644 --- a/src/components/ui/Tab.scss +++ b/src/components/ui/Tab.scss @@ -86,11 +86,11 @@ .platform { position: absolute; bottom: -0.625rem; - left: 0; + left: -0.5rem; + right: -0.5rem; opacity: 0; background-color: var(--color-primary); height: 0.1875rem; - width: 100%; border-radius: 0.1875rem 0.1875rem 0 0; pointer-events: none; box-sizing: content-box; diff --git a/src/config.ts b/src/config.ts index dbc7a5f2d..532c6e0a3 100644 --- a/src/config.ts +++ b/src/config.ts @@ -71,6 +71,7 @@ export const MESSAGE_LIST_VIEWPORT_LIMIT = MESSAGE_LIST_SLICE * 2; export const ARCHIVE_MINIMIZED_HEIGHT = 36; export const CHAT_HEIGHT_PX = 72; export const TOPIC_HEIGHT_PX = 65; +export const PEER_PICKER_ITEM_HEIGHT_PX = 56; export const CHAT_LIST_SLICE = isBigScreen ? 30 : 25; export const CHAT_LIST_LOAD_SLICE = 100; export const SHARED_MEDIA_SLICE = 42; diff --git a/src/styles/_common.scss b/src/styles/_common.scss index 578ce9139..6e5ac0889 100644 --- a/src/styles/_common.scss +++ b/src/styles/_common.scss @@ -101,9 +101,9 @@ .chat-list { background: var(--color-background); height: 100%; - padding: 0.5rem 0.4375rem 0.5rem 0.4375rem; + padding: 0.5rem; - @include mixins.adapt-padding-to-scrollbar(0.4375rem); + @include mixins.adapt-padding-to-scrollbar(0.5rem); overflow-x: hidden; overflow-y: scroll;