Added new widget to alert if a file is set at larger than 10 MB.

- Updated default widget to use template that adds a notification box.
- Added JS to add onchange & load events to look at the value in the input and trigger the notification & disable the form submits.
This commit is contained in:
Jason Kelly 2021-05-23 14:12:00 +08:00
parent c9617c4bd3
commit 6e655cb0e0
3 changed files with 53 additions and 0 deletions

View file

@ -9,6 +9,7 @@ from django.contrib.postgres.fields import ArrayField as DjangoArrayField
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.db import models from django.db import models
from django.forms import ClearableFileInput, ImageField
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from bookwyrm import activitypub from bookwyrm import activitypub
@ -332,6 +333,14 @@ class TagField(ManyToManyField):
return items return items
class ClearableFileInputWithWarning(ClearableFileInput):
template_name = 'widgets/clearable_file_input_with_warning.html'
class CustomImageField(ImageField):
widget = ClearableFileInputWithWarning
def image_serializer(value, alt): def image_serializer(value, alt):
"""helper for serializing images""" """helper for serializing images"""
if value and hasattr(value, "url"): if value and hasattr(value, "url"):
@ -395,6 +404,12 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
image_content = ContentFile(response.content) image_content = ContentFile(response.content)
return [image_name, image_content] return [image_name, image_content]
def formfield(self, **kwargs):
return super().formfield(**{
'form_class': CustomImageField,
**kwargs,
})
class DateTimeField(ActivitypubFieldMixin, models.DateTimeField): class DateTimeField(ActivitypubFieldMixin, models.DateTimeField):
"""activitypub-aware datetime field""" """activitypub-aware datetime field"""

View file

@ -3,6 +3,7 @@
let BookWyrm = new class { let BookWyrm = new class {
constructor() { constructor() {
this.MAX_FILE_SIZE = 10000000
this.initOnDOMLoaded(); this.initOnDOMLoaded();
this.initReccuringTasks(); this.initReccuringTasks();
this.initEventListeners(); this.initEventListeners();
@ -32,15 +33,26 @@ let BookWyrm = new class {
'click', 'click',
this.back) this.back)
); );
document.querySelectorAll('input[type="file"]')
.forEach(node => node.addEventListener(
'change',
this.disableIfTooLarge.bind(this)
));
} }
/** /**
* Execute code once the DOM is loaded. * Execute code once the DOM is loaded.
*/ */
initOnDOMLoaded() { initOnDOMLoaded() {
const bookwyrm = this
window.addEventListener('DOMContentLoaded', function() { window.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.tab-group') document.querySelectorAll('.tab-group')
.forEach(tabs => new TabGroup(tabs)); .forEach(tabs => new TabGroup(tabs));
document.querySelectorAll('input[type="file"]').forEach(
bookwyrm.disableIfTooLarge.bind(bookwyrm)
)
}); });
} }
@ -284,4 +296,27 @@ let BookWyrm = new class {
node.classList.remove(classname); node.classList.remove(classname);
} }
} }
disableIfTooLarge(eventOrElement) {
const { addRemoveClass, MAX_FILE_SIZE } = this
const element = eventOrElement.currentTarget || eventOrElement
const submits = element.form.querySelectorAll('[type="submit"]')
const warns = element.parentElement.querySelectorAll('.file-too-big')
const isTooBig = element.files &&
element.files[0] &&
element.files[0].size > MAX_FILE_SIZE
if (isTooBig) {
submits.forEach(submitter => submitter.disabled = true)
warns.forEach(
sib => addRemoveClass(sib, 'is-hidden', false)
)
} else {
submits.forEach(submitter => submitter.disabled = false)
warns.forEach(
sib => addRemoveClass(sib, 'is-hidden', true)
)
}
}
} }

View file

@ -0,0 +1,3 @@
{% load i18n %}
{% include "django/forms/widgets/clearable_file_input.html" %}
<span class="help file-cta is-hidden file-too-big">{% trans "File exceeds maximum size: 10MB" %}</span>