Furumi init
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
{% extends "admin/layout.html" %}
|
||||
{% block admin_title %}{% if is_edit %}{{ t.artists_edit_heading }}{% else %}{{ t.artists_new_heading }}{% endif %}{% endblock admin_title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% if is_edit %}{{ t.artists_edit_heading }}{% else %}{{ t.artists_new_heading }}{% endif %}</h1>
|
||||
|
||||
<form method="post" action="{% if is_edit %}/admin/artists/{{ form_artist_id }}/edit{% else %}/admin/artists/new{% endif %}">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="name">{{ t.artists_name }}</label></td>
|
||||
<td><input name="name" id="name" value="{{ form_name }}" required style="width:100%"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="submit" style="margin-top: 1rem; padding: .5rem 1.5rem;">{{ t.settings_save }}</button>
|
||||
</form>
|
||||
|
||||
{% if is_edit %}
|
||||
<hr style="margin: 2rem 0;">
|
||||
<h2>{{ t.artists_image }}</h2>
|
||||
|
||||
<div id="artist-image-section" style="margin-top: 1rem;">
|
||||
<!-- Current image -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
{% match current_image_url %}
|
||||
{% when Some with (url) %}
|
||||
<img id="current-image" src="{{ url }}" alt="" style="max-width: 200px; max-height: 200px; border-radius: 6px; border: 1px solid #ddd;">
|
||||
<br>
|
||||
<button type="button" onclick="removeImage()" style="margin-top: .5rem; padding: .3rem 1rem; cursor: pointer;">{{ t.artists_remove_image }}</button>
|
||||
{% when None %}
|
||||
<p style="color: #888;">{{ t.artists_no_image }}</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
|
||||
<!-- Upload custom image -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h3 style="font-size: .95rem; margin-bottom: .5rem;">{{ t.artists_upload_image }}</h3>
|
||||
<input type="file" id="image-upload" accept="image/*" style="margin-bottom: .5rem;">
|
||||
<br>
|
||||
<button type="button" id="upload-btn" onclick="uploadImage()" style="padding: .3rem 1rem; cursor: pointer;" disabled>{{ t.artists_upload }}</button>
|
||||
</div>
|
||||
|
||||
<!-- Pick from album covers -->
|
||||
<div>
|
||||
<h3 style="font-size: .95rem; margin-bottom: .5rem;">{{ t.artists_pick_cover }}</h3>
|
||||
<div id="covers-grid" style="display: flex; flex-wrap: wrap; gap: .75rem;">
|
||||
<p style="color: #888;" id="covers-loading">...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const artistId = {{ form_artist_id }};
|
||||
|
||||
// Enable upload button when file selected
|
||||
document.getElementById('image-upload').addEventListener('change', function() {
|
||||
document.getElementById('upload-btn').disabled = !this.files.length;
|
||||
});
|
||||
|
||||
// Upload custom image
|
||||
function uploadImage() {
|
||||
const fileInput = document.getElementById('image-upload');
|
||||
const file = fileInput.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
const base64 = reader.result.split(',')[1];
|
||||
fetch('/admin/artists/' + artistId + '/upload-image', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
data: base64,
|
||||
filename: file.name,
|
||||
mime_type: file.type || 'image/jpeg'
|
||||
})
|
||||
}).then(function(r) {
|
||||
if (r.ok) location.reload();
|
||||
else r.text().then(function(t) { alert('Error: ' + t); });
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
// Set image from album cover
|
||||
function setImage(mediaFileId) {
|
||||
fetch('/admin/artists/' + artistId + '/set-image', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ media_file_id: mediaFileId })
|
||||
}).then(function(r) {
|
||||
if (r.ok) location.reload();
|
||||
else r.text().then(function(t) { alert('Error: ' + t); });
|
||||
});
|
||||
}
|
||||
|
||||
// Remove image
|
||||
function removeImage() {
|
||||
fetch('/admin/artists/' + artistId + '/set-image', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ media_file_id: null })
|
||||
}).then(function(r) {
|
||||
if (r.ok) location.reload();
|
||||
else r.text().then(function(t) { alert('Error: ' + t); });
|
||||
});
|
||||
}
|
||||
|
||||
// Load available covers
|
||||
fetch('/admin/artists/' + artistId + '/available-covers')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(covers) {
|
||||
const grid = document.getElementById('covers-grid');
|
||||
grid.innerHTML = '';
|
||||
if (!covers.length) {
|
||||
grid.innerHTML = '<p style="color: #888;">{{ t.artists_no_covers }}</p>';
|
||||
return;
|
||||
}
|
||||
covers.forEach(function(c) {
|
||||
const div = document.createElement('div');
|
||||
div.style.cssText = 'cursor:pointer; text-align:center;';
|
||||
div.title = c.release_title;
|
||||
div.innerHTML = '<img src="' + c.cover_url + '" alt="" style="width:100px; height:100px; object-fit:cover; border-radius:4px; border:2px solid #ddd;">'
|
||||
+ '<br><small style="font-size:.75rem; color:#666;">' + c.release_title.substring(0, 20) + '</small>';
|
||||
div.onclick = function() { setImage(c.media_file_id); };
|
||||
grid.appendChild(div);
|
||||
});
|
||||
})
|
||||
.catch(function() {
|
||||
document.getElementById('covers-grid').innerHTML = '<p style="color: #888;">{{ t.artists_no_covers }}</p>';
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
Reference in New Issue
Block a user