Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0877d5a568 | ||
|
|
f79f3dc1ec |
+17
-1
@@ -1939,6 +1939,21 @@
|
|||||||
if (!activeStillOpen) await openRepo(path);
|
if (!activeStillOpen) await openRepo(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeRepoFromRecent(path: string, event?: MouseEvent) {
|
||||||
|
event?.stopPropagation();
|
||||||
|
if (isBusy) return;
|
||||||
|
recentRepoPaths = recentRepoPaths.filter((recentPath) => !sameRepoPath(recentPath, path));
|
||||||
|
persistRepoLists();
|
||||||
|
trackEvent("repository_removed_from_recent", {
|
||||||
|
recent_repositories: recentRepoPaths.length,
|
||||||
|
});
|
||||||
|
if (!repoTabs.some((tab) => sameRepoPath(tab.path, path)) && !isFavoriteRepo(path) && repoStatusCache[repoKey(path)]) {
|
||||||
|
const { [repoKey(path)]: _removed, ...rest } = repoStatusCache;
|
||||||
|
repoStatusCache = rest;
|
||||||
|
persistRepoStatusCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function removeRepoFromManagement(path: string, event?: MouseEvent) {
|
async function removeRepoFromManagement(path: string, event?: MouseEvent) {
|
||||||
event?.stopPropagation();
|
event?.stopPropagation();
|
||||||
if (isBusy) return;
|
if (isBusy) return;
|
||||||
@@ -3516,7 +3531,7 @@
|
|||||||
>
|
>
|
||||||
<Star size={14} aria-hidden="true" />
|
<Star size={14} aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
<button class="repo-row-icon" type="button" onclick={(event) => removeRepoFromManagement(repo.path, event)} disabled={isBusy} title="Remove from recent" aria-label={`Remove ${repo.name}`}>
|
<button class="repo-row-icon" type="button" onclick={(event) => removeRepoFromRecent(repo.path, event)} disabled={isBusy} title="Remove from recent" aria-label={`Remove ${repo.name}`}>
|
||||||
<X size={14} aria-hidden="true" />
|
<X size={14} aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -3719,6 +3734,7 @@
|
|||||||
{unstagedCount}
|
{unstagedCount}
|
||||||
{hasRepository}
|
{hasRepository}
|
||||||
{isBusy}
|
{isBusy}
|
||||||
|
{operation}
|
||||||
{status}
|
{status}
|
||||||
selectedFilePath={selectedExplorerPath}
|
selectedFilePath={selectedExplorerPath}
|
||||||
onSelectFile={selectFileFromStatus}
|
onSelectFile={selectFileFromStatus}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Check, FileDiff, RotateCcw, Undo2 } from "@lucide/svelte";
|
import { Check, FileDiff, LoaderCircle, RotateCcw, Undo2 } from "@lucide/svelte";
|
||||||
import type { FileStatusKind, GitFileStatus, GitStatus } from "../types";
|
import type { FileStatusKind, GitFileStatus, GitStatus } from "../types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
unstagedCount: number;
|
unstagedCount: number;
|
||||||
hasRepository: boolean;
|
hasRepository: boolean;
|
||||||
isBusy: boolean;
|
isBusy: boolean;
|
||||||
|
operation: string;
|
||||||
status: GitStatus | null;
|
status: GitStatus | null;
|
||||||
selectedFilePath: string;
|
selectedFilePath: string;
|
||||||
onSelectFile: (file: GitFileStatus) => void;
|
onSelectFile: (file: GitFileStatus) => void;
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
unstagedCount = 0,
|
unstagedCount = 0,
|
||||||
hasRepository = false,
|
hasRepository = false,
|
||||||
isBusy = false,
|
isBusy = false,
|
||||||
|
operation = "",
|
||||||
status = null,
|
status = null,
|
||||||
selectedFilePath = "",
|
selectedFilePath = "",
|
||||||
onSelectFile = () => {},
|
onSelectFile = () => {},
|
||||||
@@ -136,7 +138,7 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="panel grid grid-rows-[auto_auto_1fr] overflow-hidden" aria-label="Working tree status">
|
<section class="panel relative grid grid-rows-[auto_auto_1fr] overflow-hidden" aria-label="Working tree status">
|
||||||
<div class="section-head">
|
<div class="section-head">
|
||||||
<div>
|
<div>
|
||||||
<span class="eyebrow">Working tree</span>
|
<span class="eyebrow">Working tree</span>
|
||||||
@@ -278,4 +280,49 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if isBusy && hasRepository}
|
||||||
|
<div class="status-panel-overlay" role="status" aria-live="polite">
|
||||||
|
<div class="status-panel-overlay-card">
|
||||||
|
<LoaderCircle class="spin" size={22} aria-hidden="true" />
|
||||||
|
<span>{operation || "Working"}…</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.status-panel-overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 20;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
background: rgba(8, 9, 16, 0.5);
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
animation: status-panel-overlay-in 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-panel-overlay-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--color-surface-raised);
|
||||||
|
color: var(--color-ink);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes status-panel-overlay-in {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.status-panel-overlay { animation: none; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user