From 72e981f8cc0c4521fd457b2becaeb4c878509d9a Mon Sep 17 00:00:00 2001 From: Esteban Vega <35891811+estib-vega@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:50:43 +0200 Subject: [PATCH] pr details follow up (#5054) * PR Details: CMD or Ctrl + Click opens the browser * Segment: Optionally make it unfocusable Control whethe the segment can be focused on tab, or not * PR Details: Remove unused 'e' handler * Borderless Textarea: Ability to autofocus Optionally, autofocus the input field on mount * PR Details: Update focus behavior - Focus on the title input filed on mount - Make the segments unfocusable * design update * Update PrDetailsModal.svelte --------- Co-authored-by: Pavel Laptev --- apps/desktop/src/lib/pr/PrDetailsModal.svelte | 238 ++++++++++-------- .../desktop/src/lib/pr/PullRequestCard.svelte | 7 +- .../src/lib/pr/StackingPullRequestCard.svelte | 7 +- .../src/lib/shared/BorderlessTextarea.svelte | 10 +- .../ui/src/lib/segmentControl/Segment.svelte | 5 +- 5 files changed, 159 insertions(+), 108 deletions(-) diff --git a/apps/desktop/src/lib/pr/PrDetailsModal.svelte b/apps/desktop/src/lib/pr/PrDetailsModal.svelte index 42bffa2db..34db6dc76 100644 --- a/apps/desktop/src/lib/pr/PrDetailsModal.svelte +++ b/apps/desktop/src/lib/pr/PrDetailsModal.svelte @@ -22,6 +22,7 @@ import { isFailure } from '$lib/result'; import ScrollableContainer from '$lib/scroll/ScrollableContainer.svelte'; import BorderlessTextarea from '$lib/shared/BorderlessTextarea.svelte'; + import TextBox from '$lib/shared/TextBox.svelte'; import Toggle from '$lib/shared/Toggle.svelte'; import { User } from '$lib/stores/user'; import { autoHeight } from '$lib/utils/autoHeight'; @@ -245,9 +246,9 @@ onToken: (t) => { if (firstToken) { firstToken = false; - inputBody = ''; } inputBody += t; + inputBody = ''; updateFieldsHeight(); } }); @@ -260,7 +261,6 @@ inputBody = descriptionResult.value; aiIsLoading = false; - aiDescriptionDirective = undefined; await tick(); updateFieldsHeight(); @@ -268,12 +268,6 @@ function handleModalKeydown(e: KeyboardEvent) { switch (e.key) { - case 'e': - if (e.metaKey || e.ctrlKey) { - e.stopPropagation(); - e.preventDefault(); - } - break; case 'g': if ((e.metaKey || e.ctrlKey) && e.shiftKey) { e.stopPropagation(); @@ -335,111 +329,129 @@ const isPreviewOnly = props.type === 'display'; - -
- -
-
- { - inputTitle = e.currentTarget.value; - }} - /> -
+ +
+ {#if !isPreviewOnly} +

+ {!isEditing ? actualTitle : 'Create a pull request'} +

+ { + if (id === 'write') { + isEditing = true; + } else { + isEditing = false; + } + }} + > + Edit + Preview + + {:else} +

{actualTitle}

