Change pack avatar, name & attribution
This commit is contained in:
parent
15e8412326
commit
458738f06a
6 changed files with 103 additions and 22 deletions
|
@ -107,7 +107,17 @@ function useImagePackHandles(pack, sendPackContent) {
|
|||
return newKey;
|
||||
};
|
||||
|
||||
const handleEditProfile = () => false;
|
||||
const handleAvatarChange = (url) => {
|
||||
pack.setAvatarUrl(url);
|
||||
sendPackContent(pack.getContent());
|
||||
forceUpdate();
|
||||
};
|
||||
const handleEditProfile = (name, attribution) => {
|
||||
pack.setDisplayName(name);
|
||||
pack.setAttribution(attribution);
|
||||
sendPackContent(pack.getContent());
|
||||
forceUpdate();
|
||||
};
|
||||
const handleUsageChange = (newUsage) => {
|
||||
const usage = [];
|
||||
if (newUsage === 'emoticon' || newUsage === 'both') usage.push('emoticon');
|
||||
|
@ -163,6 +173,7 @@ function useImagePackHandles(pack, sendPackContent) {
|
|||
};
|
||||
|
||||
return {
|
||||
handleAvatarChange,
|
||||
handleEditProfile,
|
||||
handleUsageChange,
|
||||
handleRenameItem,
|
||||
|
@ -180,6 +191,7 @@ function ImagePack({ roomId, stateKey }) {
|
|||
const { pack, sendPackContent } = useRoomImagePack(roomId, stateKey);
|
||||
|
||||
const {
|
||||
handleAvatarChange,
|
||||
handleEditProfile,
|
||||
handleUsageChange,
|
||||
handleRenameItem,
|
||||
|
@ -196,12 +208,13 @@ function ImagePack({ roomId, stateKey }) {
|
|||
return (
|
||||
<div className="image-pack">
|
||||
<ImagePackProfile
|
||||
avatarUrl={mx.mxcUrlToHttp(pack.avatarUrl)}
|
||||
avatarUrl={pack.avatarUrl ? mx.mxcUrlToHttp(pack.avatarUrl, 42, 42, 'crop') : null}
|
||||
displayName={pack.displayName ?? 'Unknown'}
|
||||
attribution={pack.attribution}
|
||||
usage={getUsage(pack.usage)}
|
||||
onUsageChange={canChange ? handleUsageChange : undefined}
|
||||
onEdit={canChange ? handleEditProfile : undefined}
|
||||
onUsageChange={canChange ? handleUsageChange : null}
|
||||
onAvatarChange={canChange ? handleAvatarChange : null}
|
||||
onEditProfile={canChange ? handleEditProfile : null}
|
||||
/>
|
||||
{ canChange && (
|
||||
<ImagePackUpload onUpload={handleAddItem} />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './ImagePackProfile.scss';
|
||||
|
||||
|
@ -9,14 +9,30 @@ import Text from '../../atoms/text/Text';
|
|||
import Avatar from '../../atoms/avatar/Avatar';
|
||||
import Button from '../../atoms/button/Button';
|
||||
import IconButton from '../../atoms/button/IconButton';
|
||||
import Input from '../../atoms/input/Input';
|
||||
import ImageUpload from '../image-upload/ImageUpload';
|
||||
import ImagePackUsageSelector from './ImagePackUsageSelector';
|
||||
|
||||
import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
|
||||
import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
|
||||
|
||||
function ImagePackProfile({
|
||||
avatarUrl, displayName, attribution, usage, onUsageChange, onEdit,
|
||||
avatarUrl, displayName, attribution, usage,
|
||||
onUsageChange, onAvatarChange, onEditProfile,
|
||||
}) {
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const { nameInput, attributionInput } = e.target;
|
||||
const name = nameInput.value.trim() || undefined;
|
||||
const att = attributionInput.value.trim() || undefined;
|
||||
|
||||
onEditProfile(name, att);
|
||||
setIsEdit(false);
|
||||
};
|
||||
|
||||
const handleUsageSelect = (event) => {
|
||||
openReusableContextMenu(
|
||||
'bottom',
|
||||
|
@ -35,13 +51,42 @@ function ImagePackProfile({
|
|||
|
||||
return (
|
||||
<div className="image-pack-profile">
|
||||
{avatarUrl && <Avatar text={displayName} bgColor="blue" imageSrc={avatarUrl} size="normal" />}
|
||||
{
|
||||
onAvatarChange
|
||||
? (
|
||||
<ImageUpload
|
||||
bgColor="#555"
|
||||
text={displayName}
|
||||
imageSrc={avatarUrl}
|
||||
size="normal"
|
||||
onUpload={onAvatarChange}
|
||||
onRequestRemove={() => onAvatarChange(undefined)}
|
||||
/>
|
||||
)
|
||||
: <Avatar bgColor="#555" text={displayName} imageSrc={avatarUrl} size="normal" />
|
||||
}
|
||||
<div className="image-pack-profile__content">
|
||||
<div>
|
||||
<Text>{displayName}</Text>
|
||||
{onEdit && <IconButton size="extra-small" onClick={onEdit} src={PencilIC} tooltip="Edit" />}
|
||||
</div>
|
||||
{attribution && <Text variant="b3">{attribution}</Text>}
|
||||
{
|
||||
isEdit
|
||||
? (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Input name="nameInput" label="Name" value={displayName} required />
|
||||
<Input name="attributionInput" label="Attribution" value={attribution} resizable />
|
||||
<div>
|
||||
<Button variant="primary" type="submit">Save</Button>
|
||||
<Button onClick={() => setIsEdit(false)}>Cancel</Button>
|
||||
</div>
|
||||
</form>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
<Text>{displayName}</Text>
|
||||
{onEditProfile && <IconButton size="extra-small" onClick={() => setIsEdit(true)} src={PencilIC} tooltip="Edit" />}
|
||||
</div>
|
||||
{attribution && <Text variant="b3">{attribution}</Text>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className="image-pack-profile__usage">
|
||||
<Text variant="b3">Pack usage</Text>
|
||||
|
@ -64,7 +109,8 @@ ImagePackProfile.defaultProps = {
|
|||
avatarUrl: null,
|
||||
attribution: null,
|
||||
onUsageChange: null,
|
||||
onEdit: null,
|
||||
onAvatarChange: null,
|
||||
onEditProfile: null,
|
||||
};
|
||||
ImagePackProfile.propTypes = {
|
||||
avatarUrl: PropTypes.string,
|
||||
|
@ -72,7 +118,8 @@ ImagePackProfile.propTypes = {
|
|||
attribution: PropTypes.string,
|
||||
usage: PropTypes.oneOf(['emoticon', 'sticker', 'both']).isRequired,
|
||||
onUsageChange: PropTypes.func,
|
||||
onEdit: PropTypes.func,
|
||||
onAvatarChange: PropTypes.func,
|
||||
onEditProfile: PropTypes.func,
|
||||
};
|
||||
|
||||
export default ImagePackProfile;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
&__content {
|
||||
@extend .cp-fx__item-one;
|
||||
|
||||
& div:first-child {
|
||||
& > div:first-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-extra-tight);
|
||||
|
@ -18,6 +18,16 @@
|
|||
padding: var(--sp-ultra-tight);
|
||||
}
|
||||
}
|
||||
& > form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-extra-tight);
|
||||
& > div:last-child {
|
||||
margin: var(--sp-extra-tight) 0;
|
||||
display: flex;
|
||||
gap: var(--sp-tight);
|
||||
}
|
||||
}
|
||||
}
|
||||
&__usage {
|
||||
& > *:first-child {
|
||||
|
|
|
@ -41,6 +41,7 @@ function ImagePackUpload({ onUpload }) {
|
|||
const img = evt.target.files[0];
|
||||
if (!img) return;
|
||||
setImgFile(img);
|
||||
shortcodeRef.current.focus();
|
||||
};
|
||||
const handleRemove = () => {
|
||||
setImgFile(null);
|
||||
|
|
|
@ -7,9 +7,13 @@ import initMatrix from '../../../client/initMatrix';
|
|||
import Text from '../../atoms/text/Text';
|
||||
import Avatar from '../../atoms/avatar/Avatar';
|
||||
import Spinner from '../../atoms/spinner/Spinner';
|
||||
import RawIcon from '../../atoms/system-icons/RawIcon';
|
||||
|
||||
import PlusIC from '../../../../public/res/ic/outlined/plus.svg';
|
||||
|
||||
function ImageUpload({
|
||||
text, bgColor, imageSrc, onUpload, onRequestRemove,
|
||||
size,
|
||||
}) {
|
||||
const [uploadPromise, setUploadPromise] = useState(null);
|
||||
const uploadImageRef = useRef(null);
|
||||
|
@ -50,10 +54,14 @@ function ImageUpload({
|
|||
imageSrc={imageSrc}
|
||||
text={text}
|
||||
bgColor={bgColor}
|
||||
size="large"
|
||||
size={size}
|
||||
/>
|
||||
<div className={`img-upload__process ${uploadPromise === null ? ' img-upload__process--stopped' : ''}`}>
|
||||
{uploadPromise === null && <Text variant="b3" weight="bold">Upload</Text>}
|
||||
{uploadPromise === null && (
|
||||
size === 'large'
|
||||
? <Text variant="b3" weight="bold">Upload</Text>
|
||||
: <RawIcon src={PlusIC} color="white" />
|
||||
)}
|
||||
{uploadPromise !== null && <Spinner size="small" />}
|
||||
</div>
|
||||
</button>
|
||||
|
@ -75,6 +83,7 @@ ImageUpload.defaultProps = {
|
|||
text: null,
|
||||
bgColor: 'transparent',
|
||||
imageSrc: null,
|
||||
size: 'large',
|
||||
};
|
||||
|
||||
ImageUpload.propTypes = {
|
||||
|
@ -83,6 +92,7 @@ ImageUpload.propTypes = {
|
|||
imageSrc: PropTypes.string,
|
||||
onUpload: PropTypes.func.isRequired,
|
||||
onRequestRemove: PropTypes.func.isRequired,
|
||||
size: PropTypes.oneOf(['large', 'normal']),
|
||||
};
|
||||
|
||||
export default ImageUpload;
|
||||
|
|
|
@ -15,18 +15,18 @@ class ImagePack {
|
|||
this.id = eventId;
|
||||
this.content = JSON.parse(JSON.stringify(content));
|
||||
|
||||
this.displayName = room?.name ?? undefined;
|
||||
this.avatarUrl = room?.getMxcAvatarUrl() ?? undefined;
|
||||
|
||||
this.applyPack(content);
|
||||
this.applyImages(content);
|
||||
|
||||
this.displayName ??= room?.name;
|
||||
this.avatarUrl ??= room?.getMxcAvatarUrl();
|
||||
}
|
||||
|
||||
applyPack(content) {
|
||||
const pack = content.pack ?? {};
|
||||
|
||||
this.displayName = pack.display_name ?? this.displayName;
|
||||
this.avatarUrl = pack.avatar_url ?? this.avatarUrl;
|
||||
this.displayName = pack.display_name;
|
||||
this.avatarUrl = pack.avatar_url;
|
||||
this.usage = pack.usage ?? ['emoticon', 'sticker'];
|
||||
this.attribution = pack.attribution;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue