Compare commits

...
3 Commits
Author SHA1 Message Date
Christoph Brandau 0877d5a568 feat(status-panel): add loading overlay for ongoing operations
This update introduces a loading overlay in the StatusPanel component
to indicate ongoing operations. The overlay displays a spinner and
the current operation status, enhancing user experience during
long-running tasks.

- Added a loading overlay with a spinner for busy states
- Included operation status text to inform users of current actions
- Improved visual feedback for ongoing processes in the UI
2026-07-09 15:20:52 +02:00
Christoph Brandau f79f3dc1ec feat(recent-repos): add functionality to remove repositories from recent
This update introduces a new function to remove repositories from the
recent list. The user can now manage their recent repositories more
effectively, enhancing the overall user experience.

- Implemented removal of repositories from the recent list
- Updated UI to reflect changes in the recent repositories management
2026-07-09 15:14:29 +02:00
Christoph cf2773b6f4 Update version to 2026.7.16 2026-07-09 09:54:57 +02:00
5 changed files with 70 additions and 7 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "gitty", "name": "gitty",
"version": "0.200.5", "version": "2026.7.16",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "gitty", "name": "gitty",
"version": "0.200.5", "version": "2026.7.16",
"dependencies": { "dependencies": {
"@lucide/svelte": "^1.21.0", "@lucide/svelte": "^1.21.0",
"@tailwindcss/vite": "^4.3.1", "@tailwindcss/vite": "^4.3.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "gitty", "name": "gitty",
"version": "0.200.5", "version": "2026.7.16",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Gitty", "productName": "Gitty",
"version": "0.200.5", "version": "2026.7.16",
"identifier": "com.gitty", "identifier": "com.gitty",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
+17 -1
View File
@@ -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}
+49 -2
View File
@@ -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>