Refactor use of antd tab component. Closes #2098
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
return (
|
const indieAuthTabTitle = (
|
||||||
<div>
|
|
||||||
<Tabs
|
|
||||||
defaultActiveKey="1"
|
|
||||||
type="card"
|
|
||||||
size="small"
|
|
||||||
renderTabBar={federationEnabled ? null : () => null}
|
|
||||||
>
|
|
||||||
<TabPane
|
|
||||||
tab={
|
|
||||||
<span className={styles.tabContent}>
|
<span className={styles.tabContent}>
|
||||||
<img className={styles.icon} src={IndieAuthIcon.src} alt="IndieAuth" />
|
<img className={styles.icon} src={IndieAuthIcon.src} alt="IndieAuth" />
|
||||||
IndieAuth
|
IndieAuth
|
||||||
</span>
|
</span>
|
||||||
}
|
);
|
||||||
key="1"
|
const indieAuthTab = (
|
||||||
>
|
|
||||||
<IndieAuthModal
|
<IndieAuthModal
|
||||||
authenticated={authenticated}
|
authenticated={authenticated}
|
||||||
displayName={displayName}
|
displayName={displayName}
|
||||||
accessToken={accessToken}
|
accessToken={accessToken}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
);
|
||||||
<TabPane
|
|
||||||
tab={
|
const fediAuthTabTitle = (
|
||||||
<span className={styles.tabContent}>
|
<span className={styles.tabContent}>
|
||||||
<img className={styles.icon} src={FediverseIcon.src} alt="Fediverse auth" />
|
<img className={styles.icon} src={FediverseIcon.src} alt="Fediverse auth" />
|
||||||
FediAuth
|
FediAuth
|
||||||
</span>
|
</span>
|
||||||
}
|
);
|
||||||
key="2"
|
const fediAuthTab = (
|
||||||
>
|
|
||||||
<FediAuthModal
|
<FediAuthModal
|
||||||
authenticated={authenticated}
|
authenticated={authenticated}
|
||||||
displayName={displayName}
|
displayName={displayName}
|
||||||
accessToken={accessToken}
|
accessToken={accessToken}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
);
|
||||||
</Tabs>
|
|
||||||
|
const items = [
|
||||||
|
{ label: indieAuthTabTitle, key: '1', children: indieAuthTab },
|
||||||
|
{ label: fediAuthTabTitle, key: '2', children: fediAuthTab },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Tabs
|
||||||
|
defaultActiveKey="1"
|
||||||
|
items={items}
|
||||||
|
type="card"
|
||||||
|
size="small"
|
||||||
|
renderTabBar={federationEnabled ? null : () => null}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,7 +58,16 @@ 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} />;
|
||||||
|
const followersTabContent = <FollowerCollection name={name} />;
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{ label: 'About', key: '2', children: aboutTabContent },
|
||||||
|
{ label: 'Followers', key: '3', children: followersTabContent },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.lowerHalf}>
|
<div className={styles.lowerHalf}>
|
||||||
<ContentHeader
|
<ContentHeader
|
||||||
@@ -73,17 +81,11 @@ const DesktopContent = ({ name, streamTitle, summary, tags, socialHandles, extra
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.lowerSection}>
|
<div className={styles.lowerSection}>
|
||||||
<Tabs defaultActiveKey="0">
|
<Tabs defaultActiveKey="0" items={items} />
|
||||||
<TabPane tab="About" key="2">
|
|
||||||
<CustomPageContent content={extraPageContent} />
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tab="Followers" key="3">
|
|
||||||
<FollowerCollection name={name} />
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const MobileContent = ({
|
const MobileContent = ({
|
||||||
name,
|
name,
|
||||||
@@ -96,11 +98,8 @@ const MobileContent = ({
|
|||||||
chatDisplayName,
|
chatDisplayName,
|
||||||
chatUserId,
|
chatUserId,
|
||||||
showChat,
|
showChat,
|
||||||
}) => (
|
}) => {
|
||||||
<div className={classNames(styles.lowerSectionMobile)}>
|
const chatContent = showChat && (
|
||||||
<Tabs defaultActiveKey="0">
|
|
||||||
{showChat && (
|
|
||||||
<TabPane tab="Chat" key="1">
|
|
||||||
<ChatContainer
|
<ChatContainer
|
||||||
messages={messages}
|
messages={messages}
|
||||||
usernameToHighlight={chatDisplayName}
|
usernameToHighlight={chatDisplayName}
|
||||||
@@ -108,9 +107,10 @@ const MobileContent = ({
|
|||||||
isModerator={false}
|
isModerator={false}
|
||||||
height="40vh"
|
height="40vh"
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
);
|
||||||
)}
|
|
||||||
<TabPane tab="About" key="2">
|
const aboutTabContent = (
|
||||||
|
<>
|
||||||
<ContentHeader
|
<ContentHeader
|
||||||
name={name}
|
name={name}
|
||||||
title={streamTitle}
|
title={streamTitle}
|
||||||
@@ -120,13 +120,22 @@ const MobileContent = ({
|
|||||||
logo="/logo"
|
logo="/logo"
|
||||||
/>
|
/>
|
||||||
<CustomPageContent content={extraPageContent} />
|
<CustomPageContent content={extraPageContent} />
|
||||||
</TabPane>
|
</>
|
||||||
<TabPane tab="Followers" key="3">
|
);
|
||||||
<FollowerCollection name={name} />
|
const followersTabContent = <FollowerCollection name={name} />;
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
const items = [
|
||||||
|
{ label: 'Chat', key: '1', children: chatContent },
|
||||||
|
{ label: 'About', key: '2', children: aboutTabContent },
|
||||||
|
{ label: 'Followers', key: '3', children: followersTabContent },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames(styles.lowerSectionMobile)}>
|
||||||
|
<Tabs defaultActiveKey="0" items={items} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const Content: FC = () => {
|
export const Content: FC = () => {
|
||||||
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
|
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
|
||||||
|
|||||||
@@ -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} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
const blockedTabTitle = (
|
||||||
<div className="followers-section">
|
<span>Blocked {followersBlocked.length > 0 && `(${followersBlocked.length})`}</span>
|
||||||
<Tabs defaultActiveKey="1">
|
);
|
||||||
<TabPane
|
const blockedTab = (
|
||||||
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>
|
<p>
|
||||||
The following people were either rejected or blocked by you. You can approve them as a
|
The following people were either rejected or blocked by you. You can approve them as a
|
||||||
follower.
|
follower.
|
||||||
</p>
|
</p>
|
||||||
<p>{makeTable(followersBlocked, blockedColumns)}</p>
|
<p>{makeTable(followersBlocked, blockedColumns)}</p>
|
||||||
</TabPane>
|
</>
|
||||||
</Tabs>
|
);
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{ label: followersTabTitle, key: '1', children: followersTab },
|
||||||
|
isPrivate && { label: pendingRequestsTabTitle, key: '2', children: pendingRequestsTab },
|
||||||
|
{ label: blockedTabTitle, key: '3', children: blockedTab },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="followers-section">
|
||||||
|
<Tabs defaultActiveKey="1" items={items} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user