gitxelectron 1.2.8 → 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.
@@ -24015,9 +24015,9 @@ function CloneRepoWizard({ onClose, onSuccess }) {
24015
24015
  )
24016
24016
  ] })
24017
24017
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
24018
- error && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-danger/10 border border-danger/30 text-danger px-4 py-3 rounded-lg text-sm flex items-start gap-3", children: [
24019
- /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5 flex-shrink-0 mt-0.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
24020
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "break-words", children: error })
24018
+ error && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-danger/10 border border-danger/30 text-danger px-4 py-3 rounded-lg text-xs flex items-start gap-3 max-h-36 overflow-y-auto custom-scrollbar", children: [
24019
+ /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5 flex-shrink-0 mt-0.5 text-danger", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
24020
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "break-words font-mono text-[11px] leading-relaxed select-text", children: error })
24021
24021
  ] }),
24022
24022
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
24023
24023
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
@@ -24228,7 +24228,9 @@ const CollaborationRepoView = ({
24228
24228
  onRepoCardClick,
24229
24229
  onRefresh,
24230
24230
  isRefreshing,
24231
- onOpenExternal
24231
+ onOpenExternal,
24232
+ onUnlinkMapping,
24233
+ onChangeFolder
24232
24234
  }) => {
24233
24235
  const filteredRepos = collaboratedRepos.filter((repo) => {
24234
24236
  if (!collabSearch.trim()) return true;
@@ -24493,21 +24495,52 @@ const CollaborationRepoView = ({
24493
24495
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-secondary/40" }),
24494
24496
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Not cloned yet" })
24495
24497
  ] }) }),
24496
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 flex-shrink-0 self-end sm:self-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
24497
- "button",
24498
- {
24499
- type: "button",
24500
- onClick: (e) => {
24501
- e.stopPropagation();
24502
- onRepoCardClick(repo);
24503
- },
24504
- className: `px-3.5 py-1.5 text-xs font-semibold rounded-xl transition-all shadow-xs flex items-center gap-1.5 ${savedPath ? isMissing ? "bg-danger/20 hover:bg-danger/30 text-danger border border-danger/40" : "bg-brand hover:bg-brand-hover text-white shadow-brand/20" : "bg-brand hover:bg-brand-hover text-white shadow-brand/20"}`,
24505
- children: [
24506
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: savedPath ? isMissing ? "Re-Clone" : "Open Repo" : "Clone / Connect" }),
24507
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isMissing ? "☁️" : savedPath ? "→" : "☁️" })
24508
- ]
24509
- }
24510
- ) })
24498
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0 self-end sm:self-center", children: [
24499
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
24500
+ "button",
24501
+ {
24502
+ type: "button",
24503
+ onClick: (e) => {
24504
+ e.stopPropagation();
24505
+ onChangeFolder?.(repo);
24506
+ },
24507
+ className: "px-2.5 py-1.5 text-xs font-medium rounded-xl transition-all shadow-xs flex items-center gap-1 bg-surface hover:bg-surface-hover text-secondary hover:text-primary border border-border",
24508
+ title: savedPath ? "Change connected local folder" : "Select existing local folder on disk",
24509
+ children: [
24510
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "📁" }),
24511
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: savedPath ? "Change Folder" : "Choose Folder" })
24512
+ ]
24513
+ }
24514
+ ),
24515
+ savedPath && /* @__PURE__ */ jsxRuntimeExports.jsx(
24516
+ "button",
24517
+ {
24518
+ type: "button",
24519
+ onClick: (e) => {
24520
+ e.stopPropagation();
24521
+ onUnlinkMapping?.(repo.full_name);
24522
+ },
24523
+ className: "p-1.5 text-xs rounded-xl transition-all bg-surface hover:bg-danger/10 text-secondary hover:text-danger border border-border",
24524
+ title: "Clear connection",
24525
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-3.5 h-3.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
24526
+ }
24527
+ ),
24528
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
24529
+ "button",
24530
+ {
24531
+ type: "button",
24532
+ onClick: (e) => {
24533
+ e.stopPropagation();
24534
+ onRepoCardClick(repo);
24535
+ },
24536
+ className: `px-3.5 py-1.5 text-xs font-semibold rounded-xl transition-all shadow-xs flex items-center gap-1.5 ${savedPath ? isMissing ? "bg-danger/20 hover:bg-danger/30 text-danger border border-danger/40" : "bg-brand hover:bg-brand-hover text-white shadow-brand/20" : "bg-brand hover:bg-brand-hover text-white shadow-brand/20"}`,
24537
+ children: [
24538
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: savedPath ? isMissing ? "Re-Clone" : "Open Repo" : "Clone" }),
24539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isMissing ? "☁️" : savedPath ? "→" : "☁️" })
24540
+ ]
24541
+ }
24542
+ )
24543
+ ] })
24511
24544
  ] })
