open-nami 1.2.6 → 1.2.7
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 +116 -25
- 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.7",
|
|
13
13
|
description: "Open Nami: terminal-first bulk social media profile downloader for Instagram, TikTok, Facebook & X.",
|
|
14
14
|
type: "module",
|
|
15
15
|
bin: {
|
|
@@ -5352,9 +5352,9 @@ function startClipboardWatcher(options = {}) {
|
|
|
5352
5352
|
try {
|
|
5353
5353
|
const res = await dispatch({
|
|
5354
5354
|
profile: parsed,
|
|
5355
|
-
choice,
|
|
5356
|
-
outputDir: options.outputDir,
|
|
5357
|
-
writeMetadata: options.writeMetadata,
|
|
5355
|
+
choice: options.getChoice ? options.getChoice() : options.choice || "all",
|
|
5356
|
+
outputDir: resolveDefaultDownloadDir(parsed.platform, parsed.username, options.outputDir),
|
|
5357
|
+
writeMetadata: options.getWriteMetadata ? options.getWriteMetadata() : options.writeMetadata ?? false,
|
|
5358
5358
|
signal: options.signal,
|
|
5359
5359
|
onProgress: (p) => {
|
|
5360
5360
|
if (p.statusText) {
|
|
@@ -5444,16 +5444,19 @@ function revealInFileManager(targetPath) {
|
|
|
5444
5444
|
|
|
5445
5445
|
// src/components/views/watcher-view.tsx
|
|
5446
5446
|
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5447
|
+
var CHOICES = ["all", "photos", "videos", "stories", "highlights"];
|
|
5447
5448
|
function WatcherView({
|
|
5448
5449
|
onBack,
|
|
5449
5450
|
outputDir,
|
|
5450
5451
|
theme,
|
|
5451
5452
|
gapComponent: Gap2,
|
|
5452
5453
|
defaultChoice = "all",
|
|
5453
|
-
defaultWriteMetadata = false
|
|
5454
|
+
defaultWriteMetadata = false,
|
|
5455
|
+
onRegisterClickTargets
|
|
5454
5456
|
}) {
|
|
5455
5457
|
const [mediaChoice, setMediaChoice] = useState7(defaultChoice);
|
|
5456
5458
|
const [writeMetadata, setWriteMetadata] = useState7(defaultWriteMetadata);
|
|
5459
|
+
const [focusedIndex, setFocusedIndex] = useState7(0);
|
|
5457
5460
|
const [history, setHistory] = useState7([]);
|
|
5458
5461
|
const [activeJob, setActiveJob] = useState7(null);
|
|
5459
5462
|
const [stats, setStats] = useState7({ detected: 0, downloaded: 0, skipped: 0 });
|
|
@@ -5471,8 +5474,10 @@ function WatcherView({
|
|
|
5471
5474
|
useEffect6(() => {
|
|
5472
5475
|
const watcher = startClipboardWatcher({
|
|
5473
5476
|
choice: mediaChoiceRef.current,
|
|
5477
|
+
getChoice: () => mediaChoiceRef.current,
|
|
5474
5478
|
outputDir,
|
|
5475
5479
|
writeMetadata: writeMetadataRef.current,
|
|
5480
|
+
getWriteMetadata: () => writeMetadataRef.current,
|
|
5476
5481
|
onDetected: (profile) => {
|
|
5477
5482
|
setStats((prev) => ({ ...prev, detected: prev.detected + 1 }));
|
|
5478
5483
|
const newItem = {
|
|
@@ -5528,9 +5533,9 @@ function WatcherView({
|
|
|
5528
5533
|
}, [outputDir]);
|
|
5529
5534
|
const cycleChoice = useCallback3(() => {
|
|
5530
5535
|
setMediaChoice((prev) => {
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
return
|
|
5536
|
+
const idx = CHOICES.indexOf(prev);
|
|
5537
|
+
const nextChoice = CHOICES[(idx + 1) % CHOICES.length] || "all";
|
|
5538
|
+
return nextChoice;
|
|
5534
5539
|
});
|
|
5535
5540
|
}, []);
|
|
5536
5541
|
const toggleMetadata = useCallback3(() => {
|
|
@@ -5540,20 +5545,68 @@ function WatcherView({
|
|
|
5540
5545
|
const target = outputDir || resolveDefaultDownloadDir("instagram", "watcher");
|
|
5541
5546
|
revealInFileManager(target);
|
|
5542
5547
|
}, [outputDir]);
|
|
5548
|
+
useEffect6(() => {
|
|
5549
|
+
if (!onRegisterClickTargets) return;
|
|
5550
|
+
const targets = [
|
|
5551
|
+
{ match: "Target:", padX: 1, action: () => {
|
|
5552
|
+
setFocusedIndex(0);
|
|
5553
|
+
cycleChoice();
|
|
5554
|
+
} },
|
|
5555
|
+
{ match: "Sidecars:", padX: 1, action: () => {
|
|
5556
|
+
setFocusedIndex(1);
|
|
5557
|
+
toggleMetadata();
|
|
5558
|
+
} },
|
|
5559
|
+
{ match: "Open Folder", padX: 1, action: () => {
|
|
5560
|
+
setFocusedIndex(2);
|
|
5561
|
+
openFolder();
|
|
5562
|
+
} },
|
|
5563
|
+
{ match: "c target", padX: 1, action: () => {
|
|
5564
|
+
setFocusedIndex(0);
|
|
5565
|
+
cycleChoice();
|
|
5566
|
+
} },
|
|
5567
|
+
{ match: "m sidecar", padX: 1, action: () => {
|
|
5568
|
+
setFocusedIndex(1);
|
|
5569
|
+
toggleMetadata();
|
|
5570
|
+
} },
|
|
5571
|
+
{ match: "o open dir", padX: 1, action: () => {
|
|
5572
|
+
setFocusedIndex(2);
|
|
5573
|
+
openFolder();
|
|
5574
|
+
} },
|
|
5575
|
+
{ match: "esc back", padX: 1, action: onBack }
|
|
5576
|
+
];
|
|
5577
|
+
onRegisterClickTargets(targets);
|
|
5578
|
+
}, [onRegisterClickTargets, cycleChoice, toggleMetadata, openFolder, onBack, mediaChoice, writeMetadata]);
|
|
5543
5579
|
useInput4((input, key) => {
|
|
5544
5580
|
if (key.escape) {
|
|
5545
5581
|
onBack();
|
|
5546
5582
|
return;
|
|
5547
5583
|
}
|
|
5584
|
+
if (key.leftArrow) {
|
|
5585
|
+
setFocusedIndex((prev) => prev === 0 ? 2 : prev - 1);
|
|
5586
|
+
return;
|
|
5587
|
+
}
|
|
5588
|
+
if (key.rightArrow || key.tab) {
|
|
5589
|
+
setFocusedIndex((prev) => prev === 2 ? 0 : prev + 1);
|
|
5590
|
+
return;
|
|
5591
|
+
}
|
|
5592
|
+
if (key.return || input === " ") {
|
|
5593
|
+
if (focusedIndex === 0) cycleChoice();
|
|
5594
|
+
else if (focusedIndex === 1) toggleMetadata();
|
|
5595
|
+
else if (focusedIndex === 2) openFolder();
|
|
5596
|
+
return;
|
|
5597
|
+
}
|
|
5548
5598
|
if (input === "c" || input === "C") {
|
|
5599
|
+
setFocusedIndex(0);
|
|
5549
5600
|
cycleChoice();
|
|
5550
5601
|
return;
|
|
5551
5602
|
}
|
|
5552
5603
|
if (input === "m" || input === "M") {
|
|
5604
|
+
setFocusedIndex(1);
|
|
5553
5605
|
toggleMetadata();
|
|
5554
5606
|
return;
|
|
5555
5607
|
}
|
|
5556
5608
|
if (input === "o" || input === "O") {
|
|
5609
|
+
setFocusedIndex(2);
|
|
5557
5610
|
openFolder();
|
|
5558
5611
|
return;
|
|
5559
5612
|
}
|
|
@@ -5569,8 +5622,10 @@ function WatcherView({
|
|
|
5569
5622
|
] }),
|
|
5570
5623
|
/* @__PURE__ */ jsx16(ProgressBar, { indeterminate: true, width: 58, tick: pulseTick }),
|
|
5571
5624
|
/* @__PURE__ */ jsx16(Gap2, {}),
|
|
5572
|
-
/* @__PURE__ */
|
|
5573
|
-
|
|
5625
|
+
/* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
5626
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.gray, dimColor: theme.dimSecondary, children: "Auto-monitoring clipboard for profile links (Instagram, TikTok, FB, X)." }),
|
|
5627
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.gray, dimColor: theme.dimSecondary, children: "Copy any profile link in your browser: Open Nami downloads it in background." })
|
|
5628
|
+
] }),
|
|
5574
5629
|
/* @__PURE__ */ jsx16(Gap2, {}),
|
|
5575
5630
|
/* @__PURE__ */ jsx16(
|
|
5576
5631
|
Box13,
|
|
@@ -5606,15 +5661,42 @@ function WatcherView({
|
|
|
5606
5661
|
] }) : null,
|
|
5607
5662
|
/* @__PURE__ */ jsx16(Gap2, {}),
|
|
5608
5663
|
/* @__PURE__ */ jsxs13(Box13, { justifyContent: "space-between", children: [
|
|
5609
|
-
/* @__PURE__ */
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5664
|
+
/* @__PURE__ */ jsx16(
|
|
5665
|
+
Box13,
|
|
5666
|
+
{
|
|
5667
|
+
borderStyle: "round",
|
|
5668
|
+
borderColor: focusedIndex === 0 ? theme.primary : theme.gray,
|
|
5669
|
+
borderDimColor: focusedIndex !== 0,
|
|
5670
|
+
paddingX: 1,
|
|
5671
|
+
children: /* @__PURE__ */ jsxs13(Text15, { color: focusedIndex === 0 ? theme.primary : theme.gray, bold: focusedIndex === 0, children: [
|
|
5672
|
+
"[c] Target: ",
|
|
5673
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.primary, bold: true, children: mediaChoice === "all" ? "EVERYTHING" : mediaChoice.toUpperCase() })
|
|
5674
|
+
] })
|
|
5675
|
+
}
|
|
5676
|
+
),
|
|
5677
|
+
/* @__PURE__ */ jsx16(
|
|
5678
|
+
Box13,
|
|
5679
|
+
{
|
|
5680
|
+
borderStyle: "round",
|
|
5681
|
+
borderColor: focusedIndex === 1 ? theme.primary : theme.gray,
|
|
5682
|
+
borderDimColor: focusedIndex !== 1,
|
|
5683
|
+
paddingX: 1,
|
|
5684
|
+
children: /* @__PURE__ */ jsxs13(Text15, { color: focusedIndex === 1 ? theme.primary : theme.gray, bold: focusedIndex === 1, children: [
|
|
5685
|
+
"[m] Sidecars: ",
|
|
5686
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.primary, bold: true, children: writeMetadata ? "ON" : "OFF" })
|
|
5687
|
+
] })
|
|
5688
|
+
}
|
|
5689
|
+
),
|
|
5690
|
+
/* @__PURE__ */ jsx16(
|
|
5691
|
+
Box13,
|
|
5692
|
+
{
|
|
5693
|
+
borderStyle: "round",
|
|
5694
|
+
borderColor: focusedIndex === 2 ? theme.primary : theme.gray,
|
|
5695
|
+
borderDimColor: focusedIndex !== 2,
|
|
5696
|
+
paddingX: 1,
|
|
5697
|
+
children: /* @__PURE__ */ jsx16(Text15, { color: focusedIndex === 2 ? theme.primary : theme.gray, bold: focusedIndex === 2, children: "[o] Open Folder" })
|
|
5698
|
+
}
|
|
5699
|
+
)
|
|
5618
5700
|
] }),
|
|
5619
5701
|
/* @__PURE__ */ jsx16(Box13, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs13(Text15, { color: theme.gray, dimColor: theme.dimSecondary, children: [
|
|
5620
5702
|
"Session Stats: ",
|
|
@@ -5756,7 +5838,7 @@ async function runBatchQueue(options) {
|
|
|
5756
5838
|
// src/components/views/batch-view.tsx
|
|
5757
5839
|
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5758
5840
|
var PLATFORMS = ["instagram", "tiktok", "facebook", "x"];
|
|
5759
|
-
var
|
|
5841
|
+
var CHOICES2 = ["all", "photos", "videos", "stories", "highlights"];
|
|
5760
5842
|
var DATE_PRESETS2 = ["all", "24h", "7d", "30d", "2024", "2023", "2022", "2021", "custom"];
|
|
5761
5843
|
var LIMIT_PRESETS2 = [void 0, 10, 24, 50, 100, "custom"];
|
|
5762
5844
|
function BatchView({
|
|
@@ -5798,8 +5880,8 @@ function BatchView({
|
|
|
5798
5880
|
}, []);
|
|
5799
5881
|
const cycleChoice = useCallback4(() => {
|
|
5800
5882
|
setChoice((prev) => {
|
|
5801
|
-
const idx =
|
|
5802
|
-
return
|
|
5883
|
+
const idx = CHOICES2.indexOf(prev);
|
|
5884
|
+
return CHOICES2[(idx + 1) % CHOICES2.length];
|
|
5803
5885
|
});
|
|
5804
5886
|
}, []);
|
|
5805
5887
|
const cycleLimit = useCallback4(() => {
|
|
@@ -6793,6 +6875,7 @@ function InnerApp({
|
|
|
6793
6875
|
const [clipboardUrl, setClipboardUrl] = useState9(void 0);
|
|
6794
6876
|
const [settingsFocus, setSettingsFocus] = useState9("cookies");
|
|
6795
6877
|
const [batchClickTargets, setBatchClickTargets] = useState9([]);
|
|
6878
|
+
const [watcherClickTargets, setWatcherClickTargets] = useState9([]);
|
|
6796
6879
|
const columns = stdout?.columns && stdout.columns > 0 ? stdout.columns : 80;
|
|
6797
6880
|
const boxWidth = Math.max(14, Math.min(64, columns - 6));
|
|
6798
6881
|
const contentWidth = Math.max(10, Math.min(columns - 4, 78));
|
|
@@ -6944,8 +7027,11 @@ function InnerApp({
|
|
|
6944
7027
|
if (key.ctrl && (input === "w" || input === "W")) {
|
|
6945
7028
|
if (phase.name === "watcher") {
|
|
6946
7029
|
setPhase({ name: "input" });
|
|
6947
|
-
|
|
7030
|
+
return;
|
|
7031
|
+
}
|
|
7032
|
+
if (phase.name === "input" && urlInput.length === 0) {
|
|
6948
7033
|
setPhase({ name: "watcher" });
|
|
7034
|
+
return;
|
|
6949
7035
|
}
|
|
6950
7036
|
return;
|
|
6951
7037
|
}
|
|
@@ -7063,6 +7149,9 @@ function InnerApp({
|
|
|
7063
7149
|
if (phase.name === "batch") {
|
|
7064
7150
|
targets.push(...batchClickTargets);
|
|
7065
7151
|
}
|
|
7152
|
+
if (phase.name === "watcher") {
|
|
7153
|
+
targets.push(...watcherClickTargets);
|
|
7154
|
+
}
|
|
7066
7155
|
for (const [key, label] of hints) {
|
|
7067
7156
|
const action = hintAction(key);
|
|
7068
7157
|
if (action) targets.push({ match: `${key} ${label}`, action });
|
|
@@ -7083,7 +7172,8 @@ function InnerApp({
|
|
|
7083
7172
|
handlePlatformSelect,
|
|
7084
7173
|
handleModeSelect,
|
|
7085
7174
|
resetToInput,
|
|
7086
|
-
batchClickTargets
|
|
7175
|
+
batchClickTargets,
|
|
7176
|
+
watcherClickTargets
|
|
7087
7177
|
]);
|
|
7088
7178
|
useMouseClick(
|
|
7089
7179
|
(x, y) => {
|
|
@@ -7210,7 +7300,8 @@ function InnerApp({
|
|
|
7210
7300
|
theme,
|
|
7211
7301
|
gapComponent: Gap,
|
|
7212
7302
|
defaultChoice: initialChoice,
|
|
7213
|
-
defaultWriteMetadata: effectiveWriteMetadata
|
|
7303
|
+
defaultWriteMetadata: effectiveWriteMetadata,
|
|
7304
|
+
onRegisterClickTargets: setWatcherClickTargets
|
|
7214
7305
|
}
|
|
7215
7306
|
),
|
|
7216
7307
|
phase.name === "batch" && /* @__PURE__ */ jsx18(
|