Avatar defaults and colors
This commit is contained in:
parent
a001882d58
commit
12d2b1bf7c
140 changed files with 4212 additions and 1084 deletions
|
@ -4,25 +4,31 @@
|
|||
import React, {
|
||||
FormEventHandler,
|
||||
FunctionComponent,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import { LocalizerType } from '../../../types/Util';
|
||||
import { Modal } from '../../Modal';
|
||||
import { AvatarInputContainer } from '../../AvatarInputContainer';
|
||||
import { AvatarInputVariant } from '../../AvatarInput';
|
||||
import { AvatarEditor } from '../../AvatarEditor';
|
||||
import { AvatarPreview } from '../../AvatarPreview';
|
||||
import { Button, ButtonVariant } from '../../Button';
|
||||
import { Spinner } from '../../Spinner';
|
||||
import { GroupDescriptionInput } from '../../GroupDescriptionInput';
|
||||
import { GroupTitleInput } from '../../GroupTitleInput';
|
||||
import { RequestState } from './util';
|
||||
|
||||
const TEMPORARY_AVATAR_VALUE = new ArrayBuffer(0);
|
||||
import {
|
||||
AvatarDataType,
|
||||
DeleteAvatarFromDiskActionType,
|
||||
ReplaceAvatarActionType,
|
||||
SaveAvatarToDiskActionType,
|
||||
} from '../../../types/Avatar';
|
||||
import { AvatarColorType } from '../../../types/Colors';
|
||||
|
||||
type PropsType = {
|
||||
avatarColor?: AvatarColorType;
|
||||
avatarPath?: string;
|
||||
conversationId: string;
|
||||
groupDescription?: string;
|
||||
i18n: LocalizerType;
|
||||
initiallyFocusDescription: boolean;
|
||||
|
@ -36,10 +42,16 @@ type PropsType = {
|
|||
onClose: () => void;
|
||||
requestState: RequestState;
|
||||
title: string;
|
||||
deleteAvatarFromDisk: DeleteAvatarFromDiskActionType;
|
||||
replaceAvatar: ReplaceAvatarActionType;
|
||||
saveAvatarToDisk: SaveAvatarToDiskActionType;
|
||||
userAvatarData: Array<AvatarDataType>;
|
||||
};
|
||||
|
||||
export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
|
||||
avatarColor,
|
||||
avatarPath: externalAvatarPath,
|
||||
conversationId,
|
||||
groupDescription: externalGroupDescription = '',
|
||||
i18n,
|
||||
initiallyFocusDescription,
|
||||
|
@ -47,6 +59,10 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
|
|||
onClose,
|
||||
requestState,
|
||||
title: externalTitle,
|
||||
deleteAvatarFromDisk,
|
||||
replaceAvatar,
|
||||
saveAvatarToDisk,
|
||||
userAvatarData,
|
||||
}) => {
|
||||
const focusDescriptionRef = useRef<undefined | boolean>(
|
||||
initiallyFocusDescription
|
||||
|
@ -56,9 +72,8 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
|
|||
const startingTitleRef = useRef<string>(externalTitle);
|
||||
const startingAvatarPathRef = useRef<undefined | string>(externalAvatarPath);
|
||||
|
||||
const [avatar, setAvatar] = useState<undefined | ArrayBuffer>(
|
||||
externalAvatarPath ? TEMPORARY_AVATAR_VALUE : undefined
|
||||
);
|
||||
const [editingAvatar, setEditingAvatar] = useState(false);
|
||||
const [avatar, setAvatar] = useState<undefined | ArrayBuffer>();
|
||||
const [rawTitle, setRawTitle] = useState(externalTitle);
|
||||
const [rawGroupDescription, setRawGroupDescription] = useState(
|
||||
externalGroupDescription
|
||||
|
@ -112,35 +127,55 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
|
|||
makeRequest(request);
|
||||
};
|
||||
|
||||
const handleAvatarLoaded = useCallback(
|
||||
loadedAvatar => {
|
||||
setAvatar(loadedAvatar);
|
||||
},
|
||||
[setAvatar]
|
||||
);
|
||||
const avatarPathForPreview = hasAvatarChanged
|
||||
? undefined
|
||||
: externalAvatarPath;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
onClose={onClose}
|
||||
title={i18n('updateGroupAttributes__title')}
|
||||
>
|
||||
let content: JSX.Element;
|
||||
if (editingAvatar) {
|
||||
content = (
|
||||
<AvatarEditor
|
||||
avatarColor={avatarColor}
|
||||
avatarPath={avatarPathForPreview}
|
||||
avatarValue={avatar}
|
||||
conversationId={conversationId}
|
||||
deleteAvatarFromDisk={deleteAvatarFromDisk}
|
||||
i18n={i18n}
|
||||
isGroup
|
||||
onCancel={() => {
|
||||
setHasAvatarChanged(false);
|
||||
setEditingAvatar(false);
|
||||
}}
|
||||
onSave={newAvatar => {
|
||||
setAvatar(newAvatar);
|
||||
setHasAvatarChanged(true);
|
||||
setEditingAvatar(false);
|
||||
}}
|
||||
userAvatarData={userAvatarData}
|
||||
replaceAvatar={replaceAvatar}
|
||||
saveAvatarToDisk={saveAvatarToDisk}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<form
|
||||
onSubmit={onSubmit}
|
||||
className="module-EditConversationAttributesModal"
|
||||
>
|
||||
<AvatarInputContainer
|
||||
avatarPath={externalAvatarPath}
|
||||
contextMenuId="edit conversation attributes avatar input"
|
||||
disabled={isRequestActive}
|
||||
<AvatarPreview
|
||||
avatarColor={avatarColor}
|
||||
avatarPath={avatarPathForPreview}
|
||||
avatarValue={avatar}
|
||||
i18n={i18n}
|
||||
onAvatarChanged={newAvatar => {
|
||||
setAvatar(newAvatar);
|
||||
setHasAvatarChanged(true);
|
||||
isEditable
|
||||
isGroup
|
||||
onClick={() => {
|
||||
setEditingAvatar(true);
|
||||
}}
|
||||
style={{
|
||||
height: 96,
|
||||
width: 96,
|
||||
}}
|
||||
onAvatarLoaded={handleAvatarLoaded}
|
||||
variant={AvatarInputVariant.Dark}
|
||||
/>
|
||||
|
||||
<GroupTitleInput
|
||||
|
@ -191,6 +226,18 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
|
|||
</Button>
|
||||
</Modal.ButtonFooter>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
hasStickyButtons
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
onClose={onClose}
|
||||
title={i18n('updateGroupAttributes__title')}
|
||||
>
|
||||
{content}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue