mirror of
https://github.com/h3poteto/whalebird-desktop
synced 2024-12-23 15:37:59 +01:00
Merge pull request #4728 from h3poteto/iss-4653/image-description
refs #4653 Add edit media to apply description for the media
This commit is contained in:
commit
77d47478aa
@ -96,6 +96,11 @@
|
||||
"3d": "3 days",
|
||||
"7d": "7 days",
|
||||
"multiple": "multiple"
|
||||
},
|
||||
"edit_media": {
|
||||
"title": "Edit media",
|
||||
"label": "Describe for people who are blind or have low vision",
|
||||
"submit": "Apply"
|
||||
}
|
||||
},
|
||||
"alert": {
|
||||
|
@ -14,11 +14,23 @@ import {
|
||||
} from 'flowbite-react'
|
||||
import { ChangeEvent, Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { FormattedMessage, useIntl } from 'react-intl'
|
||||
import { FaEnvelope, FaFaceLaughBeam, FaGlobe, FaListCheck, FaLock, FaLockOpen, FaPaperPlane, FaPaperclip, FaXmark } from 'react-icons/fa6'
|
||||
import {
|
||||
FaEnvelope,
|
||||
FaFaceLaughBeam,
|
||||
FaGlobe,
|
||||
FaListCheck,
|
||||
FaLock,
|
||||
FaLockOpen,
|
||||
FaPaperPlane,
|
||||
FaPaperclip,
|
||||
FaPencil,
|
||||
FaXmark
|
||||
} from 'react-icons/fa6'
|
||||
import { Entity, MegalodonInterface } from 'megalodon'
|
||||
import { useToast } from '@/utils/toast'
|
||||
import Picker from '@emoji-mart/react'
|
||||
import { data } from '@/utils/emojiData'
|
||||
import EditMedia from './EditMedia'
|
||||
|
||||
type Props = {
|
||||
client: MegalodonInterface
|
||||
@ -50,6 +62,7 @@ export default function Compose(props: Props) {
|
||||
const [attachments, setAttachments] = useState<Array<Entity.Attachment | Entity.AsyncAttachment>>([])
|
||||
const [poll, setPoll] = useState<Poll | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [editMedia, setEditMedia] = useState<Entity.Attachment>()
|
||||
|
||||
const { formatMessage } = useIntl()
|
||||
const uploaderRef = useRef(null)
|
||||
@ -164,6 +177,14 @@ export default function Compose(props: Props) {
|
||||
setAttachments(current => current.filter((_, i) => i !== index))
|
||||
}
|
||||
|
||||
const openDescription = (index: number) => {
|
||||
setEditMedia(attachments[index])
|
||||
}
|
||||
|
||||
const closeDescription = () => {
|
||||
setEditMedia(undefined)
|
||||
}
|
||||
|
||||
const togglePoll = () => {
|
||||
if (poll) {
|
||||
setPoll(null)
|
||||
@ -233,6 +254,9 @@ export default function Compose(props: Props) {
|
||||
<button className="absolute bg-gray-600 rounded" onClick={() => removeFile(index)}>
|
||||
<FaXmark className="text-gray-200" />
|
||||
</button>
|
||||
<button className="absolute right-0 bg-gray-600 rounded" onClick={() => openDescription(index)}>
|
||||
<FaPencil className="text-gray-200" />
|
||||
</button>
|
||||
<img src={f.preview_url} style={{ width: '80px', height: '80px' }} className="rounded-md" />
|
||||
</div>
|
||||
))}
|
||||
@ -281,6 +305,7 @@ export default function Compose(props: Props) {
|
||||
{loading ? <Spinner size="sm" /> : <FaPaperPlane className="text-gray-400 hover:text-gray-600 cursor-pointer" onClick={post} />}
|
||||
</div>
|
||||
</div>
|
||||
<EditMedia media={editMedia} close={closeDescription} client={props.client} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
66
renderer/components/compose/EditMedia.tsx
Normal file
66
renderer/components/compose/EditMedia.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import { Label, Modal, Textarea, Button } from 'flowbite-react'
|
||||
import { Entity, MegalodonInterface } from 'megalodon'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
|
||||
type Props = {
|
||||
media: Entity.Attachment | undefined
|
||||
close: () => void
|
||||
client: MegalodonInterface
|
||||
}
|
||||
|
||||
export default function EditMedia(props: Props) {
|
||||
const [description, setDescription] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
if (props.media) {
|
||||
const f = async () => {
|
||||
const res = await props.client.getMedia(props.media.id)
|
||||
if (res.data.description) {
|
||||
setDescription(res.data.description)
|
||||
}
|
||||
}
|
||||
f()
|
||||
}
|
||||
}, [props.media, props.client])
|
||||
|
||||
const submit = async () => {
|
||||
if (!props.media || !props.client) return
|
||||
await props.client.updateMedia(props.media.id, {
|
||||
description: description
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
setDescription('')
|
||||
props.close()
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal show={props.media !== undefined} onClose={onClose} size="2xl">
|
||||
{props.media && (
|
||||
<>
|
||||
<Modal.Header>
|
||||
<FormattedMessage id="compose.edit_media.title" />
|
||||
</Modal.Header>
|
||||
<Modal.Body className="max-h-full max-w-full">
|
||||
<div className="flex gap-2">
|
||||
<div className="w-1/4">
|
||||
<Label htmlFor="description" className="mb-2 block">
|
||||
<FormattedMessage id="compose.edit_media.label" />
|
||||
</Label>
|
||||
<Textarea id="description" rows={4} value={description} onChange={ev => setDescription(ev.target.value)} />
|
||||
<Button className="mt-2" onClick={submit}>
|
||||
<FormattedMessage id="compose.edit_media.submit" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="w-3/4">
|
||||
<img src={props.media.preview_url} className="object-cover m-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user