open-nami 1.2.9 → 1.3.0

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.
Files changed (2) hide show
  1. package/dist/cli.js +78 -33
  2. 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.9",
12
+ version: "1.3.0",
13
13
  description: "Open Nami: terminal-first bulk social media profile downloader for Instagram, TikTok, Facebook & X.",
14
14
  type: "module",
15
15
  bin: {
@@ -4368,27 +4368,50 @@ async function dispatchDownload(options) {
4368
4368
  }
4369
4369
 
4370
4370
  // src/components/views/picking-view.tsx
4371
- 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";
4372
4372
  function ChoiceIndicator({ isSelected }) {
4373
4373
  const theme = useTheme();
4374
- return /* @__PURE__ */ jsx8(Box6, { marginRight: 1, children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: isSelected ? "\u276F" : " " }) });
4374
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
4375
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
4376
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: isSelected ? "\u276F " : " " })
4377
+ ] });
4375
4378
  }
4376
- function ChoiceItem({ isSelected, label }) {
4379
+ function ChoiceItem({
4380
+ isSelected,
4381
+ label,
4382
+ value,
4383
+ description
4384
+ }) {
4377
4385
  const theme = useTheme();
4378
- return /* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: isSelected, children: label });
4386
+ const rawTag = `[${value === "all" ? "EVERYTHING" : String(value || label).toUpperCase()}]`;
4387
+ const paddedTag = rawTag.padEnd(12, " ");
4388
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
4389
+ /* @__PURE__ */ jsx8(
4390
+ Text7,
4391
+ {
4392
+ color: isSelected ? theme.background : theme.primary,
4393
+ backgroundColor: isSelected ? theme.primary : void 0,
4394
+ bold: isSelected,
4395
+ children: paddedTag
4396
+ }
4397
+ ),
4398
+ /* @__PURE__ */ jsx8(Text7, { color: theme.gray, children: " " }),
4399
+ /* @__PURE__ */ jsx8(Text7, { color: isSelected ? theme.primary : theme.gray, dimColor: !isSelected, bold: isSelected, children: description || label })
4400
+ ] });
4379
4401
  }
4380
4402
  function getPickingOptions(platform) {
4381
4403
  const items = [
4382
- { label: "Photos", value: "photos" },
4383
- { label: "Videos", value: "videos" }
4404
+ { label: "Photos", value: "photos", description: "Feed images and carousels" },
4405
+ { label: "Videos", value: "videos", description: "Reels and timeline clips" }
4384
4406
  ];
4385
4407
  if (platform === "instagram") {
4386
- items.push({ label: "Stories", value: "stories" });
4387
- items.push({ label: "Highlights", value: "highlights" });
4408
+ items.push({ label: "Stories", value: "stories", description: "Active 24h stories" });
4409
+ items.push({ label: "Highlights", value: "highlights", description: "Saved story archive reels" });
4388
4410
  }
4389
4411
  items.push({
4390
4412
  label: "Everything",
4391
- value: "all"
4413
+ value: "all",
4414
+ description: "Complete profile download"
4392
4415
  });
4393
4416
  return items;
4394
4417
  }
@@ -4404,7 +4427,7 @@ function PickingView({
4404
4427
  onSelect,
4405
4428
  onHighlight,
4406
4429
  theme,
4407
- gapComponent: Gap2
4430
+ gapComponent: _Gap
4408
4431
  }) {
4409
4432
  const platformName = profile.platform.charAt(0).toUpperCase() + profile.platform.slice(1);
4410
4433
  const items = getPickingOptions(profile.platform);
@@ -4432,23 +4455,26 @@ function PickingView({
4432
4455
  resume: initialResume
4433
4456
  });
4434
4457
  };
4435
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", alignItems: "center", width: "100%", children: [
4436
- /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [
4458
+ return /* @__PURE__ */ jsx8(Box6, { flexDirection: "column", alignItems: "center", width: "100%", children: /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", width: 56, children: [
4459
+ /* @__PURE__ */ jsxs6(Box6, { children: [
4460
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
4437
4461
  /* @__PURE__ */ jsxs6(Text7, { bold: true, color: theme.primary, children: [
4438
4462
  "@",
4439
4463
  profile.username
4440
4464
  ] }),
4441
- /* @__PURE__ */ jsx8(Gap2, {}),
4442
- /* @__PURE__ */ jsxs6(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: [
4443
- "\u25B8 ",
4444
- platformName,
4445
- profile.cleanUrl ? ` \xB7 ${profile.cleanUrl}` : ""
4446
- ] }),
4447
- /* @__PURE__ */ jsx8(Gap2, {}),
4448
- /* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "Select what to download from this profile." }),
4449
- hasCheckpoint ? /* @__PURE__ */ jsx8(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: "\u26A1 Checkpoint found (cursor saved)" }) }) : null
4465
+ /* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: ` \xB7 ${platformName}` })
4466
+ ] }),
4467
+ profile.cleanUrl ? /* @__PURE__ */ jsxs6(Box6, { children: [
4468
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
4469
+ /* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: profile.cleanUrl })
4470
+ ] }) : null,
4471
+ /* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
4472
+ /* @__PURE__ */ jsxs6(Box6, { children: [
4473
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
4474
+ /* @__PURE__ */ jsx8(Text7, { color: theme.gray, dimColor: theme.dimSecondary, children: "Select target media:" })
4450
4475
  ] }),
4451
- /* @__PURE__ */ jsx8(Panel, { title: "Download", width: 44, children: /* @__PURE__ */ jsx8(Box6, { width: "100%", alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx8(
4476
+ /* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
4477
+ /* @__PURE__ */ jsx8(
4452
4478
  SelectInput,
4453
4479
  {
4454
4480
  indicatorComponent: ChoiceIndicator,
@@ -4456,13 +4482,21 @@ function PickingView({
4456
4482
  items: items.map((item, index) => ({
4457
4483
  key: String(index),
4458
4484
  label: item.label,
4459
- value: item.value
4485
+ value: item.value,
4486
+ description: item.description
4460
4487
  })),
4461
4488
  onSelect: (item) => handleItemSelect(item.value),
4462
4489
  onHighlight: (item) => onHighlight?.(item.value)
4463
4490
  }
4464
- ) }) })
4465
- ] });
4491
+ ),
4492
+ hasCheckpoint ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
4493
+ /* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E" }) }),
4494
+ /* @__PURE__ */ jsxs6(Box6, { children: [
4495
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, children: "\u258E " }),
4496
+ /* @__PURE__ */ jsx8(Text7, { color: theme.primary, bold: true, children: "\u26A1 Checkpoint found (cursor saved)" })
4497
+ ] })
4498
+ ] }) : null
4499
+ ] }) });
4466
4500
  }
