users.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import React, { useState, useEffect, useContext, ReactElement } from 'react';
  2. import { Tabs } from 'antd';
  3. import { ServerStatusContext } from '../../../utils/server-status-context';
  4. import {
  5. CONNECTED_CLIENTS,
  6. fetchData,
  7. DISABLED_USERS,
  8. MODERATORS,
  9. BANNED_IPS,
  10. } from '../../../utils/apis';
  11. import { UserTable } from '../../../components/admin/UserTable';
  12. import { ClientTable } from '../../../components/admin/ClientTable';
  13. import { BannedIPsTable } from '../../../components/admin/BannedIPsTable';
  14. import { AdminLayout } from '../../../components/layouts/AdminLayout';
  15. export const FETCH_INTERVAL = 10 * 1000; // 10 sec
  16. export default function ChatUsers() {
  17. const context = useContext(ServerStatusContext);
  18. const { online } = context || {};
  19. const [disabledUsers, setDisabledUsers] = useState([]);
  20. const [ipBans, setIPBans] = useState([]);
  21. const [clients, setClients] = useState([]);
  22. const [moderators, setModerators] = useState([]);
  23. const getInfo = async () => {
  24. try {
  25. const result = await fetchData(DISABLED_USERS);
  26. setDisabledUsers(result);
  27. } catch (error) {
  28. console.log('==== error', error);
  29. }
  30. try {
  31. const result = await fetchData(CONNECTED_CLIENTS);
  32. setClients(result);
  33. } catch (error) {
  34. console.log('==== error', error);
  35. }
  36. try {
  37. const result = await fetchData(MODERATORS);
  38. setModerators(result);
  39. } catch (error) {
  40. console.error('error fetching moderators', error);
  41. }
  42. try {
  43. const result = await fetchData(BANNED_IPS);
  44. setIPBans(result);
  45. } catch (error) {
  46. console.error('error fetching banned ips', error);
  47. }
  48. };
  49. useEffect(() => {
  50. let getStatusIntervalId = null;
  51. getInfo();
  52. getStatusIntervalId = setInterval(getInfo, FETCH_INTERVAL);
  53. // returned function will be called on component unmount
  54. return () => {
  55. clearInterval(getStatusIntervalId);
  56. };
  57. }, [online]);
  58. const connectedUsers = online ? (
  59. <>
  60. <ClientTable data={clients} />
  61. <p className="description">
  62. Visit the{' '}
  63. <a
  64. href="https://owncast.online/docs/viewers/?source=admin"
  65. target="_blank"
  66. rel="noopener noreferrer"
  67. >
  68. documentation
  69. </a>{' '}
  70. to configure additional details about your viewers.
  71. </p>
  72. </>
  73. ) : (
  74. <p className="description">
  75. When a stream is active and chat is enabled, connected chat clients will be displayed here.
  76. </p>
  77. );
  78. const connectedUserTabTitle = (
  79. <span>Connected {online ? `(${clients.length})` : '(offline)'}</span>
  80. );
  81. const bannedUsersTabTitle = <span>Banned Users ({disabledUsers.length})</span>;
  82. const bannedUsersTable = <UserTable data={disabledUsers} />;
  83. const bannedIPTabTitle = <span>IP Bans ({ipBans.length})</span>;
  84. const bannedIpTable = <BannedIPsTable data={ipBans} />;
  85. const moderatorUsersTabTitle = <span>Moderators ({moderators.length})</span>;
  86. const moderatorTable = <UserTable data={moderators} />;
  87. const items = [
  88. { label: connectedUserTabTitle, key: '1', children: connectedUsers },
  89. { label: bannedUsersTabTitle, key: '2', children: bannedUsersTable },
  90. { label: bannedIPTabTitle, key: '3', children: bannedIpTable },
  91. { label: moderatorUsersTabTitle, key: '4', children: moderatorTable },
  92. ];
  93. return <Tabs defaultActiveKey="1" items={items} />;
  94. }
  95. ChatUsers.getLayout = function getLayout(page: ReactElement) {
  96. return <AdminLayout page={page} />;
  97. };