1
0
mirror of https://github.com/h3poteto/whalebird-desktop synced 2025-01-31 01:27:26 +01:00

refs #4653 Show characters count in compose

This commit is contained in:
AkiraFukushima 2024-01-02 12:22:40 +09:00
parent acd9538d3c
commit aa8f0922fb
No known key found for this signature in database
GPG Key ID: B6E51BAC4DE1A957
2 changed files with 37 additions and 3 deletions

View File

@ -109,9 +109,13 @@
},
"alert": {
"validation": {
"attachment_type": "You can attach only images or videos"
"attachment_type": "You can attach only images or videos",
"attachment_length": "You can't attach over {limit} files"
},
"upload_error": "Failed to upload the file"
"upload_error": "Failed to upload the file",
"compose": {
"post_failed": "Failed to post a status"
}
},
"profile": {
"follow": "Follow",

View File

@ -63,12 +63,25 @@ export default function Compose(props: Props) {
const [poll, setPoll] = useState<Poll | null>(null)
const [loading, setLoading] = useState(false)
const [editMedia, setEditMedia] = useState<Entity.Attachment>()
const [maxCharacters, setMaxCharacters] = useState<number | null>(null)
const [remaining, setRemaining] = useState<number | null>(null)
const { formatMessage } = useIntl()
const uploaderRef = useRef(null)
const showToast = useToast()
const textareaRef = useRef<HTMLTextAreaElement>(null)
useEffect(() => {
if (!props.client) return
const f = async () => {
const instance = await props.client.getInstance()
if (instance.data.configuration.statuses.max_characters) {
setMaxCharacters(instance.data.configuration.statuses.max_characters)
}
}
f()
}, [props.client])
useEffect(() => {
if (!cw) {
setSpoiler('')
@ -89,6 +102,12 @@ export default function Compose(props: Props) {
}
}, [props.in_reply_to])
useEffect(() => {
if (maxCharacters) {
setRemaining(maxCharacters - body.length - spoiler.length)
}
}, [maxCharacters, body, spoiler])
const post = async () => {
if (body.length === 0) return
let options = { visibility: visibility }
@ -117,6 +136,9 @@ export default function Compose(props: Props) {
try {
await props.client.postStatus(body, options)
reset()
} catch (err) {
console.error(err)
showToast({ text: formatMessage({ id: 'alert.compose.post_failed' }), type: 'failure' })
} finally {
setLoading(false)
}
@ -128,6 +150,7 @@ export default function Compose(props: Props) {
setCW(false)
setAttachments([])
setPoll(null)
setMaxCharacters(null)
}
const handleKeyPress = useCallback(
@ -158,6 +181,10 @@ export default function Compose(props: Props) {
if (file === null || file === undefined) {
return
}
if (attachments.length >= 4) {
showToast({ text: formatMessage({ id: 'alert.validation.attachment_length' }, { limit: 4 }), type: 'failure' })
return
}
if (!file.type.includes('image') && !file.type.includes('video')) {
showToast({ text: formatMessage({ id: 'alert.validation.attachment_type' }), type: 'failure' })
return
@ -302,7 +329,10 @@ export default function Compose(props: Props) {
)}
</div>
<div className="mr-1">
{loading ? <Spinner size="sm" /> : <FaPaperPlane className="text-gray-400 hover:text-gray-600 cursor-pointer" onClick={post} />}
<span className="text-gray-400">{remaining}</span>
<button className="ml-2 text-gray-400 hover:text-gray-600" disabled={loading} onClick={post}>
{loading ? <Spinner size="sm" /> : <FaPaperPlane />}
</button>
</div>
</div>
<EditMedia media={editMedia} close={closeDescription} client={props.client} />