add new Context Menu for file Explorer
fix blocking UI when select the file in Status also select in the file History
This commit is contained in:
+76
-17
@@ -27,6 +27,7 @@
|
||||
commit,
|
||||
compareCommits,
|
||||
cancelCodeSearch,
|
||||
cancelFileHistory,
|
||||
applyFilePatch,
|
||||
createBranch,
|
||||
deleteBranch,
|
||||
@@ -39,6 +40,7 @@
|
||||
listRepositoryFiles,
|
||||
mergeBranch,
|
||||
openRepoInExplorer,
|
||||
openRepositoryFile,
|
||||
openRepositoryBundle,
|
||||
pull,
|
||||
push,
|
||||
@@ -119,6 +121,7 @@
|
||||
let fileHistory: GitCommit[] = [];
|
||||
let fileHistoryLoading = false;
|
||||
let fileHistoryRequestId = 0;
|
||||
let activeFileHistoryRequestId = "";
|
||||
let commitMessage = "";
|
||||
let errorMessage = "";
|
||||
let operation = "";
|
||||
@@ -207,6 +210,7 @@
|
||||
|
||||
onDestroy(() => {
|
||||
if (autoRefreshTimer) clearInterval(autoRefreshTimer);
|
||||
if (activeFileHistoryRequestId) void cancelFileHistory(activeFileHistoryRequestId);
|
||||
});
|
||||
|
||||
// ── Auto-refresh ───────────────────────────────────────────────────────────
|
||||
@@ -534,14 +538,56 @@
|
||||
if (selectedExplorerPath && !explorerPathExists(repoFiles, selectedExplorerPath)) {
|
||||
selectedExplorerPath = "";
|
||||
selectedExplorerKind = "file";
|
||||
cancelActiveFileHistoryLoad();
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
fileHistory = [];
|
||||
}
|
||||
}
|
||||
|
||||
function isCancellationMessage(message: string): boolean {
|
||||
return message.toLowerCase().includes("abgebrochen");
|
||||
}
|
||||
|
||||
function cancelActiveFileHistoryLoad() {
|
||||
const requestId = activeFileHistoryRequestId;
|
||||
if (!requestId) return;
|
||||
void cancelFileHistory(requestId).catch(() => {});
|
||||
}
|
||||
|
||||
async function refreshFileHistory(path = activeRepoPath, file = selectedExplorerPath) {
|
||||
const requestId = ++fileHistoryRequestId;
|
||||
const history = file ? await listFileHistory(path, file, 100) : [];
|
||||
if (requestId === fileHistoryRequestId) fileHistory = history;
|
||||
cancelActiveFileHistoryLoad();
|
||||
|
||||
if (!path || !file) {
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
fileHistory = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const historyRequestId = `file-history-${requestId}-${Date.now()}`;
|
||||
activeFileHistoryRequestId = historyRequestId;
|
||||
fileHistoryLoading = true;
|
||||
fileHistory = [];
|
||||
|
||||
try {
|
||||
const history = await listFileHistory(path, file, 100, historyRequestId);
|
||||
if (requestId === fileHistoryRequestId && activeFileHistoryRequestId === historyRequestId) {
|
||||
fileHistory = history;
|
||||
}
|
||||
} catch (error) {
|
||||
const message = errorToMessage(error);
|
||||
if (requestId === fileHistoryRequestId && activeFileHistoryRequestId === historyRequestId) {
|
||||
fileHistory = [];
|
||||
if (!isCancellationMessage(message)) errorMessage = message;
|
||||
}
|
||||
} finally {
|
||||
if (requestId === fileHistoryRequestId && activeFileHistoryRequestId === historyRequestId) {
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Repository operations ──────────────────────────────────────────────────
|
||||
@@ -1120,26 +1166,14 @@
|
||||
// (isBusy/runOperation would disable every button in the app while this awaits).
|
||||
// A request id guards against a slower, stale request overwriting a newer selection.
|
||||
async function loadSelectedFileHistory(path: string, repo = activeRepoPath) {
|
||||
const requestId = ++fileHistoryRequestId;
|
||||
fileHistoryLoading = true;
|
||||
try {
|
||||
const history = await listFileHistory(repo, path, 100);
|
||||
if (requestId === fileHistoryRequestId) fileHistory = history;
|
||||
} catch (error) {
|
||||
if (requestId === fileHistoryRequestId) {
|
||||
fileHistory = [];
|
||||
errorMessage = errorToMessage(error);
|
||||
}
|
||||
} finally {
|
||||
if (requestId === fileHistoryRequestId) fileHistoryLoading = false;
|
||||
}
|
||||
await refreshFileHistory(repo, path);
|
||||
}
|
||||
|
||||
async function selectExplorerNode(node: ExplorerNode) {
|
||||
if (!activeRepoPath || (selectedExplorerPath === node.path && selectedExplorerKind === node.kind)) return;
|
||||
selectedExplorerPath = node.path;
|
||||
selectedExplorerKind = node.kind;
|
||||
await loadSelectedFileHistory(node.path);
|
||||
void loadSelectedFileHistory(node.path);
|
||||
}
|
||||
|
||||
async function selectFileFromSearch(file: GitRepositoryFile) {
|
||||
@@ -1148,7 +1182,29 @@
|
||||
selectedExplorerKind = "file";
|
||||
expandedExplorerPaths = new Set([...expandedExplorerPaths, ...explorerParentFolders(file.path)]);
|
||||
|
||||
await loadSelectedFileHistory(file.path);
|
||||
void loadSelectedFileHistory(file.path);
|
||||
}
|
||||
|
||||
function selectFileFromStatus(file: GitFileStatus) {
|
||||
if (!activeRepoPath) return;
|
||||
selectedExplorerPath = file.path;
|
||||
selectedExplorerKind = "file";
|
||||
expandedExplorerPaths = new Set([...expandedExplorerPaths, ...explorerParentFolders(file.path)]);
|
||||
|
||||
void loadSelectedFileHistory(file.path);
|
||||
}
|
||||
|
||||
async function openFileFromExplorer(node: ExplorerNode) {
|
||||
if (!activeRepoPath || node.kind !== "file") return;
|
||||
selectedExplorerPath = node.path;
|
||||
selectedExplorerKind = "file";
|
||||
void loadSelectedFileHistory(node.path);
|
||||
|
||||
try {
|
||||
await openRepositoryFile(activeRepoPath, node.path);
|
||||
} catch (error) {
|
||||
errorMessage = errorToMessage(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function restoreSelectedFileFromCommit(target: GitCommit) {
|
||||
@@ -1590,6 +1646,7 @@
|
||||
onExpandAllFolders={expandAllExplorerFolders}
|
||||
onCollapseAllFolders={collapseAllExplorerFolders}
|
||||
onSelectNode={selectExplorerNode}
|
||||
onOpenFile={openFileFromExplorer}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
@@ -1618,6 +1675,8 @@
|
||||
{hasRepository}
|
||||
{isBusy}
|
||||
{status}
|
||||
selectedFilePath={selectedExplorerPath}
|
||||
onSelectFile={selectFileFromStatus}
|
||||
onStage={stageFile}
|
||||
onUnstage={unstageFile}
|
||||
onDiscard={discardFile}
|
||||
|
||||
Reference in New Issue
Block a user