weiro/assets/js/controllers/edit_upload.js

157 lines
4.6 KiB
JavaScript
Raw Normal View History

2026-03-25 10:09:57 +00:00
import Handlebars from "handlebars";
import {Controller} from "@hotwired/stimulus";
2026-03-26 11:14:57 +00:00
Handlebars.registerHelper("submit_on", function (id, event) {
return `data-action="${event}->edit-upload#updateProcessor" data-edit-upload-id-param="${id}"`
});
2026-03-25 10:09:57 +00:00
const processorFrame = Handlebars.compile(`
<div class="card mb-3">
<div class="card-header d-flex justify-content-between">
<span>{{name}}</span>
2026-03-26 10:44:20 +00:00
<a href="#" class="btn btn-sm btn-secondary float-end"
data-action="edit-upload#removeProcessor"
data-edit-upload-id-param="{{id}}"
>X</a>
2026-03-25 10:09:57 +00:00
</div>
<div class="card-body">
2026-03-26 11:14:57 +00:00
<form data-role="processor-params" data-params-id="{{id}}">{{{props}}}</form>
2026-03-25 10:09:57 +00:00
</div>
</div>
`);
2026-03-26 10:44:20 +00:00
const processorUIs = {
"shadow": {
2026-03-25 10:09:57 +00:00
label: "Shadow",
2026-03-26 11:14:57 +00:00
template: Handlebars.compile(`
<div class="mb-3">
<label for="{{id}}_width" class="form-label">Colour</label>
<input name="width" class="form-control" id="{{id}}_{{props.color}}" type="color" value="{{color}}" {{{submit_on id 'change'}}}>
</div>
`),
2026-03-25 10:09:57 +00:00
},
2026-03-26 10:44:20 +00:00
"resize": {
2026-03-25 10:09:57 +00:00
label: "Resize",
template: Handlebars.compile(`
<div class="mb-3">
<label for="{{id}}_width" class="form-label">Width</label>
<input name="width" class="form-control" id="{{id}}_width">
</div>
<div class="mb-3">
<label for="{{id}}_height" class="form-label">Height</label>
<input name="width" class="form-control" id="{{id}}_width">
</div>
`),
2026-03-26 10:44:20 +00:00
},
};
2026-03-25 10:09:57 +00:00
export default class UploadEditController extends Controller {
2026-03-25 11:35:53 +00:00
static targets = ['processList', 'preview'];
static values = {
uploadId: Number,
siteId: Number,
};
2026-03-25 10:09:57 +00:00
connect() {
this._rebuildProcessList();
2026-03-25 11:35:53 +00:00
this._createSession();
2026-03-25 10:09:57 +00:00
}
async addProcessor(ev) {
ev.preventDefault();
await this._addProcessor({
type: "shadow"
});
}
2026-03-26 10:44:20 +00:00
async removeProcessor(ev) {
ev.preventDefault();
let id = ev.params.id;
console.log(ev.params);
await this._removeProcessor(id);
}
2026-03-25 10:09:57 +00:00
_rebuildProcessList() {
let el = this.processListTarget;
2026-03-26 10:44:20 +00:00
if ((!this._state) || (!this._state.session) || (!this._state.session.processors)) {
return;
}
el.innerHTML = "";
for (let p of this._state.session.processors) {
let ui = processorUIs[p.type];
if (!ui) {
continue;
}
let cardOuter = processorFrame({
id: p.id,
name: ui.label,
props: ui.template(p),
});
el.innerHTML += cardOuter;
}
2026-03-25 10:09:57 +00:00
}
2026-03-25 11:35:53 +00:00
async _createSession() {
try {
let resp = await fetch(`/sites/${this.siteIdValue}/imageedit/`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
2026-03-25 11:35:53 +00:00
body: JSON.stringify({
"base_upload": this.uploadIdValue,
})
});
this._state = await resp.json();
2026-03-26 10:44:20 +00:00
this._rebuildProcessList();
this.previewTarget.src = this._state.preview_url;
2026-03-25 11:35:53 +00:00
} catch (e) {
console.error(e);
}
}
async _addProcessor(processor) {
try {
let resp = await fetch(`/sites/${this.siteIdValue}/imageedit/${this._state.session.guid}/processors`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(processor)
});
this._state = await resp.json();
2026-03-26 10:44:20 +00:00
this._rebuildProcessList();
this.previewTarget.src = this._state.preview_url;
} catch (e) {
console.error(e);
}
}
async _removeProcessor(processorID) {
await this._doReturningState(async () => {
return (await fetch(`/sites/${this.siteIdValue}/imageedit/${this._state.session.guid}/processors/${processorID}`, {
method: 'DELETE',
})).json();
})
}
async _doReturningState(fn) {
try {
this._state = await fn();
this._rebuildProcessList();
this.previewTarget.src = this._state.preview_url;
} catch (e) {
console.error(e);
}
2026-03-26 10:44:20 +00:00
}
2026-03-25 10:09:57 +00:00
}