@feedmepos/mf-media 0.0.9 → 0.0.10-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,792 +0,0 @@
1
- import { defineComponent as j, computed as S, resolveComponent as B, openBlock as c, createElementBlock as y, createElementVNode as t, normalizeStyle as ee, createVNode as k, toDisplayString as d, unref as a, createCommentVNode as A, normalizeClass as V, createTextVNode as oe, createBlock as q, Fragment as M, renderList as O, mergeModels as H, useModel as G, renderSlot as ae, withCtx as te, ref as E, withDirectives as ne, vModelText as ie, onMounted as le } from "vue";
2
- import { defineStore as re, storeToRefs as de } from "pinia";
3
- import { useI18n as N, useCoreStore as ce } from "@feedmepos/mf-common";
4
- import { useDialog as ue, useSnackbar as me } from "@feedmepos/ui-library";
5
- import { z as W, x as fe, G as pe, K as ve } from "./media-picker-e86c4195.js";
6
- const xe = { class: "rounded-xl border border-fm-color-neutral-gray-200 bg-white overflow-hidden" }, ge = ["src", "alt"], ye = {
7
- key: 1,
8
- class: "absolute inset-0 flex flex-col items-center justify-center gap-4 p-12 text-center"
9
- }, be = { class: "text-xs font-semibold" }, he = { class: "text-xs text-fm-color-typo-secondary line-clamp-3" }, _e = {
10
- key: 2,
11
- class: "absolute inset-0 flex items-center justify-center"
12
- }, $e = { class: "flex flex-col items-center gap-8" }, ke = { class: "text-xs text-fm-color-typo-secondary" }, Ie = {
13
- key: 3,
14
- class: "absolute left-8 top-8 px-4 py-4 rounded text-xs font-bold bg-black/60 text-white"
15
- }, we = {
16
- key: 0,
17
- class: "flex items-center gap-4 px-8 py-8"
18
- }, Te = { class: "flex-1 text-xs text-fm-color-typo-secondary truncate" }, Ce = ["title"], Fe = ["title"], Se = ["title"], Re = {
19
- key: 1,
20
- class: "flex justify-end px-8 py-8"
21
- }, Y = "w-32 h-32 rounded-md flex items-center justify-center text-fm-color-typo-secondary hover:bg-fm-color-neutral-gray-100", Be = /* @__PURE__ */ j({
22
- __name: "StudioImageCard",
23
- props: {
24
- item: {},
25
- ratio: {},
26
- fromRef: { type: Boolean }
27
- },
28
- emits: ["preview", "variant", "discard", "save"],
29
- setup(e, { emit: f }) {
30
- const s = e, l = f, { t: r } = N(), m = S(() => s.item.status === "success" && !!s.item.url), p = S(() => s.item.status === "failed"), w = S(() => s.ratio.replace("x", " / ")), n = S(
31
- () => s.item.width && s.item.height ? `${s.item.width}×${s.item.height}` : ""
32
- );
33
- return ($, g) => {
34
- const C = B("FmIcon"), T = B("FmCircularProgress"), F = B("FmButton");
35
- return c(), y("div", xe, [
36
- t("div", {
37
- class: "relative bg-fm-color-neutral-gray-100",
38
- style: ee({ aspectRatio: w.value })
39
- }, [
40
- m.value ? (c(), y("img", {
41
- key: 0,
42
- src: e.item.url,
43
- class: "w-full h-full object-cover",
44
- alt: n.value
45
- }, null, 8, ge)) : p.value ? (c(), y("div", ye, [
46
- k(C, {
47
- name: "error_outline",
48
- size: "md"
49
- }),
50
- t("span", be, d(a(r)("media.studio.failed")), 1),
51
- t("span", he, d(e.item.error), 1)
52
- ])) : (c(), y("div", _e, [
53
- t("div", $e, [
54
- k(T, { size: "md" }),
55
- t("span", ke, d(a(r)("media.studio.rendering")), 1)
56
- ])
57
- ])),
58
- m.value ? (c(), y("span", Ie, d(e.fromRef ? a(r)("media.studio.refTag") : a(r)("media.studio.aiTag")), 1)) : A("", !0)
59
- ], 4),
60
- m.value ? (c(), y("div", we, [
61
- t("span", Te, d(n.value), 1),
62
- t("button", {
63
- type: "button",
64
- class: V(Y),
65
- title: a(r)("media.studio.preview"),
66
- onClick: g[0] || (g[0] = (u) => l("preview"))
67
- }, [
68
- k(C, {
69
- name: "open_in_full",
70
- size: "sm"
71
- })
72
- ], 8, Ce),
73
- t("button", {
74
- type: "button",
75
- class: V(Y),
76
- title: a(r)("media.studio.variant"),
77
- onClick: g[1] || (g[1] = (u) => l("variant"))
78
- }, [
79
- k(C, {
80
- name: "add_photo_alternate",
81
- size: "sm"
82
- })
83
- ], 8, Fe),
84
- t("button", {
85
- type: "button",
86
- class: V(Y),
87
- title: a(r)("media.studio.discard"),
88
- onClick: g[2] || (g[2] = (u) => l("discard"))
89
- }, [
90
- k(C, {
91
- name: "delete",
92
- size: "sm"
93
- })
94
- ], 8, Se),
95
- k(F, {
96
- label: e.item.saved ? a(r)("media.studio.saved") : a(r)("media.studio.save"),
97
- variant: "primary",
98
- size: "md",
99
- disabled: e.item.saved,
100
- onClick: g[3] || (g[3] = (u) => l("save"))
101
- }, null, 8, ["label", "disabled"])
102
- ])) : p.value ? (c(), y("div", Re, [
103
- k(F, {
104
- label: a(r)("media.studio.retry"),
105
- variant: "tertiary",
106
- size: "md",
107
- onClick: g[4] || (g[4] = (u) => l("variant"))
108
- }, null, 8, ["label"])
109
- ])) : A("", !0)
110
- ]);
111
- };
112
- }
113
- }), ze = { class: "flex flex-col gap-12" }, Ee = { class: "flex items-center gap-12" }, Pe = { class: "flex-1 min-w-0 flex flex-col gap-4" }, Ue = { class: "text-sm font-semibold line-clamp-2" }, Ae = { class: "text-xs text-fm-color-typo-secondary" }, De = {
114
- key: 0,
115
- class: "flex items-center gap-4 text-xs font-semibold"
116
- }, Me = { class: "grid gap-16 grid-cols-[repeat(auto-fill,minmax(min(240px,100%),1fr))]" }, Oe = /* @__PURE__ */ j({
117
- __name: "StudioBatch",
118
- props: {
119
- batch: {}
120
- },
121
- emits: ["regenerate", "preview", "variant", "discard", "save"],
122
- setup(e, { emit: f }) {
123
- const s = e, l = f, { t: r } = N(), m = S(
124
- () => s.batch.items.some((n) => n.status === "pending" || n.status === "processing")
125
- ), p = S(
126
- () => !!(s.batch.params.refAssetId || s.batch.params.refTmpToken)
127
- ), w = S(() => {
128
- const n = {
129
- style: r(`media.studio.styles.${s.batch.params.style}`),
130
- ratio: s.batch.params.ratio,
131
- count: s.batch.items.length
132
- };
133
- return p.value ? r("media.studio.batchMetaRef", { ...n, strength: s.batch.params.refStrength ?? 55 }) : r("media.studio.batchMeta", n);
134
- });
135
- return (n, $) => {
136
- const g = B("FmCircularProgress"), C = B("FmButton");
137
- return c(), y("div", ze, [
138
- t("div", Ee, [
139
- t("div", Pe, [
140
- t("span", Ue, d(e.batch.params.prompt), 1),
141
- t("span", Ae, d(w.value), 1)
142
- ]),
143
- m.value ? (c(), y("span", De, [
144
- k(g, { size: "md" }),
145
- oe(" " + d(a(r)("media.studio.generating")), 1)
146
- ])) : (c(), q(C, {
147
- key: 1,
148
- label: a(r)("media.studio.regenerate"),
149
- variant: "tertiary",
150
- size: "md",
151
- "prepend-icon": "refresh",
152
- onClick: $[0] || ($[0] = (T) => l("regenerate"))
153
- }, null, 8, ["label"]))
154
- ]),
155
- t("div", Me, [
156
- (c(!0), y(M, null, O(e.batch.items, (T) => (c(), q(Be, {
157
- key: T.taskId,
158
- item: T,
159
- ratio: e.batch.params.ratio,
160
- "from-ref": p.value,
161
- onPreview: (F) => l("preview", T),
162
- onVariant: $[1] || ($[1] = (F) => l("variant")),
163
- onDiscard: (F) => l("discard", T),
164
- onSave: (F) => l("save", T)
165
- }, null, 8, ["item", "ratio", "from-ref", "onPreview", "onDiscard", "onSave"]))), 128))
166
- ])
167
- ]);
168
- };
169
- }
170
- }), Ve = [
171
- "none",
172
- "photo",
173
- "flatlay",
174
- "studio",
175
- "warm",
176
- "illus"
177
- ], je = ["1x1", "4x3", "3x4", "16x9"], Ne = [1, 2, 4];
178
- function J(e) {
179
- return `/media-v1/businesses/${e}/generations`;
180
- }
181
- async function Le(e, f) {
182
- const { data: s } = await W().post(J(e), f);
183
- return s;
184
- }
185
- async function Ge(e, f) {
186
- const { data: s } = await W().get(
187
- `${J(e)}/${f}`
188
- );
189
- return s;
190
- }
191
- async function qe(e, f) {
192
- const { data: s } = await W().post(
193
- `${J(e)}/ref-upload-intent`,
194
- f
195
- );
196
- return s;
197
- }
198
- async function He(e, f) {
199
- const s = await fetch(e.uploadUrl, {
200
- method: e.method,
201
- headers: { "Content-Type": f.type },
202
- body: f
203
- });
204
- if (!s.ok)
205
- throw new Error(`reference upload failed: ${s.status} ${await s.text()}`);
206
- }
207
- const Ke = { class: "w-[320px] max-h-screen overflow-auto flex flex-col gap-16 p-16 rounded-xl border border-fm-color-neutral-gray-200 bg-white sticky top-0 self-start" }, Ye = { class: "flex flex-col gap-8" }, We = { class: "flex items-baseline gap-8" }, Je = { class: "text-sm font-semibold" }, Qe = { class: "text-xs text-fm-color-typo-tertiary" }, Xe = { class: "grid grid-cols-2 gap-8" }, Ze = ["onClick"], et = { class: "flex items-center gap-8" }, tt = { class: "text-sm font-semibold" }, st = { class: "text-xs text-fm-color-typo-secondary" }, ot = { class: "flex flex-col gap-8" }, at = {
208
- key: 0,
209
- class: "flex items-center gap-8 px-8 py-8 rounded-lg bg-[#FFF7F0]"
210
- }, nt = { class: "text-xs" }, it = { class: "flex flex-col gap-8" }, lt = { class: "text-sm font-semibold" }, rt = { class: "flex flex-wrap gap-4" }, dt = { class: "flex flex-col gap-8" }, ct = { class: "text-sm font-semibold" }, ut = { class: "grid grid-cols-2 gap-8" }, mt = ["onClick"], ft = { class: "text-fm-color-typo-secondary" }, pt = { class: "flex flex-col gap-8" }, vt = { class: "text-sm font-semibold" }, xt = { class: "flex gap-8" }, gt = ["onClick"], yt = { class: "flex flex-col gap-8 sticky bottom-0 bg-white pt-12" }, bt = { class: "text-xs text-fm-color-typo-tertiary text-center" }, ht = "border-[--fm-color-brand-primary,#FF7823] bg-[#FFF7F0]", _t = "border-fm-color-neutral-gray-200 bg-white", $t = /* @__PURE__ */ j({
211
- __name: "StudioControls",
212
- props: /* @__PURE__ */ H({
213
- busy: { type: Boolean },
214
- hasRef: { type: Boolean }
215
- }, {
216
- prompt: { required: !0 },
217
- promptModifiers: {},
218
- style: { required: !0 },
219
- styleModifiers: {},
220
- ratio: { required: !0 },
221
- ratioModifiers: {},
222
- count: { required: !0 },
223
- countModifiers: {}
224
- }),
225
- emits: /* @__PURE__ */ H(["generate"], ["update:prompt", "update:style", "update:ratio", "update:count"]),
226
- setup(e, { emit: f }) {
227
- const s = e, l = G(e, "prompt"), r = G(e, "style"), m = G(e, "ratio"), p = G(e, "count"), w = f, { t: n } = N(), $ = ["hero", "banner", "social", "menu"], g = {
228
- hero: "restaurant",
229
- banner: "campaign",
230
- social: "photo_camera",
231
- menu: "menu_book"
232
- }, C = S(
233
- () => $.map((o) => ({
234
- key: o,
235
- icon: g[o],
236
- name: n(`media.studio.tpl.${o}.name`),
237
- desc: n(`media.studio.tpl.${o}.desc`),
238
- prompt: n(`media.studio.tpl.${o}.prompt`)
239
- }))
240
- ), T = S(
241
- () => {
242
- var o;
243
- return (o = C.value.find((v) => v.prompt === l.value)) == null ? void 0 : o.key;
244
- }
245
- ), F = S(() => /\[[^\]]+\]/.test(l.value)), u = S(() => l.value.trim().length > 0 && !s.busy);
246
- function i(o) {
247
- return o ? ht : _t;
248
- }
249
- return (o, v) => {
250
- const _ = B("FmIcon"), R = B("FmTextarea"), K = B("FmChip"), z = B("FmButton");
251
- return c(), y("div", Ke, [
252
- t("div", Ye, [
253
- t("div", We, [
254
- t("span", Je, d(a(n)("media.studio.templates")), 1),
255
- t("span", Qe, d(a(n)("media.studio.templatesHint")), 1)
256
- ]),
257
- t("div", Xe, [
258
- (c(!0), y(M, null, O(C.value, (b) => (c(), y("button", {
259
- key: b.key,
260
- type: "button",
261
- class: V(["flex flex-col items-start gap-4 p-12 rounded-lg border text-left", i(T.value === b.key)]),
262
- onClick: (L) => l.value = b.prompt
263
- }, [
264
- t("span", et, [
265
- k(_, {
266
- name: b.icon,
267
- size: "sm"
268
- }, null, 8, ["name"]),
269
- t("span", tt, d(b.name), 1)
270
- ]),
271
- t("span", st, d(b.desc), 1)
272
- ], 10, Ze))), 128))
273
- ])
274
- ]),
275
- t("div", ot, [
276
- k(R, {
277
- modelValue: l.value,
278
- "onUpdate:modelValue": v[0] || (v[0] = (b) => l.value = b),
279
- label: a(n)("media.studio.prompt"),
280
- placeholder: e.hasRef ? a(n)("media.studio.promptPlaceholderRef") : a(n)("media.studio.promptPlaceholder"),
281
- "max-length": 500,
282
- "show-word-count": ""
283
- }, null, 8, ["modelValue", "label", "placeholder"]),
284
- F.value ? (c(), y("div", at, [
285
- k(_, {
286
- name: "info",
287
- size: "sm"
288
- }),
289
- t("span", nt, d(a(n)("media.studio.slotHint")), 1)
290
- ])) : A("", !0)
291
- ]),
292
- ae(o.$slots, "default"),
293
- t("div", it, [
294
- t("span", lt, d(a(n)("media.studio.style")), 1),
295
- t("div", rt, [
296
- (c(!0), y(M, null, O(a(Ve), (b) => (c(), q(K, {
297
- key: b,
298
- label: a(n)(`media.studio.styles.${b}`),
299
- selected: r.value === b,
300
- selectable: "",
301
- compact: "",
302
- onClick: (L) => r.value = b
303
- }, null, 8, ["label", "selected", "onClick"]))), 128))
304
- ])
305
- ]),
306
- t("div", dt, [
307
- t("span", ct, d(a(n)("media.studio.ratio")), 1),
308
- t("div", ut, [
309
- (c(!0), y(M, null, O(a(je), (b) => (c(), y("button", {
310
- key: b,
311
- type: "button",
312
- class: V(["flex items-center justify-center gap-4 h-40 rounded-lg border text-xs font-semibold", i(m.value === b)]),
313
- onClick: (L) => m.value = b
314
- }, [
315
- t("span", null, d(b), 1),
316
- t("span", ft, d(a(n)(`media.studio.ratios.${b}`)), 1)
317
- ], 10, mt))), 128))
318
- ])
319
- ]),
320
- t("div", pt, [
321
- t("span", vt, d(a(n)("media.studio.count")), 1),
322
- t("div", xt, [
323
- (c(!0), y(M, null, O(a(Ne), (b) => (c(), y("button", {
324
- key: b,
325
- type: "button",
326
- class: V(["flex-1 h-40 rounded-lg border text-sm font-semibold", i(p.value === b)]),
327
- onClick: (L) => p.value = b
328
- }, " × " + d(b), 11, gt))), 128))
329
- ])
330
- ]),
331
- t("div", yt, [
332
- k(z, {
333
- label: e.busy ? a(n)("media.studio.generateBusy") : a(n)("media.studio.generate"),
334
- "prepend-icon": "auto_awesome",
335
- variant: "primary",
336
- size: "md",
337
- disabled: !u.value,
338
- onClick: v[1] || (v[1] = (b) => w("generate"))
339
- }, null, 8, ["label", "disabled"]),
340
- t("span", bt, d(a(n)("media.studio.disclaimer")), 1)
341
- ])
342
- ]);
343
- };
344
- }
345
- }), kt = {
346
- key: 0,
347
- class: "flex h-[560px]"
348
- }, It = { class: "flex-1 min-w-0 flex items-center justify-center bg-black p-16" }, wt = ["src", "alt"], Tt = { class: "w-[300px] flex-shrink-0 flex flex-col gap-12 p-16 overflow-y-auto" }, Ct = { class: "flex items-start justify-between gap-8" }, Ft = { class: "fm-typo-en-title-sm-600" }, St = ["title"], Rt = { class: "text-sm font-semibold break-words" }, Bt = { class: "text-xs text-fm-color-typo-secondary" }, zt = /* @__PURE__ */ j({
349
- __name: "StudioPreviewDialog",
350
- props: {
351
- item: {},
352
- prompt: {}
353
- },
354
- emits: ["close", "save", "variant"],
355
- setup(e, { emit: f }) {
356
- const s = e, l = f, { t: r } = N();
357
- return (m, p) => {
358
- const w = B("FmIcon"), n = B("FmButton"), $ = B("FmDialog");
359
- return c(), q($, {
360
- "model-value": !!s.item,
361
- "max-width": 920,
362
- "max-height": "560px",
363
- "content-class": "!p-0 studio-preview-dialog-content",
364
- "close-button": !1,
365
- "onUpdate:modelValue": p[3] || (p[3] = (g) => !g && l("close"))
366
- }, {
367
- default: te(() => [
368
- s.item ? (c(), y("div", kt, [
369
- t("div", It, [
370
- t("img", {
371
- src: s.item.url,
372
- class: "max-w-full max-h-full object-contain",
373
- alt: s.prompt
374
- }, null, 8, wt)
375
- ]),
376
- t("div", Tt, [
377
- t("div", Ct, [
378
- t("span", Ft, d(a(r)("media.studio.preview")), 1),
379
- t("button", {
380
- type: "button",
381
- class: "w-32 h-32 rounded-lg bg-fm-color-neutral-gray-100 flex items-center justify-center flex-shrink-0",
382
- title: a(r)("media.library.cancelButton"),
383
- onClick: p[0] || (p[0] = (g) => l("close"))
384
- }, [
385
- k(w, {
386
- name: "close",
387
- size: "sm"
388
- })
389
- ], 8, St)
390
- ]),
391
- t("span", Rt, d(s.prompt), 1),
392
- t("span", Bt, d(s.item.width) + "×" + d(s.item.height), 1),
393
- p[4] || (p[4] = t("div", { class: "flex-1" }, null, -1)),
394
- k(n, {
395
- label: a(r)("media.studio.variant"),
396
- variant: "tertiary",
397
- size: "md",
398
- onClick: p[1] || (p[1] = (g) => l("variant"))
399
- }, null, 8, ["label"]),
400
- k(n, {
401
- label: s.item.saved ? a(r)("media.studio.saved") : a(r)("media.studio.save"),
402
- variant: "primary",
403
- size: "md",
404
- disabled: s.item.saved,
405
- onClick: p[2] || (p[2] = (g) => l("save"))
406
- }, null, 8, ["label", "disabled"])
407
- ])
408
- ])) : A("", !0)
409
- ]),
410
- _: 1
411
- }, 8, ["model-value"]);
412
- };
413
- }
414
- }), Et = { class: "flex flex-col gap-8" }, Pt = { class: "flex items-baseline gap-8" }, Ut = { class: "text-sm font-semibold" }, At = { class: "text-xs text-fm-color-typo-tertiary" }, Dt = {
415
- key: 0,
416
- class: "flex items-center gap-8 p-8 rounded-lg border border-fm-color-neutral-gray-200"
417
- }, Mt = ["src"], Ot = { class: "flex-1 text-xs truncate" }, Vt = { class: "flex gap-8" }, jt = { class: "text-xs text-fm-color-typo-tertiary" }, Nt = {
418
- key: 2,
419
- class: "text-xs text-[--fm-color-typo-critical,#FF3B30]"
420
- }, Lt = {
421
- key: 3,
422
- class: "flex flex-col gap-4"
423
- }, Gt = { class: "flex items-baseline gap-8" }, qt = { class: "text-xs font-semibold" }, Ht = { class: "text-xs font-semibold" }, Kt = { class: "text-xs text-fm-color-typo-secondary" }, Yt = /* @__PURE__ */ j({
424
- __name: "StudioRefPicker",
425
- props: /* @__PURE__ */ H({
426
- businessId: {},
427
- restaurantId: {}
428
- }, {
429
- strength: { required: !0 },
430
- strengthModifiers: {}
431
- }),
432
- emits: /* @__PURE__ */ H(["change"], ["update:strength"]),
433
- setup(e, { emit: f }) {
434
- const s = e, l = G(e, "strength"), r = f, { t: m } = N(), p = E(!1), w = E(!1), n = E(""), $ = E(null), g = E(null), C = S(() => l.value <= 35 ? m("media.studio.refWeak") : l.value >= 70 ? m("media.studio.refStrong") : m("media.studio.refMid"));
435
- function T(i) {
436
- p.value = !1, n.value = "", $.value = { url: i.url, label: i.asset.fileName }, r("change", {
437
- refAssetId: i.asset.id,
438
- // null means the original was picked, and the request omits refRatio for that.
439
- refRatio: i.ratio ?? void 0,
440
- label: i.asset.fileName
441
- });
442
- }
443
- async function F(i) {
444
- var v;
445
- const o = (v = i.target.files) == null ? void 0 : v[0];
446
- if (o) {
447
- w.value = !0, n.value = "";
448
- try {
449
- const _ = await qe(s.businessId, {
450
- contentType: o.type,
451
- fileSize: o.size
452
- });
453
- await He(_, o), $.value = { url: URL.createObjectURL(o), label: o.name }, r("change", { refTmpToken: _.token, label: o.name });
454
- } catch (_) {
455
- n.value = _ instanceof Error ? _.message : String(_), $.value = null, r("change", null);
456
- } finally {
457
- w.value = !1, g.value && (g.value.value = "");
458
- }
459
- }
460
- }
461
- function u() {
462
- $.value = null, n.value = "", r("change", null);
463
- }
464
- return (i, o) => {
465
- const v = B("FmButton");
466
- return c(), y("div", Et, [
467
- t("div", Pt, [
468
- t("span", Ut, d(a(m)("media.studio.ref")), 1),
469
- t("span", At, d(a(m)("media.studio.refHint")), 1)
470
- ]),
471
- $.value ? (c(), y("div", Dt, [
472
- $.value.url ? (c(), y("img", {
473
- key: 0,
474
- src: $.value.url,
475
- class: "w-48 h-48 rounded object-cover",
476
- alt: ""
477
- }, null, 8, Mt)) : A("", !0),
478
- t("span", Ot, d($.value.label), 1),
479
- k(v, {
480
- label: a(m)("media.studio.refClear"),
481
- variant: "tertiary",
482
- size: "md",
483
- onClick: u
484
- }, null, 8, ["label"])
485
- ])) : (c(), y(M, { key: 1 }, [
486
- t("div", Vt, [
487
- k(v, {
488
- label: a(m)("media.studio.refPick"),
489
- variant: "tertiary",
490
- size: "md",
491
- class: "flex-1",
492
- onClick: o[0] || (o[0] = (_) => p.value = !0)
493
- }, null, 8, ["label"]),
494
- k(v, {
495
- label: a(m)("media.studio.refUpload"),
496
- variant: "tertiary",
497
- size: "md",
498
- class: "flex-1",
499
- disabled: w.value,
500
- onClick: o[1] || (o[1] = (_) => {
501
- var R;
502
- return (R = g.value) == null ? void 0 : R.click();
503
- })
504
- }, null, 8, ["label", "disabled"]),
505
- t("input", {
506
- ref_key: "fileInput",
507
- ref: g,
508
- type: "file",
509
- accept: "image/jpeg,image/png,image/webp",
510
- class: "hidden",
511
- onChange: F
512
- }, null, 544)
513
- ]),
514
- t("span", jt, d(a(m)("media.studio.refUploadHint")), 1)
515
- ], 64)),
516
- n.value ? (c(), y("span", Nt, d(n.value), 1)) : A("", !0),
517
- $.value ? (c(), y("div", Lt, [
518
- t("div", Gt, [
519
- t("span", qt, d(a(m)("media.studio.refStrength")), 1),
520
- o[4] || (o[4] = t("span", { class: "flex-1" }, null, -1)),
521
- t("span", Ht, d(l.value) + "%", 1)
522
- ]),
523
- ne(t("input", {
524
- "onUpdate:modelValue": o[2] || (o[2] = (_) => l.value = _),
525
- type: "range",
526
- min: "10",
527
- max: "90",
528
- step: "5",
529
- class: "w-full cursor-pointer accent-[--fm-color-brand-primary,#FF7823]"
530
- }, null, 512), [
531
- [
532
- ie,
533
- l.value,
534
- void 0,
535
- { number: !0 }
536
- ]
537
- ]),
538
- t("span", Kt, d(C.value), 1)
539
- ])) : A("", !0),
540
- k(a(fe), {
541
- open: p.value,
542
- "onUpdate:open": o[3] || (o[3] = (_) => p.value = _),
543
- "business-id": e.businessId,
544
- "restaurant-id": e.restaurantId,
545
- "allow-upload": !1,
546
- onSelect: T
547
- }, null, 8, ["open", "business-id", "restaurant-id"])
548
- ]);
549
- };
550
- }
551
- }), Wt = "ai", Jt = "ai-generated";
552
- function Qt(e) {
553
- return e === "success" || e === "failed";
554
- }
555
- function Z(e) {
556
- return e.some((f) => !Qt(f.status));
557
- }
558
- function Xt(e, f) {
559
- return e.map((s) => {
560
- const l = f.find((r) => r.taskId === s.taskId);
561
- return l ? { ...s, ...l, saved: s.saved } : s;
562
- });
563
- }
564
- function Zt(e) {
565
- const f = !!(e.refAssetId || e.refTmpToken);
566
- return {
567
- prompt: e.prompt.trim(),
568
- style: e.style,
569
- ratio: e.ratio,
570
- count: e.count,
571
- refAssetId: e.refAssetId,
572
- refRatio: e.refRatio,
573
- refTmpToken: e.refTmpToken,
574
- refStrength: f ? e.refStrength : void 0,
575
- restaurantId: e.restaurantId
576
- };
577
- }
578
- const es = 3e3, ts = re("mediaGeneration", () => {
579
- const e = E([]), f = S(() => e.value.some((u) => Z(u.items)));
580
- let s, l = "";
581
- function r(u, i) {
582
- const o = e.value.find((v) => v.batchId === u);
583
- o && (o.items = Xt(o.items, i));
584
- }
585
- function m() {
586
- s !== void 0 || !l || (s = setTimeout(async () => {
587
- s = void 0;
588
- const u = e.value.filter((i) => Z(i.items));
589
- for (const i of u)
590
- try {
591
- const o = await Ge(l, i.batchId);
592
- r(i.batchId, o.items);
593
- } catch {
594
- }
595
- f.value && m();
596
- }, es));
597
- }
598
- async function p(u, i) {
599
- l = u;
600
- const o = await Le(u, Zt(i));
601
- e.value.unshift({
602
- batchId: o.batchId,
603
- params: i,
604
- items: o.items.map((v) => ({
605
- taskId: v.taskId,
606
- assetId: v.assetId,
607
- imageId: v.imageId,
608
- status: v.status,
609
- attempts: 0,
610
- error: v.error,
611
- saved: !1
612
- }))
613
- }), m();
614
- }
615
- async function w(u, i) {
616
- await p(u, i);
617
- }
618
- async function n(u, i) {
619
- await p(u, { ...i.params });
620
- }
621
- async function $(u, i) {
622
- await p(u, { ...i.params, count: 1 });
623
- }
624
- async function g(u, i, o) {
625
- var _;
626
- await pe(u, o.assetId, [Jt]);
627
- const v = (_ = e.value.find((R) => R.batchId === i.batchId)) == null ? void 0 : _.items.find((R) => R.taskId === o.taskId);
628
- v && (v.saved = !0);
629
- }
630
- async function C(u, i, o) {
631
- await ve(u, [
632
- {
633
- refType: Wt,
634
- refId: i.batchId,
635
- imageId: o.imageId,
636
- aspectRatios: null
637
- }
638
- ]);
639
- const v = e.value.find((_) => _.batchId === i.batchId);
640
- v && (v.items = v.items.filter((_) => _.taskId !== o.taskId), v.items.length === 0 && (e.value = e.value.filter((_) => _.batchId !== i.batchId)));
641
- }
642
- function T(u) {
643
- l = u, f.value && m();
644
- }
645
- function F() {
646
- s !== void 0 && clearTimeout(s), s = void 0, e.value = [];
647
- }
648
- return { batches: e, busy: f, compose: w, regenerate: n, variantOf: $, save: g, discard: C, resume: T, reset: F };
649
- }), ss = { class: "flex items-start gap-24 p-24" }, os = { class: "flex-1 min-w-0 flex flex-col gap-24" }, as = {
650
- key: 0,
651
- class: "min-h-[340px] flex flex-col items-center justify-center gap-12 border-2 border-dashed border-fm-color-neutral-gray-300 rounded-2xl"
652
- }, ns = { class: "text-lg font-semibold" }, is = { class: "text-sm text-fm-color-typo-secondary" }, ms = /* @__PURE__ */ j({
653
- __name: "AiStudio",
654
- setup(e) {
655
- const f = ce(), { t: s } = N(), l = ue(), r = me(), m = S(() => {
656
- var h;
657
- return ((h = f.currentBusiness.value) == null ? void 0 : h.id) ?? "";
658
- }), p = S(() => {
659
- var h;
660
- return (h = f.currentRestaurant.value) == null ? void 0 : h._id;
661
- }), w = ts(), { batches: n, busy: $ } = de(w);
662
- le(() => w.resume(m.value));
663
- const g = E(""), C = E("photo"), T = E("1x1"), F = E(2), u = E(55), i = E(null), o = S(() => !!i.value);
664
- function v() {
665
- var h, x, P, U;
666
- return {
667
- prompt: g.value,
668
- style: C.value,
669
- ratio: T.value,
670
- count: F.value,
671
- refAssetId: (h = i.value) == null ? void 0 : h.refAssetId,
672
- refRatio: (x = i.value) == null ? void 0 : x.refRatio,
673
- refTmpToken: (P = i.value) == null ? void 0 : P.refTmpToken,
674
- refStrength: i.value ? u.value : void 0,
675
- refLabel: (U = i.value) == null ? void 0 : U.label,
676
- restaurantId: p.value
677
- };
678
- }
679
- function _(h) {
680
- var P, U;
681
- return ((U = (P = h == null ? void 0 : h.response) == null ? void 0 : P.data) == null ? void 0 : U.message) ?? (h instanceof Error ? h.message : String(h));
682
- }
683
- function R(h) {
684
- r.open({ type: "error", title: _(h) });
685
- }
686
- async function K() {
687
- try {
688
- await w.compose(m.value, v());
689
- } catch (h) {
690
- R(h);
691
- }
692
- }
693
- const z = E(null);
694
- async function b(h, x) {
695
- try {
696
- await w.save(m.value, h, x), r.open({ type: "success", title: s("media.studio.savedToast") });
697
- } catch (P) {
698
- R(P);
699
- }
700
- }
701
- function L(h, x) {
702
- l.open({
703
- title: s("media.studio.discardTitle"),
704
- message: s("media.studio.discardMessage"),
705
- primaryActions: { text: s("media.studio.discard"), close: !1, variant: "destructive" },
706
- secondaryActions: { text: s("media.library.cancelButton"), close: !0 }
707
- }).onPrimary(async () => {
708
- var P;
709
- try {
710
- await w.discard(m.value, h, x), ((P = z.value) == null ? void 0 : P.item.taskId) === x.taskId && (z.value = null), r.open({ type: "success", title: s("media.studio.discardedToast") });
711
- } catch (U) {
712
- R(U);
713
- }
714
- l.close();
715
- });
716
- }
717
- async function Q(h) {
718
- try {
719
- await w.variantOf(m.value, h);
720
- } catch (x) {
721
- R(x);
722
- }
723
- }
724
- async function se(h) {
725
- try {
726
- await w.regenerate(m.value, h);
727
- } catch (x) {
728
- R(x);
729
- }
730
- }
731
- return (h, x) => {
732
- var U, X;
733
- const P = B("FmIcon");
734
- return c(), y("div", ss, [
735
- k($t, {
736
- prompt: g.value,
737
- "onUpdate:prompt": x[2] || (x[2] = (I) => g.value = I),
738
- style: ee(C.value),
739
- "onUpdate:style": x[3] || (x[3] = (I) => C.value = I),
740
- ratio: T.value,
741
- "onUpdate:ratio": x[4] || (x[4] = (I) => T.value = I),
742
- count: F.value,
743
- "onUpdate:count": x[5] || (x[5] = (I) => F.value = I),
744
- class: "flex-shrink-0",
745
- busy: a($),
746
- "has-ref": o.value,
747
- onGenerate: K
748
- }, {
749
- default: te(() => [
750
- k(Yt, {
751
- strength: u.value,
752
- "onUpdate:strength": x[0] || (x[0] = (I) => u.value = I),
753
- "business-id": m.value,
754
- "restaurant-id": p.value,
755
- onChange: x[1] || (x[1] = (I) => i.value = I)
756
- }, null, 8, ["strength", "business-id", "restaurant-id"])
757
- ]),
758
- _: 1
759
- }, 8, ["prompt", "style", "ratio", "count", "busy", "has-ref"]),
760
- t("div", os, [
761
- a(n).length === 0 ? (c(), y("div", as, [
762
- k(P, {
763
- name: "auto_awesome",
764
- size: "xl"
765
- }),
766
- t("span", ns, d(a(s)("media.studio.emptyTitle")), 1),
767
- t("span", is, d(a(s)("media.studio.emptyHint")), 1)
768
- ])) : A("", !0),
769
- (c(!0), y(M, null, O(a(n), (I) => (c(), q(Oe, {
770
- key: I.batchId,
771
- batch: I,
772
- onRegenerate: (D) => se(I),
773
- onVariant: (D) => Q(I),
774
- onPreview: (D) => z.value = { batch: I, item: D },
775
- onDiscard: (D) => L(I, D),
776
- onSave: (D) => b(I, D)
777
- }, null, 8, ["batch", "onRegenerate", "onVariant", "onPreview", "onDiscard", "onSave"]))), 128))
778
- ]),
779
- k(zt, {
780
- item: ((U = z.value) == null ? void 0 : U.item) ?? null,
781
- prompt: ((X = z.value) == null ? void 0 : X.batch.params.prompt) ?? "",
782
- onClose: x[6] || (x[6] = (I) => z.value = null),
783
- onSave: x[7] || (x[7] = (I) => z.value && b(z.value.batch, z.value.item)),
784
- onVariant: x[8] || (x[8] = (I) => z.value && Q(z.value.batch))
785
- }, null, 8, ["item", "prompt"])
786
- ]);
787
- };
788
- }
789
- });
790
- export {
791
- ms as default
792
- };