working UGC content upload with multi-upload support
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
<div class="form-group">
|
||||
{{ form.title.errors }}
|
||||
<label for="{{ form.title.id_for_label }}">Title</label>
|
||||
{{ form.title }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.summary.errors }}
|
||||
<label for="{{ form.summary.id_for_label }}">Summary</label>
|
||||
{{ form.summary }}
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
{{ form.category.errors }}
|
||||
<label for="{{ form.category.id_for_label }}">Category</label>
|
||||
{{ form.category }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.description.errors }}
|
||||
<label for="{{ form.description.id_for_label }}">Description</label>
|
||||
{{ form.description }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more.</p>
|
||||
</div>
|
||||
@@ -1,17 +0,0 @@
|
||||
<div class="form-group">
|
||||
{{ form.thumbnail.errors }}
|
||||
<label for="{{ form.thumbnail.id_for_label }}">Thumbnail</label>
|
||||
{{ form.thumbnail }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Square image shown on cards and the project header.</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="tag-editor">
|
||||
<input type="text" id="tag-input" placeholder="Type a tag and press Enter… (e.g. content:threesome, species:dragon)" autocomplete="off">
|
||||
<div class="tag-suggestions" id="tag-suggestions" hidden></div>
|
||||
<div class="tag-chips" id="tag-chips"></div>
|
||||
{{ form.tags }}
|
||||
</div>
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Categories: loader, version, general, creator, content, species, non_version. Unprefixed tags go to General. Creator tags are added automatically.</p>
|
||||
</div>
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="form-group">
|
||||
{{ form.version_name.errors }}
|
||||
<label for="{{ form.version_name.id_for_label }}">{{ form.version_name.label }}</label>
|
||||
{{ form.version_name }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.file.errors }}
|
||||
<label for="{{ form.file.id_for_label }}">{{ form.file.label }}</label>
|
||||
{{ form.file }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.changelog.errors }}
|
||||
<label for="{{ form.changelog.id_for_label }}">{{ form.changelog.label }}</label>
|
||||
{{ form.changelog }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown.</p>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
<input type="file" id="media-input" accept="image/*,video/*" multiple hidden>
|
||||
<div class="upload-batch" id="media-batch" hidden>
|
||||
<i class="fas fa-circle-notch fa-spin"></i>
|
||||
<span id="media-batch-status"></span>
|
||||
<span class="upload-batch-status" id="media-batch-status"></span>
|
||||
</div>
|
||||
<div class="file-preview-grid" id="media-preview"></div>
|
||||
</div>
|
||||
@@ -41,5 +41,6 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/asset_upload.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<input type="file" id="media-input" accept="image/*,video/*" multiple hidden>
|
||||
<div class="upload-batch" id="media-batch" hidden>
|
||||
<i class="fas fa-circle-notch fa-spin"></i>
|
||||
<span id="media-batch-status"></span>
|
||||
<span class="upload-batch-status" id="media-batch-status"></span>
|
||||
</div>
|
||||
<div class="file-preview-grid" id="media-preview"></div>
|
||||
</div>
|
||||
@@ -117,6 +117,8 @@
|
||||
|
||||
{% block extra_js %}
|
||||
{{ draft_uploads|json_script:'packs-draft-uploads' }}
|
||||
{{ tag_categories|json_script:'packs-tag-categories' }}
|
||||
<script src="{% static 'js/tags.js' %}"></script>
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/create.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -135,6 +135,29 @@
|
||||
document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Gallery deletion without a page reload, behind a confirmation dialog.
|
||||
document.querySelectorAll('.gallery-delete').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (!confirm('Delete this media? This cannot be undone.')) return;
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', link.getAttribute('href'));
|
||||
xhr.setRequestHeader('X-CSRFToken', getCookie('csrftoken'));
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {
|
||||
const figure = link.closest('figure.gallery-item');
|
||||
if (figure) figure.remove();
|
||||
} else {
|
||||
alert('Could not delete media.');
|
||||
}
|
||||
};
|
||||
xhr.onerror = function () {
|
||||
alert('Network error while deleting media.');
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,17 +7,59 @@
|
||||
<h1><i class="fas fa-pen"></i> Edit {{ project.title }}</h1>
|
||||
<p><a href="{% url 'library:project_detail' project.slug %}">← Back to project</a></p>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="card project-form" id="project-form">
|
||||
<form method="post" class="card project-form create-form" id="project-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="project-form-grid">
|
||||
<div class="project-form-main">
|
||||
{% include 'library/_project_form_fields.html' with form=project_form %}
|
||||
</div>
|
||||
<div class="create-grid">
|
||||
<section class="create-panel create-panel-main">
|
||||
<h2 class="form-section-title"><i class="fas fa-folder-open"></i> Project</h2>
|
||||
|
||||
<aside class="project-form-side">
|
||||
{% include 'library/_project_form_side.html' with form=project_form %}
|
||||
</aside>
|
||||
<div class="form-group">
|
||||
{{ project_form.title.errors }}
|
||||
<label for="{{ project_form.title.id_for_label }}">Title</label>
|
||||
{{ project_form.title }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ project_form.summary.errors }}
|
||||
<label for="{{ project_form.summary.id_for_label }}">Summary</label>
|
||||
{{ project_form.summary }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ project_form.category.errors }}
|
||||
<label for="{{ project_form.category.id_for_label }}">Category</label>
|
||||
{{ project_form.category }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ project_form.description.errors }}
|
||||
<label for="{{ project_form.description.id_for_label }}">Description</label>
|
||||
{{ project_form.description }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="create-panel">
|
||||
<h2 class="form-section-title"><i class="fas fa-image"></i> Thumbnail</h2>
|
||||
<div class="upload-zone" data-upload="thumbnail">
|
||||
<div class="drop-zone" role="button" tabindex="0">
|
||||
<div class="drop-zone-inner">
|
||||
<i class="fas fa-cloud-upload-alt drop-zone-icon"></i>
|
||||
<p class="drop-zone-text">Drag & drop an image</p>
|
||||
<p class="drop-zone-sub">or click to browse</p>
|
||||
</div>
|
||||
</div>
|
||||
<input type="file" id="thumb-input" accept="image/*" hidden>
|
||||
<div class="upload-preview" id="thumb-preview"></div>
|
||||
</div>
|
||||
|
||||
<h2 class="form-section-title" style="margin-top:16px;"><i class="fas fa-tags"></i> Tags</h2>
|
||||
<div class="tag-editor">
|
||||
<input type="text" id="tag-input" placeholder="Type a tag and press Enter… (e.g. content:threesome, species:dragon)" autocomplete="off">
|
||||
<div class="tag-suggestions" id="tag-suggestions" hidden></div>
|
||||
<div class="tag-chips" id="tag-chips"></div>
|
||||
{{ project_form.tags }}
|
||||
</div>
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Categories: loader, version, general, creator, content, species, non_version. Unprefixed tags go to General.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
@@ -27,5 +69,9 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
{{ pending_uploads|json_script:'packs-pending-uploads' }}
|
||||
{{ tag_categories|json_script:'packs-tag-categories' }}
|
||||
<script src="{% static 'js/tags.js' %}"></script>
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/edit.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,11 +7,52 @@
|
||||
<h1><i class="fas fa-upload"></i> New version — {{ project.title }}</h1>
|
||||
<p><a href="{% url 'library:project_detail' project.slug %}">← Back to project</a></p>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="card project-form">
|
||||
<form method="post" class="card project-form" id="version-form">
|
||||
{% csrf_token %}
|
||||
{% include 'library/_version_form_fields.html' with form=version_form %}
|
||||
{% if version_form.non_field_errors %}
|
||||
<div class="form-group">
|
||||
<ul class="messages">
|
||||
{% for error in version_form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="form-group">
|
||||
{{ version_form.version_name.errors }}
|
||||
<label for="{{ version_form.version_name.id_for_label }}">{{ version_form.version_name.label }}</label>
|
||||
{{ version_form.version_name }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Version file</label>
|
||||
<div class="upload-zone" data-upload="version">
|
||||
<div class="drop-zone" role="button" tabindex="0">
|
||||
<div class="drop-zone-inner">
|
||||
<i class="fas fa-cloud-upload-alt drop-zone-icon"></i>
|
||||
<p class="drop-zone-text">Drag & drop the pack file</p>
|
||||
<p class="drop-zone-sub">or click to browse</p>
|
||||
</div>
|
||||
</div>
|
||||
<input type="file" id="version-input" hidden>
|
||||
<div class="upload-preview" id="version-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ version_form.changelog.errors }}
|
||||
<label for="{{ version_form.changelog.id_for_label }}">{{ version_form.changelog.label }}</label>
|
||||
{{ version_form.changelog }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown.</p>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary"><i class="fas fa-upload"></i> Upload version</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
{{ pending_uploads|json_script:'packs-pending-uploads' }}
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/version_upload.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user