Browse Source

Refactor use of antd tab component. Closes #2098

pull/2192/head
Gabe Kangas 3 years ago
parent
commit
a526decef4
No known key found for this signature in database
GPG Key ID: 9A56337728BC81EA
  1. 69
      web/components/modals/AuthModal/AuthModal.tsx
  2. 121
      web/components/ui/Content/Content.tsx
  3. 37
      web/pages/admin/chat/users.tsx
  4. 63
      web/pages/admin/federation/followers.tsx

69
web/components/modals/AuthModal/AuthModal.tsx

@ -14,8 +14,6 @@ import {
accessTokenAtom, accessTokenAtom,
} from '../../stores/ClientConfigStore'; } from '../../stores/ClientConfigStore';
const { TabPane } = Tabs;
export const AuthModal: FC = () => { export const AuthModal: FC = () => {
const currentUser = useRecoilValue(currentUserAtom); const currentUser = useRecoilValue(currentUserAtom);
if (!currentUser) { if (!currentUser) {
@ -27,45 +25,48 @@ export const AuthModal: FC = () => {
const federationEnabled = true; const federationEnabled = true;
const { displayName } = currentUser; const { displayName } = currentUser;
const indieAuthTabTitle = (
<span className={styles.tabContent}>
<img className={styles.icon} src={IndieAuthIcon.src} alt="IndieAuth" />
IndieAuth
</span>
);
const indieAuthTab = (
<IndieAuthModal
authenticated={authenticated}
displayName={displayName}
accessToken={accessToken}
/>
);
const fediAuthTabTitle = (
<span className={styles.tabContent}>
<img className={styles.icon} src={FediverseIcon.src} alt="Fediverse auth" />
FediAuth
</span>
);
const fediAuthTab = (
<FediAuthModal
authenticated={authenticated}
displayName={displayName}
accessToken={accessToken}
/>
);
const items = [
{ label: indieAuthTabTitle, key: '1', children: indieAuthTab },
{ label: fediAuthTabTitle, key: '2', children: fediAuthTab },
];
return ( return (
<div> <div>
<Tabs <Tabs
defaultActiveKey="1" defaultActiveKey="1"
items={items}
type="card" type="card"
size="small" size="small"
renderTabBar={federationEnabled ? null : () => null} renderTabBar={federationEnabled ? null : () => null}
> />
<TabPane
tab={
<span className={styles.tabContent}>
<img className={styles.icon} src={IndieAuthIcon.src} alt="IndieAuth" />
IndieAuth
</span>
}
key="1"
>
<IndieAuthModal
authenticated={authenticated}
displayName={displayName}
accessToken={accessToken}
/>
</TabPane>
<TabPane
tab={
<span className={styles.tabContent}>
<img className={styles.icon} src={FediverseIcon.src} alt="Fediverse auth" />
FediAuth
</span>
}
key="2"
>
<FediAuthModal
authenticated={authenticated}
displayName={displayName}
accessToken={accessToken}
/>
</TabPane>
</Tabs>
</div> </div>
); );
}; };

121
web/components/ui/Content/Content.tsx

@ -34,7 +34,6 @@ 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';
const { TabPane } = Tabs;
const { Content: AntContent } = Layout; const { Content: AntContent } = Layout;
// Lazy loaded components // Lazy loaded components
@ -59,31 +58,34 @@ const ChatContainer = dynamic(() =>
import('../../chat/ChatContainer/ChatContainer').then(mod => mod.ChatContainer), import('../../chat/ChatContainer/ChatContainer').then(mod => mod.ChatContainer),
); );
const DesktopContent = ({ name, streamTitle, summary, tags, socialHandles, extraPageContent }) => ( const DesktopContent = ({ name, streamTitle, summary, tags, socialHandles, extraPageContent }) => {
<> const aboutTabContent = <CustomPageContent content={extraPageContent} />;
<div className={styles.lowerHalf}> const followersTabContent = <FollowerCollection name={name} />;
<ContentHeader
name={name}
title={streamTitle}
summary={summary}
tags={tags}
links={socialHandles}
logo="/logo"
/>
</div>
<div className={styles.lowerSection}> const items = [
<Tabs defaultActiveKey="0"> { label: 'About', key: '2', children: aboutTabContent },
<TabPane tab="About" key="2"> { label: 'Followers', key: '3', children: followersTabContent },
<CustomPageContent content={extraPageContent} /> ];
</TabPane>
<TabPane tab="Followers" key="3"> return (
<FollowerCollection name={name} /> <>
</TabPane> <div className={styles.lowerHalf}>
</Tabs> <ContentHeader
</div> name={name}
</> title={streamTitle}
); summary={summary}
tags={tags}
links={socialHandles}
logo="/logo"
/>
</div>
<div className={styles.lowerSection}>
<Tabs defaultActiveKey="0" items={items} />
</div>
</>
);
};
const MobileContent = ({ const MobileContent = ({
name, name,
@ -96,37 +98,44 @@ const MobileContent = ({
chatDisplayName, chatDisplayName,
chatUserId, chatUserId,
showChat, showChat,
}) => ( }) => {
<div className={classNames(styles.lowerSectionMobile)}> const chatContent = showChat && (
<Tabs defaultActiveKey="0"> <ChatContainer
{showChat && ( messages={messages}
<TabPane tab="Chat" key="1"> usernameToHighlight={chatDisplayName}
<ChatContainer chatUserId={chatUserId}
messages={messages} isModerator={false}
usernameToHighlight={chatDisplayName} height="40vh"
chatUserId={chatUserId} />
isModerator={false} );
height="40vh"
/> const aboutTabContent = (
</TabPane> <>
)} <ContentHeader
<TabPane tab="About" key="2"> name={name}
<ContentHeader title={streamTitle}
name={name} summary={summary}
title={streamTitle} tags={tags}
summary={summary} links={socialHandles}
tags={tags} logo="/logo"
links={socialHandles} />
logo="/logo" <CustomPageContent content={extraPageContent} />
/> </>
<CustomPageContent content={extraPageContent} /> );
</TabPane> const followersTabContent = <FollowerCollection name={name} />;
<TabPane tab="Followers" key="3">
<FollowerCollection name={name} /> const items = [
</TabPane> { label: 'Chat', key: '1', children: chatContent },
</Tabs> { label: 'About', key: '2', children: aboutTabContent },
</div> { label: 'Followers', key: '3', children: followersTabContent },
); ];
return (
<div className={classNames(styles.lowerSectionMobile)}>
<Tabs defaultActiveKey="0" items={items} />
</div>
);
};
export const Content: FC = () => { export const Content: FC = () => {
const appState = useRecoilValue<AppStateOptions>(appStateAtom); const appState = useRecoilValue<AppStateOptions>(appStateAtom);

37
web/pages/admin/chat/users.tsx

@ -12,8 +12,6 @@ import { UserTable } from '../../../components/UserTable';
import { ClientTable } from '../../../components/ClientTable'; import { ClientTable } from '../../../components/ClientTable';
import { BannedIPsTable } from '../../../components/BannedIPsTable'; import { BannedIPsTable } from '../../../components/BannedIPsTable';
const { TabPane } = Tabs;
export const FETCH_INTERVAL = 10 * 1000; // 10 sec export const FETCH_INTERVAL = 10 * 1000; // 10 sec
export default function ChatUsers() { export default function ChatUsers() {
@ -88,20 +86,25 @@ export default function ChatUsers() {
</p> </p>
); );
return ( const connectedUserTabTitle = (
<Tabs defaultActiveKey="1"> <span>Connected {online ? `(${clients.length})` : '(offline)'}</span>
<TabPane tab={<span>Connected {online ? `(${clients.length})` : '(offline)'}</span>} key="1">
{connectedUsers}
</TabPane>
<TabPane tab={<span>Banned Users ({disabledUsers.length})</span>} key="2">
<UserTable data={disabledUsers} />
</TabPane>
<TabPane tab={<span>IP Bans ({ipBans.length})</span>} key="3">
<BannedIPsTable data={ipBans} />
</TabPane>
<TabPane tab={<span>Moderators ({moderators.length})</span>} key="4">
<UserTable data={moderators} />
</TabPane>
</Tabs>
); );
const bannedUsersTabTitle = <span>Banned Users ({disabledUsers.length})</span>;
const bannedUsersTable = <UserTable data={disabledUsers} />;
const bannedIPTabTitle = <span>IP Bans ({ipBans.length})</span>;
const bannedIpTable = <BannedIPsTable data={ipBans} />;
const moderatorUsersTabTitle = <span>Moderators ({moderators.length})</span>;
const moderatorTable = <UserTable data={moderators} />;
const items = [
{ label: connectedUserTabTitle, key: '1', children: connectedUsers },
{ label: bannedUsersTabTitle, key: '2', children: bannedUsersTable },
{ label: bannedIPTabTitle, key: '3', children: bannedIpTable },
{ label: moderatorUsersTabTitle, key: '4', children: moderatorTable },
];
return <Tabs defaultActiveKey="1" items={items} />;
} }

63
web/pages/admin/federation/followers.tsx

@ -13,7 +13,6 @@ import {
} from '../../../utils/apis'; } from '../../../utils/apis';
import { isEmptyObject } from '../../../utils/format'; import { isEmptyObject } from '../../../utils/format';
const { TabPane } = Tabs;
export interface Follower { export interface Follower {
link: string; link: string;
username: string; username: string;
@ -293,11 +292,21 @@ export default function FediverseFollowers() {
}, },
); );
const pendingRequestsTab = isPrivate && ( const followersTabTitle = (
<TabPane <span>Followers {followers.length > 0 && `(${followers.length})`}</span>
tab={<span>Requests {followersPending.length > 0 && `(${followersPending.length})`}</span>} );
key="2" const followersTab = (
> <>
<p>The following accounts get notified when you go live or send a post.</p>
{makeTable(followers, followersColumns)}{' '}
</>
);
const pendingRequestsTabTitle = (
<span>Requests {followersPending.length > 0 && `(${followersPending.length})`}</span>
);
const pendingRequestsTab = (
<>
<p> <p>
The following people are requesting to follow your Owncast server on the{' '} The following people are requesting to follow your Owncast server on the{' '}
<a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank" rel="noopener noreferrer"> <a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank" rel="noopener noreferrer">
@ -306,31 +315,31 @@ export default function FediverseFollowers() {
and be alerted to when you go live. Each must be approved. and be alerted to when you go live. Each must be approved.
</p> </p>
{makeTable(followersPending, pendingColumns)} {makeTable(followersPending, pendingColumns)}
</TabPane> </>
);
const blockedTabTitle = (
<span>Blocked {followersBlocked.length > 0 && `(${followersBlocked.length})`}</span>
); );
const blockedTab = (
<>
<p>
The following people were either rejected or blocked by you. You can approve them as a
follower.
</p>
<p>{makeTable(followersBlocked, blockedColumns)}</p>
</>
);
const items = [
{ label: followersTabTitle, key: '1', children: followersTab },
isPrivate && { label: pendingRequestsTabTitle, key: '2', children: pendingRequestsTab },
{ label: blockedTabTitle, key: '3', children: blockedTab },
];
return ( return (
<div className="followers-section"> <div className="followers-section">
<Tabs defaultActiveKey="1"> <Tabs defaultActiveKey="1" items={items} />
<TabPane
tab={<span>Followers {followers.length > 0 && `(${followers.length})`}</span>}
key="1"
>
<p>The following accounts get notified when you go live or send a post.</p>
{makeTable(followers, followersColumns)}{' '}
</TabPane>
{pendingRequestsTab}
<TabPane
tab={<span>Blocked {followersBlocked.length > 0 && `(${followersBlocked.length})`}</span>}
key="3"
>
<p>
The following people were either rejected or blocked by you. You can approve them as a
follower.
</p>
<p>{makeTable(followersBlocked, blockedColumns)}</p>
</TabPane>
</Tabs>
</div> </div>
); );
} }

Loading…
Cancel
Save