You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.0 KiB
106 lines
3.0 KiB
import React, { CSSProperties, FC, useState } from 'react'; |
|
import { useRecoilValue } from 'recoil'; |
|
import { Input, Button, Select, Form } from 'antd'; |
|
import { MessageType } from '../../../interfaces/socket-events'; |
|
import WebsocketService from '../../../services/websocket-service'; |
|
import { websocketServiceAtom, currentUserAtom } from '../../stores/ClientConfigStore'; |
|
import styles from './NameChangeModal.module.scss'; |
|
|
|
const { Option } = Select; |
|
|
|
export type UserColorProps = { |
|
color: number; |
|
}; |
|
|
|
const UserColor: FC<UserColorProps> = ({ color }) => { |
|
const style: CSSProperties = { |
|
textAlign: 'center', |
|
backgroundColor: `var(--theme-color-users-${color})`, |
|
width: '100%', |
|
height: '100%', |
|
}; |
|
return <div style={style} />; |
|
}; |
|
|
|
export const NameChangeModal: FC = () => { |
|
const currentUser = useRecoilValue(currentUserAtom); |
|
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom); |
|
const [newName, setNewName] = useState<string>(currentUser?.displayName); |
|
|
|
if (!currentUser) { |
|
return null; |
|
} |
|
|
|
const { displayName, displayColor } = currentUser; |
|
|
|
const saveEnabled = () => |
|
newName !== displayName && newName !== '' && websocketService?.isConnected(); |
|
|
|
const handleNameChange = () => { |
|
if (!saveEnabled()) return; |
|
|
|
const nameChange = { |
|
type: MessageType.NAME_CHANGE, |
|
newName, |
|
}; |
|
websocketService.send(nameChange); |
|
}; |
|
|
|
const handleColorChange = (color: string) => { |
|
const colorChange = { |
|
type: MessageType.COLOR_CHANGE, |
|
newColor: Number(color), |
|
}; |
|
websocketService.send(colorChange); |
|
}; |
|
|
|
const maxColor = 8; // 0...n |
|
const colorOptions = [...Array(maxColor)].map((e, i) => i); |
|
|
|
const saveButton = ( |
|
<Button |
|
type="primary" |
|
id="name-change-submit" |
|
onClick={handleNameChange} |
|
disabled={!saveEnabled()} |
|
> |
|
Change name |
|
</Button> |
|
); |
|
|
|
return ( |
|
<div> |
|
Your chat display name is what people see when you send chat messages. |
|
<Form onSubmitCapture={handleNameChange} className={styles.form}> |
|
<Input.Search |
|
enterButton={saveButton} |
|
id="name-change-field" |
|
value={newName} |
|
onChange={e => setNewName(e.target.value)} |
|
placeholder="Your chat display name" |
|
aria-label="Your chat display name" |
|
maxLength={30} |
|
showCount |
|
defaultValue={displayName} |
|
className={styles.inputGroup} |
|
/> |
|
</Form> |
|
<Form.Item label="Your Color" className={styles.colorChange}> |
|
<Select |
|
style={{ width: 120 }} |
|
onChange={handleColorChange} |
|
defaultValue={displayColor.toString()} |
|
className={styles.colorDropdown} |
|
> |
|
{colorOptions.map(e => ( |
|
<Option key={e.toString()} title={e}> |
|
<UserColor color={e} aria-label={e.toString()} /> |
|
</Option> |
|
))} |
|
</Select> |
|
</Form.Item> |
|
You can also authenticate an IndieAuth or Fediverse account via the "Authenticate" |
|
menu. |
|
</div> |
|
); |
|
};
|
|
|