import React, { FormEventHandler, useCallback, useMemo, useState } from 'react'; import { Box, Text, Avatar, AvatarImage, AvatarFallback, Button, Icon, Icons, Input, TextArea, Chip, } from 'folds'; import Linkify from 'linkify-react'; import { mxcUrlToHttp } from '../../utils/matrix'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { nameInitials } from '../../utils/common'; import { BreakWord } from '../../styles/Text.css'; import { LINKIFY_OPTS } from '../../plugins/react-custom-html-parser'; import { ContainerColor } from '../../styles/ContainerColor.css'; import { useFilePicker } from '../../hooks/useFilePicker'; import { useObjectURL } from '../../hooks/useObjectURL'; import { createUploadAtom, UploadSuccess } from '../../state/upload'; import { CompactUploadCardRenderer } from '../upload-card'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; import { PackMetaReader } from '../../plugins/custom-emoji'; type ImagePackAvatarProps = { url?: string; name?: string; }; function ImagePackAvatar({ url, name }: ImagePackAvatarProps) { return ( {url ? ( ) : ( {nameInitials(name ?? 'Unknown')} )} ); } type ImagePackProfileProps = { meta: PackMetaReader; canEdit?: boolean; onEdit?: () => void; }; export function ImagePackProfile({ meta, canEdit, onEdit }: ImagePackProfileProps) { const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); const avatarUrl = meta.avatar ? mxcUrlToHttp(mx, meta.avatar, useAuthentication) ?? undefined : undefined; return ( {meta.name ?? 'Unknown'} {meta.attribution && ( {meta.attribution} )} {canEdit && ( } onClick={onEdit} outlined > Edit )} ); } type ImagePackProfileEditProps = { meta: PackMetaReader; onCancel: () => void; onSave: (meta: PackMetaReader) => void; }; export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfileEditProps) { const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); const [avatar, setAvatar] = useState(meta.avatar); const avatarUrl = avatar ? mxcUrlToHttp(mx, avatar, useAuthentication) ?? undefined : undefined; const [imageFile, setImageFile] = useState(); const avatarFileUrl = useObjectURL(imageFile); const uploadingAvatar = avatarFileUrl ? avatar === meta.avatar : false; const uploadAtom = useMemo(() => { if (imageFile) return createUploadAtom(imageFile); return undefined; }, [imageFile]); const pickFile = useFilePicker(setImageFile, false); const handleRemoveUpload = useCallback(() => { setImageFile(undefined); setAvatar(meta.avatar); }, [meta.avatar]); const handleUploaded = useCallback((upload: UploadSuccess) => { setAvatar(upload.mxc); }, []); const handleSubmit: FormEventHandler = (evt) => { evt.preventDefault(); if (uploadingAvatar) return; const target = evt.target as HTMLFormElement | undefined; const nameInput = target?.nameInput as HTMLInputElement | undefined; const attributionTextArea = target?.attributionTextArea as HTMLTextAreaElement | undefined; if (!nameInput || !attributionTextArea) return; const name = nameInput.value.trim(); const attribution = attributionTextArea.value.trim(); if (!name) return; const metaReader = new PackMetaReader({ avatar_url: avatar, display_name: name, attribution, }); onSave(metaReader); }; return ( Pack Avatar {uploadAtom ? ( ) : ( {!avatar && meta.avatar && ( )} {avatar && ( )} )} Name Attribution