24512
24545
  ]
24513
24546
  },
@@ -25384,32 +25417,8 @@ function App() {
25384
25417
  const exists = await window.api.checkPathExists(targetPath);
25385
25418
  if (!exists) {
25386
25419
  console.warn("Target path does not exist on disk:", targetPath);
25387
- const currentMappings = JSON.parse(localStorage.getItem("gitelectron_collab_mappings") || "{}");
25388
- const matching = Object.entries(currentMappings).find(([_, p]) => p === targetPath);
25389
- if (matching) {
25390
- const [fullName] = matching;
25391
- let repo = collaboratedRepos.find((r) => r.full_name === fullName);
25392
- if (!repo) {
25393
- try {
25394
- const allCollabs = await window.api.getCollaboratedRepos();
25395
- setCollaboratedRepos(allCollabs);
25396
- repo = allCollabs.find((r) => r.full_name === fullName);
25397
- } catch (e) {
25398
- }
25399
- }
25400
- if (repo) {
25401
- showToast(`The local folder for ${fullName} was deleted. You can re-clone it now.`, "warning");
25402
- setShowCollabActionModal({
25403
- repo,
25404
- url: repo.clone_url,
25405
- name: repo.name,
25406
- fullName: repo.full_name,
25407
- missingPreviousPath: targetPath
25408
- });
25409
- setChangesTab("collaboration-repo");
25410
- return;
25411
- }
25412
- }
25420
+ showToast(`Folder not found on disk: ${targetPath}`, "warning");
25421
+ return;
25413
25422
  }
25414
25423
  } catch (e) {
25415
25424
  console.error("Error checking target path existence:", e);
@@ -25428,24 +25437,72 @@ function App() {
25428
25437
  }
25429
25438
  }).catch((err) => console.error("Failed to load repo", err));
25430
25439
  };
