Name change: better unicode handling (#3164)
* Name change: better unicode handling Client-side: * Changes the NameChangeModal to show text "Over limit" when a proposed display name is too long. * Allows names to go over limit to prevent splitting graphemes on input. Server-side: * Changes the MakeSafeStringOfLength to count number of unicode code points instead of string bytes. * name modal: check that newName is defined before iterating
This commit is contained in:
parent
dfa3a2a273
commit
3f65099910
@ -18,10 +18,14 @@ func MakeSafeStringOfLength(s string, length int) string {
|
|||||||
newString := s
|
newString := s
|
||||||
newString = StripHTML(newString)
|
newString = StripHTML(newString)
|
||||||
|
|
||||||
if len(newString) > length {
|
// Convert utf-8 string into Unicode code points.
|
||||||
newString = newString[:length]
|
codePoints := []rune(newString)
|
||||||
|
|
||||||
|
if len(codePoints) > length {
|
||||||
|
codePoints = codePoints[:length]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newString = string(codePoints)
|
||||||
newString = strings.ReplaceAll(newString, "\r", "")
|
newString = strings.ReplaceAll(newString, "\r", "")
|
||||||
newString = strings.TrimSpace(newString)
|
newString = strings.TrimSpace(newString)
|
||||||
|
|
||||||
|
@ -31,14 +31,23 @@ export const NameChangeModal: FC<NameChangeModalProps> = ({ closeModal }) => {
|
|||||||
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
||||||
const [newName, setNewName] = useState<string>(currentUser?.displayName);
|
const [newName, setNewName] = useState<string>(currentUser?.displayName);
|
||||||
|
|
||||||
|
const characterLimit = 30;
|
||||||
|
|
||||||
if (!currentUser) {
|
if (!currentUser) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { displayName, displayColor } = currentUser;
|
const { displayName, displayColor } = currentUser;
|
||||||
|
|
||||||
const saveEnabled = () =>
|
const saveEnabled = () => {
|
||||||
newName !== displayName && newName !== '' && websocketService?.isConnected();
|
const count = newName !== undefined ? Array.from(newName).length : 0;
|
||||||
|
return (
|
||||||
|
newName !== displayName &&
|
||||||
|
count > 0 &&
|
||||||
|
count <= characterLimit &&
|
||||||
|
websocketService?.isConnected()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleNameChange = () => {
|
const handleNameChange = () => {
|
||||||
if (!saveEnabled()) return;
|
if (!saveEnabled()) return;
|
||||||
@ -59,6 +68,8 @@ export const NameChangeModal: FC<NameChangeModalProps> = ({ closeModal }) => {
|
|||||||
websocketService.send(colorChange);
|
websocketService.send(colorChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showCount = info => (info.count > characterLimit ? 'Over limit' : '');
|
||||||
|
|
||||||
const maxColor = 8; // 0...n
|
const maxColor = 8; // 0...n
|
||||||
const colorOptions = [...Array(maxColor)].map((_, i) => i);
|
const colorOptions = [...Array(maxColor)].map((_, i) => i);
|
||||||
|
|
||||||
@ -84,8 +95,7 @@ export const NameChangeModal: FC<NameChangeModalProps> = ({ closeModal }) => {
|
|||||||
onChange={e => setNewName(e.target.value)}
|
onChange={e => setNewName(e.target.value)}
|
||||||
placeholder="Your chat display name"
|
placeholder="Your chat display name"
|
||||||
aria-label="Your chat display name"
|
aria-label="Your chat display name"
|
||||||
maxLength={30}
|
showCount={{ formatter: showCount }}
|
||||||
showCount
|
|
||||||
defaultValue={displayName}
|
defaultValue={displayName}
|
||||||
className={styles.inputGroup}
|
className={styles.inputGroup}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user