Refactor mobile chat into modal (#3038)

* feat(mobile): refactor mobile chat into modal

- Make page always scrollable
- Move mobile chat into a standalone modal

* fix(test): split out mobile browser test specs

* fix(mobile): force chat button to render on top of footer

* fix: some small updates from review

* fix: hide/show hide chat menu option based on width

* fix: chat button icon getting cut off

* chore(tests): add browser tests for mobile chat modal

* chore(tests): add story for ChatModal component

* fix(test): quiet shellcheck

* fix: remove unused import

* fix(tests): silence storybook linting warning

* fix(ui): reposition chat modal button icon with transform
This commit is contained in:
Gabe Kangas
2023-05-22 18:56:44 -07:00
committed by GitHub
parent b9b569f3fe
commit 69f217f758
21 changed files with 945 additions and 215 deletions

View File

@@ -3,20 +3,31 @@
.root {
button {
border: none;
.ant-space {
.ant-space-item {
color: var(--theme-unknown-2);
}
}
.ant-space {
.ant-space-item {
color: var(--theme-unknown-2);
}
}
}
.username {
display: none;
.username {
display: inline;
@include screen(desktop) {
display: inline;
font-weight: 600;
font-size: .8rem;
}
@include screen(desktop) {
font-weight: 600;
font-size: 0.8rem;
}
}
.hideTitleOnMobile {
@include screen(mobile) {
display: none;
}
}
}
.chatToggle {
@include screen(mobile) {
display: none;
}
}

View File

@@ -26,7 +26,7 @@ const Example = args => {
[],
);
return <UserDropdown {...args} />;
return <UserDropdown id="user-menu" {...args} />;
};
const Template: ComponentStory<typeof UserDropdown> = args => (

View File

@@ -1,4 +1,5 @@
import { Menu, Dropdown, Button } from 'antd';
import classnames from 'classnames';
import { useRecoilState, useRecoilValue } from 'recoil';
import { FC, useState } from 'react';
@@ -55,16 +56,29 @@ const AuthModal = dynamic(
);
export type UserDropdownProps = {
id: string;
username?: string;
hideTitleOnMobile?: boolean;
showToggleChatOption?: boolean;
};
export const UserDropdown: FC<UserDropdownProps> = ({ username: defaultUsername = undefined }) => {
export const UserDropdown: FC<UserDropdownProps> = ({
id,
username: defaultUsername = undefined,
hideTitleOnMobile = false,
showToggleChatOption: showHideChatOption = true,
}) => {
const [showNameChangeModal, setShowNameChangeModal] = useState<boolean>(false);
const [showAuthModal, setShowAuthModal] = useState<boolean>(false);
const [chatToggleVisible, setChatToggleVisible] = useRecoilState(chatVisibleToggleAtom);
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
const toggleChatVisibility = () => {
// If we don't support the hide chat option then don't do anything.
if (!showHideChatOption) {
return;
}
setChatToggleVisible(!chatToggleVisible);
};
@@ -97,12 +111,13 @@ export const UserDropdown: FC<UserDropdownProps> = ({ username: defaultUsername
<Menu.Item key="1" icon={<LockOutlined />} onClick={() => setShowAuthModal(true)}>
Authenticate
</Menu.Item>
{appState.chatAvailable && (
{showHideChatOption && appState.chatAvailable && (
<Menu.Item
key="3"
icon={<MessageOutlined />}
onClick={() => toggleChatVisibility()}
aria-expanded={chatToggleVisible}
className={styles.chatToggle}
>
{chatToggleVisible ? 'Hide Chat' : 'Show Chat'}
</Menu.Item>
@@ -121,10 +136,17 @@ export const UserDropdown: FC<UserDropdownProps> = ({ username: defaultUsername
/>
)}
>
<div id="user-menu" className={styles.root}>
<div id={id} className={styles.root}>
<Dropdown overlay={menu} trigger={['click']}>
<Button type="primary" icon={<UserOutlined className={styles.userIcon} />}>
<span className={styles.username}>{username}</span>
<span
className={classnames([
styles.username,
hideTitleOnMobile && styles.hideTitleOnMobile,
])}
>
{username}
</span>
<CaretDownOutlined />
</Button>
</Dropdown>