|
31 | 31 | import { useAvailabilityChecking } from '$lib/codegen/availabilityChecking.svelte'; |
32 | 32 | import { CLAUDE_CODE_SERVICE } from '$lib/codegen/claude'; |
33 | 33 | import { useSendMessage } from '$lib/codegen/messageQueue.svelte'; |
| 34 | + import { messageQueueSelectors, messageQueueSlice } from '$lib/codegen/messageQueueSlice'; |
34 | 35 | import { |
35 | 36 | currentStatus, |
36 | 37 | formatMessages, |
|
52 | 53 | import { SETTINGS } from '$lib/settings/userSettings'; |
53 | 54 | import { pushStatusToColor, pushStatusToIcon } from '$lib/stacks/stack'; |
54 | 55 | import { STACK_SERVICE } from '$lib/stacks/stackService.svelte'; |
| 56 | + import { CLIENT_STATE } from '$lib/state/clientState.svelte'; |
55 | 57 | import { combineResults } from '$lib/state/helpers'; |
56 | 58 | import { UI_STATE } from '$lib/state/uiState.svelte'; |
57 | 59 | import { USER } from '$lib/user/user'; |
|
95 | 97 | const urlService = inject(URL_SERVICE); |
96 | 98 | const userSettings = inject(SETTINGS); |
97 | 99 | const settingsService = inject(SETTINGS_SERVICE); |
| 100 | + const clientState = inject(CLIENT_STATE); |
98 | 101 | const claudeSettings = $derived($settingsService?.claude); |
99 | 102 |
|
100 | 103 | const stacks = $derived(stackService.stacks(projectId)); |
|
395 | 398 | cyclePermissionMode(); |
396 | 399 | } |
397 | 400 | } |
| 401 | +
|
| 402 | + const queue = $derived( |
| 403 | + messageQueueSelectors |
| 404 | + .selectAll(clientState.messageQueue) |
| 405 | + .find( |
| 406 | + (q) => |
| 407 | + q.head === selectedBranch?.head && |
| 408 | + q.stackId === selectedBranch?.stackId && |
| 409 | + q.projectId === projectId |
| 410 | + ) |
| 411 | + ); |
398 | 412 | </script> |
399 | 413 |
|
400 | 414 | <svelte:window onkeydown={handleKeydown} /> |
|
694 | 708 |
|
695 | 709 | {#snippet rightSidebar(events: ClaudeMessage[])} |
696 | 710 | {@const addedDirs = laneState?.addedDirs.current || []} |
| 711 | + {@const queueLength = queue?.messages.length || 0} |
697 | 712 | <div class="right-sidebar" bind:this={rightSidebarRef}> |
698 | | - {#if !branchChanges || !selectedBranch || (branchChanges.response && branchChanges.response.changes.length === 0 && getTodos(events).length === 0 && addedDirs.length === 0)} |
| 713 | + {#if !branchChanges || !selectedBranch || (branchChanges.response && branchChanges.response.changes.length === 0 && getTodos(events).length === 0 && addedDirs.length === 0 && queueLength === 0)} |
699 | 714 | <div class="right-sidebar__placeholder"> |
700 | 715 | <EmptyStatePlaceholder |
701 | 716 | image={filesAndChecksSvg} |
|
714 | 729 | <ReduxResult result={branchChanges.result} {projectId}> |
715 | 730 | {#snippet children({ changes }, { projectId })} |
716 | 731 | <Drawer |
717 | | - bottomBorder={todos.length > 0 || addedDirs.length > 0} |
| 732 | + bottomBorder={todos.length > 0 || addedDirs.length > 0 || queueLength > 0} |
718 | 733 | grow |
719 | 734 | defaultCollapsed={todos.length > 0} |
720 | 735 | notFoldable |
|
752 | 767 | {/if} |
753 | 768 |
|
754 | 769 | {#if todos.length > 0} |
755 | | - <Drawer defaultCollapsed={false} noshrink> |
| 770 | + <Drawer |
| 771 | + defaultCollapsed={false} |
| 772 | + noshrink |
| 773 | + bottomBorder={addedDirs.length > 0 || queueLength > 0} |
| 774 | + > |
756 | 775 | {#snippet header()} |
757 | 776 | <h4 class="text-14 text-semibold truncate">Todos</h4> |
758 | 777 | <Badge>{todos.length}</Badge> |
|
767 | 786 | {/if} |
768 | 787 |
|
769 | 788 | {#if addedDirs.length > 0} |
770 | | - <Drawer defaultCollapsed={false} noshrink> |
| 789 | + <Drawer defaultCollapsed={false} noshrink bottomBorder={queueLength > 0}> |
771 | 790 | {#snippet header()} |
772 | 791 | <h4 class="text-14 text-semibold truncate">Added Directories</h4> |
773 | 792 | <Badge>{addedDirs.length}</Badge> |
|
794 | 813 | </div> |
795 | 814 | </Drawer> |
796 | 815 | {/if} |
| 816 | + |
| 817 | + {#if queue && queue.messages.length > 0} |
| 818 | + <Drawer defaultCollapsed={false} noshrink> |
| 819 | + {#snippet header()} |
| 820 | + <h4 class="text-14 text-semibold truncate">Queued Message</h4> |
| 821 | + {/snippet} |
| 822 | + |
| 823 | + <div class="right-sidebar-list right-sidebar-list--small-gap"> |
| 824 | + {#each queue.messages as message} |
| 825 | + <div class="message-queue-item"> |
| 826 | + <span class="text-13 grow-1 message-queue-item-text">{message.prompt}</span> |
| 827 | + <Button |
| 828 | + kind="ghost" |
| 829 | + icon="bin" |
| 830 | + shrinkable |
| 831 | + onclick={() => { |
| 832 | + if (selectedBranch) { |
| 833 | + clientState.dispatch( |
| 834 | + messageQueueSlice.actions.upsert({ |
| 835 | + ...queue, |
| 836 | + messages: queue.messages.filter((m) => m !== message) |
| 837 | + }) |
| 838 | + ); |
| 839 | + } |
| 840 | + }} |
| 841 | + tooltip="Remove prompt from queue" |
| 842 | + /> |
| 843 | + </div> |
| 844 | + {/each} |
| 845 | + </div> |
| 846 | + </Drawer> |
| 847 | + {/if} |
797 | 848 | {/if} |
798 | 849 |
|
799 | 850 | <Resizer |
|
867 | 918 | projectId, |
868 | 919 | stackId |
869 | 920 | })} |
870 | | - {@const sidebarIsStackActive = claudeCodeService.isStackActive(projectId, stackId)} |
| 921 | + {@const isActive = claudeCodeService.isStackActive(projectId, stackId)} |
871 | 922 | {@const rule = rulesService.aiRuleForStack({ projectId, stackId })} |
872 | 923 |
|
873 | 924 | <ReduxResult |
|
876 | 927 | commits.result, |
877 | 928 | branchDetails.result, |
878 | 929 | events.result, |
879 | | - sidebarIsStackActive.result, |
| 930 | + isActive.result, |
880 | 931 | rule.result |
881 | 932 | )} |
882 | 933 | {projectId} |
|
995 | 1046 | <div class="not-available"> |
996 | 1047 | <DecorativeSplitView hideDetails img={vibecodingSvg}> |
997 | 1048 | <div class="not-available__content"> |
998 | | - <h1 class="text-serif-42">Set up <i>Claude Code</i></h1> |
| 1049 | + <h1 class="text-serif-40">Set up <i>Claude Code</i></h1> |
999 | 1050 | <ClaudeCheck |
1000 | 1051 | claudeExecutable={claudeExecutable.current} |
1001 | 1052 | recheckedAvailability={recheckedAvailability.current} |
|
1234 | 1285 | justify-content: space-between; |
1235 | 1286 | } |
1236 | 1287 |
|
| 1288 | + .message-queue-item { |
| 1289 | + display: flex; |
| 1290 | + align-items: center; |
| 1291 | + justify-content: space-between; |
| 1292 | + } |
| 1293 | +
|
| 1294 | + .message-queue-item-text { |
| 1295 | + overflow: hidden; |
| 1296 | + text-overflow: ellipsis; |
| 1297 | + white-space: nowrap; |
| 1298 | + } |
| 1299 | +
|
1237 | 1300 | .right-sidebar-list--small-gap { |
1238 | 1301 | gap: 4px; |
1239 | 1302 | } |
|
0 commit comments