25440
+ const getCandidateDirs = () => {
25441
+ const list = [];
25442
+ if (repoPath) {
25443
+ const p1 = repoPath.replace(/\\/g, "/").split("/").slice(0, -1).join("/");
25444
+ if (p1 && !list.includes(p1)) list.push(p1);
25445
+ const p2 = p1 ? p1.split("/").slice(0, -1).join("/") : "";
25446
+ if (p2 && !list.includes(p2)) list.push(p2);
25447
+ }
25448
+ const standard = [
25449
+ "D:/DRDO_ProjectX1",
25450
+ "D:/DRDO_ProjectX1/DRDO_Project",
25451
+ "D:/My Projects",
25452
+ "D:/My Projects/PushGitX"
25453
+ ];
25454
+ standard.forEach((d) => {
25455
+ if (!list.includes(d)) list.push(d);
25456
+ });
25457
+ Object.values(collabMappings).forEach((p) => {
25458
+ if (p) {
25459
+ const pParent = p.replace(/\\/g, "/").split("/").slice(0, -1).join("/");
25460
+ if (pParent && !list.includes(pParent)) list.push(pParent);
25461
+ }
25462
+ });
25463
+ return list;
25464
+ };
25431
25465
  reactExports.useEffect(() => {
25432
25466
  const checkAllPaths = async () => {
25433
25467
  const results = {};
25434
- for (const [fullName, path] of Object.entries(collabMappings)) {
25435
- if (path) {
25468
+ const candidateDirs = getCandidateDirs();
25469
+ for (const repo of collaboratedRepos) {
25470
+ const fullName = repo.full_name;
25471
+ const currentPath = collabMappings[fullName];
25472
+ let valid = false;
25473
+ if (currentPath) {
25436
25474
  try {
25437
- results[fullName] = await window.api.checkPathExists(path);
25475
+ const exists = await window.api.checkPathExists(currentPath);
25476
+ if (exists) {
25477
+ const gitInfo = await window.api.getDirectoryGitInfo(currentPath);
25478
+ const detectedName = (gitInfo.repoName || "").toLowerCase();
25479
+ const expectedName = (repo.name || fullName.split("/").pop() || "").toLowerCase();
25480
+ if (!detectedName || detectedName === expectedName) {
25481
+ valid = true;
25482
+ }
25483
+ }
25438
25484
  } catch {
25439
- results[fullName] = false;
25485
+ valid = false;
25440
25486
  }
25441
25487
  }
25488
+ if (!valid) {
25489
+ try {
25490
+ const found = await window.api.scanForRepoFolder(repo.name, candidateDirs);
25491
+ if (found) {
25492
+ saveMapping(fullName, found);
25493
+ valid = true;
25494
+ }
25495
+ } catch {
25496
+ }
25497
+ }
25498
+ results[fullName] = valid;
25442
25499
  }
25443
25500
  setPathExistenceMap(results);
25444
25501
  };
25445
25502
  if (changesTab === "collaboration-repo" || collaboratedRepos.length > 0) {
25446
25503
  checkAllPaths();
25447
25504
  }
25448
- }, [collabMappings, changesTab, collaboratedRepos.length]);
25505
+ }, [changesTab, collaboratedRepos.length]);
25449
25506
  reactExports.useEffect(() => {
25450
25507
  if (authStatus.status === "Verified") {
25451
25508
  window.api.getCollaboratedRepos().then((repos) => {
@@ -25603,13 +25660,24 @@ function App() {
25603
25660
  return updated;
25604
25661
  });
25605
25662
  };
25663
+ const removeMapping = (repoFullName) => {
25664
+ setCollabMappings((prev) => {
25665
+ const updated = { ...prev };
25666
+ delete updated[repoFullName];
25667
+ localStorage.setItem("gitelectron_collab_mappings", JSON.stringify(updated));
25668
+ return updated;
25669
+ });
25670
+ };
25606
25671
  const openCollabRepoPath = async (targetPath) => {
25607
25672
  localStorage.setItem("gitelectron-last-repo", targetPath);
25608
25673
  setRepoPath(targetPath);
25609
- setIsRepo(true);
25610
- await window.api.setRepoPath(targetPath);
25611
- window.api.toggleAutoSync(targetPath, true);
25612
- await refreshRepoState();
25674
+ const result = await window.api.setRepoPath(targetPath);
25675
+ const isValidRepo = result ? result.isRepo : false;
25676
+ setIsRepo(isValidRepo);
25677
+ if (isValidRepo) {
25678
+ window.api.toggleAutoSync(targetPath, true);
25679
+ await refreshRepoState();
25680
+ }
25613
25681
  setChangesTab("changes");
25614
25682
  };
25615
25683
  const handleCollabRefresh = async () => {
@@ -25625,50 +25693,114 @@ function App() {
25625
25693
  setIsRefreshing(false);
25626
25694
  }
25627
25695
  };
25696
+ const handleSelectCollabFolder = async (repo) => {
25697
+ let defaultDir = void 0;
25698
+ if (repoPath) {
25699
+ defaultDir = repoPath.replace(/\\/g, "/").split("/").slice(0, -1).join("/");
25700
+ }
25701
+ const result = await window.api.selectDirectory(defaultDir);
25702
+ if (!result) return;
25703
+ const targetRepoName = (repo.name || repo.full_name?.split("/").pop() || "").toLowerCase();
25704
+ const gitInfo = await window.api.getDirectoryGitInfo(result.path);
25705
+ const detectedRepoName = (gitInfo.repoName || "").toLowerCase();
25706
+ if (detectedRepoName && targetRepoName && detectedRepoName !== targetRepoName) {
25707
+ const confirmUse = window.confirm(
25708
+ `Notice: Folder Remote Mismatch!
25709
+
25710
+ The folder you selected appears to belong to repository "${gitInfo.repoName}", but this card is for "${repo.name}".
25711
+
25712
+ Do you want to connect "${repo.name}" to this folder anyway?`
25713
+ );
25714
+ if (!confirmUse) return;
25715
+ }
25716
+ const pathToUse = gitInfo.rootPath || result.path;
25717
+ saveMapping(repo.full_name, pathToUse);
25718
+ await openCollabRepoPath(pathToUse);
25719
+ showToast(`Connected ${repo.name} to ${pathToUse.split("\\").pop() || pathToUse}`, "success");
25720
+ };
25628
25721
  const handleRepoCardClick = async (repo) => {
25722
+ const targetRepoName = (repo.name || repo.full_name?.split("/").pop() || "").toLowerCase();
25629
25723
  const savedPath = collabMappings[repo.full_name];
25630
25724
  if (savedPath) {
25631
25725
  const exists = await window.api.checkPathExists(savedPath);
25632
25726
  if (exists) {
25633
- await openCollabRepoPath(savedPath);
25634
- return;
25635
- } else {
25636
- setShowCollabActionModal({
25637
- repo,
25638
- url: repo.clone_url,
25639
- name: repo.name,
25640
- fullName: repo.full_name,
25641
- missingPreviousPath: savedPath
25642
- });
25727
+ const gitInfo = await window.api.getDirectoryGitInfo(savedPath);
25728
+ const detectedRepoName = (gitInfo.repoName || "").toLowerCase();
25729
+ const isMatch = !detectedRepoName || detectedRepoName === targetRepoName || gitInfo.remoteUrl && (gitInfo.remoteUrl.toLowerCase().includes(targetRepoName) || gitInfo.remoteUrl.toLowerCase().includes((repo.full_name || "").toLowerCase()));
25730
+ if (isMatch) {
25731
+ await openCollabRepoPath(gitInfo.rootPath || savedPath);
25732
+ return;
25733
+ }
25734
+ console.warn(
25735
+ `Collab mapping mismatch for ${repo.full_name}: savedPath is ${detectedRepoName}, expected ${targetRepoName}`
25736
+ );
25737
+ }
25738
+ }
25739
+ const candidateDirs = getCandidateDirs();
25740
+ try {
25741
+ const autoFound = await window.api.scanForRepoFolder(repo.name, candidateDirs);
25742
+ if (autoFound) {
25743
+ saveMapping(repo.full_name, autoFound);
25744
+ showToast(
25745
+ `Auto-connected to local folder: ${autoFound.split("\\").pop() || autoFound}`,
25746
+ "success"
25747
+ );
25748
+ await openCollabRepoPath(autoFound);
25643
25749
  return;
25644
25750
  }
25751
+ } catch (e) {
25752
+ console.warn("Auto-scan error:", e);
25645
25753
  }
25646
25754
  setShowCollabActionModal({
25647
25755
  repo,
25648
25756
  url: repo.clone_url,
25649
25757
  name: repo.name,
25650
- fullName: repo.full_name
25758
+ fullName: repo.full_name,
25759
+ missingPreviousPath: savedPath
25651
25760
  });
25652
25761
  };
25653
25762
  const handleCollabMap = async () => {
25654
25763
  if (!showCollabActionModal) return;
25655
- const { fullName } = showCollabActionModal;
25764
+ const { fullName, name, repo } = showCollabActionModal;
25656
25765
  setShowCollabActionModal(null);
25657
- const result = await window.api.selectDirectory();
25766
+ let defaultDir = void 0;
25767
+ if (repoPath) {
25768
+ defaultDir = repoPath.replace(/\\/g, "/").split("/").slice(0, -1).join("/");
25769
+ }
25770
+ const result = await window.api.selectDirectory(defaultDir);
25658
25771
  if (result) {
25659
- if (fullName) {
25660
- saveMapping(fullName, result.path);
25772
+ const repoName = name || repo?.name || (fullName ? fullName.split("/").pop() : "");
25773
+ const selectedBasename = result.path.replace(/\\/g, "/").split("/").pop();
25774
+ const gitInfo = await window.api.getDirectoryGitInfo(result.path);
25775
+ const detectedRepoName = (gitInfo.repoName || "").toLowerCase();
25776
+ const targetRepoName = (repoName || "").toLowerCase();
25777
+ if (detectedRepoName && targetRepoName && detectedRepoName !== targetRepoName) {
25778
+ const confirmed = window.confirm(
25779
+ `Notice: Remote Mismatch!
25780
+
25781
+ The folder you selected appears to be for repository "${gitInfo.repoName}", but this card is "${repoName}".
25782
+
25783
+ Are you sure you want to connect "${repoName}" to this folder?`
25784
+ );
25785
+ if (!confirmed) return;
25786
+ } else if (!detectedRepoName && repoName && selectedBasename && targetRepoName !== selectedBasename.toLowerCase()) {
25787
+ const confirmed = window.confirm(
25788
+ `Warning: Folder Name Mismatch!
25789
+
25790
+ You selected the folder "${selectedBasename}", but the repository is named "${repoName}".
25791
+
25792
+ Because the folder picker often opens in the last folder you viewed, you might have accidentally selected the wrong folder.
25793
+
25794
+ Are you SURE you want to link "${repoName}" to this folder?`
25795
+ );
25796
+ if (!confirmed) return;
25661
25797
  }
25662
- localStorage.setItem("gitelectron-last-repo", result.path);
25663
- setRepoPath(result.path);
25664
- setIsRepo(result.isRepo);
25665
- if (result.isRepo) {
25666
- await window.api.setRepoPath(result.path);
25667
- await refreshRepoState();
25668
- window.api.toggleAutoSync(result.path, true);
25798
+ const pathToUse = gitInfo.rootPath || result.path;
25799
+ if (fullName) {
25800
+ saveMapping(fullName, pathToUse);
25669
25801
  }
25670
- setChangesTab("changes");
25671
- showToast(`Linked repository to ${result.path}`, "success");
25802
+ await openCollabRepoPath(pathToUse);
25803
+ showToast(`Linked repository to ${pathToUse.split("\\").pop() || pathToUse}`, "success");
25672
25804
  }
25673
25805
  };
25674
25806
  const handleCollabClone = async () => {
@@ -25842,23 +25974,7 @@ function App() {
25842
25974
  try {
25843
25975
  const exists = await window.api.checkPathExists(repoPath);
25844
25976
  if (!exists) {
25845
- const currentMappings = JSON.parse(localStorage.getItem("gitelectron_collab_mappings") || "{}");
25846
- const matching = Object.entries(currentMappings).find(([_, p]) => p === repoPath);
25847
- if (matching) {
25848
- const [fullName] = matching;
25849
- const repo = collaboratedRepos.find((r) => r.full_name === fullName);
25850
- if (repo) {
25851
- showToast(`Repository folder was deleted on disk: ${fullName}. Prompting to re-clone.`, "warning");
25852
- setShowCollabActionModal({
25853
- repo,
25854
- url: repo.clone_url,
25855
- name: repo.name,
25856
- fullName: repo.full_name,
25857
- missingPreviousPath: repoPath
25858
- });
25859
- setChangesTab("collaboration-repo");
25860
- }
25861
- }
25977
+ console.warn("Repository path does not exist on disk:", repoPath);
25862
25978
  }
25863
25979
  } catch (err) {
25864
25980
  }
@@ -26981,7 +27097,7 @@ function App() {
26981
27097
  onClick: handleCollabMap,
26982
27098
  className: "w-full py-3 px-4 bg-surface-hover hover:bg-surface-hover/80 border border-border rounded-xl text-primary text-sm font-medium transition-colors text-left flex items-center justify-between",
26983
27099
  children: [
26984
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Already have this project folder" }),
27100
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Select Existing Folder (Already on my computer)" }),
26985
27101
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-base", children: "📁" })
26986
27102
  ]
26987
27103
  }
@@ -27332,19 +27448,53 @@ function App() {
27332
27448
  const saved = collabMappings[repo.full_name];
27333
27449
  const isMissing = saved && pathExistenceMap[repo.full_name] === false;
27334
27450
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
27335
- "button",
27451
+ "div",
27336
27452
  {
27337
- onClick: () => handleRepoCardClick(repo),
27338
- className: `w-full text-left bg-canvas hover:bg-surface-hover text-primary py-2 px-3 rounded-md transition-all border text-sm truncate flex flex-col group ${isMissing ? "border-danger/40 bg-danger/5" : "border-border"}`,
27339
- title: repo.name,
27453
+ className: `relative w-full text-left bg-canvas hover:bg-surface-hover text-primary py-2 px-3 rounded-md transition-all border text-sm flex flex-col group ${isMissing ? "border-danger/40 bg-danger/5" : "border-border"}`,
27340
27454
  children: [
27341
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between w-full", children: [
27342
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate group-hover:text-brand transition-colors", children: repo.name }),
27343
- isMissing && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] bg-danger/20 text-danger px-1 rounded font-bold", children: "Deleted" })
27344
- ] }),
27345
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] text-secondary truncate", children: [
27346
- "by @",
27347
- repo.owner?.login
27455
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
27456
+ "button",
27457
+ {
27458
+ className: "w-full text-left flex flex-col truncate",
27459
+ onClick: () => handleRepoCardClick(repo),
27460
+ title: repo.name,
27461
+ children: [
27462
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between w-full pr-6", children: [
27463
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate group-hover:text-brand transition-colors", children: repo.name }),
27464
+ isMissing && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] bg-danger/20 text-danger px-1 rounded font-bold", children: "Deleted" })
27465
+ ] }),
27466
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] text-secondary truncate", children: [
27467
+ "by @",
27468
+ repo.owner?.login
27469
+ ] })
27470
+ ]
27471
+ }
27472
+ ),
27473
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute right-1 top-1.5 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-all", children: [
27474
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
27475
+ "button",
27476
+ {
27477
+ onClick: (e) => {
27478
+ e.stopPropagation();
27479
+ handleSelectCollabFolder(repo);
27480
+ },
27481
+ className: "p-1 rounded-md text-secondary hover:text-primary hover:bg-surface-hover transition-colors",
27482
+ title: saved ? "Change local folder" : "Select local folder on disk",
27483
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: "📁" })
27484
+ }
27485
+ ),
27486
+ saved && /* @__PURE__ */ jsxRuntimeExports.jsx(
27487
+ "button",
27488
+ {
27489
+ onClick: (e) => {
27490
+ e.stopPropagation();
27491
+ removeMapping(repo.full_name);
27492
+ },
27493
+ className: "p-1 rounded-md text-secondary hover:text-danger hover:bg-danger/10 transition-colors",
27494
+ title: "Clear saved link",
27495
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
27496
+ }
27497
+ )
27348
27498
  ] })
