Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 31 additions & 142 deletions staged/src/lib/RemoteBranchCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
Bot,
Copy,
GitCommitHorizontal,
FileText,
Plus,
StickyNote,
} from 'lucide-svelte';
import { listen, type UnlistenFn } from '@tauri-apps/api/event';
import Spinner from './Spinner.svelte';
Expand Down Expand Up @@ -66,12 +65,6 @@
let newSessionMode = $state<BranchSessionType>('commit');
let draftPrompt = $state('');

// Long-press picker state
let longPressTimer: ReturnType<typeof setTimeout> | null = null;
let showPicker = $state(false);
let pickerRef = $state<HTMLDivElement | null>(null);
let didLongPress = false;

// Session modal (opened from timeline or after starting a session)
let openSessionId = $state<string | null>(null);

Expand Down Expand Up @@ -198,7 +191,6 @@
function openNewSession(mode: BranchSessionType) {
newSessionMode = mode;
showNewSession = true;
showPicker = false;
}

function handleNewSessionClose(draft: { prompt: string; mode: BranchSessionType }) {
Expand All @@ -213,48 +205,6 @@
loadTimeline();
}

// =========================================================================
// Long-press button logic
// =========================================================================

function handlePointerDown() {
didLongPress = false;
longPressTimer = setTimeout(() => {
didLongPress = true;
showPicker = true;
}, 400);
}

function handlePointerUp() {
if (longPressTimer) {
clearTimeout(longPressTimer);
longPressTimer = null;
}
if (!didLongPress && !showPicker) {
openNewSession('commit');
}
}

function handlePointerLeave() {
if (longPressTimer) {
clearTimeout(longPressTimer);
longPressTimer = null;
}
}

function handlePickerClickOutside(e: MouseEvent) {
if (showPicker && pickerRef && !pickerRef.contains(e.target as Node)) {
showPicker = false;
}
}

function handlePickerKeydown(e: KeyboardEvent) {
if (showPicker && e.key === 'Escape') {
showPicker = false;
e.stopPropagation();
}
}

// =========================================================================
// Timeline item interactions
// =========================================================================
Expand Down Expand Up @@ -333,8 +283,6 @@
}
</script>

<svelte:window onclick={handlePickerClickOutside} onkeydown={handlePickerKeydown} />

<div class="branch-card remote" class:deleting>
{#if deleting}
<div class="deleting-overlay">
Expand Down Expand Up @@ -433,32 +381,28 @@
{/if}
</div>

<!-- Footer with New button (only when running) -->
<!-- Footer with separate note and commit buttons (only when running) -->
{#if status === 'running'}
<div class="card-footer">
<div class="new-btn-container" bind:this={pickerRef}>
<div class="new-btn-group">
<button
class="new-btn"
onpointerdown={handlePointerDown}
onpointerup={handlePointerUp}
onpointerleave={handlePointerLeave}
class="new-item-btn"
onclick={() => openNewSession('note')}
disabled={showNewSession}
title="New commit (hold for options)"
title="New note"
>
<Plus size={14} />
<StickyNote size={13} />
<span>New note</span>
</button>
<button
class="new-item-btn"
onclick={() => openNewSession('commit')}
disabled={showNewSession}
title="New commit"
>
<GitCommitHorizontal size={13} />
<span>New commit</span>
</button>
{#if showPicker}
<div class="picker-dropdown">
<button class="picker-item commit-item" onclick={() => openNewSession('commit')}>
<GitCommitHorizontal size={14} />
<span>Commit</span>
</button>
<button class="picker-item note-item" onclick={() => openNewSession('note')}>
<FileText size={14} />
<span>Note</span>
</button>
</div>
{/if}
</div>
</div>
{/if}
Expand Down Expand Up @@ -690,102 +634,47 @@
padding: 6px 12px;
}

/* Single "New" button with long-press picker */
.new-btn-container {
position: relative;
/* Footer with separate note/commit buttons */
.new-btn-group {
display: flex;
align-items: center;
gap: 6px;
}

.new-btn {
.new-item-btn {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
padding: 0;
gap: 5px;
padding: 4px 10px;
background: none;
border: 1px solid var(--border-subtle);
border-radius: 6px;
color: var(--text-faint);
font-size: var(--size-xs);
font-weight: 500;
cursor: pointer;
transition:
color 0.15s,
border-color 0.15s,
background-color 0.15s;
user-select: none;
-webkit-user-select: none;
touch-action: none;
white-space: nowrap;
}

.new-btn:hover:not(:disabled) {
.new-item-btn:hover:not(:disabled) {
color: var(--text-primary);
border-color: var(--border-muted);
background: var(--bg-hover);
}

.new-btn:disabled {
.new-item-btn:disabled {
opacity: 0.3;
cursor: not-allowed;
}

/* Long-press picker dropdown */
.picker-dropdown {
position: absolute;
bottom: calc(100% + 4px);
right: 0;
background: var(--bg-elevated);
border: 1px solid var(--border-muted);
border-radius: 8px;
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.12),
0 1px 4px rgba(0, 0, 0, 0.08);
overflow: hidden;
z-index: 100;
min-width: 120px;
padding: 4px 0;
}

.picker-item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 7px 12px;
background: transparent;
border: none;
color: var(--text-primary);
font-size: var(--size-sm);
cursor: pointer;
transition: background-color 0.1s;
text-align: left;
white-space: nowrap;
}

.picker-item:hover {
background: var(--bg-hover);
}

.picker-item :global(svg) {
color: var(--text-muted);
.new-item-btn :global(svg) {
flex-shrink: 0;
}

/* Commit/Note color accents for picker items */
.picker-item.commit-item :global(svg) {
color: var(--commit-color);
}

.picker-item.commit-item:hover {
background: var(--commit-bg);
}

.picker-item.note-item :global(svg) {
color: var(--note-color);
}

.picker-item.note-item:hover {
background: var(--note-bg);
}

:global(.spinner) {
animation: spin 1s linear infinite;
flex-shrink: 0;
Expand Down