|
16 | 16 | import { autoHeight } from '$lib/utils/autoHeight'; |
17 | 17 | import { splitMessage } from '$lib/utils/commitMessage'; |
18 | 18 | import { getContext, getContextStore } from '$lib/utils/context'; |
| 19 | + import { KeyName } from '$lib/utils/hotkeys'; |
19 | 20 | import { resizeObserver } from '$lib/utils/resizeObserver'; |
| 21 | + import { isWhiteSpaceString } from '$lib/utils/string'; |
20 | 22 | import { Ownership } from '$lib/vbranches/ownership'; |
21 | 23 | import { VirtualBranch, LocalFile } from '$lib/vbranches/types'; |
22 | 24 | import Checkbox from '@gitbutler/ui/Checkbox.svelte'; |
23 | 25 | import Icon from '@gitbutler/ui/Icon.svelte'; |
24 | 26 | import Tooltip from '@gitbutler/ui/Tooltip.svelte'; |
25 | | - import { createEventDispatcher, onMount } from 'svelte'; |
| 27 | + import { createEventDispatcher, onMount, tick } from 'svelte'; |
26 | 28 | import { fly } from 'svelte/transition'; |
27 | 29 |
|
28 | 30 | export let isExpanded: boolean; |
|
119 | 121 | onMount(async () => { |
120 | 122 | aiConfigurationValid = await aiService.validateConfiguration($user?.access_token); |
121 | 123 | }); |
| 124 | +
|
| 125 | + function handleDescriptionKeyDown(e: KeyboardEvent & { currentTarget: HTMLTextAreaElement }) { |
| 126 | + const value = e.currentTarget.value; |
| 127 | +
|
| 128 | + if (e.key === KeyName.Delete && value.length === 0) { |
| 129 | + e.preventDefault(); |
| 130 | + if (titleTextArea) { |
| 131 | + titleTextArea?.focus(); |
| 132 | + titleTextArea.selectionStart = titleTextArea.textLength; |
| 133 | + } |
| 134 | + autoHeight(e.currentTarget); |
| 135 | + return; |
| 136 | + } |
| 137 | +
|
| 138 | + if (e.key === 'a' && (e.metaKey || e.ctrlKey) && value.length === 0) { |
| 139 | + // select previous textarea on cmd+a if this textarea is empty |
| 140 | + e.preventDefault(); |
| 141 | + titleTextArea?.select(); |
| 142 | + return; |
| 143 | + } |
| 144 | + } |
| 145 | +
|
| 146 | + function handleSummaryKeyDown(e: KeyboardEvent & { currentTarget: HTMLTextAreaElement }) { |
| 147 | + if (commit && (e.ctrlKey || e.metaKey) && e.key === KeyName.Enter) commit(); |
| 148 | + if (e.key === KeyName.Enter) { |
| 149 | + e.preventDefault(); |
| 150 | +
|
| 151 | + const caretStart = e.currentTarget.selectionStart; |
| 152 | + const caretEnd = e.currentTarget.selectionEnd; |
| 153 | + const value = e.currentTarget.value; |
| 154 | +
|
| 155 | + // if the caret is not at the end of the text, move the rest of the text to the description |
| 156 | + // get rid of the selected text |
| 157 | + if (caretStart < value.length || caretEnd < value.length) { |
| 158 | + const toKeep = value.slice(0, caretStart); |
| 159 | + const toMove = value.slice(caretEnd); |
| 160 | + const newDescription = isWhiteSpaceString(description) |
| 161 | + ? toMove |
| 162 | + : `${toMove}\n${description}`; |
| 163 | + commitMessage = concatMessage(toKeep, newDescription); |
| 164 | + tick().then(() => { |
| 165 | + descriptionTextArea?.focus(); |
| 166 | + descriptionTextArea.setSelectionRange(0, 0); |
| 167 | + autoHeight(descriptionTextArea); |
| 168 | + }); |
| 169 | + } |
| 170 | +
|
| 171 | + descriptionTextArea?.focus(); |
| 172 | + } |
| 173 | + } |
122 | 174 | </script> |
123 | 175 |
|
124 | 176 | {#if isExpanded} |
|
137 | 189 | commitMessage = concatMessage(e.currentTarget.value, description); |
138 | 190 | autoHeight(e.currentTarget); |
139 | 191 | }} |
140 | | - on:keydown={(e) => { |
141 | | - if (commit && (e.ctrlKey || e.metaKey) && e.key === 'Enter') commit(); |
142 | | - if (e.key === 'Enter') { |
143 | | - e.preventDefault(); |
144 | | - descriptionTextArea?.focus(); |
145 | | - } |
146 | | - }} |
| 192 | + on:keydown={handleSummaryKeyDown} |
147 | 193 | ></textarea> |
148 | 194 |
|
149 | 195 | {#if title.length > 0 || description} |
|
160 | 206 | commitMessage = concatMessage(title, e.currentTarget.value); |
161 | 207 | autoHeight(e.currentTarget); |
162 | 208 | }} |
163 | | - on:keydown={(e) => { |
164 | | - const value = e.currentTarget.value; |
165 | | - if (e.key === 'Backspace' && value.length === 0) { |
166 | | - e.preventDefault(); |
167 | | - if (titleTextArea) { |
168 | | - titleTextArea?.focus(); |
169 | | - titleTextArea.selectionStart = titleTextArea.textLength; |
170 | | - } |
171 | | - autoHeight(e.currentTarget); |
172 | | - } else if (e.key === 'a' && (e.metaKey || e.ctrlKey) && value.length === 0) { |
173 | | - // select previous textarea on cmd+a if this textarea is empty |
174 | | - e.preventDefault(); |
175 | | - titleTextArea?.select(); |
176 | | - } |
177 | | - }} |
| 209 | + on:keydown={handleDescriptionKeyDown} |
178 | 210 | ></textarea> |
179 | 211 | {/if} |
180 | 212 |
|
|
0 commit comments