27349
27499
  ]
27350
27500
  },
@@ -27463,7 +27613,7 @@ function App() {
27463
27613
  )
27464
27614
  ] })
27465
27615
  ] }),
27466
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 p-6 flex flex-col overflow-hidden relative z-10", children: isRepo && status && branches ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-4 mb-6 relative z-20", children: [
27616
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 p-6 flex flex-col overflow-y-auto custom-scrollbar min-h-0 relative z-10", children: isRepo && status && branches ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-h-0 gap-4 mb-6 relative z-20", children: [
27467
27617
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap justify-between items-center bg-surface/70 backdrop-blur-md border border-border p-3 rounded-xl transition-colors duration-300 gap-4 relative z-50", children: [
27468
27618
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm", children: [
27469
27619
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 relative", children: [
@@ -27501,7 +27651,7 @@ function App() {
27501
27651
  ] })
27502
27652
  }
27503
27653
  ),
27504
- showAccountDropdown && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-full left-0 mt-2 w-64 max-w-[90vw] bg-surface backdrop-blur-xl border border-border rounded-lg shadow-xl py-2 z-[60]", children: [
27654
+ showAccountDropdown && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-full left-0 mt-2 w-64 max-w-[90vw] bg-surface backdrop-blur-xl border border-border rounded-lg shadow-2xl py-2 z-[60] account-dropdown-glass", children: [
27505
27655
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-1.5 text-xs font-semibold text-secondary uppercase tracking-wider mb-1", children: "Your Accounts" }),
27506
27656
  accounts.map((acc) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
27507
27657
  "div",
@@ -27955,12 +28105,14 @@ function App() {
27955
28105
  onRepoCardClick: handleRepoCardClick,
27956
28106
  onRefresh: handleCollabRefresh,
27957
28107
  isRefreshing,
27958
- onOpenExternal: (url) => window.api.openExternal(url)
28108
+ onOpenExternal: (url) => window.api.openExternal(url),
28109
+ onUnlinkMapping: removeMapping,
28110
+ onChangeFolder: handleSelectCollabFolder
27959
28111
  }
27960
28112
  )
