A simple way to edit images #7
|
|
@ -5,7 +5,10 @@ const processorFrame = Handlebars.compile(`
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<div class="card-header d-flex justify-content-between">
|
<div class="card-header d-flex justify-content-between">
|
||||||
<span>{{name}}</span>
|
<span>{{name}}</span>
|
||||||
<a href="#" class="btn btn-sm btn-secondary float-end">X</a>
|
<a href="#" class="btn btn-sm btn-secondary float-end"
|
||||||
|
data-action="edit-upload#removeProcessor"
|
||||||
|
data-edit-upload-id-param="{{id}}"
|
||||||
|
>X</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{{{props}}}
|
{{{props}}}
|
||||||
|
|
@ -13,14 +16,12 @@ const processorFrame = Handlebars.compile(`
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const processors = [
|
const processorUIs = {
|
||||||
{
|
"shadow": {
|
||||||
name: "shadow",
|
|
||||||
label: "Shadow",
|
label: "Shadow",
|
||||||
template: Handlebars.compile(`This processor has no properties.`),
|
template: Handlebars.compile(`This processor has no properties.`),
|
||||||
},
|
},
|
||||||
{
|
"resize": {
|
||||||
name: "resize",
|
|
||||||
label: "Resize",
|
label: "Resize",
|
||||||
template: Handlebars.compile(`
|
template: Handlebars.compile(`
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
|
@ -32,8 +33,8 @@ const processors = [
|
||||||
<input name="width" class="form-control" id="{{id}}_width">
|
<input name="width" class="form-control" id="{{id}}_width">
|
||||||
</div>
|
</div>
|
||||||
`),
|
`),
|
||||||
}
|
},
|
||||||
];
|
};
|
||||||
|
|
||||||
export default class UploadEditController extends Controller {
|
export default class UploadEditController extends Controller {
|
||||||
static targets = ['processList', 'preview'];
|
static targets = ['processList', 'preview'];
|
||||||
|
|
@ -54,19 +55,33 @@ export default class UploadEditController extends Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeProcessor(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
let id = ev.params.id;
|
||||||
|
console.log(ev.params);
|
||||||
|
await this._removeProcessor(id);
|
||||||
|
}
|
||||||
|
|
||||||
_rebuildProcessList() {
|
_rebuildProcessList() {
|
||||||
let el = this.processListTarget;
|
let el = this.processListTarget;
|
||||||
|
|
||||||
// TEMP
|
if ((!this._state) || (!this._state.session) || (!this._state.session.processors)) {
|
||||||
let cardTemplate = processors[0].template({
|
return;
|
||||||
"id": "shadow",
|
}
|
||||||
});
|
|
||||||
let cardOuter = processorFrame({
|
el.innerHTML = "";
|
||||||
name: processors[0].label,
|
for (let p of this._state.session.processors) {
|
||||||
props: cardTemplate,
|
let ui = processorUIs[p.type];
|
||||||
});
|
if (!ui) {
|
||||||
el.innerHTML = cardOuter;
|
continue;
|
||||||
// END TEMP
|
}
|
||||||
|
let cardOuter = processorFrame({
|
||||||
|
id: p.id,
|
||||||
|
name: ui.label,
|
||||||
|
props: ui.template(p),
|
||||||
|
});
|
||||||
|
el.innerHTML += cardOuter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createSession() {
|
async _createSession() {
|
||||||
|
|
@ -83,9 +98,9 @@ export default class UploadEditController extends Controller {
|
||||||
});
|
});
|
||||||
|
|
||||||
this._state = await resp.json();
|
this._state = await resp.json();
|
||||||
this.previewTarget.src = this._state.preview_url;
|
|
||||||
|
|
||||||
console.log("Session created");
|
this._rebuildProcessList();
|
||||||
|
this.previewTarget.src = this._state.preview_url;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
@ -103,9 +118,31 @@ export default class UploadEditController extends Controller {
|
||||||
});
|
});
|
||||||
|
|
||||||
this._state = await resp.json();
|
this._state = await resp.json();
|
||||||
|
|
||||||
|
this._rebuildProcessList();
|
||||||
this.previewTarget.src = this._state.preview_url;
|
this.previewTarget.src = this._state.preview_url;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -154,6 +154,7 @@ Starting weiro without any arguments will start the server.
|
||||||
|
|
||||||
siteGroup.Post("/imageedit", ieh.Create)
|
siteGroup.Post("/imageedit", ieh.Create)
|
||||||
siteGroup.Post("/imageedit/:sessionID/processors", ieh.AddProcessor)
|
siteGroup.Post("/imageedit/:sessionID/processors", ieh.AddProcessor)
|
||||||
|
siteGroup.Delete("/imageedit/:sessionID/processors/:processorID", ieh.DeleteProcessor)
|
||||||
siteGroup.Get("/imageedit/:sessionID/preview/:versionID", ieh.Preview)
|
siteGroup.Get("/imageedit/:sessionID/preview/:versionID", ieh.Preview)
|
||||||
|
|
||||||
siteGroup.Get("/settings", ssh.General)
|
siteGroup.Get("/settings", ssh.General)
|
||||||
|
|
|
||||||
|
|
@ -91,3 +91,25 @@ func (ieh ImageEditHandlers) AddProcessor(c fiber.Ctx) error {
|
||||||
PreviewURL: res.PreviewURL(),
|
PreviewURL: res.PreviewURL(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ieh ImageEditHandlers) DeleteProcessor(c fiber.Ctx) error {
|
||||||
|
sessionID := c.Params("sessionID")
|
||||||
|
if sessionID == "" {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
processorID := c.Params("processorID")
|
||||||
|
if processorID == "" {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := ieh.ImageEditService.DeleteProcessor(c.Context(), sessionID, processorID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(http.StatusOK).JSON(sessionResponse{
|
||||||
|
Session: res,
|
||||||
|
PreviewURL: res.PreviewURL(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
|
@ -46,6 +47,8 @@ func (s *Service) reprocess(ctx context.Context, session *models.ImageEditSessio
|
||||||
img = imageImageSource{resImg}
|
img = imageImageSource{resImg}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("result of processed image: %T", img)
|
||||||
|
|
||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"lmika.dev/lmika/weiro/models"
|
"lmika.dev/lmika/weiro/models"
|
||||||
"lmika.dev/lmika/weiro/services/uploads"
|
"lmika.dev/lmika/weiro/services/uploads"
|
||||||
|
"lmika.dev/pkg/modash/moslice"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
|
@ -114,6 +115,25 @@ func (s *Service) AddProcessor(ctx context.Context, sessionID string, req AddPro
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) DeleteProcessor(ctx context.Context, sessionID, processorID string) (*models.ImageEditSession, error) {
|
||||||
|
session, err := s.loadAndVerifySession(ctx, sessionID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Processors = moslice.Filter(session.Processors, func(p models.ImageEditProcessor) bool { return p.ID != processorID })
|
||||||
|
session.RecalcVersionIDs()
|
||||||
|
if err := s.sessionStore.save(session); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.reprocess(ctx, session); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) loadAndVerifySession(ctx context.Context, sessionID string) (*models.ImageEditSession, error) {
|
func (s *Service) loadAndVerifySession(ctx context.Context, sessionID string) (*models.ImageEditSession, error) {
|
||||||
site, user, err := s.fetchSiteAndUser(ctx)
|
site, user, err := s.fetchSiteAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue