open-nami 1.2.3 → 1.2.4
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/dist/cli.js +332 -127
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ var require_package = __commonJS({
|
|
|
9
9
|
"package.json"(exports, module) {
|
|
10
10
|
module.exports = {
|
|
11
11
|
name: "open-nami",
|
|
12
|
-
version: "1.2.
|
|
12
|
+
version: "1.2.4",
|
|
13
13
|
description: "Open Nami: terminal-first bulk social media profile downloader for Instagram, TikTok, Facebook & X.",
|
|
14
14
|
type: "module",
|
|
15
15
|
bin: {
|
|
@@ -287,15 +287,17 @@ function FramedInput({
|
|
|
287
287
|
children
|
|
288
288
|
}) {
|
|
289
289
|
const theme = useTheme();
|
|
290
|
-
const inner = width - 2;
|
|
291
|
-
const
|
|
290
|
+
const inner = Math.max(0, width - 2);
|
|
291
|
+
const maxTitleLen = Math.max(0, inner - 4);
|
|
292
|
+
const displayTitle = title.length > maxTitleLen ? title.slice(0, Math.max(0, maxTitleLen - 1)) + "\u2026" : title;
|
|
293
|
+
const tail = Math.max(0, inner - displayTitle.length - 3);
|
|
292
294
|
const buttonW = button ? frameButtonWidth(button) : 0;
|
|
293
295
|
const fillColor = buttonDim ? theme.gray : theme.primary;
|
|
294
296
|
return /* @__PURE__ */ jsxs2(Box3, { width: width + buttonW, children: [
|
|
295
297
|
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", width, children: [
|
|
296
|
-
/* @__PURE__ */ jsxs2(Text3, { children: [
|
|
298
|
+
/* @__PURE__ */ jsxs2(Text3, { wrap: "truncate-end", children: [
|
|
297
299
|
/* @__PURE__ */ jsx4(Text3, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u256D\u2500 " }),
|
|
298
|
-
/* @__PURE__ */ jsx4(Text3, { color: theme.primary, children:
|
|
300
|
+
/* @__PURE__ */ jsx4(Text3, { color: theme.primary, children: displayTitle }),
|
|
299
301
|
/* @__PURE__ */ jsx4(Text3, { color: theme.gray, dimColor: theme.dimSecondary, children: ` ${"\u2500".repeat(tail)}${button ? "\u2500" : "\u256E"}` })
|
|
300
302
|
] }),
|
|
301
303
|
/* @__PURE__ */ jsxs2(Box3, { width, height: 1, overflow: "hidden", children: [
|
|
@@ -661,12 +663,14 @@ import { Box as Box5, Text as Text6 } from "ink";
|
|
|
661
663
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
662
664
|
function Panel({ title, width, children }) {
|
|
663
665
|
const theme = useTheme();
|
|
664
|
-
const inner = width - 2;
|
|
665
|
-
const
|
|
666
|
+
const inner = Math.max(0, width - 2);
|
|
667
|
+
const maxTitleLen = Math.max(0, inner - 4);
|
|
668
|
+
const displayTitle = title.length > maxTitleLen ? title.slice(0, Math.max(0, maxTitleLen - 1)) + "\u2026" : title;
|
|
669
|
+
const tail = Math.max(0, inner - displayTitle.length - 3);
|
|
666
670
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", width, children: [
|
|
667
|
-
/* @__PURE__ */ jsxs5(Text6, { children: [
|
|
671
|
+
/* @__PURE__ */ jsxs5(Text6, { wrap: "truncate-end", children: [
|
|
668
672
|
/* @__PURE__ */ jsx7(Text6, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u256D\u2500 " }),
|
|
669
|
-
/* @__PURE__ */ jsx7(Text6, { color: theme.primary, children:
|
|
673
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.primary, children: displayTitle }),
|
|
670
674
|
/* @__PURE__ */ jsx7(Text6, { color: theme.gray, dimColor: theme.dimSecondary, children: ` ${"\u2500".repeat(tail)}\u256E` })
|
|
671
675
|
] }),
|
|
672
676
|
/* @__PURE__ */ jsx7(
|
|
@@ -3323,6 +3327,15 @@ function parseDateBoundary(input, boundary) {
|
|
|
3323
3327
|
return nowSeconds - offsetSeconds;
|
|
3324
3328
|
}
|
|
3325
3329
|
if (/^\d+$/.test(trimmed)) {
|
|
3330
|
+
if (trimmed.length === 4) {
|
|
3331
|
+
const year = parseInt(trimmed, 10);
|
|
3332
|
+
if (year >= 1990 && year <= 2100) {
|
|
3333
|
+
const date = boundary === "until" ? new Date(Date.UTC(year, 11, 31, 23, 59, 59, 999)) : new Date(Date.UTC(year, 0, 1, 0, 0, 0, 0));
|
|
3334
|
+
if (!isNaN(date.getTime())) {
|
|
3335
|
+
return Math.floor(date.getTime() / 1e3);
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3326
3339
|
if (trimmed.length === 8) {
|
|
3327
3340
|
const year = parseInt(trimmed.slice(0, 4), 10);
|
|
3328
3341
|
const month = parseInt(trimmed.slice(4, 6), 10) - 1;
|
|
@@ -3338,6 +3351,14 @@ function parseDateBoundary(input, boundary) {
|
|
|
3338
3351
|
}
|
|
3339
3352
|
return num;
|
|
3340
3353
|
}
|
|
3354
|
+
if (/^\d{4}-\d{2}$/.test(trimmed)) {
|
|
3355
|
+
const year = parseInt(trimmed.slice(0, 4), 10);
|
|
3356
|
+
const month = parseInt(trimmed.slice(5, 7), 10);
|
|
3357
|
+
const date = boundary === "until" ? new Date(Date.UTC(year, month, 0, 23, 59, 59, 999)) : new Date(Date.UTC(year, month - 1, 1, 0, 0, 0, 0));
|
|
3358
|
+
if (!isNaN(date.getTime())) {
|
|
3359
|
+
return Math.floor(date.getTime() / 1e3);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3341
3362
|
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
|
3342
3363
|
const timeStr = boundary === "until" ? "T23:59:59.999Z" : "T00:00:00.000Z";
|
|
3343
3364
|
const parsed2 = /* @__PURE__ */ new Date(`${trimmed}${timeStr}`);
|
|
@@ -3351,8 +3372,34 @@ function parseDateBoundary(input, boundary) {
|
|
|
3351
3372
|
}
|
|
3352
3373
|
return void 0;
|
|
3353
3374
|
}
|
|
3375
|
+
function resolveDateFilter(input) {
|
|
3376
|
+
if (!input) return {};
|
|
3377
|
+
const trimmed = input.trim();
|
|
3378
|
+
if (!trimmed || trimmed.toLowerCase() === "all" || trimmed.toLowerCase() === "none") return {};
|
|
3379
|
+
if (trimmed.includes("..") || /\s+-\s+/.test(trimmed)) {
|
|
3380
|
+
const parts = trimmed.split(/\.\.|\s+-\s+/);
|
|
3381
|
+
return {
|
|
3382
|
+
since: parts[0]?.trim(),
|
|
3383
|
+
until: parts[1]?.trim()
|
|
3384
|
+
};
|
|
3385
|
+
}
|
|
3386
|
+
if (/^\d{4}$/.test(trimmed) || /^\d{4}-\d{2}$/.test(trimmed)) {
|
|
3387
|
+
return {
|
|
3388
|
+
since: trimmed,
|
|
3389
|
+
until: trimmed
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
return {
|
|
3393
|
+
since: trimmed,
|
|
3394
|
+
until: void 0
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3354
3397
|
function parseLimit(input) {
|
|
3355
3398
|
if (input === void 0 || input === null) return void 0;
|
|
3399
|
+
if (typeof input === "string") {
|
|
3400
|
+
const trimmed = input.trim().toLowerCase();
|
|
3401
|
+
if (!trimmed || trimmed === "all" || trimmed === "none" || trimmed === "0") return void 0;
|
|
3402
|
+
}
|
|
3356
3403
|
const num = typeof input === "number" ? input : parseInt(String(input).trim(), 10);
|
|
3357
3404
|
if (isNaN(num) || num <= 0) return void 0;
|
|
3358
3405
|
return Math.floor(num);
|
|
@@ -4321,7 +4368,7 @@ async function dispatchDownload(options) {
|
|
|
4321
4368
|
}
|
|
4322
4369
|
|
|
4323
4370
|
// src/components/views/picking-view.tsx
|
|
4324
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4371
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4325
4372
|
function ChoiceIndicator({ isSelected }) {
|
|
4326
4373
|
const theme = useTheme();
|
|
4327
4374
|
return /* @__PURE__ */ jsx8(Box6, { marginRight: 1, children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: isSelected ? "\u276F" : " " }) });
|
|
@@ -4345,6 +4392,8 @@ function getPickingOptions(platform) {
|
|
|
4345
4392
|
});
|
|
4346
4393
|
return items;
|
|
4347
4394
|
}
|
|
4395
|
+
var DATE_PRESETS = ["all", "24h", "7d", "30d", "2024", "2023", "2022", "2021", "custom"];
|
|
4396
|
+
var LIMIT_PRESETS = [void 0, 10, 24, 50, 100, "custom"];
|
|
4348
4397
|
function PickingView({
|
|
4349
4398
|
contentWidth,
|
|
4350
4399
|
profile,
|
|
@@ -4362,14 +4411,17 @@ function PickingView({
|
|
|
4362
4411
|
const items = getPickingOptions(profile.platform);
|
|
4363
4412
|
const [limit, setLimit] = useState4(initialLimit);
|
|
4364
4413
|
const [dateFilter, setDateFilter] = useState4(() => {
|
|
4365
|
-
if (typeof initialSince === "string" && (
|
|
4366
|
-
return initialSince;
|
|
4414
|
+
if (typeof initialSince === "string" && initialSince.trim()) {
|
|
4415
|
+
return initialSince.trim();
|
|
4367
4416
|
}
|
|
4368
4417
|
return "all";
|
|
4369
4418
|
});
|
|
4370
4419
|
const [writeMetadata, setWriteMetadata] = useState4(initialWriteMetadata);
|
|
4371
4420
|
const [resume, setResume] = useState4(initialResume);
|
|
4372
4421
|
const [hasCheckpoint, setHasCheckpoint] = useState4(false);
|
|
4422
|
+
const [editingModal, setEditingModal] = useState4(null);
|
|
4423
|
+
const [customLimitText, setCustomLimitText] = useState4("");
|
|
4424
|
+
const [customDateText, setCustomDateText] = useState4("");
|
|
4373
4425
|
const targetDir = resolveDefaultDownloadDir(profile.platform, profile.username, outputDir);
|
|
4374
4426
|
useEffect4(() => {
|
|
4375
4427
|
let isMounted = true;
|
|
@@ -4385,29 +4437,40 @@ function PickingView({
|
|
|
4385
4437
|
};
|
|
4386
4438
|
}, [targetDir]);
|
|
4387
4439
|
const cycleLimit = useCallback(() => {
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
}
|
|
4395
|
-
|
|
4440
|
+
const curIdx = LIMIT_PRESETS.findIndex((p) => p === limit);
|
|
4441
|
+
const nextIdx = (curIdx + 1) % LIMIT_PRESETS.length;
|
|
4442
|
+
const nextVal = LIMIT_PRESETS[nextIdx];
|
|
4443
|
+
if (nextVal === "custom") {
|
|
4444
|
+
setCustomLimitText(limit ? String(limit) : "24");
|
|
4445
|
+
setEditingModal("limit");
|
|
4446
|
+
} else {
|
|
4447
|
+
setLimit(nextVal);
|
|
4448
|
+
}
|
|
4449
|
+
}, [limit]);
|
|
4396
4450
|
const cycleDate = useCallback(() => {
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4451
|
+
const curIdx = DATE_PRESETS.indexOf(dateFilter);
|
|
4452
|
+
const nextIdx = (curIdx + 1) % DATE_PRESETS.length;
|
|
4453
|
+
const nextVal = DATE_PRESETS[nextIdx];
|
|
4454
|
+
if (nextVal === "custom") {
|
|
4455
|
+
setCustomDateText(dateFilter !== "all" ? dateFilter : "2021");
|
|
4456
|
+
setEditingModal("date");
|
|
4457
|
+
} else {
|
|
4458
|
+
setDateFilter(nextVal);
|
|
4459
|
+
}
|
|
4460
|
+
}, [dateFilter]);
|
|
4404
4461
|
const toggleMetadata = useCallback(() => {
|
|
4405
4462
|
setWriteMetadata((prev) => !prev);
|
|
4406
4463
|
}, []);
|
|
4407
4464
|
const toggleResume = useCallback(() => {
|
|
4408
4465
|
setResume((prev) => !prev);
|
|
4409
4466
|
}, []);
|
|
4410
|
-
useInput2((input) => {
|
|
4467
|
+
useInput2((input, key) => {
|
|
4468
|
+
if (editingModal) {
|
|
4469
|
+
if (key.escape) {
|
|
4470
|
+
setEditingModal(null);
|
|
4471
|
+
}
|
|
4472
|
+
return;
|
|
4473
|
+
}
|
|
4411
4474
|
if (input === "l" || input === "L") {
|
|
4412
4475
|
cycleLimit();
|
|
4413
4476
|
return;
|
|
@@ -4426,10 +4489,13 @@ function PickingView({
|
|
|
4426
4489
|
}
|
|
4427
4490
|
}, { isActive: Boolean(process.stdin.isTTY) });
|
|
4428
4491
|
const handleItemSelect = (selectedChoice) => {
|
|
4492
|
+
if (editingModal) return;
|
|
4493
|
+
const dateRange = resolveDateFilter(dateFilter);
|
|
4429
4494
|
onSelect({
|
|
4430
4495
|
choice: selectedChoice,
|
|
4431
4496
|
limit,
|
|
4432
|
-
since:
|
|
4497
|
+
since: dateRange.since,
|
|
4498
|
+
until: dateRange.until,
|
|
4433
4499
|
writeMetadata,
|
|
4434
4500
|
resume
|
|
4435
4501
|
});
|
|
@@ -4447,12 +4513,11 @@ function PickingView({
|
|
|
4447
4513
|
profile.cleanUrl ? ` \xB7 ${profile.cleanUrl}` : ""
|
|
4448
4514
|
] }),
|
|
4449
4515
|
/* @__PURE__ */ jsx8(Gap2, {}),
|
|
4450
|
-
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "
|
|
4451
|
-
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "Use hotkeys [l], [d], [m], [r] to adjust options." }),
|
|
4516
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "Select media type. Hotkeys [l], [d], [m], [r] adjust options." }),
|
|
4452
4517
|
hasCheckpoint ? /* @__PURE__ */ jsx8(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: "\u26A1 Checkpoint found (cursor saved)" }) }) : null
|
|
4453
4518
|
] }),
|
|
4454
4519
|
/* @__PURE__ */ jsxs6(Panel, { title: "Download", width: 38, children: [
|
|
4455
|
-
/* @__PURE__ */ jsx8(
|
|
4520
|
+
!editingModal && /* @__PURE__ */ jsx8(
|
|
4456
4521
|
SelectInput,
|
|
4457
4522
|
{
|
|
4458
4523
|
indicatorComponent: ChoiceIndicator,
|
|
@@ -4466,29 +4531,61 @@ function PickingView({
|
|
|
4466
4531
|
onHighlight: (item) => onHighlight?.(item.value)
|
|
4467
4532
|
}
|
|
4468
4533
|
),
|
|
4469
|
-
/* @__PURE__ */
|
|
4534
|
+
/* @__PURE__ */ jsx8(
|
|
4470
4535
|
Box6,
|
|
4471
4536
|
{
|
|
4472
4537
|
flexDirection: "column",
|
|
4473
4538
|
marginTop: 1,
|
|
4474
4539
|
borderStyle: "round",
|
|
4475
|
-
borderColor: theme.gray,
|
|
4476
|
-
borderDimColor:
|
|
4540
|
+
borderColor: editingModal ? theme.primary : theme.gray,
|
|
4541
|
+
borderDimColor: !editingModal,
|
|
4477
4542
|
paddingX: 1,
|
|
4478
|
-
children: [
|
|
4543
|
+
children: editingModal === "limit" ? /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
4544
|
+
/* @__PURE__ */ jsx8(Text7, { bold: true, color: theme.primary, children: "Set post limit (e.g. 24, all):" }),
|
|
4545
|
+
/* @__PURE__ */ jsx8(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
4546
|
+
TextInput,
|
|
4547
|
+
{
|
|
4548
|
+
value: customLimitText,
|
|
4549
|
+
onChange: setCustomLimitText,
|
|
4550
|
+
onSubmit: (val) => {
|
|
4551
|
+
const parsed = parseLimit(val);
|
|
4552
|
+
setLimit(parsed);
|
|
4553
|
+
setEditingModal(null);
|
|
4554
|
+
},
|
|
4555
|
+
width: 24
|
|
4556
|
+
}
|
|
4557
|
+
) }),
|
|
4558
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
|
|
4559
|
+
] }) : editingModal === "date" ? /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
4560
|
+
/* @__PURE__ */ jsx8(Text7, { bold: true, color: theme.primary, children: "Set date or year (e.g. 2021, 7d):" }),
|
|
4561
|
+
/* @__PURE__ */ jsx8(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
4562
|
+
TextInput,
|
|
4563
|
+
{
|
|
4564
|
+
value: customDateText,
|
|
4565
|
+
onChange: setCustomDateText,
|
|
4566
|
+
onSubmit: (val) => {
|
|
4567
|
+
const trimmed = val.trim();
|
|
4568
|
+
setDateFilter(trimmed ? trimmed : "all");
|
|
4569
|
+
setEditingModal(null);
|
|
4570
|
+
},
|
|
4571
|
+
width: 24
|
|
4572
|
+
}
|
|
4573
|
+
) }),
|
|
4574
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
|
|
4575
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
4479
4576
|
/* @__PURE__ */ jsxs6(Box6, { justifyContent: "space-between", children: [
|
|
4480
4577
|
/* @__PURE__ */ jsxs6(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
4481
|
-
"[l]
|
|
4578
|
+
"[l] Posts: ",
|
|
4482
4579
|
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: limit ? `${limit}` : "ALL" })
|
|
4483
4580
|
] }),
|
|
4484
4581
|
/* @__PURE__ */ jsxs6(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
4485
4582
|
"[d] Date: ",
|
|
4486
|
-
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: dateFilter
|
|
4583
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: dateFilter.toUpperCase() })
|
|
4487
4584
|
] })
|
|
4488
4585
|
] }),
|
|
4489
4586
|
/* @__PURE__ */ jsxs6(Box6, { justifyContent: "space-between", children: [
|
|
4490
4587
|
/* @__PURE__ */ jsxs6(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
4491
|
-
"[m]
|
|
4588
|
+
"[m] Meta: ",
|
|
4492
4589
|
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: writeMetadata ? "ON" : "OFF" })
|
|
4493
4590
|
] }),
|
|
4494
4591
|
/* @__PURE__ */ jsxs6(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
@@ -4496,7 +4593,7 @@ function PickingView({
|
|
|
4496
4593
|
/* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: resume ? "ON" : "OFF" })
|
|
4497
4594
|
] })
|
|
4498
4595
|
] })
|
|
4499
|
-
]
|
|
4596
|
+
] })
|
|
4500
4597
|
}
|
|
4501
4598
|
)
|
|
4502
4599
|
] })
|
|
@@ -4711,7 +4808,7 @@ function DownloadingView({
|
|
|
4711
4808
|
// src/components/views/completion-view.tsx
|
|
4712
4809
|
import os7 from "os";
|
|
4713
4810
|
import { Box as Box10, Text as Text12 } from "ink";
|
|
4714
|
-
import { Fragment as
|
|
4811
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4715
4812
|
var DONE_LABEL = "\u21B5 download another";
|
|
4716
4813
|
function CompletionView({
|
|
4717
4814
|
profile,
|
|
@@ -4723,10 +4820,10 @@ function CompletionView({
|
|
|
4723
4820
|
const plural = result.downloadedCount === 1 ? "" : "s";
|
|
4724
4821
|
const skipText = result.skippedCount > 0 ? ` (${result.skippedCount} archived)` : "";
|
|
4725
4822
|
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", alignItems: "center", children: [
|
|
4726
|
-
/* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(
|
|
4823
|
+
/* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4727
4824
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile scanned " }),
|
|
4728
4825
|
/* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "\u2014 0 media items found" })
|
|
4729
|
-
] }) : /* @__PURE__ */ jsxs10(
|
|
4826
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4730
4827
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile downloaded! " }),
|
|
4731
4828
|
/* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "saved to:" })
|
|
4732
4829
|
] }) }),
|
|
@@ -5646,7 +5743,9 @@ async function runBatchQueue(options) {
|
|
|
5646
5743
|
}
|
|
5647
5744
|
|
|
5648
5745
|
// src/components/views/batch-view.tsx
|
|
5649
|
-
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5746
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5747
|
+
var DATE_PRESETS2 = ["all", "24h", "7d", "30d", "2024", "2023", "2022", "2021", "custom"];
|
|
5748
|
+
var LIMIT_PRESETS2 = [void 0, 10, 24, 50, 100, "custom"];
|
|
5650
5749
|
function BatchView({
|
|
5651
5750
|
onBack,
|
|
5652
5751
|
outputDir,
|
|
@@ -5662,6 +5761,9 @@ function BatchView({
|
|
|
5662
5761
|
const [rawText, setRawText] = useState8("");
|
|
5663
5762
|
const [filePath, setFilePath] = useState8("");
|
|
5664
5763
|
const [errorMessage, setErrorMessage] = useState8(null);
|
|
5764
|
+
const [focusSection, setFocusSection] = useState8("input");
|
|
5765
|
+
const [customLimitText, setCustomLimitText] = useState8("");
|
|
5766
|
+
const [customDateText, setCustomDateText] = useState8("");
|
|
5665
5767
|
const [choice, setChoice] = useState8(defaultChoice);
|
|
5666
5768
|
const [limit, setLimit] = useState8(defaultLimit);
|
|
5667
5769
|
const [dateFilter, setDateFilter] = useState8("all");
|
|
@@ -5681,22 +5783,27 @@ function BatchView({
|
|
|
5681
5783
|
});
|
|
5682
5784
|
}, []);
|
|
5683
5785
|
const cycleLimit = useCallback4(() => {
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
}
|
|
5691
|
-
|
|
5786
|
+
const curIdx = LIMIT_PRESETS2.findIndex((p) => p === limit);
|
|
5787
|
+
const nextIdx = (curIdx + 1) % LIMIT_PRESETS2.length;
|
|
5788
|
+
const nextVal = LIMIT_PRESETS2[nextIdx];
|
|
5789
|
+
if (nextVal === "custom") {
|
|
5790
|
+
setCustomLimitText(limit ? String(limit) : "24");
|
|
5791
|
+
setFocusSection("custom-limit");
|
|
5792
|
+
} else {
|
|
5793
|
+
setLimit(nextVal);
|
|
5794
|
+
}
|
|
5795
|
+
}, [limit]);
|
|
5692
5796
|
const cycleDate = useCallback4(() => {
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5797
|
+
const curIdx = DATE_PRESETS2.indexOf(dateFilter);
|
|
5798
|
+
const nextIdx = (curIdx + 1) % DATE_PRESETS2.length;
|
|
5799
|
+
const nextVal = DATE_PRESETS2[nextIdx];
|
|
5800
|
+
if (nextVal === "custom") {
|
|
5801
|
+
setCustomDateText(dateFilter !== "all" ? dateFilter : "2021");
|
|
5802
|
+
setFocusSection("custom-date");
|
|
5803
|
+
} else {
|
|
5804
|
+
setDateFilter(nextVal);
|
|
5805
|
+
}
|
|
5806
|
+
}, [dateFilter]);
|
|
5700
5807
|
const toggleMetadata = useCallback4(() => {
|
|
5701
5808
|
setWriteMetadata((prev) => !prev);
|
|
5702
5809
|
}, []);
|
|
@@ -5727,12 +5834,14 @@ function BatchView({
|
|
|
5727
5834
|
abortControllerRef.current = controller;
|
|
5728
5835
|
setPhase("running");
|
|
5729
5836
|
try {
|
|
5837
|
+
const dateRange = resolveDateFilter(dateFilter);
|
|
5730
5838
|
const queueRes = await runBatchQueue({
|
|
5731
5839
|
filePath: inputField === "file" ? filePath.trim() : void 0,
|
|
5732
5840
|
lines: inputField === "text" ? lines : void 0,
|
|
5733
5841
|
choice,
|
|
5734
5842
|
outputDir,
|
|
5735
|
-
since:
|
|
5843
|
+
since: dateRange.since,
|
|
5844
|
+
until: dateRange.until,
|
|
5736
5845
|
limit,
|
|
5737
5846
|
resume,
|
|
5738
5847
|
writeMetadata,
|
|
@@ -5748,7 +5857,7 @@ function BatchView({
|
|
|
5748
5857
|
return next;
|
|
5749
5858
|
});
|
|
5750
5859
|
},
|
|
5751
|
-
onAccountProgress: (
|
|
5860
|
+
onAccountProgress: (_item, progress) => {
|
|
5752
5861
|
setCurrentProgressText(progress.statusText);
|
|
5753
5862
|
},
|
|
5754
5863
|
onAccountComplete: (item, idx) => {
|
|
@@ -5785,6 +5894,14 @@ function BatchView({
|
|
|
5785
5894
|
}, [inputField, filePath, rawText, choice, outputDir, dateFilter, limit, resume, writeMetadata]);
|
|
5786
5895
|
useInput5((input, key) => {
|
|
5787
5896
|
if (key.escape) {
|
|
5897
|
+
if (focusSection === "custom-limit" || focusSection === "custom-date") {
|
|
5898
|
+
setFocusSection("options");
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5901
|
+
if (focusSection === "options") {
|
|
5902
|
+
setFocusSection("input");
|
|
5903
|
+
return;
|
|
5904
|
+
}
|
|
5788
5905
|
if (phase === "running") {
|
|
5789
5906
|
abortControllerRef.current?.abort();
|
|
5790
5907
|
setPhase("input");
|
|
@@ -5806,25 +5923,67 @@ function BatchView({
|
|
|
5806
5923
|
return;
|
|
5807
5924
|
}
|
|
5808
5925
|
if (phase === "input") {
|
|
5809
|
-
if (
|
|
5810
|
-
cycleChoice();
|
|
5926
|
+
if (focusSection === "custom-limit" || focusSection === "custom-date") {
|
|
5811
5927
|
return;
|
|
5812
5928
|
}
|
|
5813
|
-
if (
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5929
|
+
if (key.ctrl) {
|
|
5930
|
+
if (input === "l" || input === "L") {
|
|
5931
|
+
setCustomLimitText(limit ? String(limit) : "24");
|
|
5932
|
+
setFocusSection("custom-limit");
|
|
5933
|
+
return;
|
|
5934
|
+
}
|
|
5935
|
+
if (input === "d" || input === "D") {
|
|
5936
|
+
setCustomDateText(dateFilter !== "all" ? dateFilter : "2021");
|
|
5937
|
+
setFocusSection("custom-date");
|
|
5938
|
+
return;
|
|
5939
|
+
}
|
|
5940
|
+
if (input === "c" || input === "C") {
|
|
5941
|
+
cycleChoice();
|
|
5942
|
+
return;
|
|
5943
|
+
}
|
|
5944
|
+
if (input === "m" || input === "M") {
|
|
5945
|
+
toggleMetadata();
|
|
5946
|
+
return;
|
|
5947
|
+
}
|
|
5948
|
+
if (input === "r" || input === "R") {
|
|
5949
|
+
toggleResume();
|
|
5950
|
+
return;
|
|
5951
|
+
}
|
|
5824
5952
|
}
|
|
5825
|
-
if (
|
|
5826
|
-
|
|
5827
|
-
|
|
5953
|
+
if (focusSection === "input") {
|
|
5954
|
+
if (key.downArrow) {
|
|
5955
|
+
setFocusSection("options");
|
|
5956
|
+
return;
|
|
5957
|
+
}
|
|
5958
|
+
} else if (focusSection === "options") {
|
|
5959
|
+
if (key.upArrow) {
|
|
5960
|
+
setFocusSection("input");
|
|
5961
|
+
return;
|
|
5962
|
+
}
|
|
5963
|
+
if (key.return) {
|
|
5964
|
+
startQueue();
|
|
5965
|
+
return;
|
|
5966
|
+
}
|
|
5967
|
+
if (input === "c" || input === "C") {
|
|
5968
|
+
cycleChoice();
|
|
5969
|
+
return;
|
|
5970
|
+
}
|
|
5971
|
+
if (input === "l" || input === "L") {
|
|
5972
|
+
cycleLimit();
|
|
5973
|
+
return;
|
|
5974
|
+
}
|
|
5975
|
+
if (input === "d" || input === "D") {
|
|
5976
|
+
cycleDate();
|
|
5977
|
+
return;
|
|
5978
|
+
}
|
|
5979
|
+
if (input === "m" || input === "M") {
|
|
5980
|
+
toggleMetadata();
|
|
5981
|
+
return;
|
|
5982
|
+
}
|
|
5983
|
+
if (input === "r" || input === "R") {
|
|
5984
|
+
toggleResume();
|
|
5985
|
+
return;
|
|
5986
|
+
}
|
|
5828
5987
|
}
|
|
5829
5988
|
}
|
|
5830
5989
|
}, { isActive: Boolean(process.stdin.isTTY) });
|
|
@@ -5833,70 +5992,114 @@ function BatchView({
|
|
|
5833
5992
|
const totalCount = queueItems.length > 0 ? queueItems.length : 1;
|
|
5834
5993
|
const percent = Math.min(100, Math.floor(completedCount / totalCount * 100));
|
|
5835
5994
|
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", alignItems: "center", children: [
|
|
5836
|
-
phase === "input" && /* @__PURE__ */ jsx17(Panel, { title: "Batch
|
|
5837
|
-
/* @__PURE__ */
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
/* @__PURE__ */ jsx17(Text16, { bold: true, color: inputField === "
|
|
5841
|
-
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: " (Tab to switch) " }),
|
|
5842
|
-
/* @__PURE__ */ jsx17(Text16, { bold: true, color: inputField === "file" ? theme.primary : theme.gray, children: inputField === "file" ? "\u25CF Load Batch File (.txt)" : "\u25CB Load Batch File (.txt)" })
|
|
5995
|
+
phase === "input" && /* @__PURE__ */ jsx17(Panel, { title: "Batch Queue", width: Math.max(60, boxWidth), children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingY: 1, children: [
|
|
5996
|
+
/* @__PURE__ */ jsxs14(Box14, { marginBottom: 1, justifyContent: "center", children: [
|
|
5997
|
+
/* @__PURE__ */ jsx17(Text16, { bold: true, color: inputField === "text" ? theme.primary : theme.gray, children: inputField === "text" ? "\u25CF Links / Handles" : "\u25CB Links / Handles" }),
|
|
5998
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: " \xB7 " }),
|
|
5999
|
+
/* @__PURE__ */ jsx17(Text16, { bold: true, color: inputField === "file" ? theme.primary : theme.gray, children: inputField === "file" ? "\u25CF File (.txt)" : "\u25CB File (.txt)" })
|
|
5843
6000
|
] }),
|
|
5844
|
-
inputField === "text" ? /* @__PURE__ */ jsx17(FramedInput, { title: "
|
|
6001
|
+
inputField === "text" ? /* @__PURE__ */ jsx17(FramedInput, { title: "Links or @handles", width: Math.max(56, boxWidth - 4), children: /* @__PURE__ */ jsx17(
|
|
5845
6002
|
TextInput,
|
|
5846
6003
|
{
|
|
5847
6004
|
value: rawText,
|
|
5848
6005
|
onChange: setRawText,
|
|
5849
6006
|
onSubmit: startQueue,
|
|
5850
|
-
placeholder: "
|
|
5851
|
-
width: Math.max(
|
|
6007
|
+
placeholder: "@user1, @user2, tiktok.com/@user3\u2026",
|
|
6008
|
+
width: Math.max(50, boxWidth - 10),
|
|
6009
|
+
focus: focusSection === "input",
|
|
5852
6010
|
onTab: () => setInputField("file"),
|
|
5853
|
-
onArrowDown: () =>
|
|
6011
|
+
onArrowDown: () => setFocusSection("options")
|
|
5854
6012
|
}
|
|
5855
|
-
) }) : /* @__PURE__ */ jsx17(FramedInput, { title: "
|
|
6013
|
+
) }) : /* @__PURE__ */ jsx17(FramedInput, { title: "Batch file (.txt)", width: Math.max(56, boxWidth - 4), children: /* @__PURE__ */ jsx17(
|
|
5856
6014
|
TextInput,
|
|
5857
6015
|
{
|
|
5858
6016
|
value: filePath,
|
|
5859
6017
|
onChange: setFilePath,
|
|
5860
6018
|
onSubmit: startQueue,
|
|
5861
|
-
placeholder: "e.g.
|
|
5862
|
-
width: Math.max(
|
|
6019
|
+
placeholder: "e.g. creators.txt or C:\\path\\creators.txt",
|
|
6020
|
+
width: Math.max(50, boxWidth - 10),
|
|
6021
|
+
focus: focusSection === "input",
|
|
5863
6022
|
onTab: () => setInputField("text"),
|
|
5864
|
-
|
|
6023
|
+
onArrowDown: () => setFocusSection("options")
|
|
5865
6024
|
}
|
|
5866
6025
|
) }),
|
|
5867
6026
|
errorMessage ? /* @__PURE__ */ jsx17(Box14, { marginTop: 1, children: /* @__PURE__ */ jsxs14(Text16, { color: "red", children: [
|
|
5868
6027
|
"\u2717 ",
|
|
5869
6028
|
errorMessage
|
|
5870
6029
|
] }) }) : null,
|
|
5871
|
-
/* @__PURE__ */ jsx17(
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
/* @__PURE__ */
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
6030
|
+
/* @__PURE__ */ jsx17(
|
|
6031
|
+
Box14,
|
|
6032
|
+
{
|
|
6033
|
+
flexDirection: "column",
|
|
6034
|
+
marginTop: 1,
|
|
6035
|
+
borderStyle: "round",
|
|
6036
|
+
borderColor: focusSection === "options" || focusSection === "custom-limit" || focusSection === "custom-date" ? theme.primary : theme.gray,
|
|
6037
|
+
borderDimColor: focusSection === "input",
|
|
6038
|
+
paddingX: 1,
|
|
6039
|
+
children: focusSection === "custom-limit" ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
6040
|
+
/* @__PURE__ */ jsx17(Text16, { bold: true, color: theme.primary, children: "Set post limit (e.g. 24, all):" }),
|
|
6041
|
+
/* @__PURE__ */ jsx17(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx17(
|
|
6042
|
+
TextInput,
|
|
6043
|
+
{
|
|
6044
|
+
value: customLimitText,
|
|
6045
|
+
onChange: setCustomLimitText,
|
|
6046
|
+
onSubmit: (val) => {
|
|
6047
|
+
const parsed = parseLimit(val);
|
|
6048
|
+
setLimit(parsed);
|
|
6049
|
+
setFocusSection("options");
|
|
6050
|
+
},
|
|
6051
|
+
width: 24
|
|
6052
|
+
}
|
|
6053
|
+
) }),
|
|
6054
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
|
|
6055
|
+
] }) : focusSection === "custom-date" ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
6056
|
+
/* @__PURE__ */ jsx17(Text16, { bold: true, color: theme.primary, children: "Set date or year (e.g. 2021, 2022, 7d):" }),
|
|
6057
|
+
/* @__PURE__ */ jsx17(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx17(
|
|
6058
|
+
TextInput,
|
|
6059
|
+
{
|
|
6060
|
+
value: customDateText,
|
|
6061
|
+
onChange: setCustomDateText,
|
|
6062
|
+
onSubmit: (val) => {
|
|
6063
|
+
const trimmed = val.trim();
|
|
6064
|
+
setDateFilter(trimmed ? trimmed : "all");
|
|
6065
|
+
setFocusSection("options");
|
|
6066
|
+
},
|
|
6067
|
+
width: 24
|
|
6068
|
+
}
|
|
6069
|
+
) }),
|
|
6070
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
|
|
6071
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
6072
|
+
/* @__PURE__ */ jsxs14(Box14, { justifyContent: "space-between", children: [
|
|
6073
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
6074
|
+
"[c] Media: ",
|
|
6075
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: choice.toUpperCase() })
|
|
6076
|
+
] }),
|
|
6077
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
6078
|
+
"[l] Posts: ",
|
|
6079
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: limit ? `${limit}` : "ALL" })
|
|
6080
|
+
] }),
|
|
6081
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
6082
|
+
"[d] Date: ",
|
|
6083
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: dateFilter.toUpperCase() })
|
|
6084
|
+
] })
|
|
6085
|
+
] }),
|
|
6086
|
+
/* @__PURE__ */ jsxs14(Box14, { justifyContent: "space-between", marginTop: 1, children: [
|
|
6087
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
6088
|
+
"[m] Meta: ",
|
|
6089
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: writeMetadata ? "ON" : "OFF" })
|
|
6090
|
+
] }),
|
|
6091
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
6092
|
+
"[r] Resume: ",
|
|
6093
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: resume ? "ON" : "OFF" })
|
|
6094
|
+
] }),
|
|
6095
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.primary, bold: true, children: "[\u21B5] Start Queue" })
|
|
6096
|
+
] })
|
|
6097
|
+
] })
|
|
6098
|
+
}
|
|
6099
|
+
),
|
|
6100
|
+
/* @__PURE__ */ jsx17(Box14, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: focusSection === "input" ? "Press \u2193 to adjust options \xB7 \u21B5 to start queue" : "Hotkeys [c] [l] [d] [m] [r] \xB7 \u2191 to edit text \xB7 \u21B5 to start" }) })
|
|
5898
6101
|
] }) }),
|
|
5899
|
-
phase === "running" && /* @__PURE__ */ jsx17(Panel, { title: "Batch Queue Running
|
|
6102
|
+
phase === "running" && /* @__PURE__ */ jsx17(Panel, { title: "Batch Queue Running", width: Math.max(60, boxWidth), children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingY: 1, children: [
|
|
5900
6103
|
/* @__PURE__ */ jsxs14(Box14, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
5901
6104
|
/* @__PURE__ */ jsxs14(Text16, { color: theme.primary, bold: true, children: [
|
|
5902
6105
|
"Account ",
|
|
@@ -5907,9 +6110,9 @@ function BatchView({
|
|
|
5907
6110
|
percent,
|
|
5908
6111
|
"%)"
|
|
5909
6112
|
] }),
|
|
5910
|
-
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: isCooldown ? "\u23F3
|
|
6113
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: isCooldown ? "\u23F3 Cooldown active" : "\u25B6 Downloading" })
|
|
5911
6114
|
] }),
|
|
5912
|
-
/* @__PURE__ */ jsx17(ProgressBar, { percent, width:
|
|
6115
|
+
/* @__PURE__ */ jsx17(ProgressBar, { percent, width: 54 }),
|
|
5913
6116
|
/* @__PURE__ */ jsx17(Gap2, {}),
|
|
5914
6117
|
currentItem ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.primary, paddingX: 1, paddingY: 1, children: [
|
|
5915
6118
|
/* @__PURE__ */ jsxs14(Box14, { children: [
|
|
@@ -5931,7 +6134,7 @@ function BatchView({
|
|
|
5931
6134
|
/* @__PURE__ */ jsx17(Gap2, {}),
|
|
5932
6135
|
/* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "[esc] Stop queue and return" })
|
|
5933
6136
|
] }) }),
|
|
5934
|
-
phase === "done" && result && /* @__PURE__ */ jsx17(Panel, { title: "Batch Queue Completed", width: Math.max(
|
|
6137
|
+
phase === "done" && result && /* @__PURE__ */ jsx17(Panel, { title: "Batch Queue Completed", width: Math.max(60, boxWidth), children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingY: 1, children: [
|
|
5935
6138
|
/* @__PURE__ */ jsxs14(Text16, { bold: true, color: theme.primary, children: [
|
|
5936
6139
|
"\u2713 Successfully processed ",
|
|
5937
6140
|
result.total,
|
|
@@ -5951,7 +6154,7 @@ function BatchView({
|
|
|
5951
6154
|
result.totalDownloaded
|
|
5952
6155
|
] }),
|
|
5953
6156
|
/* @__PURE__ */ jsxs14(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
5954
|
-
"\u2022 Total items skipped
|
|
6157
|
+
"\u2022 Total items skipped: ",
|
|
5955
6158
|
result.totalSkipped
|
|
5956
6159
|
] }),
|
|
5957
6160
|
/* @__PURE__ */ jsx17(Gap2, {}),
|
|
@@ -6015,7 +6218,7 @@ function frameRowSpan(row) {
|
|
|
6015
6218
|
}
|
|
6016
6219
|
|
|
6017
6220
|
// src/app.tsx
|
|
6018
|
-
import { Fragment as
|
|
6221
|
+
import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6019
6222
|
var TAGLINE = "grab any profile. paste. download. done.";
|
|
6020
6223
|
var DOWNLOAD_BUTTON = "download";
|
|
6021
6224
|
var Gap = ({ lines = 1 }) => /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", flexShrink: 0, children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx18(Text17, { children: " " }, i)) });
|
|
@@ -6187,6 +6390,7 @@ function InnerApp({
|
|
|
6187
6390
|
const targetChoice = typeof choiceOrOptions === "string" ? choiceOrOptions : choiceOrOptions.choice;
|
|
6188
6391
|
const targetLimit = typeof choiceOrOptions === "string" ? effectiveLimit : choiceOrOptions.limit ?? effectiveLimit;
|
|
6189
6392
|
const targetSince = typeof choiceOrOptions === "string" ? since : choiceOrOptions.since ?? since;
|
|
6393
|
+
const targetUntil = typeof choiceOrOptions === "string" ? until : choiceOrOptions.until ?? until;
|
|
6190
6394
|
const targetResume = typeof choiceOrOptions === "string" ? resume : choiceOrOptions.resume ?? resume;
|
|
6191
6395
|
const targetWriteMetadata = typeof choiceOrOptions === "string" ? effectiveWriteMetadata : choiceOrOptions.writeMetadata ?? effectiveWriteMetadata;
|
|
6192
6396
|
setPhase({ name: "downloading", profile, choice: targetChoice });
|
|
@@ -6197,7 +6401,7 @@ function InnerApp({
|
|
|
6197
6401
|
choice: targetChoice,
|
|
6198
6402
|
outputDir: targetDir,
|
|
6199
6403
|
since: targetSince,
|
|
6200
|
-
until,
|
|
6404
|
+
until: targetUntil,
|
|
6201
6405
|
limit: targetLimit,
|
|
6202
6406
|
resume: targetResume,
|
|
6203
6407
|
writeMetadata: targetWriteMetadata,
|
|
@@ -6483,6 +6687,7 @@ function InnerApp({
|
|
|
6483
6687
|
outputDir,
|
|
6484
6688
|
initialLimit: effectiveLimit,
|
|
6485
6689
|
initialSince: since,
|
|
6690
|
+
initialUntil: until,
|
|
6486
6691
|
initialWriteMetadata: effectiveWriteMetadata,
|
|
6487
6692
|
initialResume: resume,
|
|
6488
6693
|
onSelect: (choiceOrOptions) => handleModeSelect(choiceOrOptions, phase.profile),
|
|
@@ -6559,7 +6764,7 @@ function InnerApp({
|
|
|
6559
6764
|
defaultWriteMetadata: effectiveWriteMetadata
|
|
6560
6765
|
}
|
|
6561
6766
|
),
|
|
6562
|
-
hints.length > 0 ? /* @__PURE__ */ jsxs15(
|
|
6767
|
+
hints.length > 0 ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
6563
6768
|
/* @__PURE__ */ jsx18(Gap, { lines: 2 }),
|
|
6564
6769
|
/* @__PURE__ */ jsx18(
|
|
6565
6770
|
Shortcuts,
|