27961
28113
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
27962
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { id: "split-pane-container", className: "flex-1 overflow-hidden flex flex-col lg:flex-row pb-2", children: [
27963
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: leftPanelWidth }, className: "bg-surface/70 backdrop-blur-md rounded-xl border border-border flex flex-col transition-colors duration-300 overflow-hidden min-h-[250px]", children: [
28114
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { id: "split-pane-container", className: "flex-1 overflow-hidden min-h-0 flex flex-col lg:flex-row pb-2", children: [
28115
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: leftPanelWidth }, className: "bg-surface/70 backdrop-blur-md rounded-xl border border-border flex flex-col transition-colors duration-300 overflow-hidden min-h-[250px] min-w-0 min-h-0", children: [
27964
28116
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-nowrap overflow-x-auto custom-scrollbar items-center border-b border-border px-4 pt-3 pb-1 gap-y-2 gap-x-1", children: [
27965
28117
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
27966
28118
  "button",
@@ -28027,9 +28179,9 @@ function App() {
28027
28179
  MassivePushLoader,
28028
28180
  {
28029
28181
  percentage: massivePushData?.percentage || 0,
28030
- eta: massivePushData?.eta || "calculating..."
28182
+ eta: gitProgress > 0 && gitProgress < 100 ? `Uploading Chunk: ${Math.round(gitProgress)}%` : massivePushData?.eta || "calculating..."
28031
28183
  }
28032
- ) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-auto p-4 custom-scrollbar", children: [
28184
+ ) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto min-h-0 p-4 custom-scrollbar", children: [
28033
28185
  changesTab === "changes" && /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "space-y-1", children: [
28034
28186
  status.conflicted.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
28035
28187
  "li",
@@ -28200,9 +28352,9 @@ function App() {
28200
28352
  children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `h-12 w-1 rounded-full transition-colors ${isResizing ? "bg-accent" : "bg-border group-hover:bg-accent/50"}` })
28201
28353
  }
28202
28354
  ),
28203
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: 100 - leftPanelWidth }, className: "bg-surface/70 backdrop-blur-md rounded-xl p-4 border border-border flex flex-col transition-colors duration-300 min-h-[250px]", children: [
28204
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "font-semibold mb-4 text-primary text-sm", children: "Staged Changes" }),
28205
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto pr-2 custom-scrollbar", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "space-y-1", children: [
28355
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: 100 - leftPanelWidth }, className: "bg-surface/70 backdrop-blur-md rounded-xl p-4 border border-border flex flex-col transition-colors duration-300 overflow-hidden min-h-0 min-w-0", children: [
28356
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "font-semibold mb-4 text-primary text-sm shrink-0", children: "Staged Changes" }),
28357
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto min-h-0 pr-2 custom-scrollbar", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "space-y-1", children: [
28206
28358
  status.staged.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
28207
28359
  "li",
28208
28360
  {
@@ -28242,7 +28394,7 @@ function App() {
28242
28394
  ] }) })
28243
28395
  ] })
28244
28396
  ] }),
28245
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 bg-surface/70 backdrop-blur-md p-4 rounded-xl border border-border flex gap-3 items-center transition-colors duration-300", children: [
28397
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 shrink-0 bg-surface/70 backdrop-blur-md p-4 rounded-xl border border-border flex flex-col sm:flex-row gap-3 items-center transition-colors duration-300", children: [
28246
28398
  /* @__PURE__ */ jsxRuntimeExports.jsx(
28247
28399
  "input",
28248
28400
  {
@@ -28295,7 +28447,9 @@ function App() {
28295
28447
  onRepoCardClick: handleRepoCardClick,
28296
28448
  onRefresh: handleCollabRefresh,
28297
28449
  isRefreshing,
28298
- onOpenExternal: (url) => window.api.openExternal(url)
28450
+ onOpenExternal: (url) => window.api.openExternal(url),
28451
+ onUnlinkMapping: removeMapping,
28452
+ onChangeFolder: handleSelectCollabFolder
28299
28453
  }
28300
28454
  )
28301
28455
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center text-secondary relative z-10", children: [