4467
4501
 
4468
4502
  // src/components/views/platform-view.tsx
@@ -4673,7 +4707,7 @@ function DownloadingView({
4673
4707
  // src/components/views/completion-view.tsx
4674
4708
  import os7 from "os";
4675
4709
  import { Box as Box10, Text as Text12 } from "ink";
4676
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
4710
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
4677
4711
  var DONE_LABEL = "\u21B5 download another";
4678
4712
  function CompletionView({
4679
4713
  profile,
@@ -4685,10 +4719,10 @@ function CompletionView({
4685
4719
  const plural = result.downloadedCount === 1 ? "" : "s";
4686
4720
  const skipText = result.skippedCount > 0 ? ` (${result.skippedCount} archived)` : "";
4687
4721
  return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", alignItems: "center", children: [
4688
- /* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
4722
+ /* @__PURE__ */ jsx13(Text12, { children: isZero ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
4689
4723
  /* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile scanned " }),
4690
4724
  /* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "\u2014 0 media items found" })
4691
- ] }) : /* @__PURE__ */ jsxs10(Fragment2, { children: [
4725
+ ] }) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
4692
4726
  /* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.primary, children: "\u2713 profile downloaded! " }),
4693
4727
  /* @__PURE__ */ jsx13(Text12, { color: theme.primary, children: "saved to:" })
4694
4728
  ] }) }),
@@ -5701,7 +5735,7 @@ async function runBatchQueue(options) {
5701
5735
  }
5702
5736
 
5703
5737
  // src/components/views/batch-view.tsx
5704
- import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
5738
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
5705
5739
  var PLATFORMS = ["instagram", "tiktok", "facebook", "x"];
5706
5740
  var CHOICES2 = ["all", "photos", "videos", "stories", "highlights"];
5707
5741
  var DATE_PRESETS = ["all", "24h", "7d", "30d", "2024", "2023", "2022", "2021", "custom"];
@@ -6408,7 +6442,7 @@ function BatchView({
6408
6442
  }
6409
6443
  ) }),
6410
6444
  /* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "\u21B5 confirm \xB7 esc cancel" })
6411
- ] }) : /* @__PURE__ */ jsxs14(Fragment3, { children: [
6445
+ ] }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
6412
6446
  /* @__PURE__ */ jsxs14(Box14, { justifyContent: "space-between", width: "100%", children: [
6413
6447
  /* @__PURE__ */ jsxs14(Box14, { width: colWidth, children: [
6414
6448
  /* @__PURE__ */ jsx17(Text16, { color: theme.gray, dimColor: theme.dimSecondary, children: "[p] Platform: " }),
@@ -6620,7 +6654,7 @@ function frameRowSpan(row) {
6620
6654
  }
6621
6655
 
6622
6656
  // src/app.tsx
6623
- import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
6657
+ import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
6624
6658
  var TAGLINE = "grab any profile. paste. download. done.";
6625
6659
  var DOWNLOAD_BUTTON = "download";
6626
6660
  var Gap = ({ lines = 1 }) => /* @__PURE__ */ jsx18(Box15, { flexDirection: "column", flexShrink: 0, children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx18(Text17, { children: " " }, i)) });
@@ -7001,6 +7035,17 @@ function InnerApp({
7001
7035
  match: item.label,
7002
7036
  action: () => handleModeSelect(item.value, phase.profile)
7003
7037
  });
7038
+ const tag = `[${item.value === "all" ? "EVERYTHING" : item.value.toUpperCase()}]`;
7039
+ targets.push({
7040
+ match: tag,
7041
+ action: () => handleModeSelect(item.value, phase.profile)
7042
+ });
7043
+ if (item.description) {
7044
+ targets.push({
7045
+ match: item.description,
7046
+ action: () => handleModeSelect(item.value, phase.profile)
7047
+ });
7048
+ }
7004
7049
  }
7005
7050
  }
7006
7051
  if (phase.name === "done") {
@@ -7184,7 +7229,7 @@ function InnerApp({
7184
7229
  onRegisterClickTargets: setBatchClickTargets
7185
7230
  }
7186
7231
  ),
7187
- hints.length > 0 ? /* @__PURE__ */ jsxs15(Fragment4, { children: [
7232
+ hints.length > 0 ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
7188
7233
  /* @__PURE__ */ jsx18(Gap, { lines: 2 }),
7189
7234
  /* @__PURE__ */ jsx18(
7190
7235
  Shortcuts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-nami",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Open Nami: terminal-first bulk social media profile downloader for Instagram, TikTok, Facebook & X.",
5
5
  "type": "module",
6
6
  "bin": {