mirror of
				https://github.com/owncast/owncast.git
				synced 2025-10-31 18:18:06 +08:00 
			
		
		
		
	![renovate[bot]](/assets/img/avatar_default.png) 44eafe69ac
			
		
	
	44eafe69ac
	
	
	
		
			
			* fix(deps): update dependency date-fns to v3 * fix(deps): update usage of date-fns format --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Gabe Kangas <gabek@real-ity.com>
		
			
				
	
	
		
			151 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // This displays a clickable user name (or whatever children element you provide), and displays a simple tooltip of created time. OnClick a modal with more information about the user is displayed.
 | |
| 
 | |
| import { useState, ReactNode, FC } from 'react';
 | |
| import { Divider, Modal, Typography, Row, Col, Space, Tooltip } from 'antd';
 | |
| import { format, formatDistanceToNow } from 'date-fns';
 | |
| import { uniq } from 'lodash';
 | |
| 
 | |
| import { BanUserButton } from './BanUserButton';
 | |
| import { ModeratorUserButton } from './ModeratorUserButton';
 | |
| 
 | |
| import { User, UserConnectionInfo } from '../../types/chat';
 | |
| import { formatDisplayDate } from './UserTable';
 | |
| import { formatUAstring } from '../../utils/format';
 | |
| 
 | |
| export type UserPopoverProps = {
 | |
|   user: User;
 | |
|   connectionInfo?: UserConnectionInfo | null;
 | |
|   children: ReactNode;
 | |
| };
 | |
| 
 | |
| export const UserPopover: FC<UserPopoverProps> = ({ user, connectionInfo, children }) => {
 | |
|   const [isModalOpen, setIsModalOpen] = useState(false);
 | |
|   const handleShowModal = () => {
 | |
|     setIsModalOpen(true);
 | |
|   };
 | |
|   const handleCloseModal = () => {
 | |
|     setIsModalOpen(false);
 | |
|   };
 | |
| 
 | |
|   const { displayName, createdAt, previousNames, nameChangedAt, disabledAt } = user;
 | |
|   const { connectedAt, messageCount, userAgent } = connectionInfo || {};
 | |
| 
 | |
|   let lastNameChangeDate = null;
 | |
|   const nameList = previousNames && [...previousNames];
 | |
| 
 | |
|   if (previousNames && previousNames.length > 1 && nameChangedAt) {
 | |
|     lastNameChangeDate = new Date(nameChangedAt);
 | |
|     // reverse prev names for display purposes
 | |
|     nameList.reverse();
 | |
|   }
 | |
| 
 | |
|   const dateObject = new Date(createdAt);
 | |
|   const createdAtDate = format(dateObject, 'PP pp');
 | |
| 
 | |
|   const lastNameChangeDuration = lastNameChangeDate
 | |
|     ? formatDistanceToNow(lastNameChangeDate)
 | |
|     : null;
 | |
| 
 | |
|   return (
 | |
|     <>
 | |
|       <Tooltip
 | |
|         title={
 | |
|           <>
 | |
|             Created at: {createdAtDate}.
 | |
|             <br /> Click for more info.
 | |
|           </>
 | |
|         }
 | |
|         placement="bottomLeft"
 | |
|       >
 | |
|         <button
 | |
|           type="button"
 | |
|           aria-label="Display more details about this user"
 | |
|           className="user-item-container"
 | |
|           onClick={handleShowModal}
 | |
|         >
 | |
|           {children}
 | |
|         </button>
 | |
|       </Tooltip>
 | |
| 
 | |
|       <Modal
 | |
|         destroyOnClose
 | |
|         width={600}
 | |
|         cancelText="Close"
 | |
|         okButtonProps={{ style: { display: 'none' } }}
 | |
|         title={`User details: ${displayName}`}
 | |
|         open={isModalOpen}
 | |
|         onOk={handleCloseModal}
 | |
|         onCancel={handleCloseModal}
 | |
|       >
 | |
|         <div className="user-details">
 | |
|           <Typography.Title level={4}>{displayName}</Typography.Title>
 | |
|           <p className="created-at">User created at {createdAtDate}.</p>
 | |
|           <Row gutter={16}>
 | |
|             {connectionInfo && (
 | |
|               <Col md={lastNameChangeDate ? 12 : 24}>
 | |
|                 <Typography.Title level={5}>
 | |
|                   This user is currently connected to Chat.
 | |
|                 </Typography.Title>
 | |
|                 <ul className="connection-info">
 | |
|                   <li>
 | |
|                     <strong>Active for:</strong> {formatDistanceToNow(new Date(connectedAt))}
 | |
|                   </li>
 | |
|                   <li>
 | |
|                     <strong>Messages sent:</strong> {messageCount}
 | |
|                   </li>
 | |
|                   <li>
 | |
|                     <strong>User Agent:</strong>
 | |
|                     <br />
 | |
|                     {formatUAstring(userAgent)}
 | |
|                   </li>
 | |
|                 </ul>
 | |
|               </Col>
 | |
|             )}
 | |
|             {lastNameChangeDate && (
 | |
|               <Col md={connectionInfo ? 12 : 24}>
 | |
|                 <Typography.Title level={5}>This user is also seen as:</Typography.Title>
 | |
|                 <ul className="previous-names-list">
 | |
|                   {uniq(nameList).map((name, index) => (
 | |
|                     <li className={index === 0 ? 'latest' : ''}>
 | |
|                       <span className="user-name-item">{name}</span>
 | |
|                       {index === 0 ? ` (Changed ${lastNameChangeDuration} ago)` : ''}
 | |
|                     </li>
 | |
|                   ))}
 | |
|                 </ul>
 | |
|               </Col>
 | |
|             )}
 | |
|           </Row>
 | |
|           <Divider />
 | |
|           <Space direction="horizontal">
 | |
|             {disabledAt ? (
 | |
|               <>
 | |
|                 This user was banned on <code>{formatDisplayDate(disabledAt)}</code>.
 | |
|                 <br />
 | |
|                 <br />
 | |
|                 <BanUserButton
 | |
|                   label="Unban this user"
 | |
|                   user={user}
 | |
|                   isEnabled={false}
 | |
|                   onClick={handleCloseModal}
 | |
|                 />
 | |
|               </>
 | |
|             ) : (
 | |
|               <BanUserButton
 | |
|                 label="Ban this user"
 | |
|                 user={user}
 | |
|                 isEnabled
 | |
|                 onClick={handleCloseModal}
 | |
|               />
 | |
|             )}
 | |
|             <ModeratorUserButton user={user} onClick={handleCloseModal} />
 | |
|           </Space>
 | |
|         </div>
 | |
|       </Modal>
 | |
|     </>
 | |
|   );
 | |
| };
 | |
| 
 | |
| UserPopover.defaultProps = {
 | |
|   connectionInfo: null,
 | |
| };
 |