@flonix/ig-embed 0.0.0-stage → 0.1.1
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.
- package/README.md +274 -2
- package/dist/flonix-ig.global.js +220 -0
- package/dist/flonix-ig.global.js.map +1 -0
- package/dist/index.d.mts +205 -0
- package/dist/index.d.ts +205 -0
- package/dist/index.js +1331 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1324 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +41 -4
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1324 @@
|
|
|
1
|
+
// src/logo-data.ts
|
|
2
|
+
var FLONIX_LOGO_PNG = "data:image/png;base64,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";
|
|
3
|
+
|
|
4
|
+
// src/branding.ts
|
|
5
|
+
function escapeHtml(value) {
|
|
6
|
+
return value.replace(
|
|
7
|
+
/[&<>"']/g,
|
|
8
|
+
(c) => c === "&" ? "&" : c === "<" ? "<" : c === ">" ? ">" : c === '"' ? """ : "'"
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
var WORDMARK_FONT = "Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif";
|
|
12
|
+
function flonixLogo(size = 20) {
|
|
13
|
+
return `<span class="flxig-brand" style="--flxig-logo-size:${size}px" role="img" aria-label="Flonix">
|
|
14
|
+
<span class="flxig-brand__chip">
|
|
15
|
+
<img class="flxig-brand__img" src="${FLONIX_LOGO_PNG}" alt="" draggable="false" />
|
|
16
|
+
</span>
|
|
17
|
+
<svg class="flxig-brand__wordmark" viewBox="0 0 55 22" fill="currentColor" aria-hidden="true">
|
|
18
|
+
<text x="0" y="19" font-size="22" font-weight="700" letter-spacing="-0.4" font-family="${WORDMARK_FONT}" textLength="55" lengthAdjust="spacingAndGlyphs">flonix</text>
|
|
19
|
+
</svg>
|
|
20
|
+
</span>`;
|
|
21
|
+
}
|
|
22
|
+
function cobrandLockup(partner) {
|
|
23
|
+
const name = escapeHtml(partner.name);
|
|
24
|
+
const light = escapeHtml(partner.logo);
|
|
25
|
+
const dark = partner.logoDark ? escapeHtml(partner.logoDark) : "";
|
|
26
|
+
const partnerImgs = dark ? `<img class="flxig-partner__img flxig-partner__img--light" src="${light}" alt="${name}" draggable="false" />
|
|
27
|
+
<img class="flxig-partner__img flxig-partner__img--dark" src="${dark}" alt="${name}" draggable="false" />` : `<img class="flxig-partner__img" src="${light}" alt="${name}" draggable="false" />`;
|
|
28
|
+
return `<span class="flxig-cobrand">
|
|
29
|
+
<span class="flxig-partner" data-has-dark="${dark ? "true" : "false"}">${partnerImgs}</span>
|
|
30
|
+
<span class="flxig-cobrand__x">\xD7</span>
|
|
31
|
+
${flonixLogo(18)}
|
|
32
|
+
</span>`;
|
|
33
|
+
}
|
|
34
|
+
var icons = {
|
|
35
|
+
instagram: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
36
|
+
<rect x="2" y="2" width="20" height="20" rx="5" ry="5"/>
|
|
37
|
+
<path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/>
|
|
38
|
+
<line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/>
|
|
39
|
+
</svg>`,
|
|
40
|
+
comment: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
41
|
+
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
|
|
42
|
+
</svg>`,
|
|
43
|
+
dm: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
44
|
+
<line x1="22" y1="2" x2="11" y2="13"/>
|
|
45
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2"/>
|
|
46
|
+
</svg>`,
|
|
47
|
+
check: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
48
|
+
<polyline points="20 6 9 17 4 12"/>
|
|
49
|
+
</svg>`,
|
|
50
|
+
close: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
51
|
+
<line x1="18" y1="6" x2="6" y2="18"/>
|
|
52
|
+
<line x1="6" y1="6" x2="18" y2="18"/>
|
|
53
|
+
</svg>`,
|
|
54
|
+
plus: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
55
|
+
<line x1="12" y1="5" x2="12" y2="19"/>
|
|
56
|
+
<line x1="5" y1="12" x2="19" y2="12"/>
|
|
57
|
+
</svg>`,
|
|
58
|
+
link: (size = 15) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
59
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
|
60
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
|
61
|
+
</svg>`,
|
|
62
|
+
bolt: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
63
|
+
<path d="M13 2 4.5 13.5H11L10 22l8.5-11.5H12L13 2Z"/>
|
|
64
|
+
</svg>`,
|
|
65
|
+
spinner: (size = 18) => `<svg class="flxig-spin" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true">
|
|
66
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56"/>
|
|
67
|
+
</svg>`,
|
|
68
|
+
video: (size = 14) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
69
|
+
<path d="M8 5v14l11-7L8 5Z"/>
|
|
70
|
+
</svg>`,
|
|
71
|
+
layers: (size = 14) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
72
|
+
<polygon points="12 2 2 7 12 12 22 7 12 2"/>
|
|
73
|
+
<polyline points="2 17 12 22 22 17"/>
|
|
74
|
+
<polyline points="2 12 12 17 22 12"/>
|
|
75
|
+
</svg>`
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/client.ts
|
|
79
|
+
function authHeaders(token) {
|
|
80
|
+
return {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
Authorization: `Bearer ${token}`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function createHttpTransport(baseUrl) {
|
|
86
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
87
|
+
async function call(path, init) {
|
|
88
|
+
let res;
|
|
89
|
+
try {
|
|
90
|
+
res = await fetch(`${base}${path}`, init);
|
|
91
|
+
} catch {
|
|
92
|
+
throw new Error("Network error \u2014 please try again.");
|
|
93
|
+
}
|
|
94
|
+
const json = await res.json().catch(() => null);
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
throw new Error((json == null ? void 0 : json.error) || `Request failed (${res.status})`);
|
|
97
|
+
}
|
|
98
|
+
return json;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
session: ({ apiKey, user }) => call("/api/embed/session", {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: authHeaders(apiKey),
|
|
104
|
+
body: JSON.stringify({ user })
|
|
105
|
+
}),
|
|
106
|
+
connectStart: ({ token, returnUrl }) => call("/api/embed/connect/start", {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: authHeaders(token),
|
|
109
|
+
body: JSON.stringify({ returnUrl })
|
|
110
|
+
}),
|
|
111
|
+
posts: ({ token, cursor }) => call(
|
|
112
|
+
`/api/embed/posts${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ""}`,
|
|
113
|
+
{ method: "GET", headers: authHeaders(token) }
|
|
114
|
+
),
|
|
115
|
+
createAutomation: ({ token, data }) => call("/api/embed/automations", {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: authHeaders(token),
|
|
118
|
+
body: JSON.stringify(data)
|
|
119
|
+
})
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/dom.ts
|
|
124
|
+
function el(tag, attrs = {}, ...children) {
|
|
125
|
+
const node = document.createElement(tag);
|
|
126
|
+
if (attrs.class) node.className = attrs.class;
|
|
127
|
+
if (attrs.text != null) node.textContent = attrs.text;
|
|
128
|
+
if (attrs.html != null) node.innerHTML = attrs.html;
|
|
129
|
+
if (attrs.style) node.setAttribute("style", attrs.style);
|
|
130
|
+
if (attrs.dataset) {
|
|
131
|
+
for (const [key, value] of Object.entries(attrs.dataset)) {
|
|
132
|
+
node.dataset[key] = value;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (attrs.attrs) {
|
|
136
|
+
for (const [key, value] of Object.entries(attrs.attrs)) {
|
|
137
|
+
if (value == null || value === false) continue;
|
|
138
|
+
node.setAttribute(key, value === true ? "" : String(value));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (attrs.on) {
|
|
142
|
+
for (const [event, handler] of Object.entries(attrs.on)) {
|
|
143
|
+
node.addEventListener(event, handler);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
append(node, children);
|
|
147
|
+
return node;
|
|
148
|
+
}
|
|
149
|
+
function append(parent, children) {
|
|
150
|
+
for (const child of children) {
|
|
151
|
+
if (child == null || child === false) continue;
|
|
152
|
+
parent.appendChild(
|
|
153
|
+
child instanceof Node ? child : document.createTextNode(String(child))
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function clear(node) {
|
|
158
|
+
while (node.firstChild) node.removeChild(node.firstChild);
|
|
159
|
+
}
|
|
160
|
+
function fromMarkup(markup) {
|
|
161
|
+
var _a;
|
|
162
|
+
const wrapper = document.createElement("div");
|
|
163
|
+
wrapper.innerHTML = markup.trim();
|
|
164
|
+
return (_a = wrapper.firstElementChild) != null ? _a : wrapper;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/components.ts
|
|
168
|
+
function button(opts) {
|
|
169
|
+
var _a;
|
|
170
|
+
const classes = [
|
|
171
|
+
"flxig-btn",
|
|
172
|
+
`flxig-btn--${(_a = opts.variant) != null ? _a : "primary"}`,
|
|
173
|
+
opts.block ? "flxig-btn--block" : "",
|
|
174
|
+
opts.large ? "flxig-btn--lg" : ""
|
|
175
|
+
].filter(Boolean).join(" ");
|
|
176
|
+
const btn = el("button", {
|
|
177
|
+
class: classes,
|
|
178
|
+
attrs: { type: "button", disabled: opts.disabled },
|
|
179
|
+
on: opts.onClick ? { click: opts.onClick } : void 0
|
|
180
|
+
});
|
|
181
|
+
if (opts.icon) btn.appendChild(fromMarkup(opts.icon));
|
|
182
|
+
append(btn, [el("span", { text: opts.label })]);
|
|
183
|
+
return btn;
|
|
184
|
+
}
|
|
185
|
+
function field(label, control, hint) {
|
|
186
|
+
return el(
|
|
187
|
+
"div",
|
|
188
|
+
{ class: "flxig-field" },
|
|
189
|
+
el("span", { class: "flxig-label", text: label }),
|
|
190
|
+
control,
|
|
191
|
+
hint ? el("span", { class: "flxig-hint", text: hint }) : null
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
function textInput(opts) {
|
|
195
|
+
var _a, _b;
|
|
196
|
+
return el("input", {
|
|
197
|
+
class: "flxig-input",
|
|
198
|
+
attrs: { type: "text", value: (_a = opts.value) != null ? _a : "", placeholder: (_b = opts.placeholder) != null ? _b : "" }
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function textArea(opts) {
|
|
202
|
+
var _a, _b, _c;
|
|
203
|
+
const ta = el("textarea", {
|
|
204
|
+
class: "flxig-textarea",
|
|
205
|
+
attrs: { placeholder: (_a = opts.placeholder) != null ? _a : "", rows: (_b = opts.rows) != null ? _b : 3 }
|
|
206
|
+
});
|
|
207
|
+
ta.value = (_c = opts.value) != null ? _c : "";
|
|
208
|
+
return ta;
|
|
209
|
+
}
|
|
210
|
+
function switchToggle(opts) {
|
|
211
|
+
const input = el("input", { attrs: { type: "checkbox" } });
|
|
212
|
+
input.checked = opts.checked;
|
|
213
|
+
if (opts.onChange) {
|
|
214
|
+
input.addEventListener("change", () => opts.onChange(input.checked));
|
|
215
|
+
}
|
|
216
|
+
const element = el(
|
|
217
|
+
"span",
|
|
218
|
+
{ class: "flxig-switch" },
|
|
219
|
+
input,
|
|
220
|
+
el("span", { class: "flxig-switch__track" }),
|
|
221
|
+
el("span", { class: "flxig-switch__thumb" })
|
|
222
|
+
);
|
|
223
|
+
return { element, input };
|
|
224
|
+
}
|
|
225
|
+
function chipsInput(opts) {
|
|
226
|
+
var _a;
|
|
227
|
+
let values = [...opts.values];
|
|
228
|
+
const list = el("span", { class: "flxig-chips" });
|
|
229
|
+
const input = el("input", {
|
|
230
|
+
attrs: { type: "text", placeholder: (_a = opts.placeholder) != null ? _a : "Add keyword\u2026" }
|
|
231
|
+
});
|
|
232
|
+
const render = () => {
|
|
233
|
+
while (list.firstChild && list.firstChild !== input) {
|
|
234
|
+
list.removeChild(list.firstChild);
|
|
235
|
+
}
|
|
236
|
+
const chips = values.map(
|
|
237
|
+
(value, index) => el(
|
|
238
|
+
"span",
|
|
239
|
+
{ class: "flxig-chip" },
|
|
240
|
+
el("span", { text: value }),
|
|
241
|
+
el("button", {
|
|
242
|
+
attrs: { type: "button", "aria-label": `Remove ${value}` },
|
|
243
|
+
html: icons.close(12),
|
|
244
|
+
on: {
|
|
245
|
+
click: () => {
|
|
246
|
+
values.splice(index, 1);
|
|
247
|
+
render();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
list.prepend(...chips);
|
|
254
|
+
};
|
|
255
|
+
const commit = () => {
|
|
256
|
+
const raw = input.value.trim().replace(/,$/, "").trim();
|
|
257
|
+
if (raw && !values.includes(raw)) {
|
|
258
|
+
values.push(raw);
|
|
259
|
+
render();
|
|
260
|
+
}
|
|
261
|
+
input.value = "";
|
|
262
|
+
};
|
|
263
|
+
input.addEventListener("keydown", (ev) => {
|
|
264
|
+
if (ev.key === "Enter" || ev.key === ",") {
|
|
265
|
+
ev.preventDefault();
|
|
266
|
+
commit();
|
|
267
|
+
} else if (ev.key === "Backspace" && !input.value && values.length) {
|
|
268
|
+
values.pop();
|
|
269
|
+
render();
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
input.addEventListener("blur", commit);
|
|
273
|
+
list.appendChild(input);
|
|
274
|
+
render();
|
|
275
|
+
return { element: list, getValues: () => [...values] };
|
|
276
|
+
}
|
|
277
|
+
function linkButtonsEditor(opts) {
|
|
278
|
+
const rows = el("div", { class: "flxig-links" });
|
|
279
|
+
const addBtn = button({
|
|
280
|
+
label: "Add link",
|
|
281
|
+
variant: "ghost",
|
|
282
|
+
icon: icons.plus(15),
|
|
283
|
+
onClick: () => {
|
|
284
|
+
if (rows.querySelectorAll(".flxig-link").length >= opts.max) return;
|
|
285
|
+
addRow({ label: "", url: "" });
|
|
286
|
+
syncAdd();
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
addBtn.classList.add("flxig-links__add");
|
|
290
|
+
function syncAdd() {
|
|
291
|
+
addBtn.disabled = rows.querySelectorAll(".flxig-link").length >= opts.max;
|
|
292
|
+
}
|
|
293
|
+
function addRow(value) {
|
|
294
|
+
const label = textInput({ value: value.label, placeholder: "Button label" });
|
|
295
|
+
label.classList.add("flxig-link__label");
|
|
296
|
+
const url = el("input", {
|
|
297
|
+
class: "flxig-input flxig-link__url",
|
|
298
|
+
attrs: { type: "url", value: value.url, placeholder: "https://\u2026", inputmode: "url" }
|
|
299
|
+
});
|
|
300
|
+
const row = el(
|
|
301
|
+
"div",
|
|
302
|
+
{ class: "flxig-link" },
|
|
303
|
+
fromMarkup(`<span class="flxig-link__ic">${icons.link(15)}</span>`),
|
|
304
|
+
el("div", { class: "flxig-link__inputs" }, label, url),
|
|
305
|
+
el("button", {
|
|
306
|
+
class: "flxig-iconbtn",
|
|
307
|
+
attrs: { type: "button", "aria-label": "Remove link" },
|
|
308
|
+
html: icons.close(16),
|
|
309
|
+
on: {
|
|
310
|
+
click: () => {
|
|
311
|
+
row.remove();
|
|
312
|
+
syncAdd();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
})
|
|
316
|
+
);
|
|
317
|
+
rows.appendChild(row);
|
|
318
|
+
}
|
|
319
|
+
const seed = opts.values.length ? opts.values : [{ label: "", url: "" }];
|
|
320
|
+
seed.slice(0, opts.max).forEach(addRow);
|
|
321
|
+
syncAdd();
|
|
322
|
+
const element = el("div", { class: "flxig-links__wrap" }, rows, addBtn);
|
|
323
|
+
return {
|
|
324
|
+
element,
|
|
325
|
+
getValues: () => [...rows.querySelectorAll(".flxig-link")].map((row) => ({
|
|
326
|
+
label: row.querySelector(".flxig-link__label").value.trim(),
|
|
327
|
+
url: row.querySelector(".flxig-link__url").value.trim()
|
|
328
|
+
})).filter((b) => b.label || b.url)
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function stateBlock(opts) {
|
|
332
|
+
var _a;
|
|
333
|
+
return el(
|
|
334
|
+
"div",
|
|
335
|
+
{ class: "flxig-state" },
|
|
336
|
+
opts.icon ? fromMarkup(opts.icon) : null,
|
|
337
|
+
el("p", { class: "flxig-h2", text: opts.title }),
|
|
338
|
+
opts.detail ? el("p", { class: "flxig-muted", text: opts.detail }) : null,
|
|
339
|
+
(_a = opts.action) != null ? _a : null
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/screens/connect.ts
|
|
344
|
+
function renderConnect(opts) {
|
|
345
|
+
const cta = button({
|
|
346
|
+
label: opts.connecting ? "Redirecting\u2026" : "Connect Instagram",
|
|
347
|
+
variant: "primary",
|
|
348
|
+
large: true,
|
|
349
|
+
block: true,
|
|
350
|
+
disabled: opts.connecting,
|
|
351
|
+
icon: opts.connecting ? icons.spinner() : icons.instagram(),
|
|
352
|
+
onClick: opts.onConnect
|
|
353
|
+
});
|
|
354
|
+
return el(
|
|
355
|
+
"div",
|
|
356
|
+
{ class: "flxig-connect" },
|
|
357
|
+
el(
|
|
358
|
+
"div",
|
|
359
|
+
{ class: "flxig-connect__copy" },
|
|
360
|
+
el("h1", { class: "flxig-h1", text: "Connect your Instagram with Flonix" }),
|
|
361
|
+
el("p", {
|
|
362
|
+
class: "flxig-muted",
|
|
363
|
+
text: "Link your Instagram account to set up comment and DM automations on your posts \u2014 directly from here."
|
|
364
|
+
})
|
|
365
|
+
),
|
|
366
|
+
el("div", { class: "flxig-connect__cta" }, cta),
|
|
367
|
+
fromMarkup(`<div class="flxig-connect__foot">${cobrandLockup(opts.partner)}</div>`)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// src/screens/posts.ts
|
|
372
|
+
var TYPE_META = {
|
|
373
|
+
IMAGE: { label: "Image", icon: icons.instagram(12) },
|
|
374
|
+
VIDEO: { label: "Video", icon: icons.video() },
|
|
375
|
+
REELS: { label: "Reel", icon: icons.video() },
|
|
376
|
+
CAROUSEL: { label: "Album", icon: icons.layers() }
|
|
377
|
+
};
|
|
378
|
+
function postTile(post, onAutomate) {
|
|
379
|
+
var _a, _b, _c;
|
|
380
|
+
const meta = (_a = TYPE_META[post.mediaType]) != null ? _a : TYPE_META.IMAGE;
|
|
381
|
+
const media = el("div", { class: "flxig-tile__media" });
|
|
382
|
+
if (post.media) {
|
|
383
|
+
append(media, [
|
|
384
|
+
el("img", {
|
|
385
|
+
attrs: { src: post.media, alt: (_b = post.caption) != null ? _b : "Instagram post", loading: "lazy" }
|
|
386
|
+
})
|
|
387
|
+
]);
|
|
388
|
+
} else {
|
|
389
|
+
append(media, [fromMarkup(`<div class="flxig-tile__ph">${icons.instagram(28)}</div>`)]);
|
|
390
|
+
}
|
|
391
|
+
append(media, [
|
|
392
|
+
fromMarkup(
|
|
393
|
+
`<span class="flxig-tile__type">${meta.icon}<span>${meta.label}</span></span>`
|
|
394
|
+
)
|
|
395
|
+
]);
|
|
396
|
+
return el(
|
|
397
|
+
"div",
|
|
398
|
+
{ class: "flxig-tile" },
|
|
399
|
+
media,
|
|
400
|
+
el(
|
|
401
|
+
"div",
|
|
402
|
+
{ class: "flxig-tile__body" },
|
|
403
|
+
el("p", {
|
|
404
|
+
class: "flxig-tile__cap",
|
|
405
|
+
text: ((_c = post.caption) == null ? void 0 : _c.trim()) || "No caption"
|
|
406
|
+
}),
|
|
407
|
+
button({
|
|
408
|
+
label: "Automate",
|
|
409
|
+
variant: "secondary",
|
|
410
|
+
block: true,
|
|
411
|
+
icon: icons.bolt(),
|
|
412
|
+
onClick: () => onAutomate(post)
|
|
413
|
+
})
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
function renderPosts(opts) {
|
|
418
|
+
var _a;
|
|
419
|
+
const username = (_a = opts.account) == null ? void 0 : _a.username;
|
|
420
|
+
const grid = el("div", { class: "flxig-grid" });
|
|
421
|
+
const sentinel = el("div", { class: "flxig-sentinel" });
|
|
422
|
+
const loadMore = el("div", { class: "flxig-loadmore" });
|
|
423
|
+
const header = el(
|
|
424
|
+
"div",
|
|
425
|
+
{ class: "flxig-header" },
|
|
426
|
+
el(
|
|
427
|
+
"div",
|
|
428
|
+
{ class: "flxig-header__id" },
|
|
429
|
+
fromMarkup(`<span class="flxig-avatar">${icons.instagram(18)}</span>`),
|
|
430
|
+
el(
|
|
431
|
+
"div",
|
|
432
|
+
{},
|
|
433
|
+
el("div", { class: "flxig-h2", text: username ? `@${username}` : "Instagram" }),
|
|
434
|
+
el("div", { class: "flxig-muted", text: "Pick a post to automate" })
|
|
435
|
+
)
|
|
436
|
+
),
|
|
437
|
+
fromMarkup(
|
|
438
|
+
`<span class="flxig-badge">${icons.check(13)}<span>Connected</span></span>`
|
|
439
|
+
)
|
|
440
|
+
);
|
|
441
|
+
const attribution = fromMarkup(
|
|
442
|
+
`<div class="flxig-attrib"><span>Automations by</span>${flonixLogo(15)}</div>`
|
|
443
|
+
);
|
|
444
|
+
const root = el(
|
|
445
|
+
"div",
|
|
446
|
+
{},
|
|
447
|
+
header,
|
|
448
|
+
grid,
|
|
449
|
+
loadMore,
|
|
450
|
+
sentinel,
|
|
451
|
+
attribution
|
|
452
|
+
);
|
|
453
|
+
let hasMore = true;
|
|
454
|
+
let loading = false;
|
|
455
|
+
let empty = false;
|
|
456
|
+
const observer = typeof IntersectionObserver !== "undefined" ? new IntersectionObserver(
|
|
457
|
+
(entries) => {
|
|
458
|
+
if (entries.some((e) => e.isIntersecting) && hasMore && !loading && !empty) {
|
|
459
|
+
opts.onLoadMore();
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
{ rootMargin: "240px" }
|
|
463
|
+
) : null;
|
|
464
|
+
observer == null ? void 0 : observer.observe(sentinel);
|
|
465
|
+
const renderLoadMore = () => {
|
|
466
|
+
clear(loadMore);
|
|
467
|
+
if (loading) {
|
|
468
|
+
append(loadMore, [fromMarkup(icons.spinner(20))]);
|
|
469
|
+
} else if (hasMore && !observer) {
|
|
470
|
+
append(loadMore, [
|
|
471
|
+
button({ label: "Load more", variant: "ghost", onClick: opts.onLoadMore })
|
|
472
|
+
]);
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
return {
|
|
476
|
+
element: root,
|
|
477
|
+
appendPosts(posts) {
|
|
478
|
+
empty = false;
|
|
479
|
+
append(
|
|
480
|
+
grid,
|
|
481
|
+
posts.map((post) => postTile(post, opts.onAutomate))
|
|
482
|
+
);
|
|
483
|
+
},
|
|
484
|
+
setLoadingMore(value) {
|
|
485
|
+
loading = value;
|
|
486
|
+
renderLoadMore();
|
|
487
|
+
},
|
|
488
|
+
setHasMore(value) {
|
|
489
|
+
hasMore = value;
|
|
490
|
+
renderLoadMore();
|
|
491
|
+
if (!value) observer == null ? void 0 : observer.disconnect();
|
|
492
|
+
},
|
|
493
|
+
showEmpty() {
|
|
494
|
+
empty = true;
|
|
495
|
+
hasMore = false;
|
|
496
|
+
observer == null ? void 0 : observer.disconnect();
|
|
497
|
+
clear(grid);
|
|
498
|
+
grid.replaceWith(
|
|
499
|
+
stateBlock({
|
|
500
|
+
icon: icons.instagram(30),
|
|
501
|
+
title: "No posts yet",
|
|
502
|
+
detail: "Publish a post on Instagram, then come back to automate it."
|
|
503
|
+
})
|
|
504
|
+
);
|
|
505
|
+
},
|
|
506
|
+
destroy() {
|
|
507
|
+
observer == null ? void 0 : observer.disconnect();
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// src/prefill.ts
|
|
513
|
+
function profileUrl(account) {
|
|
514
|
+
if (account == null ? void 0 : account.username) return `https://instagram.com/${account.username}`;
|
|
515
|
+
return "https://instagram.com/";
|
|
516
|
+
}
|
|
517
|
+
function buildPrefill(post, account, type) {
|
|
518
|
+
const handle = (account == null ? void 0 : account.username) ? `@${account.username}` : "us";
|
|
519
|
+
const common = {
|
|
520
|
+
postId: post.id,
|
|
521
|
+
type,
|
|
522
|
+
entryButtonLabel: "Send me the link",
|
|
523
|
+
deliveryMessage: "Thanks for reaching out! \u{1F64C} Here's the link you asked for \u{1F447}",
|
|
524
|
+
// One link button prefilled; the merchant fills in their own URL.
|
|
525
|
+
linkButtons: [{ label: "Shop now", url: "" }],
|
|
526
|
+
// Follow-gate is ON and prefilled by default, per product spec.
|
|
527
|
+
followGate: {
|
|
528
|
+
enabled: true,
|
|
529
|
+
followProfileUrl: profileUrl(account),
|
|
530
|
+
followButtonLabel: `Follow ${handle}`,
|
|
531
|
+
followConfirmButtonLabel: "I'm following \u2705",
|
|
532
|
+
followUpMessage: "Awesome \u2014 thanks for following! \u{1F499} Here's your link \u{1F447}"
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
if (type === "COMMENT") {
|
|
536
|
+
return {
|
|
537
|
+
...common,
|
|
538
|
+
name: "Comment \u2192 DM automation",
|
|
539
|
+
keywords: ["link", "price", "info"],
|
|
540
|
+
commentReply: "Just sent you a DM! \u{1F4E9}"
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
...common,
|
|
545
|
+
name: "DM keyword automation",
|
|
546
|
+
keywords: ["link", "info"],
|
|
547
|
+
commentReply: null
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/types.ts
|
|
552
|
+
var MAX_LINK_BUTTONS = 3;
|
|
553
|
+
|
|
554
|
+
// src/screens/automate-dialog.ts
|
|
555
|
+
var TYPE_OPTIONS = [
|
|
556
|
+
{
|
|
557
|
+
type: "COMMENT",
|
|
558
|
+
title: "Comment automation",
|
|
559
|
+
detail: "Reply + DM when someone comments a keyword",
|
|
560
|
+
icon: icons.comment(20)
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
type: "DM",
|
|
564
|
+
title: "DM automation",
|
|
565
|
+
detail: "Auto-reply when someone DMs a keyword",
|
|
566
|
+
icon: icons.dm(20)
|
|
567
|
+
}
|
|
568
|
+
];
|
|
569
|
+
function openAutomateDialog(opts) {
|
|
570
|
+
var _a;
|
|
571
|
+
let type = "COMMENT";
|
|
572
|
+
let draft = buildPrefill(opts.post, opts.account, type);
|
|
573
|
+
let submitting = false;
|
|
574
|
+
const body = el("div", { class: "flxig-dialog__body" });
|
|
575
|
+
const overlay = el("div", { class: "flxig-overlay" });
|
|
576
|
+
const close = () => {
|
|
577
|
+
document.removeEventListener("keydown", onKey);
|
|
578
|
+
overlay.remove();
|
|
579
|
+
};
|
|
580
|
+
const onKey = (ev) => {
|
|
581
|
+
if (ev.key === "Escape" && !submitting) close();
|
|
582
|
+
};
|
|
583
|
+
document.addEventListener("keydown", onKey);
|
|
584
|
+
overlay.addEventListener("click", (ev) => {
|
|
585
|
+
if (ev.target === overlay && !submitting) close();
|
|
586
|
+
});
|
|
587
|
+
const picker = el("div", { class: "flxig-seg" });
|
|
588
|
+
const renderPicker = () => {
|
|
589
|
+
picker.replaceChildren(
|
|
590
|
+
...TYPE_OPTIONS.map(
|
|
591
|
+
(opt) => el(
|
|
592
|
+
"div",
|
|
593
|
+
{
|
|
594
|
+
class: "flxig-seg__opt",
|
|
595
|
+
dataset: { active: String(opt.type === type) },
|
|
596
|
+
attrs: { role: "button", tabindex: "0" },
|
|
597
|
+
on: {
|
|
598
|
+
click: () => {
|
|
599
|
+
if (opt.type === type) return;
|
|
600
|
+
type = opt.type;
|
|
601
|
+
draft = buildPrefill(opts.post, opts.account, type);
|
|
602
|
+
renderPicker();
|
|
603
|
+
renderForm();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
fromMarkup(`<span class="flxig-seg__ic">${opt.icon}</span>`),
|
|
608
|
+
el(
|
|
609
|
+
"div",
|
|
610
|
+
{},
|
|
611
|
+
el("div", { class: "flxig-seg__t", text: opt.title }),
|
|
612
|
+
el("div", { class: "flxig-seg__d", text: opt.detail })
|
|
613
|
+
)
|
|
614
|
+
)
|
|
615
|
+
)
|
|
616
|
+
);
|
|
617
|
+
};
|
|
618
|
+
let readForm = () => draft;
|
|
619
|
+
const renderForm = () => {
|
|
620
|
+
var _a2;
|
|
621
|
+
const keywords = chipsInput({
|
|
622
|
+
values: draft.keywords,
|
|
623
|
+
placeholder: "Add keyword\u2026"
|
|
624
|
+
});
|
|
625
|
+
const commentReply = textInput({ value: (_a2 = draft.commentReply) != null ? _a2 : "" });
|
|
626
|
+
const deliveryMessage = textArea({ value: draft.deliveryMessage, rows: 3 });
|
|
627
|
+
const entryButtonLabel = textInput({ value: draft.entryButtonLabel });
|
|
628
|
+
const links = linkButtonsEditor({
|
|
629
|
+
values: draft.linkButtons,
|
|
630
|
+
max: MAX_LINK_BUTTONS
|
|
631
|
+
});
|
|
632
|
+
const followUpMessage = textArea({ value: draft.followGate.followUpMessage, rows: 2 });
|
|
633
|
+
const followButtonLabel = textInput({ value: draft.followGate.followButtonLabel });
|
|
634
|
+
const followProfileUrl = textInput({ value: draft.followGate.followProfileUrl });
|
|
635
|
+
const followConfirmLabel = textInput({ value: draft.followGate.followConfirmButtonLabel });
|
|
636
|
+
const gateFields = el(
|
|
637
|
+
"div",
|
|
638
|
+
{ class: "flxig-gate__fields", dataset: { off: String(!draft.followGate.enabled) } },
|
|
639
|
+
field("Follow profile URL", followProfileUrl),
|
|
640
|
+
field("Follow button label", followButtonLabel),
|
|
641
|
+
field("Confirm button label", followConfirmLabel),
|
|
642
|
+
field("Message after they follow", followUpMessage)
|
|
643
|
+
);
|
|
644
|
+
const gateSwitch = switchToggle({
|
|
645
|
+
checked: draft.followGate.enabled,
|
|
646
|
+
onChange: (checked) => {
|
|
647
|
+
gateFields.dataset.off = String(!checked);
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
const gate = el(
|
|
651
|
+
"div",
|
|
652
|
+
{ class: "flxig-gate" },
|
|
653
|
+
el(
|
|
654
|
+
"div",
|
|
655
|
+
{ class: "flxig-gate__top" },
|
|
656
|
+
el(
|
|
657
|
+
"div",
|
|
658
|
+
{},
|
|
659
|
+
el("div", { class: "flxig-label", text: "Follow gate" }),
|
|
660
|
+
el("div", {
|
|
661
|
+
class: "flxig-hint",
|
|
662
|
+
text: "Require users to follow before they get the link."
|
|
663
|
+
})
|
|
664
|
+
),
|
|
665
|
+
gateSwitch.element
|
|
666
|
+
),
|
|
667
|
+
gateFields
|
|
668
|
+
);
|
|
669
|
+
const fields = [
|
|
670
|
+
field(
|
|
671
|
+
type === "COMMENT" ? "Trigger keywords (in comments)" : "Trigger keywords (in DMs)",
|
|
672
|
+
keywords.element,
|
|
673
|
+
"Press Enter or comma to add. The automation fires on these words."
|
|
674
|
+
)
|
|
675
|
+
];
|
|
676
|
+
if (type === "COMMENT") {
|
|
677
|
+
fields.push(field("Public comment reply", commentReply, "Posted under the comment."));
|
|
678
|
+
}
|
|
679
|
+
fields.push(
|
|
680
|
+
field("DM message", deliveryMessage, "The direct message delivered to the user."),
|
|
681
|
+
field(
|
|
682
|
+
"Link buttons",
|
|
683
|
+
links.element,
|
|
684
|
+
`Where they enter the link(s). Up to ${MAX_LINK_BUTTONS} \u2014 each has a label and a URL.`
|
|
685
|
+
),
|
|
686
|
+
field("Opt-in button label", entryButtonLabel, "Button users tap in the first DM."),
|
|
687
|
+
gate
|
|
688
|
+
);
|
|
689
|
+
body.replaceChildren(...fields);
|
|
690
|
+
readForm = () => ({
|
|
691
|
+
postId: opts.post.id,
|
|
692
|
+
type,
|
|
693
|
+
name: draft.name,
|
|
694
|
+
keywords: keywords.getValues(),
|
|
695
|
+
commentReply: type === "COMMENT" ? commentReply.value.trim() || null : null,
|
|
696
|
+
entryButtonLabel: entryButtonLabel.value.trim(),
|
|
697
|
+
deliveryMessage: deliveryMessage.value.trim(),
|
|
698
|
+
linkButtons: links.getValues(),
|
|
699
|
+
followGate: {
|
|
700
|
+
enabled: gateSwitch.input.checked,
|
|
701
|
+
followProfileUrl: followProfileUrl.value.trim(),
|
|
702
|
+
followButtonLabel: followButtonLabel.value.trim(),
|
|
703
|
+
followConfirmButtonLabel: followConfirmLabel.value.trim(),
|
|
704
|
+
followUpMessage: followUpMessage.value.trim()
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
body.prepend(
|
|
708
|
+
el("div", { class: "flxig-field" }, el("span", { class: "flxig-label", text: "Automation type" }), picker)
|
|
709
|
+
);
|
|
710
|
+
};
|
|
711
|
+
const saveBtn = button({
|
|
712
|
+
label: "Create automation",
|
|
713
|
+
variant: "primary",
|
|
714
|
+
icon: icons.bolt(),
|
|
715
|
+
onClick: async () => {
|
|
716
|
+
if (submitting) return;
|
|
717
|
+
const data = readForm();
|
|
718
|
+
if (!data.keywords.length) {
|
|
719
|
+
opts.onToast("Add at least one keyword");
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
if (!data.deliveryMessage) {
|
|
723
|
+
opts.onToast("Add a DM message");
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
submitting = true;
|
|
727
|
+
saveBtn.disabled = true;
|
|
728
|
+
saveBtn.replaceChildren(fromMarkup(icons.spinner()), el("span", { text: "Creating\u2026" }));
|
|
729
|
+
try {
|
|
730
|
+
await opts.onSubmit(data);
|
|
731
|
+
close();
|
|
732
|
+
} catch (error) {
|
|
733
|
+
opts.onToast(error instanceof Error ? error.message : "Something went wrong");
|
|
734
|
+
submitting = false;
|
|
735
|
+
saveBtn.disabled = false;
|
|
736
|
+
saveBtn.replaceChildren(fromMarkup(icons.bolt()), el("span", { text: "Create automation" }));
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
const dialog = el(
|
|
741
|
+
"div",
|
|
742
|
+
{ class: "flxig-dialog", attrs: { role: "dialog", "aria-modal": "true" } },
|
|
743
|
+
el(
|
|
744
|
+
"div",
|
|
745
|
+
{ class: "flxig-dialog__head" },
|
|
746
|
+
el(
|
|
747
|
+
"div",
|
|
748
|
+
{},
|
|
749
|
+
el("div", { class: "flxig-h2", text: "Automate this post" }),
|
|
750
|
+
el("div", {
|
|
751
|
+
class: "flxig-muted",
|
|
752
|
+
text: ((_a = opts.post.caption) == null ? void 0 : _a.trim()) ? truncate(opts.post.caption.trim(), 70) : "Set up comment & DM replies"
|
|
753
|
+
})
|
|
754
|
+
),
|
|
755
|
+
el("button", {
|
|
756
|
+
class: "flxig-iconbtn",
|
|
757
|
+
attrs: { type: "button", "aria-label": "Close" },
|
|
758
|
+
html: icons.close(),
|
|
759
|
+
on: { click: () => !submitting && close() }
|
|
760
|
+
})
|
|
761
|
+
),
|
|
762
|
+
body,
|
|
763
|
+
el(
|
|
764
|
+
"div",
|
|
765
|
+
{ class: "flxig-dialog__foot" },
|
|
766
|
+
button({ label: "Cancel", variant: "ghost", onClick: () => !submitting && close() }),
|
|
767
|
+
saveBtn
|
|
768
|
+
)
|
|
769
|
+
);
|
|
770
|
+
renderPicker();
|
|
771
|
+
renderForm();
|
|
772
|
+
append(overlay, [dialog]);
|
|
773
|
+
opts.mount.appendChild(overlay);
|
|
774
|
+
return { close };
|
|
775
|
+
}
|
|
776
|
+
function truncate(value, max) {
|
|
777
|
+
return value.length > max ? `${value.slice(0, max - 1)}\u2026` : value;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// src/theme.ts
|
|
781
|
+
var DEFAULT_FONT_FAMILY = '"Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
782
|
+
var DEFAULT_RADIUS = "12px";
|
|
783
|
+
var DEFAULT_TOKENS = {
|
|
784
|
+
light: {
|
|
785
|
+
background: "#ffffff",
|
|
786
|
+
foreground: "#0a0a0b",
|
|
787
|
+
card: "#ffffff",
|
|
788
|
+
cardForeground: "#0a0a0b",
|
|
789
|
+
popover: "#ffffff",
|
|
790
|
+
popoverForeground: "#0a0a0b",
|
|
791
|
+
primary: "#2563eb",
|
|
792
|
+
primaryForeground: "#ffffff",
|
|
793
|
+
secondary: "#f4f4f5",
|
|
794
|
+
secondaryForeground: "#18181b",
|
|
795
|
+
muted: "#f4f4f5",
|
|
796
|
+
mutedForeground: "#71717a",
|
|
797
|
+
accent: "#eef2ff",
|
|
798
|
+
accentForeground: "#1e3a8a",
|
|
799
|
+
destructive: "#ef4444",
|
|
800
|
+
destructiveForeground: "#ffffff",
|
|
801
|
+
border: "#e4e4e7",
|
|
802
|
+
input: "#e4e4e7",
|
|
803
|
+
ring: "#2563eb"
|
|
804
|
+
},
|
|
805
|
+
dark: {
|
|
806
|
+
background: "#0a0a0b",
|
|
807
|
+
foreground: "#fafafa",
|
|
808
|
+
card: "#131316",
|
|
809
|
+
cardForeground: "#fafafa",
|
|
810
|
+
popover: "#131316",
|
|
811
|
+
popoverForeground: "#fafafa",
|
|
812
|
+
primary: "#3b82f6",
|
|
813
|
+
primaryForeground: "#ffffff",
|
|
814
|
+
secondary: "#27272a",
|
|
815
|
+
secondaryForeground: "#fafafa",
|
|
816
|
+
muted: "#1b1b1f",
|
|
817
|
+
mutedForeground: "#a1a1aa",
|
|
818
|
+
accent: "#1e293b",
|
|
819
|
+
accentForeground: "#bfdbfe",
|
|
820
|
+
destructive: "#f87171",
|
|
821
|
+
destructiveForeground: "#0a0a0b",
|
|
822
|
+
border: "#27272a",
|
|
823
|
+
input: "#2a2a2e",
|
|
824
|
+
ring: "#3b82f6"
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
function resolveTheme(config = {}) {
|
|
828
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
829
|
+
return {
|
|
830
|
+
mode: (_a = config.mode) != null ? _a : "auto",
|
|
831
|
+
fontFamily: (_b = config.fontFamily) != null ? _b : DEFAULT_FONT_FAMILY,
|
|
832
|
+
radius: (_c = config.radius) != null ? _c : DEFAULT_RADIUS,
|
|
833
|
+
light: { ...DEFAULT_TOKENS.light, ...(_e = (_d = config.tokens) == null ? void 0 : _d.light) != null ? _e : {} },
|
|
834
|
+
dark: { ...DEFAULT_TOKENS.dark, ...(_g = (_f = config.tokens) == null ? void 0 : _f.dark) != null ? _g : {} }
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
var camelToKebab = (key) => key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
838
|
+
function tokensToVars(tokens) {
|
|
839
|
+
return Object.keys(tokens).map((key) => ` --flxig-${camelToKebab(key)}: ${tokens[key]};`).join("\n");
|
|
840
|
+
}
|
|
841
|
+
function buildThemeVars(theme) {
|
|
842
|
+
return `:host {
|
|
843
|
+
${tokensToVars(theme.light)}
|
|
844
|
+
--flxig-radius: ${theme.radius};
|
|
845
|
+
--flxig-font: ${theme.fontFamily};
|
|
846
|
+
}
|
|
847
|
+
:host(.flxig-dark) {
|
|
848
|
+
${tokensToVars(theme.dark)}
|
|
849
|
+
}`;
|
|
850
|
+
}
|
|
851
|
+
function isDarkActive(mode) {
|
|
852
|
+
if (mode === "dark") return true;
|
|
853
|
+
if (mode === "light") return false;
|
|
854
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// src/styles.ts
|
|
858
|
+
var STYLES = `
|
|
859
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
860
|
+
|
|
861
|
+
.flxig-root {
|
|
862
|
+
font-family: var(--flxig-font);
|
|
863
|
+
color: var(--flxig-foreground);
|
|
864
|
+
background: var(--flxig-background);
|
|
865
|
+
border: 1px solid var(--flxig-border);
|
|
866
|
+
border-radius: var(--flxig-radius);
|
|
867
|
+
padding: clamp(20px, 4vw, 36px);
|
|
868
|
+
line-height: 1.5;
|
|
869
|
+
-webkit-font-smoothing: antialiased;
|
|
870
|
+
text-rendering: optimizeLegibility;
|
|
871
|
+
container-type: inline-size;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/* Borderless / full-bleed: blends into the host page and fills its container.
|
|
875
|
+
Only the OUTER chrome is removed \u2014 internal borders (tiles, inputs) stay. */
|
|
876
|
+
.flxig-root.flxig-plain {
|
|
877
|
+
border: none;
|
|
878
|
+
border-radius: 0;
|
|
879
|
+
padding: 0;
|
|
880
|
+
background: transparent;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/* ---- typography ---- */
|
|
884
|
+
.flxig-h1 { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.015em; margin: 0; }
|
|
885
|
+
.flxig-h2 { font-size: 1.05rem; font-weight: 650; letter-spacing: -0.01em; margin: 0; }
|
|
886
|
+
.flxig-muted { color: var(--flxig-muted-foreground); font-size: 0.9rem; margin: 0; }
|
|
887
|
+
.flxig-label { display: block; font-size: 0.8rem; font-weight: 600; margin-bottom: 6px; }
|
|
888
|
+
.flxig-hint { font-size: 0.75rem; color: var(--flxig-muted-foreground); margin-top: 4px; }
|
|
889
|
+
|
|
890
|
+
/* ---- buttons ---- */
|
|
891
|
+
.flxig-btn {
|
|
892
|
+
appearance: none; border: 1px solid transparent; cursor: pointer;
|
|
893
|
+
font-family: inherit; font-size: 0.9rem; font-weight: 600;
|
|
894
|
+
border-radius: calc(var(--flxig-radius) - 4px);
|
|
895
|
+
padding: 10px 16px; display: inline-flex; align-items: center; justify-content: center;
|
|
896
|
+
gap: 8px; transition: filter .15s ease, background .15s ease, border-color .15s ease, opacity .15s ease;
|
|
897
|
+
text-decoration: none; white-space: nowrap;
|
|
898
|
+
}
|
|
899
|
+
.flxig-btn:disabled { opacity: .55; cursor: not-allowed; }
|
|
900
|
+
.flxig-btn--primary { background: var(--flxig-primary); color: var(--flxig-primary-foreground); }
|
|
901
|
+
.flxig-btn--primary:hover:not(:disabled) { filter: brightness(1.07); }
|
|
902
|
+
.flxig-btn--secondary { background: var(--flxig-secondary); color: var(--flxig-secondary-foreground); border-color: var(--flxig-border); }
|
|
903
|
+
.flxig-btn--secondary:hover:not(:disabled) { background: var(--flxig-muted); }
|
|
904
|
+
.flxig-btn--ghost { background: transparent; color: var(--flxig-foreground); }
|
|
905
|
+
.flxig-btn--ghost:hover:not(:disabled) { background: var(--flxig-muted); }
|
|
906
|
+
.flxig-btn--block { width: 100%; }
|
|
907
|
+
.flxig-btn--lg { padding: 13px 20px; font-size: 0.98rem; }
|
|
908
|
+
|
|
909
|
+
/* ---- brand logo: delta chip (light) / bare delta (dark) + wordmark ---- */
|
|
910
|
+
.flxig-brand { display: inline-flex; align-items: center; gap: 7px; color: var(--flxig-foreground); }
|
|
911
|
+
.flxig-brand__chip { display: inline-flex; align-items: center; justify-content: center; background: var(--flxig-primary); border-radius: 6px; padding: 3px; }
|
|
912
|
+
.flxig-brand__img { display: block; width: var(--flxig-logo-size, 18px); height: var(--flxig-logo-size, 18px); object-fit: contain; }
|
|
913
|
+
.flxig-brand__wordmark { display: block; height: var(--flxig-logo-size, 18px); width: auto; }
|
|
914
|
+
:host(.flxig-dark) .flxig-brand__chip { background: transparent; padding: 0; }
|
|
915
|
+
|
|
916
|
+
/* ---- co-brand lockup: "<partner logo> \xD7 flonix" ---- */
|
|
917
|
+
.flxig-cobrand { display: inline-flex; align-items: center; gap: 9px; font-size: 0.9rem; }
|
|
918
|
+
.flxig-cobrand__x { color: var(--flxig-muted-foreground); font-weight: 400; }
|
|
919
|
+
.flxig-partner { display: inline-flex; align-items: center; }
|
|
920
|
+
.flxig-partner__img { display: block; height: 18px; width: auto; max-width: 120px; object-fit: contain; }
|
|
921
|
+
.flxig-partner[data-has-dark="true"] .flxig-partner__img--dark { display: none; }
|
|
922
|
+
:host(.flxig-dark) .flxig-partner[data-has-dark="true"] .flxig-partner__img--light { display: none; }
|
|
923
|
+
:host(.flxig-dark) .flxig-partner[data-has-dark="true"] .flxig-partner__img--dark { display: block; }
|
|
924
|
+
|
|
925
|
+
/* ---- connect screen ---- */
|
|
926
|
+
.flxig-connect { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 18px; padding: clamp(20px, 6cqw, 52px) 8px; }
|
|
927
|
+
.flxig-connect__copy { display: flex; flex-direction: column; gap: 8px; max-width: 420px; }
|
|
928
|
+
.flxig-connect__cta { width: 100%; max-width: 340px; margin-top: 4px; }
|
|
929
|
+
.flxig-connect__foot { margin-top: 6px; }
|
|
930
|
+
|
|
931
|
+
/* ---- posts header ---- */
|
|
932
|
+
.flxig-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
|
|
933
|
+
.flxig-header__id { display: flex; align-items: center; gap: 10px; min-width: 0; }
|
|
934
|
+
.flxig-avatar { width: 38px; height: 38px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--flxig-accent); color: var(--flxig-accent-foreground); flex: none; }
|
|
935
|
+
.flxig-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 0.72rem; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--flxig-accent); color: var(--flxig-accent-foreground); }
|
|
936
|
+
|
|
937
|
+
/* ---- posts grid ---- */
|
|
938
|
+
.flxig-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
|
|
939
|
+
@container (min-width: 520px) { .flxig-grid { grid-template-columns: repeat(3, 1fr); } }
|
|
940
|
+
@container (min-width: 760px) { .flxig-grid { grid-template-columns: repeat(4, 1fr); } }
|
|
941
|
+
|
|
942
|
+
.flxig-tile { border: 1px solid var(--flxig-border); border-radius: var(--flxig-radius); overflow: hidden; background: var(--flxig-card); display: flex; flex-direction: column; }
|
|
943
|
+
.flxig-tile__media { position: relative; aspect-ratio: 1 / 1; background: var(--flxig-muted); overflow: hidden; }
|
|
944
|
+
.flxig-tile__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
945
|
+
.flxig-tile__ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--flxig-muted-foreground); }
|
|
946
|
+
.flxig-tile__type { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; gap: 4px; font-size: 0.68rem; font-weight: 600; padding: 3px 7px; border-radius: 999px; background: color-mix(in srgb, #000 55%, transparent); color: #fff; backdrop-filter: blur(4px); }
|
|
947
|
+
.flxig-tile__body { padding: 10px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
|
|
948
|
+
.flxig-tile__cap { font-size: 0.78rem; color: var(--flxig-muted-foreground); margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.1em; }
|
|
949
|
+
|
|
950
|
+
.flxig-sentinel { height: 1px; }
|
|
951
|
+
.flxig-loadmore { display: flex; justify-content: center; padding: 18px 0 2px; color: var(--flxig-muted-foreground); }
|
|
952
|
+
|
|
953
|
+
/* ---- empty / error / loading ---- */
|
|
954
|
+
.flxig-state { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; padding: 48px 16px; color: var(--flxig-muted-foreground); }
|
|
955
|
+
|
|
956
|
+
/* ---- dialog ---- */
|
|
957
|
+
.flxig-overlay { position: fixed; inset: 0; background: color-mix(in srgb, #000 55%, transparent); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 2147483000; animation: flxig-fade .15s ease; }
|
|
958
|
+
.flxig-dialog { background: var(--flxig-popover); color: var(--flxig-popover-foreground); border: 1px solid var(--flxig-border); border-radius: var(--flxig-radius); width: min(560px, 100%); max-height: min(88vh, 760px); display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 24px 60px -20px rgba(0,0,0,.5); animation: flxig-pop .18s cubic-bezier(.2,.8,.2,1); }
|
|
959
|
+
.flxig-dialog__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--flxig-border); }
|
|
960
|
+
.flxig-dialog__body { padding: 18px 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
|
|
961
|
+
.flxig-dialog__foot { padding: 14px 20px; border-top: 1px solid var(--flxig-border); display: flex; gap: 10px; justify-content: flex-end; }
|
|
962
|
+
.flxig-iconbtn { appearance: none; background: transparent; border: none; color: var(--flxig-muted-foreground); cursor: pointer; padding: 4px; border-radius: 8px; display: inline-flex; }
|
|
963
|
+
.flxig-iconbtn:hover { background: var(--flxig-muted); color: var(--flxig-foreground); }
|
|
964
|
+
|
|
965
|
+
/* ---- type picker (segmented) ---- */
|
|
966
|
+
.flxig-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
|
967
|
+
.flxig-seg__opt { border: 1px solid var(--flxig-border); border-radius: calc(var(--flxig-radius) - 2px); padding: 12px; cursor: pointer; display: flex; gap: 10px; align-items: flex-start; background: var(--flxig-card); transition: border-color .15s, background .15s; }
|
|
968
|
+
.flxig-seg__opt:hover { border-color: var(--flxig-ring); }
|
|
969
|
+
.flxig-seg__opt[data-active="true"] { border-color: var(--flxig-primary); background: var(--flxig-accent); }
|
|
970
|
+
.flxig-seg__ic { color: var(--flxig-primary); margin-top: 2px; }
|
|
971
|
+
.flxig-seg__t { font-weight: 650; font-size: 0.88rem; }
|
|
972
|
+
.flxig-seg__d { font-size: 0.74rem; color: var(--flxig-muted-foreground); margin-top: 2px; }
|
|
973
|
+
|
|
974
|
+
/* ---- form fields ---- */
|
|
975
|
+
.flxig-field { display: block; }
|
|
976
|
+
.flxig-input, .flxig-textarea {
|
|
977
|
+
width: 100%; font-family: inherit; font-size: 0.88rem; color: var(--flxig-foreground);
|
|
978
|
+
background: var(--flxig-background); border: 1px solid var(--flxig-input);
|
|
979
|
+
border-radius: calc(var(--flxig-radius) - 4px); padding: 9px 11px; transition: border-color .15s, box-shadow .15s;
|
|
980
|
+
}
|
|
981
|
+
.flxig-input:focus, .flxig-textarea:focus { outline: none; border-color: var(--flxig-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--flxig-ring) 25%, transparent); }
|
|
982
|
+
.flxig-textarea { resize: vertical; min-height: 72px; }
|
|
983
|
+
|
|
984
|
+
/* ---- follow-gate card + switch ---- */
|
|
985
|
+
.flxig-gate { border: 1px solid var(--flxig-border); border-radius: calc(var(--flxig-radius) - 2px); padding: 14px; display: flex; flex-direction: column; gap: 12px; background: var(--flxig-card); }
|
|
986
|
+
.flxig-gate__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
987
|
+
.flxig-gate__fields { display: flex; flex-direction: column; gap: 12px; }
|
|
988
|
+
.flxig-gate__fields[data-off="true"] { opacity: .5; pointer-events: none; }
|
|
989
|
+
|
|
990
|
+
.flxig-switch { position: relative; width: 40px; height: 23px; flex: none; }
|
|
991
|
+
.flxig-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
|
|
992
|
+
.flxig-switch__track { position: absolute; inset: 0; background: var(--flxig-input); border-radius: 999px; transition: background .15s; }
|
|
993
|
+
.flxig-switch__thumb { position: absolute; top: 2px; left: 2px; width: 19px; height: 19px; border-radius: 999px; background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0,0,0,.3); }
|
|
994
|
+
.flxig-switch input:checked ~ .flxig-switch__track { background: var(--flxig-primary); }
|
|
995
|
+
.flxig-switch input:checked ~ .flxig-switch__thumb { transform: translateX(17px); }
|
|
996
|
+
|
|
997
|
+
/* ---- chips (keywords) ---- */
|
|
998
|
+
.flxig-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px; border: 1px solid var(--flxig-input); border-radius: calc(var(--flxig-radius) - 4px); background: var(--flxig-background); }
|
|
999
|
+
.flxig-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--flxig-secondary); color: var(--flxig-secondary-foreground); font-size: 0.78rem; font-weight: 600; padding: 4px 8px; border-radius: 999px; }
|
|
1000
|
+
.flxig-chip button { appearance: none; border: none; background: transparent; color: inherit; cursor: pointer; opacity: .6; padding: 0; display: inline-flex; }
|
|
1001
|
+
.flxig-chip button:hover { opacity: 1; }
|
|
1002
|
+
.flxig-chips input { flex: 1; min-width: 80px; border: none; outline: none; background: transparent; color: var(--flxig-foreground); font-family: inherit; font-size: 0.82rem; padding: 4px; }
|
|
1003
|
+
|
|
1004
|
+
/* ---- link buttons editor ---- */
|
|
1005
|
+
.flxig-links__wrap { display: flex; flex-direction: column; gap: 10px; }
|
|
1006
|
+
.flxig-links { display: flex; flex-direction: column; gap: 10px; }
|
|
1007
|
+
.flxig-link { display: flex; align-items: center; gap: 8px; }
|
|
1008
|
+
.flxig-link__ic { color: var(--flxig-muted-foreground); flex: none; display: inline-flex; }
|
|
1009
|
+
.flxig-link__inputs { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr); gap: 8px; flex: 1; min-width: 0; }
|
|
1010
|
+
.flxig-links__add { align-self: flex-start; padding-left: 8px; padding-right: 12px; }
|
|
1011
|
+
@container (max-width: 440px) { .flxig-link__inputs { grid-template-columns: 1fr; } }
|
|
1012
|
+
|
|
1013
|
+
/* ---- toast ---- */
|
|
1014
|
+
.flxig-toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--flxig-foreground); color: var(--flxig-background); font-size: 0.85rem; font-weight: 600; padding: 10px 16px; border-radius: 999px; display: inline-flex; align-items: center; gap: 8px; z-index: 2147483001; box-shadow: 0 10px 30px -10px rgba(0,0,0,.5); animation: flxig-pop .2s ease; }
|
|
1015
|
+
|
|
1016
|
+
/* ---- footer attribution ---- */
|
|
1017
|
+
.flxig-attrib { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--flxig-border); display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 0.72rem; color: var(--flxig-muted-foreground); }
|
|
1018
|
+
|
|
1019
|
+
/* ---- animations ---- */
|
|
1020
|
+
.flxig-spin { animation: flxig-rotate .8s linear infinite; }
|
|
1021
|
+
@keyframes flxig-rotate { to { transform: rotate(360deg); } }
|
|
1022
|
+
@keyframes flxig-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
1023
|
+
@keyframes flxig-pop { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: scale(1); } }
|
|
1024
|
+
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; } }
|
|
1025
|
+
`;
|
|
1026
|
+
|
|
1027
|
+
// src/widget.ts
|
|
1028
|
+
var RETURN_FLAG = "flxig_connected";
|
|
1029
|
+
var DEFAULT_BASE_URL = "https://flonix.pro";
|
|
1030
|
+
var Widget = class {
|
|
1031
|
+
constructor(target, config) {
|
|
1032
|
+
this.mediaQuery = null;
|
|
1033
|
+
this.token = null;
|
|
1034
|
+
this.account = null;
|
|
1035
|
+
this.postsView = null;
|
|
1036
|
+
this.cursor = null;
|
|
1037
|
+
this.connecting = false;
|
|
1038
|
+
this.destroyed = false;
|
|
1039
|
+
// ---- lifecycle ----
|
|
1040
|
+
this.onSchemeChange = (ev) => this.applyMode(ev.matches);
|
|
1041
|
+
var _a, _b;
|
|
1042
|
+
this.config = config;
|
|
1043
|
+
this.transport = (_b = config.transport) != null ? _b : createHttpTransport((_a = config.baseUrl) != null ? _a : DEFAULT_BASE_URL);
|
|
1044
|
+
this.host = document.createElement("div");
|
|
1045
|
+
this.host.setAttribute("data-flonix-ig", "");
|
|
1046
|
+
target.appendChild(this.host);
|
|
1047
|
+
this.shadow = this.host.attachShadow({ mode: "open" });
|
|
1048
|
+
const theme = resolveTheme(config.theme);
|
|
1049
|
+
this.shadow.appendChild(
|
|
1050
|
+
el("style", { text: `${buildThemeVars(theme)}
|
|
1051
|
+
${STYLES}` })
|
|
1052
|
+
);
|
|
1053
|
+
this.root = el("div", {
|
|
1054
|
+
class: config.appearance === "plain" ? "flxig-root flxig-plain" : "flxig-root"
|
|
1055
|
+
});
|
|
1056
|
+
this.content = el("div", { class: "flxig-content" });
|
|
1057
|
+
this.root.appendChild(this.content);
|
|
1058
|
+
this.shadow.appendChild(this.root);
|
|
1059
|
+
this.applyMode(isDarkActive(theme.mode));
|
|
1060
|
+
if (theme.mode === "auto" && typeof window.matchMedia === "function") {
|
|
1061
|
+
this.mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1062
|
+
this.mediaQuery.addEventListener("change", this.onSchemeChange);
|
|
1063
|
+
}
|
|
1064
|
+
void this.init();
|
|
1065
|
+
}
|
|
1066
|
+
applyMode(dark) {
|
|
1067
|
+
this.host.classList.toggle("flxig-dark", dark);
|
|
1068
|
+
}
|
|
1069
|
+
refresh() {
|
|
1070
|
+
this.cursor = null;
|
|
1071
|
+
void this.init();
|
|
1072
|
+
}
|
|
1073
|
+
unmount() {
|
|
1074
|
+
var _a, _b;
|
|
1075
|
+
this.destroyed = true;
|
|
1076
|
+
(_a = this.postsView) == null ? void 0 : _a.destroy();
|
|
1077
|
+
(_b = this.mediaQuery) == null ? void 0 : _b.removeEventListener("change", this.onSchemeChange);
|
|
1078
|
+
this.host.remove();
|
|
1079
|
+
}
|
|
1080
|
+
fail(error) {
|
|
1081
|
+
var _a, _b;
|
|
1082
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1083
|
+
(_b = (_a = this.config).onError) == null ? void 0 : _b.call(_a, err);
|
|
1084
|
+
return err;
|
|
1085
|
+
}
|
|
1086
|
+
// ---- flow ----
|
|
1087
|
+
async init() {
|
|
1088
|
+
var _a, _b, _c;
|
|
1089
|
+
this.renderLoading();
|
|
1090
|
+
try {
|
|
1091
|
+
const session = await this.transport.session({
|
|
1092
|
+
apiKey: this.config.apiKey,
|
|
1093
|
+
user: this.config.user
|
|
1094
|
+
});
|
|
1095
|
+
if (this.destroyed) return;
|
|
1096
|
+
this.token = session.token;
|
|
1097
|
+
this.account = session.account;
|
|
1098
|
+
if (session.connected) {
|
|
1099
|
+
this.clearReturnFlag();
|
|
1100
|
+
(_c = (_b = this.config).onConnected) == null ? void 0 : _c.call(_b, (_a = session.account) != null ? _a : { instagramId: null, username: null });
|
|
1101
|
+
await this.renderPosts();
|
|
1102
|
+
} else {
|
|
1103
|
+
this.renderConnect();
|
|
1104
|
+
}
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
this.renderError(this.fail(error).message);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
async startConnect() {
|
|
1110
|
+
if (!this.token || this.connecting) return;
|
|
1111
|
+
this.connecting = true;
|
|
1112
|
+
this.renderConnect();
|
|
1113
|
+
try {
|
|
1114
|
+
const { authorizeUrl } = await this.transport.connectStart({
|
|
1115
|
+
token: this.token,
|
|
1116
|
+
returnUrl: this.resolveReturnUrl()
|
|
1117
|
+
});
|
|
1118
|
+
window.location.href = authorizeUrl;
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
this.connecting = false;
|
|
1121
|
+
this.renderConnect();
|
|
1122
|
+
this.toast(this.fail(error).message);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
async renderPosts() {
|
|
1126
|
+
const view = renderPosts({
|
|
1127
|
+
account: this.account,
|
|
1128
|
+
onAutomate: (post) => this.openDialog(post),
|
|
1129
|
+
onLoadMore: () => void this.loadMore()
|
|
1130
|
+
});
|
|
1131
|
+
this.postsView = view;
|
|
1132
|
+
this.swap(view.element);
|
|
1133
|
+
await this.loadMore(true);
|
|
1134
|
+
}
|
|
1135
|
+
async loadMore(initial = false) {
|
|
1136
|
+
const view = this.postsView;
|
|
1137
|
+
if (!view || !this.token) return;
|
|
1138
|
+
view.setLoadingMore(true);
|
|
1139
|
+
try {
|
|
1140
|
+
const { posts, nextCursor } = await this.transport.posts({
|
|
1141
|
+
token: this.token,
|
|
1142
|
+
cursor: this.cursor
|
|
1143
|
+
});
|
|
1144
|
+
if (this.destroyed) return;
|
|
1145
|
+
if (initial && posts.length === 0) {
|
|
1146
|
+
view.showEmpty();
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
view.appendPosts(posts);
|
|
1150
|
+
this.cursor = nextCursor;
|
|
1151
|
+
view.setHasMore(Boolean(nextCursor));
|
|
1152
|
+
} catch (error) {
|
|
1153
|
+
this.toast(this.fail(error).message);
|
|
1154
|
+
} finally {
|
|
1155
|
+
view.setLoadingMore(false);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
openDialog(post) {
|
|
1159
|
+
if (!this.token) return;
|
|
1160
|
+
openAutomateDialog({
|
|
1161
|
+
mount: this.shadow,
|
|
1162
|
+
post,
|
|
1163
|
+
account: this.account,
|
|
1164
|
+
onToast: (message) => this.toast(message),
|
|
1165
|
+
onSubmit: (data) => this.createAutomation(data)
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
async createAutomation(data) {
|
|
1169
|
+
var _a, _b;
|
|
1170
|
+
if (!this.token) throw new Error("Not connected");
|
|
1171
|
+
const result = await this.transport.createAutomation({ token: this.token, data });
|
|
1172
|
+
(_b = (_a = this.config).onAutomationCreated) == null ? void 0 : _b.call(_a, result);
|
|
1173
|
+
this.toast("Automation created \u2713");
|
|
1174
|
+
}
|
|
1175
|
+
// ---- rendering helpers ----
|
|
1176
|
+
swap(node) {
|
|
1177
|
+
clear(this.content);
|
|
1178
|
+
this.content.appendChild(node);
|
|
1179
|
+
}
|
|
1180
|
+
renderConnect() {
|
|
1181
|
+
this.swap(
|
|
1182
|
+
renderConnect({
|
|
1183
|
+
connecting: this.connecting,
|
|
1184
|
+
partner: this.config.partner,
|
|
1185
|
+
onConnect: () => void this.startConnect()
|
|
1186
|
+
})
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
renderLoading() {
|
|
1190
|
+
this.swap(stateBlock({ icon: icons.spinner(26), title: "Loading\u2026" }));
|
|
1191
|
+
}
|
|
1192
|
+
renderError(message) {
|
|
1193
|
+
this.swap(
|
|
1194
|
+
stateBlock({
|
|
1195
|
+
icon: icons.close(26),
|
|
1196
|
+
title: "Couldn't load",
|
|
1197
|
+
detail: message
|
|
1198
|
+
})
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
toast(message) {
|
|
1202
|
+
const toast = fromMarkup(
|
|
1203
|
+
`<div class="flxig-toast">${icons.bolt(14)}<span></span></div>`
|
|
1204
|
+
);
|
|
1205
|
+
toast.querySelector("span").textContent = message;
|
|
1206
|
+
this.shadow.appendChild(toast);
|
|
1207
|
+
setTimeout(() => toast.remove(), 2600);
|
|
1208
|
+
}
|
|
1209
|
+
// ---- return-from-OAuth handling ----
|
|
1210
|
+
resolveReturnUrl() {
|
|
1211
|
+
if (this.config.returnUrl) return this.config.returnUrl;
|
|
1212
|
+
if (typeof window === "undefined") return "";
|
|
1213
|
+
return window.location.href;
|
|
1214
|
+
}
|
|
1215
|
+
clearReturnFlag() {
|
|
1216
|
+
var _a;
|
|
1217
|
+
if (typeof window === "undefined" || !((_a = window.history) == null ? void 0 : _a.replaceState)) return;
|
|
1218
|
+
const url = new URL(window.location.href);
|
|
1219
|
+
if (url.searchParams.has(RETURN_FLAG)) {
|
|
1220
|
+
url.searchParams.delete(RETURN_FLAG);
|
|
1221
|
+
window.history.replaceState({}, "", url.toString());
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
// src/mock.ts
|
|
1227
|
+
var delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1228
|
+
var TYPES = ["IMAGE", "CAROUSEL", "REELS", "VIDEO", "IMAGE"];
|
|
1229
|
+
var CAPTIONS = [
|
|
1230
|
+
"New drop is live \u{1F525} comment LINK for the shop",
|
|
1231
|
+
"Behind the scenes of today's shoot",
|
|
1232
|
+
"Our bestseller is back in stock \u2728",
|
|
1233
|
+
"How to style this 3 ways \u{1F447}",
|
|
1234
|
+
"Limited edition \u2014 only 50 made",
|
|
1235
|
+
"Weekend sale starts now \u{1F6CD}\uFE0F",
|
|
1236
|
+
null,
|
|
1237
|
+
"Tag a friend who needs this \u{1F499}"
|
|
1238
|
+
];
|
|
1239
|
+
function makePage(page, perPage) {
|
|
1240
|
+
return Array.from({ length: perPage }, (_, i) => {
|
|
1241
|
+
var _a, _b;
|
|
1242
|
+
const n = page * perPage + i;
|
|
1243
|
+
return {
|
|
1244
|
+
id: `mock_${n}`,
|
|
1245
|
+
caption: (_a = CAPTIONS[n % CAPTIONS.length]) != null ? _a : null,
|
|
1246
|
+
media: `https://picsum.photos/seed/flonix${n}/600/600`,
|
|
1247
|
+
mediaType: (_b = TYPES[n % TYPES.length]) != null ? _b : "IMAGE",
|
|
1248
|
+
permalink: null,
|
|
1249
|
+
timestamp: new Date(Date.now() - n * 864e5).toISOString()
|
|
1250
|
+
};
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
function createMockTransport(options = {}) {
|
|
1254
|
+
var _a, _b, _c;
|
|
1255
|
+
const totalPages = (_a = options.totalPages) != null ? _a : 3;
|
|
1256
|
+
const perPage = (_b = options.perPage) != null ? _b : 8;
|
|
1257
|
+
const storageKey = `flxig.mock.connected.${(_c = options.namespace) != null ? _c : "default"}`;
|
|
1258
|
+
const isConnected = () => {
|
|
1259
|
+
try {
|
|
1260
|
+
return localStorage.getItem(storageKey) === "1";
|
|
1261
|
+
} catch {
|
|
1262
|
+
return false;
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
return {
|
|
1266
|
+
async session() {
|
|
1267
|
+
await delay(400);
|
|
1268
|
+
const connected = isConnected();
|
|
1269
|
+
return {
|
|
1270
|
+
connected,
|
|
1271
|
+
token: "mock-session-token",
|
|
1272
|
+
account: connected ? { instagramId: "17890000000", username: "your_brand" } : null
|
|
1273
|
+
};
|
|
1274
|
+
},
|
|
1275
|
+
async connectStart({ returnUrl }) {
|
|
1276
|
+
await delay(500);
|
|
1277
|
+
try {
|
|
1278
|
+
localStorage.setItem(storageKey, "1");
|
|
1279
|
+
} catch {
|
|
1280
|
+
}
|
|
1281
|
+
const url = new URL(returnUrl, window.location.href);
|
|
1282
|
+
url.searchParams.set("flxig_connected", "1");
|
|
1283
|
+
return { authorizeUrl: url.toString() };
|
|
1284
|
+
},
|
|
1285
|
+
async posts({ cursor }) {
|
|
1286
|
+
await delay(500);
|
|
1287
|
+
const page = cursor ? Number(cursor) : 0;
|
|
1288
|
+
const posts = makePage(page, perPage);
|
|
1289
|
+
const next = page + 1;
|
|
1290
|
+
return { posts, nextCursor: next < totalPages ? String(next) : null };
|
|
1291
|
+
},
|
|
1292
|
+
async createAutomation() {
|
|
1293
|
+
await delay(700);
|
|
1294
|
+
return { id: `mock_automation_${Date.now()}` };
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// src/index.ts
|
|
1300
|
+
var version = "0.1.1";
|
|
1301
|
+
function mount(target, config) {
|
|
1302
|
+
var _a, _b, _c;
|
|
1303
|
+
const element = typeof target === "string" ? document.querySelector(target) : target;
|
|
1304
|
+
if (!element) {
|
|
1305
|
+
throw new Error(`FlonixIG.mount: target not found: ${String(target)}`);
|
|
1306
|
+
}
|
|
1307
|
+
if (!(config == null ? void 0 : config.apiKey)) {
|
|
1308
|
+
throw new Error("FlonixIG.mount: config.apiKey is required");
|
|
1309
|
+
}
|
|
1310
|
+
if (!((_a = config == null ? void 0 : config.user) == null ? void 0 : _a.id)) {
|
|
1311
|
+
throw new Error("FlonixIG.mount: config.user.id is required");
|
|
1312
|
+
}
|
|
1313
|
+
if (!((_b = config == null ? void 0 : config.partner) == null ? void 0 : _b.logo) || !((_c = config == null ? void 0 : config.partner) == null ? void 0 : _c.name)) {
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
"FlonixIG.mount: config.partner.name and config.partner.logo are required"
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
return new Widget(element, config);
|
|
1319
|
+
}
|
|
1320
|
+
var FlonixIG = { mount, version };
|
|
1321
|
+
|
|
1322
|
+
export { DEFAULT_TOKENS, FlonixIG, createHttpTransport, createMockTransport, mount, version };
|
|
1323
|
+
//# sourceMappingURL=index.mjs.map
|
|
1324
|
+
//# sourceMappingURL=index.mjs.map
|