feat(ui): add max. file size check before upload attachment (#2709)

Co-authored-by: TAKAHASHI Shuuji <shuuji3@gmail.com>
This commit is contained in:
Joaquín Sánchez 2024-04-04 12:28:18 +02:00 committed by GitHub
parent 8f04ea8eee
commit 3f0b234cc4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 66 additions and 1 deletions

View file

@ -77,3 +77,32 @@ export function useTimeAgoOptions(short = false): UseTimeAgoOptions<false> {
}, },
} }
} }
export function useFileSizeFormatter() {
const { locale } = useI18n()
const formatters = computed(() => ([
Intl.NumberFormat(locale.value, {
style: 'unit',
unit: 'megabyte',
unitDisplay: 'narrow',
maximumFractionDigits: 0,
}),
Intl.NumberFormat(locale.value, {
style: 'unit',
unit: 'kilobyte',
unitDisplay: 'narrow',
maximumFractionDigits: 0,
}),
]))
const megaByte = 1024 * 1024
function formatFileSize(size: number) {
return size >= megaByte
? formatters.value[0].format(size / megaByte)
: formatters.value[1].format(size / 1024)
}
return { formatFileSize }
}

View file

@ -155,6 +155,7 @@ export type MediaAttachmentUploadError = [filename: string, message: string]
export function useUploadMediaAttachment(draft: Ref<Draft>) { export function useUploadMediaAttachment(draft: Ref<Draft>) {
const { client } = useMasto() const { client } = useMasto()
const { t } = useI18n() const { t } = useI18n()
const { formatFileSize } = useFileSizeFormatter()
const isUploading = ref<boolean>(false) const isUploading = ref<boolean>(false)
const isExceedingAttachmentLimit = ref<boolean>(false) const isExceedingAttachmentLimit = ref<boolean>(false)
@ -224,8 +225,32 @@ export function useUploadMediaAttachment(draft: Ref<Draft>) {
// TODO: display some kind of message if too many media are selected // TODO: display some kind of message if too many media are selected
// DONE // DONE
const limit = currentInstance.value!.configuration?.statuses.maxMediaAttachments || 4 const limit = currentInstance.value!.configuration?.statuses.maxMediaAttachments || 4
const maxVideoSize = currentInstance.value!.configuration?.mediaAttachments.videoSizeLimit || 0
const maxImageSize = currentInstance.value!.configuration?.mediaAttachments.imageSizeLimit || 0
for (const file of files.slice(0, limit)) { for (const file of files.slice(0, limit)) {
if (draft.value.attachments.length < limit) { if (draft.value.attachments.length < limit) {
if (file.type.startsWith('image/')) {
if (maxImageSize > 0 && file.size > maxImageSize) {
failedAttachments.value = [...failedAttachments.value, [file.name, t('state.attachments_limit_image_error', [formatFileSize(maxImageSize)])]]
continue
}
}
else {
if (maxVideoSize > 0 && file.size > maxVideoSize) {
const key
= file.type.startsWith('audio/')
? 'state.attachments_limit_audio_error'
: file.type.startsWith('video/')
? 'state.attachments_limit_video_error'
: 'state.attachments_limit_unknown_error'
const errorMessage = t(key, [formatFileSize(maxVideoSize)])
failedAttachments.value = [
...failedAttachments.value,
[file.name, errorMessage],
]
continue
}
}
isExceedingAttachmentLimit.value = false isExceedingAttachmentLimit.value = false
try { try {
const attachment = await client.value.v1.media.create({ const attachment = await client.value.v1.media.create({

View file

@ -594,7 +594,11 @@
}, },
"state": { "state": {
"attachments_exceed_server_limit": "The number of attachments exceeded the limit per post.", "attachments_exceed_server_limit": "The number of attachments exceeded the limit per post.",
"attachments_limit_audio_error": "Maximum audio size exceeded: {0}",
"attachments_limit_error": "Limit per post exceeded", "attachments_limit_error": "Limit per post exceeded",
"attachments_limit_image_error": "Maximum image size exceeded: {0}",
"attachments_limit_unknown_error": "Maximum file size exceeded: {0}",
"attachments_limit_video_error": "Maximum video size exceeded: {0}",
"edited": "(Edited)", "edited": "(Edited)",
"editing": "Editing", "editing": "Editing",
"loading": "Loading...", "loading": "Loading...",

View file

@ -184,6 +184,9 @@
"label": "Usuarios en línea" "label": "Usuarios en línea"
} }
}, },
"state": {
"attachments_limit_video_error": "Tamaño máximo de video excedido: {0}"
},
"status": { "status": {
"spoiler_show_less": "Menos" "spoiler_show_less": "Menos"
}, },

View file

@ -591,7 +591,11 @@
}, },
"state": { "state": {
"attachments_exceed_server_limit": "Número máximo de archivos adjuntos por publicación excedido.", "attachments_exceed_server_limit": "Número máximo de archivos adjuntos por publicación excedido.",
"attachments_limit_audio_error": "Tamaño máximo de audio excedido: {0}",
"attachments_limit_error": "Límite por publicación excedido", "attachments_limit_error": "Límite por publicación excedido",
"attachments_limit_image_error": "Tamaño máximo de imagen excedido: {0}",
"attachments_limit_unknown_error": "Tamaño máximo de archivo excedido: {0}",
"attachments_limit_video_error": "Tamaño máximo de vídeo excedido: {0}",
"edited": "(Editado)", "edited": "(Editado)",
"editing": "Editando", "editing": "Editando",
"loading": "Cargando...", "loading": "Cargando...",
@ -708,7 +712,7 @@
"tooltip": { "tooltip": {
"add_content_warning": "Añadir advertencia de contenido", "add_content_warning": "Añadir advertencia de contenido",
"add_emojis": "Agregar emojis", "add_emojis": "Agregar emojis",
"add_media": "Añadir imágenes, video o audio", "add_media": "Añadir imágenes, vídeo o audio",
"add_publishable_content": "Publicar contenido", "add_publishable_content": "Publicar contenido",
"change_content_visibility": "Cambiar visibilidad de contenido", "change_content_visibility": "Cambiar visibilidad de contenido",
"change_language": "Cambiar idioma", "change_language": "Cambiar idioma",