Split out desktop and mobile layouts to make it easier to work on them
This commit is contained in:
@@ -18,7 +18,6 @@ import {
|
|||||||
serverStatusState,
|
serverStatusState,
|
||||||
} from '../../stores/ClientConfigStore';
|
} from '../../stores/ClientConfigStore';
|
||||||
import { ClientConfig } from '../../../interfaces/client-config.model';
|
import { ClientConfig } from '../../../interfaces/client-config.model';
|
||||||
import { CustomPageContent } from '../CustomPageContent/CustomPageContent';
|
|
||||||
|
|
||||||
import styles from './Content.module.scss';
|
import styles from './Content.module.scss';
|
||||||
import { Sidebar } from '../Sidebar/Sidebar';
|
import { Sidebar } from '../Sidebar/Sidebar';
|
||||||
@@ -30,26 +29,16 @@ import { OfflineBanner } from '../OfflineBanner/OfflineBanner';
|
|||||||
import { AppStateOptions } from '../../stores/application-state';
|
import { AppStateOptions } from '../../stores/application-state';
|
||||||
import { FollowButton } from '../../action-buttons/FollowButton';
|
import { FollowButton } from '../../action-buttons/FollowButton';
|
||||||
import { NotifyButton } from '../../action-buttons/NotifyButton';
|
import { NotifyButton } from '../../action-buttons/NotifyButton';
|
||||||
import { ContentHeader } from '../../common/ContentHeader/ContentHeader';
|
|
||||||
import { ServerStatus } from '../../../interfaces/server-status.model';
|
import { ServerStatus } from '../../../interfaces/server-status.model';
|
||||||
import { Statusbar } from '../Statusbar/Statusbar';
|
import { Statusbar } from '../Statusbar/Statusbar';
|
||||||
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
||||||
import { ExternalAction } from '../../../interfaces/external-action';
|
import { ExternalAction } from '../../../interfaces/external-action';
|
||||||
import { Modal } from '../Modal/Modal';
|
import { Modal } from '../Modal/Modal';
|
||||||
import { ActionButtonMenu } from '../../action-buttons/ActionButtonMenu/ActionButtonMenu';
|
import { DesktopContent } from './DesktopContent';
|
||||||
|
import { MobileContent } from './MobileContent';
|
||||||
|
|
||||||
// Lazy loaded components
|
// Lazy loaded components
|
||||||
|
|
||||||
const FollowerCollection = dynamic(
|
|
||||||
() =>
|
|
||||||
import('../followers/FollowerCollection/FollowerCollection').then(
|
|
||||||
mod => mod.FollowerCollection,
|
|
||||||
),
|
|
||||||
{
|
|
||||||
ssr: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const FollowModal = dynamic(
|
const FollowModal = dynamic(
|
||||||
() => import('../../modals/FollowModal/FollowModal').then(mod => mod.FollowModal),
|
() => import('../../modals/FollowModal/FollowModal').then(mod => mod.FollowModal),
|
||||||
{
|
{
|
||||||
@@ -85,140 +74,6 @@ const OwncastPlayer = dynamic(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const ChatContainer = dynamic(
|
|
||||||
() => import('../../chat/ChatContainer/ChatContainer').then(mod => mod.ChatContainer),
|
|
||||||
{
|
|
||||||
ssr: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const Tabs = dynamic(() => import('antd').then(mod => mod.Tabs), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const DesktopContent = ({
|
|
||||||
name,
|
|
||||||
streamTitle,
|
|
||||||
summary,
|
|
||||||
tags,
|
|
||||||
socialHandles,
|
|
||||||
extraPageContent,
|
|
||||||
setShowFollowModal,
|
|
||||||
supportFediverseFeatures,
|
|
||||||
}) => {
|
|
||||||
const aboutTabContent = <CustomPageContent content={extraPageContent} />;
|
|
||||||
const followersTabContent = (
|
|
||||||
<div>
|
|
||||||
<FollowerCollection name={name} onFollowButtonClick={() => setShowFollowModal(true)} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const items = [{ label: 'About', key: '2', children: aboutTabContent }];
|
|
||||||
if (supportFediverseFeatures) {
|
|
||||||
items.push({ label: 'Followers', key: '3', children: followersTabContent });
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className={styles.lowerHalf} id="skip-to-content">
|
|
||||||
<ContentHeader
|
|
||||||
name={name}
|
|
||||||
title={streamTitle}
|
|
||||||
summary={summary}
|
|
||||||
tags={tags}
|
|
||||||
links={socialHandles}
|
|
||||||
logo="/logo"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.lowerSection}>
|
|
||||||
{items.length > 1 ? <Tabs defaultActiveKey="0" items={items} /> : aboutTabContent}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const MobileContent = ({
|
|
||||||
name,
|
|
||||||
streamTitle,
|
|
||||||
summary,
|
|
||||||
tags,
|
|
||||||
socialHandles,
|
|
||||||
extraPageContent,
|
|
||||||
messages,
|
|
||||||
currentUser,
|
|
||||||
showChat,
|
|
||||||
actions,
|
|
||||||
setExternalActionToDisplay,
|
|
||||||
setShowNotifyPopup,
|
|
||||||
setShowFollowModal,
|
|
||||||
supportFediverseFeatures,
|
|
||||||
supportsBrowserNotifications,
|
|
||||||
}) => {
|
|
||||||
if (!currentUser) {
|
|
||||||
return <Skeleton loading active paragraph={{ rows: 7 }} />;
|
|
||||||
}
|
|
||||||
const { id, displayName } = currentUser;
|
|
||||||
|
|
||||||
const chatContent = showChat && (
|
|
||||||
<ChatContainer
|
|
||||||
messages={messages}
|
|
||||||
usernameToHighlight={displayName}
|
|
||||||
chatUserId={id}
|
|
||||||
isModerator={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const aboutTabContent = (
|
|
||||||
<>
|
|
||||||
<ContentHeader
|
|
||||||
name={name}
|
|
||||||
title={streamTitle}
|
|
||||||
summary={summary}
|
|
||||||
tags={tags}
|
|
||||||
links={socialHandles}
|
|
||||||
logo="/logo"
|
|
||||||
/>
|
|
||||||
<CustomPageContent content={extraPageContent} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
const followersTabContent = (
|
|
||||||
<FollowerCollection name={name} onFollowButtonClick={() => setShowFollowModal(true)} />
|
|
||||||
);
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
showChat && { label: 'Chat', key: '0', children: chatContent },
|
|
||||||
{ label: 'About', key: '2', children: aboutTabContent },
|
|
||||||
{ label: 'Followers', key: '3', children: followersTabContent },
|
|
||||||
];
|
|
||||||
|
|
||||||
const replacementTabBar = (props, DefaultTabBar) => (
|
|
||||||
<div className={styles.replacementBar}>
|
|
||||||
<DefaultTabBar {...props} className={styles.defaultTabBar} />
|
|
||||||
<ActionButtonMenu
|
|
||||||
className={styles.actionButtonMenu}
|
|
||||||
showFollowItem={supportFediverseFeatures}
|
|
||||||
showNotifyItem={supportsBrowserNotifications}
|
|
||||||
actions={actions}
|
|
||||||
externalActionSelected={setExternalActionToDisplay}
|
|
||||||
notifyItemSelected={() => setShowNotifyPopup(true)}
|
|
||||||
followItemSelected={() => setShowFollowModal(true)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.lowerSectionMobile}>
|
|
||||||
<Tabs
|
|
||||||
className={styles.tabs}
|
|
||||||
defaultActiveKey="0"
|
|
||||||
items={items}
|
|
||||||
renderTabBar={replacementTabBar}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ExternalModal = ({ externalActionToDisplay, setExternalActionToDisplay }) => {
|
const ExternalModal = ({ externalActionToDisplay, setExternalActionToDisplay }) => {
|
||||||
const { title, description, url } = externalActionToDisplay;
|
const { title, description, url } = externalActionToDisplay;
|
||||||
return (
|
return (
|
||||||
@@ -423,6 +278,9 @@ export const Content: FC = () => {
|
|||||||
setShowFollowModal={setShowFollowModal}
|
setShowFollowModal={setShowFollowModal}
|
||||||
supportFediverseFeatures={supportFediverseFeatures}
|
supportFediverseFeatures={supportFediverseFeatures}
|
||||||
supportsBrowserNotifications={supportsBrowserNotifications}
|
supportsBrowserNotifications={supportsBrowserNotifications}
|
||||||
|
notifyItemSelected={() => setShowNotifyModal(true)}
|
||||||
|
followItemSelected={() => setShowFollowModal(true)}
|
||||||
|
externalActionSelected={externalActionSelected}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<DesktopContent
|
<DesktopContent
|
||||||
|
|||||||
76
web/components/ui/Content/DesktopContent.tsx
Normal file
76
web/components/ui/Content/DesktopContent.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React, { ComponentType, FC } from 'react';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
import { TabsProps } from 'antd';
|
||||||
|
import { SocialLink } from '../../../interfaces/social-link.model';
|
||||||
|
import styles from './Content.module.scss';
|
||||||
|
import { CustomPageContent } from '../CustomPageContent/CustomPageContent';
|
||||||
|
import { ContentHeader } from '../../common/ContentHeader/ContentHeader';
|
||||||
|
|
||||||
|
export type DesktopContentProps = {
|
||||||
|
name: string;
|
||||||
|
streamTitle: string;
|
||||||
|
summary: string;
|
||||||
|
tags: string[];
|
||||||
|
socialHandles: SocialLink[];
|
||||||
|
extraPageContent: string;
|
||||||
|
setShowFollowModal: (show: boolean) => void;
|
||||||
|
supportFediverseFeatures: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
// lazy loaded components
|
||||||
|
|
||||||
|
const Tabs: ComponentType<TabsProps> = dynamic(() => import('antd').then(mod => mod.Tabs), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const FollowerCollection = dynamic(
|
||||||
|
() =>
|
||||||
|
import('../followers/FollowerCollection/FollowerCollection').then(
|
||||||
|
mod => mod.FollowerCollection,
|
||||||
|
),
|
||||||
|
{
|
||||||
|
ssr: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const DesktopContent: FC<DesktopContentProps> = ({
|
||||||
|
name,
|
||||||
|
streamTitle,
|
||||||
|
summary,
|
||||||
|
tags,
|
||||||
|
socialHandles,
|
||||||
|
extraPageContent,
|
||||||
|
setShowFollowModal,
|
||||||
|
supportFediverseFeatures,
|
||||||
|
}) => {
|
||||||
|
const aboutTabContent = <CustomPageContent content={extraPageContent} />;
|
||||||
|
const followersTabContent = (
|
||||||
|
<div>
|
||||||
|
<FollowerCollection name={name} onFollowButtonClick={() => setShowFollowModal(true)} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const items = [{ label: 'About', key: '2', children: aboutTabContent }];
|
||||||
|
if (supportFediverseFeatures) {
|
||||||
|
items.push({ label: 'Followers', key: '3', children: followersTabContent });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={styles.lowerHalf} id="skip-to-content">
|
||||||
|
<ContentHeader
|
||||||
|
name={name}
|
||||||
|
title={streamTitle}
|
||||||
|
summary={summary}
|
||||||
|
tags={tags}
|
||||||
|
links={socialHandles}
|
||||||
|
logo="/logo"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.lowerSection}>
|
||||||
|
{items.length > 1 ? <Tabs defaultActiveKey="0" items={items} /> : aboutTabContent}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
136
web/components/ui/Content/MobileContent.tsx
Normal file
136
web/components/ui/Content/MobileContent.tsx
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import React, { ComponentType, FC } from 'react';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
import { Skeleton, TabsProps } from 'antd';
|
||||||
|
import { SocialLink } from '../../../interfaces/social-link.model';
|
||||||
|
import styles from './Content.module.scss';
|
||||||
|
import { CustomPageContent } from '../CustomPageContent/CustomPageContent';
|
||||||
|
import { ContentHeader } from '../../common/ContentHeader/ContentHeader';
|
||||||
|
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
||||||
|
import { CurrentUser } from '../../../interfaces/current-user';
|
||||||
|
import { ActionButtonMenu } from '../../action-buttons/ActionButtonMenu/ActionButtonMenu';
|
||||||
|
import { ExternalAction } from '../../../interfaces/external-action';
|
||||||
|
|
||||||
|
export type MobileContentProps = {
|
||||||
|
name: string;
|
||||||
|
streamTitle: string;
|
||||||
|
summary: string;
|
||||||
|
tags: string[];
|
||||||
|
socialHandles: SocialLink[];
|
||||||
|
extraPageContent: string;
|
||||||
|
notifyItemSelected: () => void;
|
||||||
|
followItemSelected: () => void;
|
||||||
|
setExternalActionToDisplay: (action: ExternalAction) => void;
|
||||||
|
setShowNotifyPopup: (show: boolean) => void;
|
||||||
|
setShowFollowModal: (show: boolean) => void;
|
||||||
|
supportFediverseFeatures: boolean;
|
||||||
|
messages: ChatMessage[];
|
||||||
|
currentUser: CurrentUser;
|
||||||
|
showChat: boolean;
|
||||||
|
actions: ExternalAction[];
|
||||||
|
externalActionSelected: (action: ExternalAction) => void;
|
||||||
|
supportsBrowserNotifications: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
// lazy loaded components
|
||||||
|
|
||||||
|
const Tabs: ComponentType<TabsProps> = dynamic(() => import('antd').then(mod => mod.Tabs), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const FollowerCollection = dynamic(
|
||||||
|
() =>
|
||||||
|
import('../followers/FollowerCollection/FollowerCollection').then(
|
||||||
|
mod => mod.FollowerCollection,
|
||||||
|
),
|
||||||
|
{
|
||||||
|
ssr: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const ChatContainer = dynamic(
|
||||||
|
() => import('../../chat/ChatContainer/ChatContainer').then(mod => mod.ChatContainer),
|
||||||
|
{
|
||||||
|
ssr: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const MobileContent: FC<MobileContentProps> = ({
|
||||||
|
name,
|
||||||
|
streamTitle,
|
||||||
|
summary,
|
||||||
|
tags,
|
||||||
|
socialHandles,
|
||||||
|
extraPageContent,
|
||||||
|
messages,
|
||||||
|
currentUser,
|
||||||
|
showChat,
|
||||||
|
actions,
|
||||||
|
setExternalActionToDisplay,
|
||||||
|
setShowNotifyPopup,
|
||||||
|
setShowFollowModal,
|
||||||
|
supportFediverseFeatures,
|
||||||
|
supportsBrowserNotifications,
|
||||||
|
}) => {
|
||||||
|
if (!currentUser) {
|
||||||
|
return <Skeleton loading active paragraph={{ rows: 7 }} />;
|
||||||
|
}
|
||||||
|
const { id, displayName } = currentUser;
|
||||||
|
|
||||||
|
const chatContent = showChat && (
|
||||||
|
<ChatContainer
|
||||||
|
messages={messages}
|
||||||
|
usernameToHighlight={displayName}
|
||||||
|
chatUserId={id}
|
||||||
|
isModerator={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const aboutTabContent = (
|
||||||
|
<>
|
||||||
|
<ContentHeader
|
||||||
|
name={name}
|
||||||
|
title={streamTitle}
|
||||||
|
summary={summary}
|
||||||
|
tags={tags}
|
||||||
|
links={socialHandles}
|
||||||
|
logo="/logo"
|
||||||
|
/>
|
||||||
|
<CustomPageContent content={extraPageContent} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
const followersTabContent = (
|
||||||
|
<FollowerCollection name={name} onFollowButtonClick={() => setShowFollowModal(true)} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
showChat && { label: 'Chat', key: '0', children: chatContent },
|
||||||
|
{ label: 'About', key: '2', children: aboutTabContent },
|
||||||
|
{ label: 'Followers', key: '3', children: followersTabContent },
|
||||||
|
];
|
||||||
|
|
||||||
|
const replacementTabBar = (props, DefaultTabBar) => (
|
||||||
|
<div className={styles.replacementBar}>
|
||||||
|
<DefaultTabBar {...props} className={styles.defaultTabBar} />
|
||||||
|
<ActionButtonMenu
|
||||||
|
className={styles.actionButtonMenu}
|
||||||
|
showFollowItem={supportFediverseFeatures}
|
||||||
|
showNotifyItem={supportsBrowserNotifications}
|
||||||
|
actions={actions}
|
||||||
|
externalActionSelected={setExternalActionToDisplay}
|
||||||
|
notifyItemSelected={() => setShowNotifyPopup(true)}
|
||||||
|
followItemSelected={() => setShowFollowModal(true)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.lowerSectionMobile}>
|
||||||
|
<Tabs
|
||||||
|
className={styles.tabs}
|
||||||
|
defaultActiveKey="0"
|
||||||
|
items={items}
|
||||||
|
renderTabBar={replacementTabBar}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user