mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-28 04:36:53 -05:00
Compare commits
1 Commits
codex/cli-
...
v2026.2.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cab111965 |
@@ -32,22 +32,30 @@ export interface GitCallbacks {
|
|||||||
|
|
||||||
const onSuccess = () => queryClient.invalidateQueries({ queryKey: ['git'] });
|
const onSuccess = () => queryClient.invalidateQueries({ queryKey: ['git'] });
|
||||||
|
|
||||||
export function useGit(dir: string, callbacks: GitCallbacks) {
|
export function useGit(dir: string, callbacks: GitCallbacks, refreshKey?: string) {
|
||||||
const mutations = useMemo(() => gitMutations(dir, callbacks), [dir, callbacks]);
|
const mutations = useMemo(() => gitMutations(dir, callbacks), [dir, callbacks]);
|
||||||
|
const fetchAll = useQuery<void, string>({
|
||||||
|
queryKey: ['git', 'fetch_all', dir, refreshKey],
|
||||||
|
queryFn: () => invoke('cmd_git_fetch_all', { dir }),
|
||||||
|
refetchInterval: 10 * 60_000,
|
||||||
|
});
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
remotes: useQuery<GitRemote[], string>({
|
remotes: useQuery<GitRemote[], string>({
|
||||||
queryKey: ['git', 'remotes', dir],
|
queryKey: ['git', 'remotes', dir, refreshKey],
|
||||||
queryFn: () => getRemotes(dir),
|
queryFn: () => getRemotes(dir),
|
||||||
|
placeholderData: (prev) => prev,
|
||||||
}),
|
}),
|
||||||
log: useQuery<GitCommit[], string>({
|
log: useQuery<GitCommit[], string>({
|
||||||
queryKey: ['git', 'log', dir],
|
queryKey: ['git', 'log', dir, refreshKey],
|
||||||
queryFn: () => invoke('cmd_git_log', { dir }),
|
queryFn: () => invoke('cmd_git_log', { dir }),
|
||||||
|
placeholderData: (prev) => prev,
|
||||||
}),
|
}),
|
||||||
status: useQuery<GitStatusSummary, string>({
|
status: useQuery<GitStatusSummary, string>({
|
||||||
refetchOnMount: true,
|
refetchOnMount: true,
|
||||||
queryKey: ['git', 'status', dir],
|
queryKey: ['git', 'status', dir, refreshKey, fetchAll.dataUpdatedAt],
|
||||||
queryFn: () => invoke('cmd_git_status', { dir }),
|
queryFn: () => invoke('cmd_git_status', { dir }),
|
||||||
|
placeholderData: (prev) => prev,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
mutations,
|
mutations,
|
||||||
@@ -152,10 +160,7 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
|||||||
},
|
},
|
||||||
onSuccess,
|
onSuccess,
|
||||||
}),
|
}),
|
||||||
fetchAll: createFastMutation<void, string, void>({
|
|
||||||
mutationKey: ['git', 'fetch_all', dir],
|
|
||||||
mutationFn: () => invoke('cmd_git_fetch_all', { dir }),
|
|
||||||
}),
|
|
||||||
push: createFastMutation<PushResult, string, void>({
|
push: createFastMutation<PushResult, string, void>({
|
||||||
mutationKey: ['git', 'push', dir],
|
mutationKey: ['git', 'push', dir],
|
||||||
mutationFn: push,
|
mutationFn: push,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { forwardRef } from 'react';
|
|||||||
import { openWorkspaceSettings } from '../../commands/openWorkspaceSettings';
|
import { openWorkspaceSettings } from '../../commands/openWorkspaceSettings';
|
||||||
import { activeWorkspaceAtom, activeWorkspaceMetaAtom } from '../../hooks/useActiveWorkspace';
|
import { activeWorkspaceAtom, activeWorkspaceMetaAtom } from '../../hooks/useActiveWorkspace';
|
||||||
import { useKeyValue } from '../../hooks/useKeyValue';
|
import { useKeyValue } from '../../hooks/useKeyValue';
|
||||||
|
import { useRandomKey } from '../../hooks/useRandomKey';
|
||||||
import { sync } from '../../init/sync';
|
import { sync } from '../../init/sync';
|
||||||
import { showConfirm, showConfirmDelete } from '../../lib/confirm';
|
import { showConfirm, showConfirmDelete } from '../../lib/confirm';
|
||||||
import { showDialog } from '../../lib/dialog';
|
import { showDialog } from '../../lib/dialog';
|
||||||
@@ -36,6 +37,7 @@ export function GitDropdown() {
|
|||||||
|
|
||||||
function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
||||||
const workspace = useAtomValue(activeWorkspaceAtom);
|
const workspace = useAtomValue(activeWorkspaceAtom);
|
||||||
|
const [refreshKey, regenerateKey] = useRandomKey();
|
||||||
const [
|
const [
|
||||||
{ status, log },
|
{ status, log },
|
||||||
{
|
{
|
||||||
@@ -43,7 +45,6 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
deleteBranch,
|
deleteBranch,
|
||||||
deleteRemoteBranch,
|
deleteRemoteBranch,
|
||||||
renameBranch,
|
renameBranch,
|
||||||
fetchAll,
|
|
||||||
mergeBranch,
|
mergeBranch,
|
||||||
push,
|
push,
|
||||||
pull,
|
pull,
|
||||||
@@ -51,7 +52,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
resetChanges,
|
resetChanges,
|
||||||
init,
|
init,
|
||||||
},
|
},
|
||||||
] = useGit(syncDir, gitCallbacks(syncDir));
|
] = useGit(syncDir, gitCallbacks(syncDir), refreshKey);
|
||||||
|
|
||||||
const localBranches = status.data?.localBranches ?? [];
|
const localBranches = status.data?.localBranches ?? [];
|
||||||
const remoteBranches = status.data?.remoteBranches ?? [];
|
const remoteBranches = status.data?.remoteBranches ?? [];
|
||||||
@@ -172,7 +173,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: 'Push',
|
label: 'Push',
|
||||||
disabled: !hasRemotes || ahead === 0,
|
hidden: !hasRemotes,
|
||||||
leftSlot: <Icon icon="arrow_up_from_line" />,
|
leftSlot: <Icon icon="arrow_up_from_line" />,
|
||||||
waitForOnSelect: true,
|
waitForOnSelect: true,
|
||||||
async onSelect() {
|
async onSelect() {
|
||||||
@@ -191,7 +192,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Pull',
|
label: 'Pull',
|
||||||
disabled: !hasRemotes || behind === 0,
|
hidden: !hasRemotes,
|
||||||
leftSlot: <Icon icon="arrow_down_to_line" />,
|
leftSlot: <Icon icon="arrow_down_to_line" />,
|
||||||
waitForOnSelect: true,
|
waitForOnSelect: true,
|
||||||
async onSelect() {
|
async onSelect() {
|
||||||
@@ -210,7 +211,7 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Commit...',
|
label: 'Commit...',
|
||||||
disabled: !hasChanges,
|
|
||||||
leftSlot: <Icon icon="git_commit_vertical" />,
|
leftSlot: <Icon icon="git_commit_vertical" />,
|
||||||
onSelect() {
|
onSelect() {
|
||||||
showDialog({
|
showDialog({
|
||||||
@@ -502,15 +503,25 @@ function SyncDropdownWithSyncDir({ syncDir }: { syncDir: string }) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown fullWidth items={items} onOpen={fetchAll.mutate}>
|
<Dropdown fullWidth items={items} onOpen={regenerateKey}>
|
||||||
<GitMenuButton>
|
<GitMenuButton>
|
||||||
<InlineCode className="flex items-center gap-1">
|
<InlineCode className="flex items-center gap-1">
|
||||||
<Icon icon="git_branch" size="xs" className="opacity-50" />
|
<Icon icon="git_branch" size="xs" className="opacity-50" />
|
||||||
{currentBranch}
|
{currentBranch}
|
||||||
</InlineCode>
|
</InlineCode>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
{ahead > 0 && <span className="text-xs flex items-center gap-0.5"><span className="text-primary">↗</span>{ahead}</span>}
|
{ahead > 0 && (
|
||||||
{behind > 0 && <span className="text-xs flex items-center gap-0.5"><span className="text-info">↙</span>{behind}</span>}
|
<span className="text-xs flex items-center gap-0.5">
|
||||||
|
<span className="text-primary">↗</span>
|
||||||
|
{ahead}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{behind > 0 && (
|
||||||
|
<span className="text-xs flex items-center gap-0.5">
|
||||||
|
<span className="text-info">↙</span>
|
||||||
|
{behind}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</GitMenuButton>
|
</GitMenuButton>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|||||||
Reference in New Issue
Block a user