+ {/if} +
- {#if !isPreviewOnly} - { - if (id === 'write') { - isEditing = true; - } else { - isEditing = false; - } - }} - > - Edit - Preview - - {/if} -
+ - + + +
{#if isPreviewOnly || !isEditing}
{:else} - { - inputBody = e.currentTarget.value; - }} - /> - {/if} +
+ { + inputTitle = e.detail; + }} + /> - - {#if !isPreviewOnly && canUseAI && isEditing} -
- {#if showAiBox} + +
{ - aiDescriptionDirective = e.currentTarget.value; + inputBody = e.currentTarget.value; }} /> -
- - -
- {:else} -
- -
- {/if} + + + {#if !isPreviewOnly && canUseAI && isEditing} +
+ {#if showAiBox} + { + aiDescriptionDirective = e.currentTarget.value; + }} + /> +
+ + +
+ {:else} +
+ +
+ {/if} +
+ {/if} +
{/if} - -
+
+
@@ -492,14 +504,34 @@ .pr-content { display: flex; flex-direction: column; + padding: 0 16px 16px; } .pr-header { display: flex; + align-items: center; gap: 16px; - padding: 16px 16px 12px 20px; + padding: 16px 16px 14px; } + /* FIELDS */ + + .pr-fields { + display: flex; + flex-direction: column; + gap: 10px; + } + + .pr-description-field { + flex: 1; + display: flex; + flex-direction: column; + /* reset .text-input padding */ + padding: 0; + } + + /* PREVIEW */ + .pr-title { flex: 1; margin-top: 4px; @@ -508,7 +540,6 @@ .pr-description-preview { overflow-y: auto; display: flex; - padding: 0 16px 16px 20px; } /* AI BOX */ @@ -519,13 +550,14 @@ } .show-ai-box { + margin-top: 12px; border-top: 1px solid var(--clr-border-3); } .pr-ai__actions { display: flex; gap: 6px; - padding: 12px 20px 16px; + padding: 12px; } /* FOOTER */ @@ -539,7 +571,7 @@ .pr-footer__actions { display: flex; - gap: 8px; + gap: 6px; } .draft-toggle__wrap { diff --git a/apps/desktop/src/lib/pr/PullRequestCard.svelte b/apps/desktop/src/lib/pr/PullRequestCard.svelte index cf05cfbfd..f039ab8f3 100644 --- a/apps/desktop/src/lib/pr/PullRequestCard.svelte +++ b/apps/desktop/src/lib/pr/PullRequestCard.svelte @@ -9,6 +9,7 @@ import { getGitHostPrService } from '$lib/gitHost/interface/gitHostPrService'; import { getContext } from '$lib/utils/context'; import * as toasts from '$lib/utils/toasts'; + import { openExternalUrl } from '$lib/utils/url'; import { VirtualBranchService } from '$lib/vbranches/virtualBranch'; import Button from '@gitbutler/ui/Button.svelte'; import { type ComponentColor } from '@gitbutler/ui/utils/colorTypes'; @@ -202,7 +203,11 @@ style="ghost" outline icon="description-small" - onclick={() => { + onclick={(e: MouseEvent) => { + if (e.ctrlKey || e.metaKey) { + openExternalUrl($pr.htmlUrl); + return; + } prDetailsModal?.show(); }} > diff --git a/apps/desktop/src/lib/pr/StackingPullRequestCard.svelte b/apps/desktop/src/lib/pr/StackingPullRequestCard.svelte index 321380b1c..48be5bda6 100644 --- a/apps/desktop/src/lib/pr/StackingPullRequestCard.svelte +++ b/apps/desktop/src/lib/pr/StackingPullRequestCard.svelte @@ -9,6 +9,7 @@ import { getGitHostPrService } from '$lib/gitHost/interface/gitHostPrService'; import { getContext } from '$lib/utils/context'; import * as toasts from '$lib/utils/toasts'; + import { openExternalUrl } from '$lib/utils/url'; import { VirtualBranchService } from '$lib/vbranches/virtualBranch'; import Button from '@gitbutler/ui/Button.svelte'; import { type ComponentColor } from '@gitbutler/ui/utils/colorTypes'; @@ -205,7 +206,11 @@ style="ghost" outline icon="description-small" - onclick={() => { + onclick={(e: MouseEvent) => { + if (e.ctrlKey || e.metaKey) { + openExternalUrl(pr.htmlUrl); + return; + } prDetailsModal?.show(); }} > diff --git a/apps/desktop/src/lib/shared/BorderlessTextarea.svelte b/apps/desktop/src/lib/shared/BorderlessTextarea.svelte index 9bfec2d53..7382f167c 100644 --- a/apps/desktop/src/lib/shared/BorderlessTextarea.svelte +++ b/apps/desktop/src/lib/shared/BorderlessTextarea.svelte @@ -11,6 +11,7 @@ readonly?: boolean; fontSize?: number; maxHeight?: string; + autofocus?: boolean; padding?: { top: number; right: number; @@ -29,6 +30,7 @@ readonly, fontSize = 14, maxHeight = 'none', + autofocus = false, padding = { top: 0, right: 0, bottom: 0, left: 0 }, oninput, onfocus, @@ -37,12 +39,18 @@ onMount(() => { setTimeout(() => { - if (ref) autoHeight(ref); + if (ref) { + autoHeight(ref); + if (autofocus) { + ref.focus(); + } + } }, 0); });