Middle Header: Add edit button (#3449)

This commit is contained in:
Alexander Zinchuk 2023-07-05 13:15:04 +02:00
parent efc36cb517
commit af973d6f20
7 changed files with 74 additions and 17 deletions

View File

@ -21,6 +21,7 @@ import {
selectTabState,
selectUser,
selectUserFullInfo,
selectCanManage, selectIsRightColumnShown,
} from '../../global/selectors';
import {
getCanAddContact,
@ -108,6 +109,8 @@ type StateProps = {
canEditTopic?: boolean;
hasLinkedChat?: boolean;
isChatInfoShown?: boolean;
isRightColumnShown?: boolean;
canManage?: boolean;
};
const CLOSE_MENU_ANIMATION_DURATION = 200;
@ -145,6 +148,8 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
canAddContact,
canCreateTopic,
canEditTopic,
canManage,
isRightColumnShown,
onJoinRequestsClick,
onSubscribeChannel,
onSearchClick,
@ -168,10 +173,12 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
openCreateTopicPanel,
openEditTopicPanel,
openChat,
toggleManagement,
} = getActions();
const { isMobile } = useAppLayout();
const [isMenuOpen, setIsMenuOpen] = useState(true);
const [shouldCloseFast, setShouldCloseFast] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isReportModalOpen, setIsReportModalOpen] = useState(false);
const [isMuteModalOpen, setIsMuteModalOpen] = useState(false);
@ -210,6 +217,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
const handleViewGroupInfo = useLastCallback(() => {
openChatWithInfo({ id: chatId, threadId });
setShouldCloseFast(!isRightColumnShown);
closeMenu();
});
@ -239,11 +247,19 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
const handleCreateTopicClick = useLastCallback(() => {
openCreateTopicPanel({ chatId });
setShouldCloseFast(!isRightColumnShown);
closeMenu();
});
const handleEditClick = useLastCallback(() => {
toggleManagement({ force: true });
setShouldCloseFast(!isRightColumnShown);
closeMenu();
});
const handleEditTopicClick = useLastCallback(() => {
openEditTopicPanel({ chatId, topicId: threadId });
setShouldCloseFast(!isRightColumnShown);
closeMenu();
});
@ -303,6 +319,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
const handleStatisticsClick = useLastCallback(() => {
toggleStatistics();
setShouldCloseFast(!isRightColumnShown);
closeMenu();
});
@ -354,6 +371,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
positionX="right"
style={`left: ${x}px;top: ${y}px;`}
onClose={closeMenu}
shouldCloseFast={shouldCloseFast}
>
{isMobile && canSearch && (
<MenuItem
@ -382,6 +400,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
{isTopic ? lang('lng_context_view_topic') : lang('lng_context_view_group')}
</MenuItem>
)}
{canManage && !canEditTopic && (
<MenuItem
icon="edit"
onClick={handleEditClick}
>
{lang('Edit')}
</MenuItem>
)}
{canEditTopic && (
<MenuItem
icon="edit"
@ -598,6 +624,7 @@ export default memo(withGlobal<OwnProps>(
chat.isCreator || !isUserRightBanned(chat, 'manageTopics') || getHasAdminRight(chat, 'manageTopics')
);
const canEditTopic = topic && getCanManageTopic(chat, topic);
const canManage = selectCanManage(global, chatId);
return {
chat,
@ -615,6 +642,8 @@ export default memo(withGlobal<OwnProps>(
&& currentChatId === chatId && currentThreadId === threadId,
canCreateTopic,
canEditTopic,
canManage,
isRightColumnShown: selectIsRightColumnShown(global),
};
},
)(HeaderMenuContainer));

View File

@ -12,17 +12,17 @@ import { ANIMATION_END_DELAY } from '../../config';
import { debounce } from '../../util/schedulers';
import buildClassName from '../../util/buildClassName';
import {
selectCanManage,
selectChat,
selectChatFullInfo,
selectCurrentGifSearch,
selectCurrentStickerSearch,
selectCurrentTextSearch,
selectIsChatWithSelf,
selectTabState,
selectUser,
} from '../../global/selectors';
import {
getCanAddContact, getCanManageTopic, isChatAdmin, isChatChannel, isUserBot, isUserId,
getCanAddContact, getCanManageTopic, isChatChannel, isUserBot, isUserId,
} from '../../global/helpers';
import { getDayStartAt } from '../../util/dateFormat';
@ -464,7 +464,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
<i className="icon icon-add-user" />
</Button>
)}
{canManage && !isInsideTopic && !isBot && (
{canManage && !isInsideTopic && (
<Button
round
color="translucent"
@ -561,15 +561,8 @@ export default memo(withGlobal<OwnProps>(
const isBot = user && isUserBot(user);
const canAddContact = user && getCanAddContact(user);
const canManage = Boolean(
!isManagement
&& isProfile
&& !canAddContact
&& chat
&& !selectIsChatWithSelf(global, chat.id)
// chat.isCreator is for Basic Groups
&& (isUserId(chat.id) || ((isChatAdmin(chat) || chat.isCreator) && !chat.isNotJoined)),
);
const canManage = Boolean(!isManagement && isProfile && chatId && selectCanManage(global, chatId));
const isEditingInvite = Boolean(chatId && tabState.management.byChatId[chatId]?.editingInvite);
const canViewStatistics = !isInsideTopic && chatId
? selectChatFullInfo(global, chatId)?.canViewStatistics

View File

@ -38,6 +38,10 @@
transition: opacity 0.2s ease-in, transform 0.2s ease-in !important;
}
&.close-fast {
transition-duration: 70ms !important;
}
body.no-context-menu-animations & {
transform: none !important;
transition: opacity 0.15s !important;

View File

@ -23,6 +23,7 @@ type OwnProps = {
ref?: RefObject<HTMLDivElement>;
containerRef?: RefObject<HTMLElement>;
isOpen: boolean;
shouldCloseFast?: boolean;
id?: string;
className?: string;
bubbleClassName?: string;
@ -54,6 +55,7 @@ const ANIMATION_DURATION = 200;
const Menu: FC<OwnProps> = ({
ref,
containerRef,
shouldCloseFast,
isOpen,
id,
className,
@ -131,6 +133,7 @@ const Menu: FC<OwnProps> = ({
footer && 'with-footer',
transitionClassNames,
bubbleClassName,
shouldCloseFast && 'close-fast',
);
const transformOriginYStyle = transformOriginY !== undefined ? `${transformOriginY}px` : undefined;

View File

@ -61,7 +61,7 @@ addActionHandler('resetLeftColumnWidth', (global): ActionReturnType => {
});
addActionHandler('toggleManagement', (global, actions, payload): ActionReturnType => {
const { tabId = getCurrentTabId() } = payload || {};
const { force, tabId = getCurrentTabId() } = payload || {};
const { chatId } = selectCurrentMessageList(global, tabId) || {};
if (!chatId) {
@ -76,7 +76,7 @@ addActionHandler('toggleManagement', (global, actions, payload): ActionReturnTyp
...tabState.management.byChatId,
[chatId]: {
...tabState.management.byChatId[chatId],
isActive: !(tabState.management.byChatId[chatId] || {}).isActive,
isActive: force !== undefined ? force : !(tabState.management.byChatId[chatId] || {}).isActive,
},
},
},

View File

@ -1,10 +1,14 @@
import type { GlobalState, TabArgs } from '../types';
import { selectCurrentMessageList } from './messages';
import { selectChat } from './chats';
import { isChatGroup, isUserId } from '../helpers';
import { selectChat, selectIsChatWithSelf } from './chats';
import {
getCanAddContact,
isChatAdmin, isChatGroup, isUserBot, isUserId,
} from '../helpers';
import { selectTabState } from './tabs';
import { getCurrentTabId } from '../../util/establishMultitabRole';
import { selectUser } from './users';
export function selectManagement<T extends GlobalState>(
global: T, chatId: string,
@ -54,3 +58,25 @@ export function selectCurrentManagementType<T extends GlobalState>(
return 'channel';
}
export function selectCanManage<T extends GlobalState>(
global: T,
chatId: string,
) {
const chat = selectChat(global, chatId);
if (!chat || chat.isRestricted) return false;
const isPrivate = isUserId(chat.id);
const user = isPrivate ? selectUser(global, chatId) : undefined;
const canAddContact = user && getCanAddContact(user);
const isBot = user && isUserBot(user);
return Boolean(
!canAddContact
&& chat
&& !selectIsChatWithSelf(global, chat.id)
// chat.isCreator is for Basic Groups
&& (isUserId(chat.id) || ((isChatAdmin(chat) || chat.isCreator) && !chat.isNotJoined))
&& !isBot,
);
}

View File

@ -1526,7 +1526,9 @@ export interface ActionPayloads {
hideChatReportPanel: {
chatId: string;
};
toggleManagement: WithTabId | undefined;
toggleManagement: ({
force?: boolean;
} & WithTabId) | undefined;
requestNextManagementScreen: ({
screen?: ManagementScreens;
} & WithTabId) | undefined;