Made more like Github Desktop

This commit is contained in:
2026-05-10 20:33:03 +12:00
parent 346f8536f0
commit ac7fc231a0
7 changed files with 3630 additions and 1000 deletions
+1400 -414
View File
File diff suppressed because it is too large Load Diff
+59 -4
View File
@@ -1,10 +1,16 @@
import { loadSettings, saveSettings } from "./storage.js";
const initialSettings = loadSettings();
const state = {
settings: loadSettings(),
selectedRepoPath: "",
selectedRepoName: "",
settings: initialSettings,
selectedRepoPath: initialSettings.lastSelectedRepoPath || "",
selectedRepoName: initialSettings.lastSelectedRepoPath ? initialSettings.lastSelectedRepoPath.split(/[/\\]/).filter(Boolean).pop() || "" : "",
repoSearch: "",
changesFilter: "",
historyFilter: "",
commitSummary: "",
commitDescription: "",
localRepoPathInput: "",
localRepoScanRootInput: "",
localRepoScanResults: [],
@@ -13,6 +19,55 @@ const state = {
cloneUrlInput: "",
cloneDestinationInput: "",
commitMessage: "",
workingTree: {
loading: false,
error: "",
branch: "",
upstream: "",
ahead: 0,
behind: 0,
files: [],
selectedPaths: new Set(),
selectedPath: "",
selectedDiff: null,
diffLoading: false,
diffError: "",
},
sync: {
loading: false,
error: "",
operation: "",
branch: "",
upstream: "",
upstreamRemote: "",
defaultRemote: "",
ahead: 0,
behind: 0,
hasRemote: false,
isDetached: false,
isUnpublished: false,
lastUpdated: 0,
},
branches: {
loading: false,
error: "",
items: [],
createName: "",
menuOpen: false,
dialog: {
mode: "",
target: "",
value: "",
error: "",
},
},
history: {
loading: false,
error: "",
commits: [],
selectedHash: "",
selectedCommit: null,
},
viewer: {
source: "",
repoName: "",
@@ -47,7 +102,7 @@ export function addRecentRepo(path) {
if (!path) return;
const current = state.settings.recentRepositories.filter((item) => item !== path);
const next = [path, ...current].slice(0, 15);
updateSettings({ recentRepositories: next });
updateSettings({ recentRepositories: next, lastSelectedRepoPath: path });
}
export function getActiveServer() {
+3
View File
@@ -5,6 +5,9 @@ export function getDefaultSettings() {
theme: "dark",
gitExecutablePath: "",
defaultCloneDirectory: "",
externalEditorPath: "",
autoFetchOnRepoOpen: false,
lastSelectedRepoPath: "",
activeServerId: null,
servers: [],
recentRepositories: [],
+96
View File
@@ -25,6 +25,21 @@ export async function runGitPush(repoPath, gitPath) {
return invoke("git_push", { repoPath, gitPath: gitPath || null });
}
export async function runGitPublishBranch(repoPath, remote, gitPath) {
ensureInvoke();
return invoke("git_publish_branch", { repoPath, remote: remote || null, gitPath: gitPath || null });
}
export async function runGitFetch(repoPath, gitPath) {
ensureInvoke();
return invoke("git_fetch", { repoPath, gitPath: gitPath || null });
}
export async function runGitSync(repoPath, gitPath) {
ensureInvoke();
return invoke("git_sync", { repoPath, gitPath: gitPath || null });
}
export async function runGitStatus(repoPath, gitPath) {
ensureInvoke();
return invoke("git_status", { repoPath, gitPath: gitPath || null });
@@ -35,6 +50,87 @@ export async function runGitBranch(repoPath, gitPath) {
return invoke("git_branch", { repoPath, gitPath: gitPath || null });
}
export async function getWorkingTreeStatus(repoPath, gitPath) {
ensureInvoke();
return invoke("working_tree_status", { repoPath, gitPath: gitPath || null });
}
export async function getRepositorySyncStatus(repoPath, gitPath) {
ensureInvoke();
return invoke("repository_sync_status", { repoPath, gitPath: gitPath || null });
}
export async function getFileDiff(repoPath, path, status, gitPath) {
ensureInvoke();
return invoke("get_file_diff", { repoPath, path, status, gitPath: gitPath || null });
}
export async function stageFiles(repoPath, paths, gitPath) {
ensureInvoke();
return invoke("stage_files", { repoPath, paths, gitPath: gitPath || null });
}
export async function unstageFiles(repoPath, paths, gitPath) {
ensureInvoke();
return invoke("unstage_files", { repoPath, paths, gitPath: gitPath || null });
}
export async function commitChanges(repoPath, paths, summary, description, gitPath) {
ensureInvoke();
return invoke("commit_changes", {
repoPath,
paths,
summary,
description: description || null,
gitPath: gitPath || null,
});
}
export async function checkoutBranch(repoPath, branch, gitPath) {
ensureInvoke();
return invoke("checkout_branch", { repoPath, branch, gitPath: gitPath || null });
}
export async function createBranch(repoPath, branch, gitPath) {
ensureInvoke();
return invoke("create_branch", { repoPath, branch, gitPath: gitPath || null });
}
export async function deleteBranch(repoPath, branch, force, gitPath) {
ensureInvoke();
return invoke("delete_branch", { repoPath, branch, force: !!force, gitPath: gitPath || null });
}
export async function renameBranch(repoPath, oldBranch, newBranch, gitPath) {
ensureInvoke();
return invoke("rename_branch", {
repoPath,
oldBranch,
newBranch,
gitPath: gitPath || null,
});
}
export async function getCommitHistory(repoPath, limit, gitPath) {
ensureInvoke();
return invoke("commit_history", { repoPath, limit, gitPath: gitPath || null });
}
export async function getCommitDetail(repoPath, hash, gitPath) {
ensureInvoke();
return invoke("commit_detail", { repoPath, hash, gitPath: gitPath || null });
}
export async function openInFileExplorer(repoPath) {
ensureInvoke();
return invoke("open_in_file_explorer", { repoPath });
}
export async function openInExternalEditor(repoPath, editorPath) {
ensureInvoke();
return invoke("open_in_external_editor", { repoPath, editorPath });
}
export async function scanLocalRepos(roots = [], allowedRemoteUrls = [], gitPath = "", maxDepth = 4, maxResults = 200) {
ensureInvoke();
return invoke("scan_local_repos", {