From f001beddfa654be6bb8c20616613e3fd2f2eca5e Mon Sep 17 00:00:00 2001 From: Ahnaf Mahmud <44692189+infinitepower18@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:49:56 +0600 Subject: [PATCH 01/84] Add winget as community release --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b572740774..663a8dfedf 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,7 @@ The release notes for the latest beta versions are available [here](https://desk There are several community-supported package managers that can be used to install GitHub Desktop: - - Windows users can install using [Chocolatey](https://chocolatey.org/) package manager: - `c:\> choco install github-desktop` + - Windows users can install using [winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/) `c:/> winget install github-desktop` or [Chocolatey](https://chocolatey.org/) `c:\> choco install github-desktop` - macOS users can install using [Homebrew](https://brew.sh/) package manager: `$ brew install --cask github` From a5d27abc450f5c39ba0fdba457a917b74c70a8fe Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 14 Sep 2022 14:35:23 -0400 Subject: [PATCH 02/84] Create pull request diff component --- .../open-pull-request/pull-request-diff.tsx | 22 +++++++++++++++++++ app/styles/_ui.scss | 1 + app/styles/ui/_pull-request-diff.scss | 0 3 files changed, 23 insertions(+) create mode 100644 app/src/ui/open-pull-request/pull-request-diff.tsx create mode 100644 app/styles/ui/_pull-request-diff.scss diff --git a/app/src/ui/open-pull-request/pull-request-diff.tsx b/app/src/ui/open-pull-request/pull-request-diff.tsx new file mode 100644 index 0000000000..b2968cca89 --- /dev/null +++ b/app/src/ui/open-pull-request/pull-request-diff.tsx @@ -0,0 +1,22 @@ +import * as React from 'react' +import { IDiff } from '../../models/diff' + +interface IPullRequestDiffProps { + readonly diff: IDiff | null +} + +/** + * A component for viewing the file diff for a pull request. + */ +export class PullRequestDiff extends React.Component< + IPullRequestDiffProps, + {} +> { + private renderDiff() { + return 'Diff' + } + + public render() { + return
{this.renderDiff()}
+ } +} diff --git a/app/styles/_ui.scss b/app/styles/_ui.scss index 7b65c88757..4b9da79b1c 100644 --- a/app/styles/_ui.scss +++ b/app/styles/_ui.scss @@ -100,3 +100,4 @@ @import 'ui/discard-changes-retry'; @import 'ui/_git-email-not-found-warning'; @import 'ui/_branch-select.scss'; +@import 'ui/_pull-request-diff'; diff --git a/app/styles/ui/_pull-request-diff.scss b/app/styles/ui/_pull-request-diff.scss new file mode 100644 index 0000000000..e69de29bb2 From b60a3d0d4e29a86c8b4c2418f6bee687edd6789b Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 07:20:25 -0400 Subject: [PATCH 03/84] Use diff component --- .../ui/open-pull-request/open-pull-request-dialog.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 391ddbbf60..90efe5265b 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -5,6 +5,7 @@ import { Repository } from '../../models/repository' import { DialogFooter, OkCancelButtonGroup, Dialog } from '../dialog' import { Dispatcher } from '../dispatcher' import { OpenPullRequestDialogHeader } from './open-pull-request-header' +import { PullRequestDiff } from './pull-request-diff' interface IOpenPullRequestDialogProps { readonly repository: Repository @@ -70,7 +71,13 @@ export class OpenPullRequestDialog extends React.ComponentContent + return
{this.renderFilesChanged()}
+ } + + private renderFilesChanged() { + const { commitSelection } = this.props.pullRequestState + const { diff } = commitSelection + return } private renderFooter() { From 4ccda73ce605ca8673e13390af2227d919f8a836 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 08:03:49 -0400 Subject: [PATCH 04/84] Displaying the diff of the selected file --- app/src/ui/app.tsx | 10 ++- .../open-pull-request-dialog.tsx | 39 ++++++++-- .../open-pull-request/pull-request-diff.tsx | 78 ++++++++++++++++++- app/styles/ui/_pull-request-diff.scss | 4 + app/styles/ui/dialogs/_open-pull-request.scss | 5 ++ 5 files changed, 127 insertions(+), 9 deletions(-) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 7ae6ef43b2..a3cd3dc838 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2243,7 +2243,12 @@ export class App extends React.Component { ) } case PopupType.StartPullRequest: { - const { selectedState } = this.state + const { + selectedState, + imageDiffType, + hideWhitespaceInHistoryDiff, + showSideBySideDiff, + } = this.state if ( selectedState == null || selectedState.type !== SelectionType.Repository @@ -2270,9 +2275,12 @@ export class App extends React.Component { currentBranch={currentBranch} defaultBranch={defaultBranch} dispatcher={this.props.dispatcher} + hideWhitespaceInDiff={hideWhitespaceInHistoryDiff} + imageDiffType={imageDiffType} pullRequestState={pullRequestState} recentBranches={recentBranches} repository={repository} + showSideBySideDiff={showSideBySideDiff} onDismissed={onPopupDismissedFn} /> ) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 90efe5265b..79c9b24b7d 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -1,6 +1,7 @@ import * as React from 'react' import { IPullRequestState } from '../../lib/app-state' import { Branch } from '../../models/branch' +import { ImageDiffType } from '../../models/diff' import { Repository } from '../../models/repository' import { DialogFooter, OkCancelButtonGroup, Dialog } from '../dialog' import { Dispatcher } from '../dispatcher' @@ -36,6 +37,15 @@ interface IOpenPullRequestDialogProps { */ readonly recentBranches: ReadonlyArray + /** Whether we should display side by side diffs. */ + readonly showSideBySideDiff: boolean + + /** Whether we should hide whitespace in diff. */ + readonly hideWhitespaceInDiff: boolean + + /** The type of image diff to display. */ + readonly imageDiffType: ImageDiffType + /** Called to dismiss the dialog */ readonly onDismissed: () => void } @@ -71,13 +81,31 @@ export class OpenPullRequestDialog extends React.Component{this.renderFilesChanged()} + return
{this.renderFilesChanged()}
} private renderFilesChanged() { - const { commitSelection } = this.props.pullRequestState - const { diff } = commitSelection - return + const { + dispatcher, + hideWhitespaceInDiff, + imageDiffType, + pullRequestState, + repository, + } = this.props + const { commitSelection } = pullRequestState + const { diff, file } = commitSelection + + return ( + + ) } private renderFooter() { @@ -100,8 +128,7 @@ export class OpenPullRequestDialog extends React.Component {this.renderHeader()} -
{this.renderContent()}
- + {this.renderContent()} {this.renderFooter()} ) diff --git a/app/src/ui/open-pull-request/pull-request-diff.tsx b/app/src/ui/open-pull-request/pull-request-diff.tsx index b2968cca89..9149303c6b 100644 --- a/app/src/ui/open-pull-request/pull-request-diff.tsx +++ b/app/src/ui/open-pull-request/pull-request-diff.tsx @@ -1,8 +1,29 @@ import * as React from 'react' -import { IDiff } from '../../models/diff' +import { IDiff, ImageDiffType } from '../../models/diff' +import { Repository } from '../../models/repository' +import { CommittedFileChange } from '../../models/status' +import { SeamlessDiffSwitcher } from '../diff/seamless-diff-switcher' +import { Dispatcher } from '../dispatcher' +import { openFile } from '../lib/open-file' interface IPullRequestDiffProps { + readonly repository: Repository + readonly dispatcher: Dispatcher + + /** The file whose diff should be displayed. */ + readonly selectedFile: CommittedFileChange | null + + /** The diff that should be rendered */ readonly diff: IDiff | null + + /** The type of image diff to display. */ + readonly imageDiffType: ImageDiffType + + /** Whether we should display side by side diffs. */ + readonly showSideBySideDiff: boolean + + /** Whether we should hide whitespace in diff. */ + readonly hideWhitespaceInDiff: boolean } /** @@ -12,11 +33,64 @@ export class PullRequestDiff extends React.Component< IPullRequestDiffProps, {} > { + /** + * Opens a binary file in an the system-assigned application for + * said file type. + */ + private onOpenBinaryFile = (fullPath: string) => { + openFile(fullPath, this.props.dispatcher) + } + + /** Called when the user changes the hide whitespace in diffs setting. */ + private onHideWhitespaceInDiffChanged = (hideWhitespaceInDiff: boolean) => { + const { selectedFile } = this.props + return this.props.dispatcher.onHideWhitespaceInHistoryDiffChanged( + hideWhitespaceInDiff, + this.props.repository, + selectedFile as CommittedFileChange + ) + } + + /** + * Called when the user is viewing an image diff and requests + * to change the diff presentation mode. + */ + private onChangeImageDiffType = (imageDiffType: ImageDiffType) => { + this.props.dispatcher.changeImageDiffType(imageDiffType) + } + private renderDiff() { - return 'Diff' + const { diff, selectedFile } = this.props + + if (diff === null || selectedFile === null) { + return + } + + const { + repository, + imageDiffType, + hideWhitespaceInDiff, + showSideBySideDiff, + } = this.props + + return ( + + ) } public render() { + // TODO: handle empty change set return
{this.renderDiff()}
} } diff --git a/app/styles/ui/_pull-request-diff.scss b/app/styles/ui/_pull-request-diff.scss index e69de29bb2..981ec1fdb1 100644 --- a/app/styles/ui/_pull-request-diff.scss +++ b/app/styles/ui/_pull-request-diff.scss @@ -0,0 +1,4 @@ +.pull-request-diff-viewer { + height: 500px; + display: flex; +} diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index b981ddd470..9738b2709c 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -15,4 +15,9 @@ padding: var(--spacing-half); } } + + .content { + height: 500px; + overflow: hidden; + } } From 2131d6af7d351c5fbf57d89ce236ac5bde839867 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 08:58:30 -0400 Subject: [PATCH 05/84] Move needed properties to popup model --- app/src/lib/stores/app-store.ts | 29 +++++++++++++++++++++++++++++ app/src/models/popup.ts | 12 +++++++++++- app/src/ui/app.tsx | 27 +++++++-------------------- app/src/ui/dispatcher/dispatcher.ts | 4 ---- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index a3577dd0f2..750edbb3d7 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7194,6 +7194,35 @@ export class AppStore extends TypedBaseStore { changesetData.files[0] ) } + + const { pullRequestState } = this.repositoryStateCache.get(repository) + if (pullRequestState === null) { + // This shouldn't happen.. we just initialized it. + sendNonFatalException( + 'startPullRequest', + new Error( + 'Failed to start pull request because pull request state was null' + ) + ) + return + } + + const { allBranches, recentBranches } = branchesState + const { imageDiffType, hideWhitespaceInHistoryDiff, showSideBySideDiff } = + this.getState() + + this._showPopup({ + type: PopupType.StartPullRequest, + allBranches, + currentBranch, + defaultBranch, + hideWhitespaceInHistoryDiff, + imageDiffType, + pullRequestState, + recentBranches, + repository, + showSideBySideDiff, + }) } public async _changePullRequestFileSelection( diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index e8ab5268fa..76064bd3c7 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -14,7 +14,7 @@ import { Commit, CommitOneLine, ICommitContext } from './commit' import { IStashEntry } from './stash-entry' import { Account } from '../models/account' import { Progress } from './progress' -import { ITextDiff, DiffSelection } from './diff' +import { ITextDiff, DiffSelection, ImageDiffType } from './diff' import { RepositorySettingsTab } from '../ui/repository-settings/repository-settings' import { ICommitMessage } from './commit-message' import { IAuthor } from './author' @@ -22,6 +22,7 @@ import { IRefCheck } from '../lib/ci-checks/ci-checks' import { GitHubRepository } from './github-repository' import { ValidNotificationPullRequestReview } from '../lib/valid-notification-pull-request-review' import { UnreachableCommitsTab } from '../ui/history/unreachable-commits-dialog' +import { IPullRequestState } from '../lib/app-state' export enum PopupType { RenameBranch = 1, @@ -362,4 +363,13 @@ export type Popup = } | { type: PopupType.StartPullRequest + allBranches: ReadonlyArray + currentBranch: Branch + defaultBranch: Branch | null + hideWhitespaceInHistoryDiff: boolean + imageDiffType: ImageDiffType + pullRequestState: IPullRequestState + recentBranches: ReadonlyArray + repository: Repository + showSideBySideDiff: boolean } diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index a3cd3dc838..97533aec63 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2244,29 +2244,16 @@ export class App extends React.Component { } case PopupType.StartPullRequest: { const { - selectedState, + allBranches, + currentBranch, + defaultBranch, imageDiffType, hideWhitespaceInHistoryDiff, showSideBySideDiff, - } = this.state - if ( - selectedState == null || - selectedState.type !== SelectionType.Repository - ) { - return null - } - - const { state: repoState, repository } = selectedState - const { pullRequestState, branchesState } = repoState - if ( - pullRequestState === null || - branchesState.tip.kind !== TipState.Valid - ) { - return null - } - const { allBranches, recentBranches, defaultBranch, tip } = - branchesState - const currentBranch = tip.branch + pullRequestState, + recentBranches, + repository, + } = popup return ( Date: Tue, 20 Sep 2022 09:17:29 -0400 Subject: [PATCH 06/84] Rename to files-changed to reflect what all it will house --- app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 4 ++-- ...pull-request-diff.tsx => pull-request-files-changed.tsx} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename app/src/ui/open-pull-request/{pull-request-diff.tsx => pull-request-files-changed.tsx} (95%) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 79c9b24b7d..410dc74e36 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -6,7 +6,7 @@ import { Repository } from '../../models/repository' import { DialogFooter, OkCancelButtonGroup, Dialog } from '../dialog' import { Dispatcher } from '../dispatcher' import { OpenPullRequestDialogHeader } from './open-pull-request-header' -import { PullRequestDiff } from './pull-request-diff' +import { PullRequestFilesChanged } from './pull-request-files-changed' interface IOpenPullRequestDialogProps { readonly repository: Repository @@ -96,7 +96,7 @@ export class OpenPullRequestDialog extends React.Component { /** From e78ec961535cf5d7a94673eb23f0ee4cf0f4bd38 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 09:55:57 -0400 Subject: [PATCH 07/84] Add non-functional file list --- .../open-pull-request-dialog.tsx | 4 +- .../pull-request-files-changed.tsx | 42 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 410dc74e36..62ed761daf 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -93,12 +93,14 @@ export class OpenPullRequestDialog extends React.Component + /** The diff that should be rendered */ readonly diff: IDiff | null @@ -89,8 +94,43 @@ export class PullRequestFilesChanged extends React.Component< ) } + private onDiffResize(newWidth: number) {} + + private onDiffSizeReset() {} + + private onContextMenu() {} + + private onFileSelected() {} + + private renderFileList() { + const { files, selectedFile } = this.props + + return ( + + + + ) + } + public render() { // TODO: handle empty change set - return
{this.renderDiff()}
+ return ( +
+ {this.renderFileList()} + {this.renderDiff()} +
+ ) } } From 44feaecde903603542bbc51f249be1a61b2b604b Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:42:19 -0400 Subject: [PATCH 08/84] Add file selection in diff viewer --- app/src/lib/stores/app-store.ts | 14 +-------- app/src/models/popup.ts | 2 -- app/src/ui/app.tsx | 29 ++++++++++++++++++- app/src/ui/dispatcher/dispatcher.ts | 10 +++++++ .../pull-request-files-changed.tsx | 12 ++++++-- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 750edbb3d7..f4d491d612 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7195,18 +7195,6 @@ export class AppStore extends TypedBaseStore { ) } - const { pullRequestState } = this.repositoryStateCache.get(repository) - if (pullRequestState === null) { - // This shouldn't happen.. we just initialized it. - sendNonFatalException( - 'startPullRequest', - new Error( - 'Failed to start pull request because pull request state was null' - ) - ) - return - } - const { allBranches, recentBranches } = branchesState const { imageDiffType, hideWhitespaceInHistoryDiff, showSideBySideDiff } = this.getState() @@ -7218,7 +7206,6 @@ export class AppStore extends TypedBaseStore { defaultBranch, hideWhitespaceInHistoryDiff, imageDiffType, - pullRequestState, recentBranches, repository, showSideBySideDiff, @@ -7252,6 +7239,7 @@ export class AppStore extends TypedBaseStore { diff: null, }) ) + this.emitUpdate() if (commitSHAs.length === 0) { diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index 76064bd3c7..08ac4139c6 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -22,7 +22,6 @@ import { IRefCheck } from '../lib/ci-checks/ci-checks' import { GitHubRepository } from './github-repository' import { ValidNotificationPullRequestReview } from '../lib/valid-notification-pull-request-review' import { UnreachableCommitsTab } from '../ui/history/unreachable-commits-dialog' -import { IPullRequestState } from '../lib/app-state' export enum PopupType { RenameBranch = 1, @@ -368,7 +367,6 @@ export type Popup = defaultBranch: Branch | null hideWhitespaceInHistoryDiff: boolean imageDiffType: ImageDiffType - pullRequestState: IPullRequestState recentBranches: ReadonlyArray repository: Repository showSideBySideDiff: boolean diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 97533aec63..1e7a666893 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -158,6 +158,7 @@ import { SSHUserPassword } from './ssh/ssh-user-password' import { showContextualMenu } from '../lib/menu-item' import { UnreachableCommitsDialog } from './history/unreachable-commits-dialog' import { OpenPullRequestDialog } from './open-pull-request/open-pull-request-dialog' +import { sendNonFatalException } from '../lib/helpers/non-fatal-exception' const MinuteInMilliseconds = 1000 * 60 const HourInMilliseconds = MinuteInMilliseconds * 60 @@ -2243,6 +2244,21 @@ export class App extends React.Component { ) } case PopupType.StartPullRequest: { + // Intentionally chose to get the current pull request state on + // rerender because state variables such as file selection change + // via the dispatcher. + const pullRequestState = this.getPullRequestState() + if (pullRequestState === null) { + // This shouldn't happen.. + sendNonFatalException( + 'FailedToStartPullRequest', + new Error( + 'Failed to start pull request because pull request state was null' + ) + ) + return null + } + const { allBranches, currentBranch, @@ -2250,7 +2266,6 @@ export class App extends React.Component { imageDiffType, hideWhitespaceInHistoryDiff, showSideBySideDiff, - pullRequestState, recentBranches, repository, } = popup @@ -2277,6 +2292,18 @@ export class App extends React.Component { } } + private getPullRequestState() { + const { selectedState } = this.state + if ( + selectedState == null || + selectedState.type !== SelectionType.Repository + ) { + return null + } + + return selectedState.state.pullRequestState + } + private getWarnForcePushDialogOnBegin( onBegin: () => void, onPopupDismissedFn: () => void diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index 06c18a2fbe..ad4bd590e5 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -3964,4 +3964,14 @@ export class Dispatcher { public startPullRequest(repository: Repository) { this.appStore._startPullRequest(repository) } + + /** + * Change the selected changed file of the current pull request state. + */ + public changePullRequestFileSelection( + repository: Repository, + file: CommittedFileChange + ): Promise { + return this.appStore._changePullRequestFileSelection(repository, file) + } } diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index e667cca2ad..22a68d54ea 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -65,13 +65,14 @@ export class PullRequestFilesChanged extends React.Component< } private renderDiff() { - const { diff, selectedFile } = this.props + const { selectedFile } = this.props - if (diff === null || selectedFile === null) { + if (selectedFile === null) { return } const { + diff, repository, imageDiffType, hideWhitespaceInDiff, @@ -100,7 +101,12 @@ export class PullRequestFilesChanged extends React.Component< private onContextMenu() {} - private onFileSelected() {} + private onFileSelected = (file: CommittedFileChange) => { + this.props.dispatcher.changePullRequestFileSelection( + this.props.repository, + file + ) + } private renderFileList() { const { files, selectedFile } = this.props From 99447820dbddbde46e05a93d0b268a550bafcace Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:57:40 -0400 Subject: [PATCH 09/84] Add file context menu --- app/src/lib/stores/app-store.ts | 9 +- app/src/models/popup.ts | 1 + app/src/ui/app.tsx | 2 + .../open-pull-request-dialog.tsx | 5 ++ .../pull-request-files-changed.tsx | 85 ++++++++++++++++++- 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index f4d491d612..6a7632e15f 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7196,8 +7196,12 @@ export class AppStore extends TypedBaseStore { } const { allBranches, recentBranches } = branchesState - const { imageDiffType, hideWhitespaceInHistoryDiff, showSideBySideDiff } = - this.getState() + const { + imageDiffType, + hideWhitespaceInHistoryDiff, + showSideBySideDiff, + selectedExternalEditor, + } = this.getState() this._showPopup({ type: PopupType.StartPullRequest, @@ -7209,6 +7213,7 @@ export class AppStore extends TypedBaseStore { recentBranches, repository, showSideBySideDiff, + externalEditorLabel: selectedExternalEditor ?? undefined, }) } diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index 08ac4139c6..96fd09c3d9 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -365,6 +365,7 @@ export type Popup = allBranches: ReadonlyArray currentBranch: Branch defaultBranch: Branch | null + externalEditorLabel?: string hideWhitespaceInHistoryDiff: boolean imageDiffType: ImageDiffType recentBranches: ReadonlyArray diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 1e7a666893..fe2b5f8384 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2265,6 +2265,7 @@ export class App extends React.Component { defaultBranch, imageDiffType, hideWhitespaceInHistoryDiff, + externalEditorLabel, showSideBySideDiff, recentBranches, repository, @@ -2282,6 +2283,7 @@ export class App extends React.Component { pullRequestState={pullRequestState} recentBranches={recentBranches} repository={repository} + externalEditorLabel={externalEditorLabel} showSideBySideDiff={showSideBySideDiff} onDismissed={onPopupDismissedFn} /> diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 62ed761daf..2f65eb4d30 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -46,6 +46,9 @@ interface IOpenPullRequestDialogProps { /** The type of image diff to display. */ readonly imageDiffType: ImageDiffType + /** Label for selected external editor */ + readonly externalEditorLabel?: string + /** Called to dismiss the dialog */ readonly onDismissed: () => void } @@ -87,6 +90,7 @@ export class OpenPullRequestDialog extends React.Component { + private onOpenFile = (path: string) => { + const fullPath = Path.join(this.props.repository.path, path) + this.onOpenBinaryFile(fullPath) + } + /** * Opens a binary file in an the system-assigned application for * said file type. @@ -99,7 +120,67 @@ export class PullRequestFilesChanged extends React.Component< private onDiffSizeReset() {} - private onContextMenu() {} + private onFileContextMenu = async ( + file: CommittedFileChange, + event: React.MouseEvent + ) => { + event.preventDefault() + + const { repository } = this.props + + const fullPath = Path.join(repository.path, file.path) + const fileExistsOnDisk = await pathExists(fullPath) + if (!fileExistsOnDisk) { + showContextualMenu([ + { + label: __DARWIN__ + ? 'File Does Not Exist on Disk' + : 'File does not exist on disk', + enabled: false, + }, + ]) + return + } + + const { externalEditorLabel, dispatcher } = this.props + + const extension = Path.extname(file.path) + const isSafeExtension = isSafeFileExtension(extension) + const openInExternalEditor = + externalEditorLabel !== undefined + ? `Open in ${externalEditorLabel}` + : DefaultEditorLabel + + const items: IMenuItem[] = [ + { + label: RevealInFileManagerLabel, + action: () => revealInFileManager(repository, file.path), + enabled: fileExistsOnDisk, + }, + { + label: openInExternalEditor, + action: () => dispatcher.openInExternalEditor(fullPath), + enabled: fileExistsOnDisk, + }, + { + label: OpenWithDefaultProgramLabel, + action: () => this.onOpenFile(file.path), + enabled: isSafeExtension && fileExistsOnDisk, + }, + { type: 'separator' }, + { + label: CopyFilePathLabel, + action: () => clipboard.writeText(fullPath), + }, + { + label: CopyRelativeFilePathLabel, + action: () => clipboard.writeText(Path.normalize(file.path)), + }, + { type: 'separator' }, + ] + + showContextualMenu(items) + } private onFileSelected = (file: CommittedFileChange) => { this.props.dispatcher.changePullRequestFileSelection( @@ -124,7 +205,7 @@ export class PullRequestFilesChanged extends React.Component< onSelectedFileChanged={this.onFileSelected} selectedFile={selectedFile} availableWidth={400} - onContextMenu={this.onContextMenu} + onContextMenu={this.onFileContextMenu} /> ) From 892c4aa2ab0ebbfe4ecf49da6bca70a9dd20e009 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 21 Sep 2022 10:56:02 -0400 Subject: [PATCH 10/84] Make file list resizable --- app/src/lib/app-state.ts | 3 + app/src/lib/stores/app-store.ts | 69 +++++++++++++++++++ app/src/ui/app.tsx | 3 + app/src/ui/dispatcher/dispatcher.ts | 14 ++++ .../open-pull-request-dialog.tsx | 7 +- .../pull-request-files-changed.tsx | 27 +++++--- app/styles/ui/dialogs/_open-pull-request.scss | 3 + 7 files changed, 116 insertions(+), 10 deletions(-) diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index 1f0e0d42f7..35a697597b 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -170,6 +170,9 @@ export interface IAppState { /** The width of the files list in the stash view */ readonly stashedFilesWidth: IConstrainedValue + /** The width of the files list in the pull request files changed view */ + readonly pullRequestFilesListWidth: IConstrainedValue + /** * Used to highlight access keys throughout the app when the * Alt key is pressed. Only applicable on non-macOS platforms. diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 6a7632e15f..83583fbbc8 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -323,6 +323,9 @@ const commitSummaryWidthConfigKey: string = 'commit-summary-width' const defaultStashedFilesWidth: number = 250 const stashedFilesWidthConfigKey: string = 'stashed-files-width' +const defaultPullRequestFileListWidth: number = 250 +const pullRequestFileListConfigKey: string = 'stashed-files-width' + const askToMoveToApplicationsFolderDefault: boolean = true const confirmRepoRemovalDefault: boolean = true const confirmDiscardChangesDefault: boolean = true @@ -424,6 +427,7 @@ export class AppStore extends TypedBaseStore { private sidebarWidth = constrain(defaultSidebarWidth) private commitSummaryWidth = constrain(defaultCommitSummaryWidth) private stashedFilesWidth = constrain(defaultStashedFilesWidth) + private pullRequestFileListWidth = constrain(defaultPullRequestFileListWidth) private windowState: WindowState | null = null private windowZoomFactor: number = 1 @@ -901,6 +905,7 @@ export class AppStore extends TypedBaseStore { sidebarWidth: this.sidebarWidth, commitSummaryWidth: this.commitSummaryWidth, stashedFilesWidth: this.stashedFilesWidth, + pullRequestFilesListWidth: this.pullRequestFileListWidth, appMenuState: this.appMenu ? this.appMenu.openMenus : [], highlightAccessKeys: this.highlightAccessKeys, isUpdateAvailableBannerVisible: this.isUpdateAvailableBannerVisible, @@ -1951,8 +1956,13 @@ export class AppStore extends TypedBaseStore { this.stashedFilesWidth = constrain( getNumber(stashedFilesWidthConfigKey, defaultStashedFilesWidth) ) + this.pullRequestFileListWidth = constrain( + getNumber(pullRequestFileListConfigKey, defaultPullRequestFileListWidth) + ) this.updateResizableConstraints() + // TODO: Initiliaze here for now... maybe move to dialog mounting + this.updatePullRequestResizableConstraints() this.askToMoveToApplicationsFolderSetting = getBoolean( askToMoveToApplicationsFolderKey, @@ -2077,6 +2087,41 @@ export class AppStore extends TypedBaseStore { this.stashedFilesWidth = constrain(this.stashedFilesWidth, 100, filesMax) } + /** + * Calculate the constraints of the resizable pane in the pull request dialog + * whenever the window dimensions change. + */ + private updatePullRequestResizableConstraints() { + // TODO: Get width of PR dialog -> determine if we will have default width + // for pr dialog. The goal is for it expand to fill some percent of + // available window so it will change on window resize. We may have some max + // value and min value of where to derive a default is we cannot obtain the + // width for some reason (like initialization nad no pr dialog is open) + // Thoughts -> ß + // 1. Use dialog id to grab dialog if exists, else use default + // 2. Pass dialog width up when and call this contrainst on dialog mounting + // to initialize and subscribe to window resize inside dialog to be able + // to pass up dialog width on window resize. + + // Get the width of the dialog + const available = 850 + const dialogPadding = 20 + + // This is a pretty silly width for a diff but it will fit ~9 chars per line + // in unified mode after subtracting the width of the unified gutter and ~4 + // chars per side in split diff mode. No one would want to use it this way + // but it doesn't break the layout and it allows users to temporarily + // maximize the width of the file list to see long path names. + const diffPaneMinWidth = 150 + const filesListMax = available - dialogPadding - diffPaneMinWidth + + this.pullRequestFileListWidth = constrain( + this.pullRequestFileListWidth, + 100, + filesListMax + ) + } + private updateSelectedExternalEditor( selectedEditor: string | null ): Promise { @@ -7285,6 +7330,30 @@ export class AppStore extends TypedBaseStore { this.emitUpdate() } + + public _setPullRequestFileListWidth(width: number): Promise { + this.pullRequestFileListWidth = { + ...this.pullRequestFileListWidth, + value: width, + } + setNumber(pullRequestFileListConfigKey, width) + this.updatePullRequestResizableConstraints() + this.emitUpdate() + + return Promise.resolve() + } + + public _resetPullRequestFileListWidth(): Promise { + this.pullRequestFileListWidth = { + ...this.pullRequestFileListWidth, + value: defaultPullRequestFileListWidth, + } + localStorage.removeItem(pullRequestFileListConfigKey) + this.updatePullRequestResizableConstraints() + this.emitUpdate() + + return Promise.resolve() + } } /** diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index fe2b5f8384..2f0945610b 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2259,6 +2259,8 @@ export class App extends React.Component { return null } + const { pullRequestFilesListWidth } = this.state + const { allBranches, currentBranch, @@ -2278,6 +2280,7 @@ export class App extends React.Component { currentBranch={currentBranch} defaultBranch={defaultBranch} dispatcher={this.props.dispatcher} + fileListWidth={pullRequestFilesListWidth} hideWhitespaceInDiff={hideWhitespaceInHistoryDiff} imageDiffType={imageDiffType} pullRequestState={pullRequestState} diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index ad4bd590e5..d6ac77637e 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -3974,4 +3974,18 @@ export class Dispatcher { ): Promise { return this.appStore._changePullRequestFileSelection(repository, file) } + + /** + * Set the width of the file list column in the pull request files changed + */ + public setPullRequestFileListWidth(width: number): Promise { + return this.appStore._setPullRequestFileListWidth(width) + } + + /** + * Reset the width of the file list column in the pull request files changed + */ + public resetPullRequestFileListWidth(): Promise { + return this.appStore._resetPullRequestFileListWidth() + } } diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 2f65eb4d30..0505d9e3e4 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import { IPullRequestState } from '../../lib/app-state' +import { IConstrainedValue, IPullRequestState } from '../../lib/app-state' import { Branch } from '../../models/branch' import { ImageDiffType } from '../../models/diff' import { Repository } from '../../models/repository' @@ -49,6 +49,9 @@ interface IOpenPullRequestDialogProps { /** Label for selected external editor */ readonly externalEditorLabel?: string + /** Width to use for the files list pane in the files changed view */ + readonly fileListWidth: IConstrainedValue + /** Called to dismiss the dialog */ readonly onDismissed: () => void } @@ -95,6 +98,7 @@ export class OpenPullRequestDialog extends React.Component { + this.props.dispatcher.setPullRequestFileListWidth(width) + } - private onDiffSizeReset() {} + private onFileListSizeReset = () => { + this.props.dispatcher.resetPullRequestFileListWidth() + } private onFileContextMenu = async ( file: CommittedFileChange, @@ -190,21 +199,21 @@ export class PullRequestFilesChanged extends React.Component< } private renderFileList() { - const { files, selectedFile } = this.props + const { files, selectedFile, fileListWidth } = this.props return ( diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index 9738b2709c..c53f0896a1 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -1,4 +1,7 @@ .open-pull-request { + width: 850px; + max-width: none; + header.dialog-header { padding-bottom: var(--spacing); From e63dba3cb1a6a625849e4acefa929e18df1d870f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 15:31:53 +0000 Subject: [PATCH 11/84] Bump peter-evans/create-pull-request from 4.1.1 to 4.1.2 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.1 to 4.1.2. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v4.1.1...v4.1.2) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/release-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index b359d10533..3b3811a498 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -37,7 +37,7 @@ jobs: private_key: ${{ secrets.DESKTOP_RELEASES_APP_PRIVATE_KEY }} - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v4.1.1 + uses: peter-evans/create-pull-request@v4.1.2 if: | startsWith(github.ref, 'refs/heads/releases/') && !contains(github.ref, 'test') with: From 20fa2895966fad3974f1010c070a5db292a2a362 Mon Sep 17 00:00:00 2001 From: Patrick Organ Date: Tue, 27 Sep 2022 21:05:31 -0400 Subject: [PATCH 12/84] add phpstorm, webstorm editors --- app/src/lib/editors/linux.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/lib/editors/linux.ts b/app/src/lib/editors/linux.ts index 84806820d7..087638fee1 100644 --- a/app/src/lib/editors/linux.ts +++ b/app/src/lib/editors/linux.ts @@ -62,6 +62,14 @@ const editors: ILinuxExternalEditor[] = [ name: 'Lite XL', paths: ['/usr/bin/lite-xl'], }, + { + name: 'Jetbrains PhpStorm', + paths: ['/snap/bin/phpstorm'], + }, + { + name: 'Jetbrains WebStorm', + paths: ['/snap/bin/webstorm'], + } ] async function getAvailablePath(paths: string[]): Promise { From 0fab6943cbf45c9feac525eb36fc674ac4089b96 Mon Sep 17 00:00:00 2001 From: Tsvetilian Yankov Date: Wed, 28 Sep 2022 17:33:50 +0300 Subject: [PATCH 13/84] Add toggle discard stash popup option to the store --- app/src/lib/app-state.ts | 3 +++ app/src/lib/stores/app-store.ts | 18 ++++++++++++++++++ app/src/ui/app.tsx | 1 + app/src/ui/dispatcher/dispatcher.ts | 4 ++++ app/src/ui/preferences/preferences.tsx | 14 ++++++++++++++ app/src/ui/preferences/prompts.tsx | 22 ++++++++++++++++++++++ 6 files changed, 62 insertions(+) diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index 1f0e0d42f7..d7277a281f 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -194,6 +194,9 @@ export interface IAppState { /** Whether we should show a confirmation dialog */ readonly askForConfirmationOnDiscardChangesPermanently: boolean + /** Should the app propt the user to confirm a discard stash */ + readonly askForConfirmationOnDiscardStash: boolean + /** Should the app prompt the user to confirm a force push? */ readonly askForConfirmationOnForcePush: boolean diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 750edbb3d7..3bdf748db4 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -327,11 +327,13 @@ const askToMoveToApplicationsFolderDefault: boolean = true const confirmRepoRemovalDefault: boolean = true const confirmDiscardChangesDefault: boolean = true const confirmDiscardChangesPermanentlyDefault: boolean = true +const confirmDiscardStashDefault: boolean = true const askForConfirmationOnForcePushDefault = true const confirmUndoCommitDefault: boolean = true const askToMoveToApplicationsFolderKey: string = 'askToMoveToApplicationsFolder' const confirmRepoRemovalKey: string = 'confirmRepoRemoval' const confirmDiscardChangesKey: string = 'confirmDiscardChanges' +const confirmDiscardStashKey: string = 'confirmDiscardStash' const confirmDiscardChangesPermanentlyKey: string = 'confirmDiscardChangesPermanentlyKey' const confirmForcePushKey: string = 'confirmForcePush' @@ -437,6 +439,7 @@ export class AppStore extends TypedBaseStore { private confirmDiscardChanges: boolean = confirmDiscardChangesDefault private confirmDiscardChangesPermanently: boolean = confirmDiscardChangesPermanentlyDefault + private confirmDiscardStash: boolean = confirmDiscardStashDefault private askForConfirmationOnForcePush = askForConfirmationOnForcePushDefault private confirmUndoCommit: boolean = confirmUndoCommitDefault private imageDiffType: ImageDiffType = imageDiffTypeDefault @@ -913,6 +916,7 @@ export class AppStore extends TypedBaseStore { askForConfirmationOnDiscardChanges: this.confirmDiscardChanges, askForConfirmationOnDiscardChangesPermanently: this.confirmDiscardChangesPermanently, + askForConfirmationOnDiscardStash: this.confirmDiscardStash, askForConfirmationOnForcePush: this.askForConfirmationOnForcePush, askForConfirmationOnUndoCommit: this.confirmUndoCommit, uncommittedChangesStrategy: this.uncommittedChangesStrategy, @@ -1974,6 +1978,11 @@ export class AppStore extends TypedBaseStore { confirmDiscardChangesPermanentlyDefault ) + this.confirmDiscardStash = getBoolean( + confirmDiscardStashKey, + confirmDiscardStashDefault + ) + this.askForConfirmationOnForcePush = getBoolean( confirmForcePushKey, askForConfirmationOnForcePushDefault @@ -5193,6 +5202,15 @@ export class AppStore extends TypedBaseStore { return Promise.resolve() } + public _setConfirmDiscardStashSetting(value: boolean): Promise { + this.confirmDiscardStash = value + + setBoolean(confirmDiscardStashKey, value) + this.emitUpdate() + + return Promise.resolve() + } + public _setConfirmForcePushSetting(value: boolean): Promise { this.askForConfirmationOnForcePush = value setBoolean(confirmForcePushKey, value) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 97533aec63..4d16414fba 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -1481,6 +1481,7 @@ export class App extends React.Component { confirmDiscardChangesPermanently={ this.state.askForConfirmationOnDiscardChangesPermanently } + confirmDiscardStash={this.state.askForConfirmationOnDiscardStash} confirmForcePush={this.state.askForConfirmationOnForcePush} confirmUndoCommit={this.state.askForConfirmationOnUndoCommit} uncommittedChangesStrategy={this.state.uncommittedChangesStrategy} diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index 06c18a2fbe..f60f35abd1 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -2338,6 +2338,10 @@ export class Dispatcher { await this.appStore._loadStatus(repository) } + public setConfirmDiscardStashSetting(value: boolean) { + return this.appStore._setConfirmDiscardStashSetting(value) + } + public setConfirmForcePushSetting(value: boolean) { return this.appStore._setConfirmForcePushSetting(value) } diff --git a/app/src/ui/preferences/preferences.tsx b/app/src/ui/preferences/preferences.tsx index c66de88fc0..e4616e9474 100644 --- a/app/src/ui/preferences/preferences.tsx +++ b/app/src/ui/preferences/preferences.tsx @@ -54,6 +54,7 @@ interface IPreferencesProps { readonly confirmRepositoryRemoval: boolean readonly confirmDiscardChanges: boolean readonly confirmDiscardChangesPermanently: boolean + readonly confirmDiscardStash: boolean readonly confirmForcePush: boolean readonly confirmUndoCommit: boolean readonly uncommittedChangesStrategy: UncommittedChangesStrategy @@ -79,6 +80,7 @@ interface IPreferencesState { readonly confirmRepositoryRemoval: boolean readonly confirmDiscardChanges: boolean readonly confirmDiscardChangesPermanently: boolean + readonly confirmDiscardStash: boolean readonly confirmForcePush: boolean readonly confirmUndoCommit: boolean readonly uncommittedChangesStrategy: UncommittedChangesStrategy @@ -121,6 +123,7 @@ export class Preferences extends React.Component< confirmRepositoryRemoval: false, confirmDiscardChanges: false, confirmDiscardChangesPermanently: false, + confirmDiscardStash: false, confirmForcePush: false, confirmUndoCommit: false, uncommittedChangesStrategy: defaultUncommittedChangesStrategy, @@ -178,6 +181,7 @@ export class Preferences extends React.Component< confirmDiscardChanges: this.props.confirmDiscardChanges, confirmDiscardChangesPermanently: this.props.confirmDiscardChangesPermanently, + confirmDiscardStash: this.props.confirmDiscardStash, confirmForcePush: this.props.confirmForcePush, confirmUndoCommit: this.props.confirmUndoCommit, uncommittedChangesStrategy: this.props.uncommittedChangesStrategy, @@ -333,12 +337,14 @@ export class Preferences extends React.Component< confirmDiscardChangesPermanently={ this.state.confirmDiscardChangesPermanently } + confirmDiscardStash={this.state.confirmDiscardStash} confirmForcePush={this.state.confirmForcePush} confirmUndoCommit={this.state.confirmUndoCommit} onConfirmRepositoryRemovalChanged={ this.onConfirmRepositoryRemovalChanged } onConfirmDiscardChangesChanged={this.onConfirmDiscardChangesChanged} + onConfirmDiscardStashChanged={this.onConfirmDiscardStashChanged} onConfirmForcePushChanged={this.onConfirmForcePushChanged} onConfirmDiscardChangesPermanentlyChanged={ this.onConfirmDiscardChangesPermanentlyChanged @@ -410,6 +416,10 @@ export class Preferences extends React.Component< this.setState({ confirmDiscardChanges: value }) } + private onConfirmDiscardStashChanged = (value: boolean) => { + this.setState({ confirmDiscardStash: value }) + } + private onConfirmDiscardChangesPermanentlyChanged = (value: boolean) => { this.setState({ confirmDiscardChangesPermanently: value }) } @@ -562,6 +572,10 @@ export class Preferences extends React.Component< this.state.confirmForcePush ) + await this.props.dispatcher.setConfirmDiscardStashSetting( + this.state.confirmDiscardStash + ) + await this.props.dispatcher.setConfirmUndoCommitSetting( this.state.confirmUndoCommit ) diff --git a/app/src/ui/preferences/prompts.tsx b/app/src/ui/preferences/prompts.tsx index 30ee4d83fd..ef65ec2738 100644 --- a/app/src/ui/preferences/prompts.tsx +++ b/app/src/ui/preferences/prompts.tsx @@ -6,10 +6,12 @@ interface IPromptsPreferencesProps { readonly confirmRepositoryRemoval: boolean readonly confirmDiscardChanges: boolean readonly confirmDiscardChangesPermanently: boolean + readonly confirmDiscardStash: boolean readonly confirmForcePush: boolean readonly confirmUndoCommit: boolean readonly onConfirmDiscardChangesChanged: (checked: boolean) => void readonly onConfirmDiscardChangesPermanentlyChanged: (checked: boolean) => void + readonly onConfirmDiscardStashChanged: (checked: boolean) => void readonly onConfirmRepositoryRemovalChanged: (checked: boolean) => void readonly onConfirmForcePushChanged: (checked: boolean) => void readonly onConfirmUndoCommitChanged: (checked: boolean) => void @@ -19,6 +21,7 @@ interface IPromptsPreferencesState { readonly confirmRepositoryRemoval: boolean readonly confirmDiscardChanges: boolean readonly confirmDiscardChangesPermanently: boolean + readonly confirmDiscardStash: boolean readonly confirmForcePush: boolean readonly confirmUndoCommit: boolean } @@ -35,6 +38,7 @@ export class Prompts extends React.Component< confirmDiscardChanges: this.props.confirmDiscardChanges, confirmDiscardChangesPermanently: this.props.confirmDiscardChangesPermanently, + confirmDiscardStash: this.props.confirmDiscardStash, confirmForcePush: this.props.confirmForcePush, confirmUndoCommit: this.props.confirmUndoCommit, } @@ -58,6 +62,15 @@ export class Prompts extends React.Component< this.props.onConfirmDiscardChangesPermanentlyChanged(value) } + private onConfirmDiscardStashChanged = ( + event: React.FormEvent + ) => { + const value = event.currentTarget.checked + + this.setState({ confirmDiscardStash: value }) + this.props.onConfirmDiscardStashChanged(value) + } + private onConfirmForcePushChanged = ( event: React.FormEvent ) => { @@ -116,6 +129,15 @@ export class Prompts extends React.Component< } onChange={this.onConfirmDiscardChangesPermanentlyChanged} /> + Date: Wed, 28 Sep 2022 17:36:12 +0300 Subject: [PATCH 14/84] Handle discard stash button when popup disabled --- app/src/ui/app.tsx | 3 ++ app/src/ui/repository.tsx | 4 +++ app/src/ui/stashing/stash-diff-header.tsx | 43 ++++++++++++++++++----- app/src/ui/stashing/stash-diff-viewer.tsx | 6 ++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 4d16414fba..6609225ced 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2951,6 +2951,9 @@ export class App extends React.Component { askForConfirmationOnDiscardChanges={ state.askForConfirmationOnDiscardChanges } + askForConfirmationOnDiscardStash={ + state.askForConfirmationOnDiscardStash + } accounts={state.accounts} externalEditorLabel={externalEditorLabel} resolvedExternalEditor={state.resolvedExternalEditor} diff --git a/app/src/ui/repository.tsx b/app/src/ui/repository.tsx index e307461278..85e6e97484 100644 --- a/app/src/ui/repository.tsx +++ b/app/src/ui/repository.tsx @@ -50,6 +50,7 @@ interface IRepositoryViewProps { readonly hideWhitespaceInHistoryDiff: boolean readonly showSideBySideDiff: boolean readonly askForConfirmationOnDiscardChanges: boolean + readonly askForConfirmationOnDiscardStash: boolean readonly focusCommitMessage: boolean readonly commitSpellcheckEnabled: boolean readonly accounts: ReadonlyArray @@ -355,6 +356,9 @@ export class RepositoryView extends React.Component< fileListWidth={this.props.stashedFilesWidth} repository={this.props.repository} dispatcher={this.props.dispatcher} + askForConfirmationOnDiscardStash={ + this.props.askForConfirmationOnDiscardStash + } isWorkingTreeClean={isWorkingTreeClean} showSideBySideDiff={this.props.showSideBySideDiff} onOpenBinaryFile={this.onOpenBinaryFile} diff --git a/app/src/ui/stashing/stash-diff-header.tsx b/app/src/ui/stashing/stash-diff-header.tsx index b631a559ba..c9b8bbbacd 100644 --- a/app/src/ui/stashing/stash-diff-header.tsx +++ b/app/src/ui/stashing/stash-diff-header.tsx @@ -11,11 +11,13 @@ interface IStashDiffHeaderProps { readonly stashEntry: IStashEntry readonly repository: Repository readonly dispatcher: Dispatcher + readonly askForConfirmationOnDiscardStash: boolean readonly isWorkingTreeClean: boolean } interface IStashDiffHeaderState { readonly isRestoring: boolean + readonly isDiscarding: boolean } /** @@ -31,12 +33,13 @@ export class StashDiffHeader extends React.Component< this.state = { isRestoring: false, + isDiscarding: false, } } public render() { const { isWorkingTreeClean } = this.props - const { isRestoring } = this.state + const { isRestoring, isDiscarding } = this.state return (
@@ -44,10 +47,12 @@ export class StashDiffHeader extends React.Component<
{this.renderExplanatoryText()} @@ -80,13 +85,33 @@ export class StashDiffHeader extends React.Component< ) } - private onDiscardClick = () => { - const { dispatcher, repository, stashEntry } = this.props - dispatcher.showPopup({ - type: PopupType.ConfirmDiscardStash, - stash: stashEntry, + private onDiscardClick = async () => { + const { + dispatcher, repository, - }) + stashEntry, + askForConfirmationOnDiscardStash, + } = this.props + + if (!askForConfirmationOnDiscardStash) { + this.setState({ + isDiscarding: true, + }) + + try { + await dispatcher.dropStash(repository, stashEntry) + } finally { + this.setState({ + isDiscarding: false, + }) + } + } else { + dispatcher.showPopup({ + type: PopupType.ConfirmDiscardStash, + stash: stashEntry, + repository, + }) + } } private onRestoreClick = async () => { diff --git a/app/src/ui/stashing/stash-diff-viewer.tsx b/app/src/ui/stashing/stash-diff-viewer.tsx index bc3b467556..fc9baecaba 100644 --- a/app/src/ui/stashing/stash-diff-viewer.tsx +++ b/app/src/ui/stashing/stash-diff-viewer.tsx @@ -27,6 +27,9 @@ interface IStashDiffViewerProps { readonly repository: Repository readonly dispatcher: Dispatcher + /** Should the app propt the user to confirm a discard stash */ + readonly askForConfirmationOnDiscardStash: boolean + /** Whether we should display side by side diffs. */ readonly showSideBySideDiff: boolean @@ -113,6 +116,9 @@ export class StashDiffViewer extends React.PureComponent repository={repository} dispatcher={dispatcher} isWorkingTreeClean={isWorkingTreeClean} + askForConfirmationOnDiscardStash={ + this.props.askForConfirmationOnDiscardStash + } />
Date: Thu, 29 Sep 2022 07:48:48 -0400 Subject: [PATCH 15/84] Needs it's own key doesn't it.. Co-authored-by: Sergio Padrino --- app/src/lib/stores/app-store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 83583fbbc8..db44b7a2c0 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -324,7 +324,7 @@ const defaultStashedFilesWidth: number = 250 const stashedFilesWidthConfigKey: string = 'stashed-files-width' const defaultPullRequestFileListWidth: number = 250 -const pullRequestFileListConfigKey: string = 'stashed-files-width' +const pullRequestFileListConfigKey: string = 'pull-request-files-width' const askToMoveToApplicationsFolderDefault: boolean = true const confirmRepoRemovalDefault: boolean = true From a2914b67b4be2ef764a4e2736476a20e87eb5417 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:28:06 -0400 Subject: [PATCH 16/84] Create method for commit url generation --- app/src/lib/commit-url.ts | 24 ++++++++++++++++++++++++ app/src/ui/app.tsx | 23 +++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 app/src/lib/commit-url.ts diff --git a/app/src/lib/commit-url.ts b/app/src/lib/commit-url.ts new file mode 100644 index 0000000000..8dd293c8be --- /dev/null +++ b/app/src/lib/commit-url.ts @@ -0,0 +1,24 @@ +import * as crypto from 'crypto' +import { GitHubRepository } from '../models/github-repository' + +/** Method to create the url for viewing a commit on dotcom */ +export function createCommitURL( + gitHubRepository: GitHubRepository, + SHA: string, + filePath?: string +): string | null { + const baseURL = gitHubRepository.htmlURL + + if (baseURL === null) { + return null + } + + if (filePath === undefined) { + return `${baseURL}/commit/${SHA}` + } + + const fileHash = crypto.createHash('sha256').update(filePath).digest('hex') + const fileSuffix = '#diff-' + fileHash + + return `${baseURL}/commit/${SHA}${fileSuffix}` +} diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 2f0945610b..fcfc29e92e 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import * as crypto from 'crypto' import { TransitionGroup, CSSTransition } from 'react-transition-group' import { IAppState, @@ -159,6 +158,7 @@ import { showContextualMenu } from '../lib/menu-item' import { UnreachableCommitsDialog } from './history/unreachable-commits-dialog' import { OpenPullRequestDialog } from './open-pull-request/open-pull-request-dialog' import { sendNonFatalException } from '../lib/helpers/non-fatal-exception' +import { createCommitURL } from '../lib/commit-url' const MinuteInMilliseconds = 1000 * 60 const HourInMilliseconds = MinuteInMilliseconds * 60 @@ -3076,22 +3076,17 @@ export class App extends React.Component { return } - const baseURL = repository.gitHubRepository.htmlURL + const commitURL = createCommitURL( + repository.gitHubRepository, + SHA, + filePath + ) - let fileSuffix = '' - if (filePath != null) { - const fileHash = crypto - .createHash('sha256') - .update(filePath) - .digest('hex') - fileSuffix = '#diff-' + fileHash + if (commitURL === null) { + return } - if (baseURL) { - this.props.dispatcher.openInBrowser( - `${baseURL}/commit/${SHA}${fileSuffix}` - ) - } + this.props.dispatcher.openInBrowser(commitURL) } private onBranchDeleted = (repository: Repository) => { From 01099472bfceb26688a6729554cc475111dedecd Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:28:37 -0400 Subject: [PATCH 17/84] Add latest non local commit to PR popup model --- app/src/lib/stores/app-store.ts | 7 ++++++- app/src/models/popup.ts | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index db44b7a2c0..2c30b2afd4 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7185,7 +7185,8 @@ export class AppStore extends TypedBaseStore { } public async _startPullRequest(repository: Repository) { - const { branchesState } = this.repositoryStateCache.get(repository) + const { branchesState, localCommitSHAs } = + this.repositoryStateCache.get(repository) const { defaultBranch, tip } = branchesState if (defaultBranch === null || tip.kind !== TipState.Valid) { @@ -7259,6 +7260,10 @@ export class AppStore extends TypedBaseStore { repository, showSideBySideDiff, externalEditorLabel: selectedExternalEditor ?? undefined, + nonLocalCommitSHA: + commitSHAs.length > 0 && !localCommitSHAs.includes(commitSHAs[0]) + ? commitSHAs[0] + : null, }) } diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index 96fd09c3d9..188d8f0b0c 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -371,4 +371,5 @@ export type Popup = recentBranches: ReadonlyArray repository: Repository showSideBySideDiff: boolean + nonLocalCommitSHA: string | null } From 3b0436d4f9abd9af84c9c447105d605dcadbe5bf Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:28:57 -0400 Subject: [PATCH 18/84] Pass nonLocalCommitSHA down --- app/src/ui/app.tsx | 2 ++ app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 6 ++++++ app/src/ui/open-pull-request/pull-request-files-changed.tsx | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index fcfc29e92e..ad04787b84 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2268,6 +2268,7 @@ export class App extends React.Component { imageDiffType, hideWhitespaceInHistoryDiff, externalEditorLabel, + nonLocalCommitSHA, showSideBySideDiff, recentBranches, repository, @@ -2283,6 +2284,7 @@ export class App extends React.Component { fileListWidth={pullRequestFilesListWidth} hideWhitespaceInDiff={hideWhitespaceInHistoryDiff} imageDiffType={imageDiffType} + nonLocalCommitSHA={nonLocalCommitSHA} pullRequestState={pullRequestState} recentBranches={recentBranches} repository={repository} diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 0505d9e3e4..4333ce7c85 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -52,6 +52,10 @@ interface IOpenPullRequestDialogProps { /** Width to use for the files list pane in the files changed view */ readonly fileListWidth: IConstrainedValue + /** If the latest commit of the pull request is not local, this will contain + * it's SHA */ + readonly nonLocalCommitSHA: string | null + /** Called to dismiss the dialog */ readonly onDismissed: () => void } @@ -99,6 +103,7 @@ export class OpenPullRequestDialog extends React.Component Date: Thu, 29 Sep 2022 08:29:29 -0400 Subject: [PATCH 19/84] Add menu item to open file on GitHub --- .../pull-request-files-changed.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index 50f3a8825b..d9b645862d 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -22,6 +22,8 @@ import { revealInFileManager } from '../../lib/app-shell' import { clipboard } from 'electron' import { IConstrainedValue } from '../../lib/app-state' import { clamp } from '../../lib/clamp' +import { getDotComAPIEndpoint } from '../../lib/api' +import { createCommitURL } from '../../lib/commit-url' interface IPullRequestFilesChangedProps { readonly repository: Repository @@ -133,6 +135,27 @@ export class PullRequestFilesChanged extends React.Component< this.props.dispatcher.resetPullRequestFileListWidth() } + private onViewOnGitHub = (file: CommittedFileChange) => { + const { nonLocalCommitSHA, repository, dispatcher } = this.props + const { gitHubRepository } = repository + + if (gitHubRepository === null || nonLocalCommitSHA === null) { + return + } + + const commitURL = createCommitURL( + gitHubRepository, + nonLocalCommitSHA, + file.path + ) + + if (commitURL === null) { + return + } + + dispatcher.openInBrowser(commitURL) + } + private onFileContextMenu = async ( file: CommittedFileChange, event: React.MouseEvent @@ -192,6 +215,17 @@ export class PullRequestFilesChanged extends React.Component< { type: 'separator' }, ] + const { nonLocalCommitSHA } = this.props + const { gitHubRepository } = repository + const isEnterprise = + gitHubRepository && gitHubRepository.endpoint !== getDotComAPIEndpoint() + + items.push({ + label: `View on GitHub${isEnterprise ? ' Enterprise' : ''}`, + action: () => this.onViewOnGitHub(file), + enabled: nonLocalCommitSHA !== null && gitHubRepository !== null, + }) + showContextualMenu(items) } From 4fd9550e3af02f2b35ed60ce6b55a3c569d93166 Mon Sep 17 00:00:00 2001 From: Patrick Organ Date: Thu, 29 Sep 2022 09:19:45 -0400 Subject: [PATCH 20/84] apply formatting --- app/src/lib/editors/linux.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/editors/linux.ts b/app/src/lib/editors/linux.ts index 087638fee1..de7953eb3d 100644 --- a/app/src/lib/editors/linux.ts +++ b/app/src/lib/editors/linux.ts @@ -69,7 +69,7 @@ const editors: ILinuxExternalEditor[] = [ { name: 'Jetbrains WebStorm', paths: ['/snap/bin/webstorm'], - } + }, ] async function getAvailablePath(paths: string[]): Promise { From b09726226c7cc2ecb89538116bbaf1de00e1ef60 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:55:29 -0400 Subject: [PATCH 21/84] Move render methods together --- .../pull-request-files-changed.tsx | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index d9b645862d..15e491b8b3 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -96,37 +96,6 @@ export class PullRequestFilesChanged extends React.Component< this.props.dispatcher.changeImageDiffType(imageDiffType) } - private renderDiff() { - const { selectedFile } = this.props - - if (selectedFile === null) { - return - } - - const { - diff, - repository, - imageDiffType, - hideWhitespaceInDiff, - showSideBySideDiff, - } = this.props - - return ( - - ) - } - private onFileListResize = (width: number) => { this.props.dispatcher.setPullRequestFileListWidth(width) } @@ -258,10 +227,42 @@ export class PullRequestFilesChanged extends React.Component< ) } + private renderDiff() { + const { selectedFile } = this.props + + if (selectedFile === null) { + return + } + + const { + diff, + repository, + imageDiffType, + hideWhitespaceInDiff, + showSideBySideDiff, + } = this.props + + return ( + + ) + } + public render() { // TODO: handle empty change set return (
+ {this.renderHeader()} {this.renderFileList()} {this.renderDiff()}
From 10fae06e5d4d163fd19c354e0919e0c98215cce2 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 21 Sep 2022 12:16:12 -0400 Subject: [PATCH 22/84] Add header and inset styling to files changed component --- .../pull-request-files-changed.tsx | 16 +++++++++++++--- app/styles/ui/_pull-request-diff.scss | 16 +++++++++++++--- app/styles/ui/dialogs/_open-pull-request.scss | 3 +-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index 15e491b8b3..d08e9a30a9 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -205,6 +205,14 @@ export class PullRequestFilesChanged extends React.Component< ) } + private renderHeader() { + return ( +
+
Showing changes from all commits
+
+ ) + } + private renderFileList() { const { files, selectedFile, fileListWidth } = this.props @@ -261,10 +269,12 @@ export class PullRequestFilesChanged extends React.Component< public render() { // TODO: handle empty change set return ( -
+
{this.renderHeader()} - {this.renderFileList()} - {this.renderDiff()} +
+ {this.renderFileList()} + {this.renderDiff()} +
) } diff --git a/app/styles/ui/_pull-request-diff.scss b/app/styles/ui/_pull-request-diff.scss index 981ec1fdb1..0c6ace3a3b 100644 --- a/app/styles/ui/_pull-request-diff.scss +++ b/app/styles/ui/_pull-request-diff.scss @@ -1,4 +1,14 @@ -.pull-request-diff-viewer { - height: 500px; - display: flex; +.pull-request-files-changed { + border: var(--base-border); + border-radius: var(--border-radius); + + .files-changed-header { + padding: var(--spacing-half); + border-bottom: var(--base-border); + } + + .files-diff-viewer { + height: 500px; + display: flex; + } } diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index c53f0896a1..0c007acb04 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -20,7 +20,6 @@ } .content { - height: 500px; - overflow: hidden; + padding: var(--spacing); } } From 15132f8840829a7b8295707b33370e8529861390 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 21 Sep 2022 12:26:15 -0400 Subject: [PATCH 23/84] Using regular spacing --- app/styles/ui/_pull-request-diff.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/ui/_pull-request-diff.scss b/app/styles/ui/_pull-request-diff.scss index 0c6ace3a3b..69954b1f55 100644 --- a/app/styles/ui/_pull-request-diff.scss +++ b/app/styles/ui/_pull-request-diff.scss @@ -3,7 +3,7 @@ border-radius: var(--border-radius); .files-changed-header { - padding: var(--spacing-half); + padding: var(--spacing); border-bottom: var(--base-border); } From 05a305e274eb08169523ae5b70f0e174644c5292 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Fri, 23 Sep 2022 10:04:34 -0400 Subject: [PATCH 24/84] Scope content class (so it doesn't interfere with split diffs) --- app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 6 +++++- app/styles/ui/dialogs/_open-pull-request.scss | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 4333ce7c85..c6991954b0 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -91,7 +91,11 @@ export class OpenPullRequestDialog extends React.Component{this.renderFilesChanged()}
+ return ( +
+ {this.renderFilesChanged()} +
+ ) } private renderFilesChanged() { diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index 0c007acb04..2c6f174137 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -19,7 +19,7 @@ } } - .content { + .open-pull-request-content { padding: var(--spacing); } } From e33172adf6202647a9701798480c454784b2fd5a Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:51:35 -0400 Subject: [PATCH 25/84] create reusable popover dropdown component based on branch select --- app/src/ui/lib/popover-dropdown.tsx | 125 +++++++++++++++++++++++++++ app/styles/_ui.scss | 3 +- app/styles/ui/_popover-dropdown.scss | 46 ++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 app/src/ui/lib/popover-dropdown.tsx create mode 100644 app/styles/ui/_popover-dropdown.scss diff --git a/app/src/ui/lib/popover-dropdown.tsx b/app/src/ui/lib/popover-dropdown.tsx new file mode 100644 index 0000000000..557676541a --- /dev/null +++ b/app/src/ui/lib/popover-dropdown.tsx @@ -0,0 +1,125 @@ +import * as React from 'react' +import { Button } from './button' +import { Popover, PopoverCaretPosition } from './popover' +import { Octicon } from '../octicons' +import * as OcticonSymbol from '../octicons/octicons.generated' + +const defaultPopoverContentHeight = 300 +const maxPopoverContentHeight = 500 + +interface IPopoverDropdownProps { + readonly contentTitle: string + readonly buttonContent: JSX.Element | string +} + +interface IPopoverDropdownState { + readonly showPopover: boolean + readonly popoverContentHeight: number +} + +/** + * A select element for filter and selecting a branch. + */ +export class PopoverSelect extends React.Component< + IPopoverDropdownProps, + IPopoverDropdownState +> { + private invokeButtonRef: HTMLButtonElement | null = null + + public constructor(props: IPopoverDropdownProps) { + super(props) + + this.state = { + showPopover: false, + popoverContentHeight: defaultPopoverContentHeight, + } + } + + public componentDidMount() { + this.calculateDropdownListHeight() + } + + public componentDidUpdate() { + this.calculateDropdownListHeight() + } + + private calculateDropdownListHeight = () => { + if (this.invokeButtonRef === null) { + return + } + + const windowHeight = window.innerHeight + const bottomOfButton = this.invokeButtonRef.getBoundingClientRect().bottom + const listHeaderHeight = 75 + const calcMaxHeight = Math.round( + windowHeight - bottomOfButton - listHeaderHeight + ) + + const popoverContentHeight = + calcMaxHeight > maxPopoverContentHeight + ? maxPopoverContentHeight + : calcMaxHeight + if (popoverContentHeight !== this.state.popoverContentHeight) { + this.setState({ popoverContentHeight }) + } + } + + private onInvokeButtonRef = (buttonRef: HTMLButtonElement | null) => { + this.invokeButtonRef = buttonRef + } + + private togglePopover = () => { + this.setState({ showPopover: !this.state.showPopover }) + } + + private closePopover = () => { + this.setState({ showPopover: false }) + } + + public renderPopover() { + if (!this.state.showPopover) { + return + } + + const { contentTitle } = this.props + const { popoverContentHeight } = this.state + const contentStyle = { height: `${popoverContentHeight}px` } + + return ( + +
+ {contentTitle} + +
+
+ {this.props.children} +
+
+ ) + } + + public render() { + return ( +
+ + {this.renderPopover()} +
+ ) + } +} diff --git a/app/styles/_ui.scss b/app/styles/_ui.scss index 4b9da79b1c..99b8c5aeb0 100644 --- a/app/styles/_ui.scss +++ b/app/styles/_ui.scss @@ -99,5 +99,6 @@ @import 'ui/_pull-request-quick-view'; @import 'ui/discard-changes-retry'; @import 'ui/_git-email-not-found-warning'; -@import 'ui/_branch-select.scss'; +@import 'ui/_branch-select'; @import 'ui/_pull-request-diff'; +@import 'ui/_popover-dropdown'; diff --git a/app/styles/ui/_popover-dropdown.scss b/app/styles/ui/_popover-dropdown.scss new file mode 100644 index 0000000000..a7999447c0 --- /dev/null +++ b/app/styles/ui/_popover-dropdown.scss @@ -0,0 +1,46 @@ +.popover-dropdown-component { + display: inline-flex; + + button { + border: none; + background-color: inherit; + border: none; + padding: 0; + margin: 0; + color: #149ad4; + font-weight: bold; + + &.button-component { + overflow: visible; + + &:hover, + &:focus { + border: none; + box-shadow: none; + } + } + } + + .popover-dropdown-popover { + position: absolute; + min-height: 200px; + width: 365px; + padding: 0; + margin-top: 25px; + + .popover-dropdown-header { + padding: var(--spacing); + font-weight: var(--font-weight-semibold); + display: flex; + border-bottom: var(--base-border); + + .close { + margin-right: 0; + } + } + + .popover-dropdown-content { + display: flex; + } + } +} From 7dcb83c656f4e6d2050e3548825b24f22009e890 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:44:13 -0400 Subject: [PATCH 26/84] Make branch select component use the popover dropdown --- app/src/ui/branches/branch-select.tsx | 110 +++----------------------- app/src/ui/lib/popover-dropdown.tsx | 18 +++-- app/styles/ui/_branch-select.scss | 59 +------------- app/styles/ui/_popover-dropdown.scss | 3 +- 4 files changed, 28 insertions(+), 162 deletions(-) diff --git a/app/src/ui/branches/branch-select.tsx b/app/src/ui/branches/branch-select.tsx index a3cd692189..4cde775e46 100644 --- a/app/src/ui/branches/branch-select.tsx +++ b/app/src/ui/branches/branch-select.tsx @@ -1,19 +1,12 @@ import * as React from 'react' import { IMatches } from '../../lib/fuzzy-find' import { Branch } from '../../models/branch' -import { Button } from '../lib/button' import { ClickSource } from '../lib/list' -import { Popover } from '../lib/popover' -import { Ref } from '../lib/ref' -import { Octicon } from '../octicons' -import * as OcticonSymbol from '../octicons/octicons.generated' +import { PopoverDropdown } from '../lib/popover-dropdown' import { BranchList } from './branch-list' import { renderDefaultBranch } from './branch-renderer' import { IBranchListItem } from './group-branches' -const defaultDropdownListHeight = 300 -const maxDropdownListHeight = 500 - interface IBranchSelectProps { /** The initially selected branch. */ readonly branch: Branch @@ -43,10 +36,8 @@ interface IBranchSelectProps { } interface IBranchSelectState { - readonly showBranchDropdown: boolean readonly selectedBranch: Branch | null readonly filterText: string - readonly dropdownListHeight: number } /** @@ -56,67 +47,25 @@ export class BranchSelect extends React.Component< IBranchSelectProps, IBranchSelectState > { - private invokeButtonRef: HTMLButtonElement | null = null + private popoverRef = React.createRef() public constructor(props: IBranchSelectProps) { super(props) this.state = { - showBranchDropdown: false, selectedBranch: props.branch, filterText: '', - dropdownListHeight: defaultDropdownListHeight, } } - public componentDidMount() { - this.calculateDropdownListHeight() - } - - public componentDidUpdate() { - this.calculateDropdownListHeight() - } - - private calculateDropdownListHeight = () => { - if (this.invokeButtonRef === null) { - return - } - - const windowHeight = window.innerHeight - const bottomOfButton = this.invokeButtonRef.getBoundingClientRect().bottom - const listHeaderHeight = 75 - const calcMaxHeight = Math.round( - windowHeight - bottomOfButton - listHeaderHeight - ) - - const dropdownListHeight = - calcMaxHeight > maxDropdownListHeight - ? maxDropdownListHeight - : calcMaxHeight - if (dropdownListHeight !== this.state.dropdownListHeight) { - this.setState({ dropdownListHeight }) - } - } - - private onInvokeButtonRef = (buttonRef: HTMLButtonElement | null) => { - this.invokeButtonRef = buttonRef - } - - private toggleBranchDropdown = () => { - this.setState({ showBranchDropdown: !this.state.showBranchDropdown }) - } - - private closeBranchDropdown = () => { - this.setState({ showBranchDropdown: false }) - } - private renderBranch = (item: IBranchListItem, matches: IMatches) => { return renderDefaultBranch(item, matches, this.props.currentBranch) } private onItemClick = (branch: Branch, source: ClickSource) => { source.event.preventDefault() - this.setState({ showBranchDropdown: false, selectedBranch: branch }) + this.popoverRef.current?.closePopover() + this.setState({ selectedBranch: branch }) this.props.onChange?.(branch) } @@ -124,34 +73,19 @@ export class BranchSelect extends React.Component< this.setState({ filterText }) } - public renderBranchDropdown() { - if (!this.state.showBranchDropdown) { - return - } - + public render() { const { currentBranch, defaultBranch, recentBranches, allBranches } = this.props - const { filterText, selectedBranch, dropdownListHeight } = this.state + const { filterText, selectedBranch } = this.state return ( - -
- Choose a base branch - -
-
+ base: + -
-
- ) - } - - public render() { - return ( -
- - {this.renderBranchDropdown()} +
) } diff --git a/app/src/ui/lib/popover-dropdown.tsx b/app/src/ui/lib/popover-dropdown.tsx index 557676541a..d2e18518d1 100644 --- a/app/src/ui/lib/popover-dropdown.tsx +++ b/app/src/ui/lib/popover-dropdown.tsx @@ -3,11 +3,13 @@ import { Button } from './button' import { Popover, PopoverCaretPosition } from './popover' import { Octicon } from '../octicons' import * as OcticonSymbol from '../octicons/octicons.generated' +import classNames from 'classnames' const defaultPopoverContentHeight = 300 const maxPopoverContentHeight = 500 interface IPopoverDropdownProps { + readonly className?: string readonly contentTitle: string readonly buttonContent: JSX.Element | string } @@ -18,9 +20,10 @@ interface IPopoverDropdownState { } /** - * A select element for filter and selecting a branch. + * A dropdown component for displaying a dropdown button that opens + * a popover to display contents relative to the button content. */ -export class PopoverSelect extends React.Component< +export class PopoverDropdown extends React.Component< IPopoverDropdownProps, IPopoverDropdownState > { @@ -72,11 +75,11 @@ export class PopoverSelect extends React.Component< this.setState({ showPopover: !this.state.showPopover }) } - private closePopover = () => { + public closePopover = () => { this.setState({ showPopover: false }) } - public renderPopover() { + private renderPopover() { if (!this.state.showPopover) { return } @@ -109,13 +112,16 @@ export class PopoverSelect extends React.Component< } public render() { + const { className, buttonContent } = this.props + const cn = classNames('popover-dropdown-component', className) + return ( -
+
{this.renderPopover()} diff --git a/app/styles/ui/_branch-select.scss b/app/styles/ui/_branch-select.scss index 38c9a62fc8..c0ae93fd27 100644 --- a/app/styles/ui/_branch-select.scss +++ b/app/styles/ui/_branch-select.scss @@ -1,66 +1,9 @@ .branch-select-component { - display: inline-flex; + display: inline; .base-label { font-weight: var(--font-weight-semibold); color: var(--text-secondary-color); margin: 0 var(--spacing-half); } - - button { - border: none; - background-color: inherit; - border: none; - padding: 0; - margin: 0; - font-style: normal; - font-family: var(--font-family-monospace); - - .ref-component { - padding: 1px; - } - - &.button-component { - overflow: visible; - - &:hover, - &:focus { - border: none; - box-shadow: none; - - .ref-component { - border-color: var(--path-segment-background-focus); - box-shadow: 0 0 0 1px var(--path-segment-background-focus); - } - } - } - } - - .ref-component { - display: inline-flex; - align-items: center; - } - - .branch-select-dropdown { - position: absolute; - min-height: 200px; - width: 365px; - padding: 0; - margin-top: 25px; - - .branch-select-dropdown-header { - padding: var(--spacing); - font-weight: var(--font-weight-semibold); - display: flex; - border-bottom: var(--base-border); - - .close { - margin-right: 0; - } - } - - .branch-select-dropdown-list { - display: flex; - } - } } diff --git a/app/styles/ui/_popover-dropdown.scss b/app/styles/ui/_popover-dropdown.scss index a7999447c0..178674cb77 100644 --- a/app/styles/ui/_popover-dropdown.scss +++ b/app/styles/ui/_popover-dropdown.scss @@ -7,8 +7,9 @@ border: none; padding: 0; margin: 0; - color: #149ad4; + color: var(--link-button-color); font-weight: bold; + text-decoration: underline; &.button-component { overflow: visible; From c59263b92ba75b4ad5362f6493b9331839e40389 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:50:23 -0400 Subject: [PATCH 27/84] Add diff options component --- app/src/ui/changes/changed-file-details.tsx | 3 +-- app/src/ui/diff/diff-options.tsx | 5 ++--- app/src/ui/history/commit-summary.tsx | 3 +-- .../pull-request-files-changed.tsx | 19 +++++++++++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/src/ui/changes/changed-file-details.tsx b/app/src/ui/changes/changed-file-details.tsx index b47b7d2918..cab1ce5d52 100644 --- a/app/src/ui/changes/changed-file-details.tsx +++ b/app/src/ui/changes/changed-file-details.tsx @@ -6,7 +6,6 @@ import { Octicon, iconForStatus } from '../octicons' import * as OcticonSymbol from '../octicons/octicons.generated' import { mapStatus } from '../../lib/status' import { DiffOptions } from '../diff/diff-options' -import { RepositorySectionTab } from '../../lib/app-state' interface IChangedFileDetailsProps { readonly path: string @@ -61,7 +60,7 @@ export class ChangedFileDetails extends React.Component< return ( - {this.props.sourceTab === RepositorySectionTab.Changes && ( + {this.props.isInteractiveDiff && (

Interacting with individual lines or hunks will be disabled while hiding whitespace. diff --git a/app/src/ui/history/commit-summary.tsx b/app/src/ui/history/commit-summary.tsx index 2182f63011..af82a4156e 100644 --- a/app/src/ui/history/commit-summary.tsx +++ b/app/src/ui/history/commit-summary.tsx @@ -12,7 +12,6 @@ import { CommitAttribution } from '../lib/commit-attribution' import { Tokenizer, TokenResult } from '../../lib/text-token-parser' import { wrapRichTextCommitMessage } from '../../lib/wrap-rich-text-commit-message' import { DiffOptions } from '../diff/diff-options' -import { RepositorySectionTab } from '../../lib/app-state' import { IChangesetData } from '../../lib/git' import { TooltippedContent } from '../lib/tooltipped-content' import { AppFileStatusKind } from '../../models/status' @@ -505,7 +504,7 @@ export class CommitSummary extends React.Component< title="Diff Options" > { + this.props.dispatcher.onShowSideBySideDiffChanged(showSideBySideDiff) + } + + private onDiffOptionsOpened = () => { + this.props.dispatcher.recordDiffOptionsViewed() + } + /** * Called when the user is viewing an image diff and requests * to change the diff presentation mode. @@ -209,6 +218,16 @@ export class PullRequestFilesChanged extends React.Component< return (

Showing changes from all commits
+ + +
) } From a0e9ea9ec2492366d1a82ad2db3f64cedccd4b2f Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:54:47 -0400 Subject: [PATCH 28/84] Display settings to right Also rename style file name to match component name --- .../pull-request-files-changed.tsx | 22 +++++++++---------- app/styles/_ui.scss | 2 +- ....scss => _pull-request-files-changed.scss} | 5 +++++ 3 files changed, 17 insertions(+), 12 deletions(-) rename app/styles/ui/{_pull-request-diff.scss => _pull-request-files-changed.scss} (78%) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index f2b4af91de..868ac1044f 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -217,17 +217,17 @@ export class PullRequestFilesChanged extends React.Component< private renderHeader() { return (
-
Showing changes from all commits
- - - +
+ Showing changes from all commits +
+
) } diff --git a/app/styles/_ui.scss b/app/styles/_ui.scss index 99b8c5aeb0..53c78ec973 100644 --- a/app/styles/_ui.scss +++ b/app/styles/_ui.scss @@ -100,5 +100,5 @@ @import 'ui/discard-changes-retry'; @import 'ui/_git-email-not-found-warning'; @import 'ui/_branch-select'; -@import 'ui/_pull-request-diff'; @import 'ui/_popover-dropdown'; +@import 'ui/_pull-request-files-changed'; diff --git a/app/styles/ui/_pull-request-diff.scss b/app/styles/ui/_pull-request-files-changed.scss similarity index 78% rename from app/styles/ui/_pull-request-diff.scss rename to app/styles/ui/_pull-request-files-changed.scss index 69954b1f55..ef3555c387 100644 --- a/app/styles/ui/_pull-request-diff.scss +++ b/app/styles/ui/_pull-request-files-changed.scss @@ -5,6 +5,11 @@ .files-changed-header { padding: var(--spacing); border-bottom: var(--base-border); + display: flex; + + .commits-displayed { + flex-grow: 1; + } } .files-diff-viewer { From 82b1c682ab8fbc82b4dcde8ac74470af7d981bd7 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:56:59 -0400 Subject: [PATCH 29/84] Tidying --- app/src/ui/open-pull-request/pull-request-files-changed.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index 868ac1044f..6a8921e261 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -215,6 +215,7 @@ export class PullRequestFilesChanged extends React.Component< } private renderHeader() { + const { hideWhitespaceInDiff, showSideBySideDiff } = this.props return (
@@ -222,9 +223,9 @@ export class PullRequestFilesChanged extends React.Component<
From 147120897b306d47863e3e6ea4a8568fa2be6b15 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 13:25:34 -0400 Subject: [PATCH 30/84] Get the diff state variables off the current state --- app/src/ui/app.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index ad04787b84..4a6e1a1caa 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2259,17 +2259,19 @@ export class App extends React.Component { return null } - const { pullRequestFilesListWidth } = this.state + const { + pullRequestFilesListWidth, + hideWhitespaceInHistoryDiff, + showSideBySideDiff, + } = this.state const { allBranches, currentBranch, defaultBranch, imageDiffType, - hideWhitespaceInHistoryDiff, externalEditorLabel, nonLocalCommitSHA, - showSideBySideDiff, recentBranches, repository, } = popup From e3165804529c33f526d957f03d35fcfd9101f1da Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 13:54:17 -0400 Subject: [PATCH 31/84] Remove state tracked variables from popover --- app/src/lib/stores/app-store.ts | 9 +-------- app/src/models/popup.ts | 2 -- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 2c30b2afd4..7ad2314c38 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7242,23 +7242,16 @@ export class AppStore extends TypedBaseStore { } const { allBranches, recentBranches } = branchesState - const { - imageDiffType, - hideWhitespaceInHistoryDiff, - showSideBySideDiff, - selectedExternalEditor, - } = this.getState() + const { imageDiffType, selectedExternalEditor } = this.getState() this._showPopup({ type: PopupType.StartPullRequest, allBranches, currentBranch, defaultBranch, - hideWhitespaceInHistoryDiff, imageDiffType, recentBranches, repository, - showSideBySideDiff, externalEditorLabel: selectedExternalEditor ?? undefined, nonLocalCommitSHA: commitSHAs.length > 0 && !localCommitSHAs.includes(commitSHAs[0]) diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index 188d8f0b0c..dfca4a6a28 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -366,10 +366,8 @@ export type Popup = currentBranch: Branch defaultBranch: Branch | null externalEditorLabel?: string - hideWhitespaceInHistoryDiff: boolean imageDiffType: ImageDiffType recentBranches: ReadonlyArray repository: Repository - showSideBySideDiff: boolean nonLocalCommitSHA: string | null } From 5be997fa708a1d0f5b107ab931cedc45333af245 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 22 Sep 2022 14:10:41 -0400 Subject: [PATCH 32/84] Add hideWhitespaceinPullRequestDiff tracking --- app/src/lib/app-state.ts | 3 +++ app/src/lib/stores/app-store.ts | 24 ++++++++++++++++++- app/src/ui/app.tsx | 4 ++-- app/src/ui/diff/diff-options.tsx | 2 +- app/src/ui/dispatcher/dispatcher.ts | 13 ++++++++++ .../pull-request-files-changed.tsx | 4 ++-- 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index 35a697597b..6b99e1ef19 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -233,6 +233,9 @@ export interface IAppState { /** Whether we should hide white space changes in history diff */ readonly hideWhitespaceInHistoryDiff: boolean + /** Whether we should hide white space changes in the pull request diff */ + readonly hideWhitespaceInPullRequestDiff: boolean + /** Whether we should show side by side diffs */ readonly showSideBySideDiff: boolean diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 7ad2314c38..970bcd9490 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -351,6 +351,8 @@ const hideWhitespaceInChangesDiffDefault = false const hideWhitespaceInChangesDiffKey = 'hide-whitespace-in-changes-diff' const hideWhitespaceInHistoryDiffDefault = false const hideWhitespaceInHistoryDiffKey = 'hide-whitespace-in-diff' +const hideWhitespaceInPullRequestDiffDefault = false +const hideWhitespaceInPullRequestDiffKey = 'hide-whitespace-in-diff' const commitSpellcheckEnabledDefault = true const commitSpellcheckEnabledKey = 'commit-spellcheck-enabled' @@ -448,6 +450,8 @@ export class AppStore extends TypedBaseStore { hideWhitespaceInChangesDiffDefault private hideWhitespaceInHistoryDiff: boolean = hideWhitespaceInHistoryDiffDefault + private hideWhitespaceInPullRequestDiff: boolean = + hideWhitespaceInPullRequestDiffDefault /** Whether or not the spellchecker is enabled for commit summary and description */ private commitSpellcheckEnabled: boolean = commitSpellcheckEnabledDefault private showSideBySideDiff: boolean = ShowSideBySideDiffDefault @@ -925,6 +929,7 @@ export class AppStore extends TypedBaseStore { imageDiffType: this.imageDiffType, hideWhitespaceInChangesDiff: this.hideWhitespaceInChangesDiff, hideWhitespaceInHistoryDiff: this.hideWhitespaceInHistoryDiff, + hideWhitespaceInPullRequestDiff: this.hideWhitespaceInPullRequestDiff, showSideBySideDiff: this.showSideBySideDiff, selectedShell: this.selectedShell, repositoryFilterText: this.repositoryFilterText, @@ -2021,6 +2026,10 @@ export class AppStore extends TypedBaseStore { hideWhitespaceInHistoryDiffKey, false ) + this.hideWhitespaceInPullRequestDiff = getBoolean( + hideWhitespaceInPullRequestDiffKey, + false + ) this.commitSpellcheckEnabled = getBoolean( commitSpellcheckEnabledKey, commitSpellcheckEnabledDefault @@ -5324,6 +5333,19 @@ export class AppStore extends TypedBaseStore { } } + public _setHideWhitespaceInPullRequestDiff( + hideWhitespaceInDiff: boolean, + repository: Repository, + file: CommittedFileChange | null + ) { + setBoolean(hideWhitespaceInPullRequestDiffKey, hideWhitespaceInDiff) + this.hideWhitespaceInPullRequestDiff = hideWhitespaceInDiff + + if (file !== null) { + this._changePullRequestFileSelection(repository, file) + } + } + public _setShowSideBySideDiff(showSideBySideDiff: boolean) { if (showSideBySideDiff !== this.showSideBySideDiff) { setShowSideBySideDiff(showSideBySideDiff) @@ -7305,7 +7327,7 @@ export class AppStore extends TypedBaseStore { file, baseBranch.name, currentBranch.name, - this.hideWhitespaceInHistoryDiff, + this.hideWhitespaceInPullRequestDiff, commitSHAs[0] ) )) ?? null diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 4a6e1a1caa..8bb82c098a 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2261,7 +2261,7 @@ export class App extends React.Component { const { pullRequestFilesListWidth, - hideWhitespaceInHistoryDiff, + hideWhitespaceInPullRequestDiff, showSideBySideDiff, } = this.state @@ -2284,7 +2284,7 @@ export class App extends React.Component { defaultBranch={defaultBranch} dispatcher={this.props.dispatcher} fileListWidth={pullRequestFilesListWidth} - hideWhitespaceInDiff={hideWhitespaceInHistoryDiff} + hideWhitespaceInDiff={hideWhitespaceInPullRequestDiff} imageDiffType={imageDiffType} nonLocalCommitSHA={nonLocalCommitSHA} pullRequestState={pullRequestState} diff --git a/app/src/ui/diff/diff-options.tsx b/app/src/ui/diff/diff-options.tsx index f2ec38a893..f5791f5e44 100644 --- a/app/src/ui/diff/diff-options.tsx +++ b/app/src/ui/diff/diff-options.tsx @@ -10,7 +10,7 @@ interface IDiffOptionsProps { readonly hideWhitespaceChanges: boolean readonly onHideWhitespaceChangesChanged: ( hideWhitespaceChanges: boolean - ) => Promise + ) => Promise | void readonly showSideBySideDiff: boolean readonly onShowSideBySideDiffChanged: (showSideBySideDiff: boolean) => void diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index d6ac77637e..dec5515def 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -2122,6 +2122,19 @@ export class Dispatcher { ) } + /** Change the hide whitespace in pull request diff setting */ + public onHideWhitespaceInPullRequestDiffChanged( + hideWhitespaceInDiff: boolean, + repository: Repository, + file: CommittedFileChange | null = null + ) { + this.appStore._setHideWhitespaceInPullRequestDiff( + hideWhitespaceInDiff, + repository, + file + ) + } + /** Change the side by side diff setting */ public onShowSideBySideDiffChanged(showSideBySideDiff: boolean) { return this.appStore._setShowSideBySideDiff(showSideBySideDiff) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index 6a8921e261..d297240562 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -60,7 +60,7 @@ interface IPullRequestFilesChangedProps { } /** - * A component for viewing the file diff for a pull request. + * A component for viewing the file changes for a pull request. */ export class PullRequestFilesChanged extends React.Component< IPullRequestFilesChangedProps, @@ -82,7 +82,7 @@ export class PullRequestFilesChanged extends React.Component< /** Called when the user changes the hide whitespace in diffs setting. */ private onHideWhitespaceInDiffChanged = (hideWhitespaceInDiff: boolean) => { const { selectedFile } = this.props - return this.props.dispatcher.onHideWhitespaceInHistoryDiffChanged( + return this.props.dispatcher.onHideWhitespaceInPullRequestDiffChanged( hideWhitespaceInDiff, this.props.repository, selectedFile as CommittedFileChange From 785664c7e91b57d4f044ea1d9202500f6301297d Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 08:03:04 -0400 Subject: [PATCH 33/84] Remove copy/pasta casting --- app/src/ui/open-pull-request/pull-request-files-changed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index d297240562..a41d6c9d31 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -85,7 +85,7 @@ export class PullRequestFilesChanged extends React.Component< return this.props.dispatcher.onHideWhitespaceInPullRequestDiffChanged( hideWhitespaceInDiff, this.props.repository, - selectedFile as CommittedFileChange + selectedFile ) } From 27caadcde931c1fd584c53c92f7668a351a55821 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 08:16:16 -0400 Subject: [PATCH 34/84] Move sideBySidediff state management to files changed component --- app/src/lib/stores/app-store.ts | 4 ++- app/src/models/popup.ts | 1 + app/src/ui/app.tsx | 8 +++--- .../pull-request-files-changed.tsx | 27 ++++++++++++------- .../ui/_pull-request-files-changed.scss | 4 +++ 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 970bcd9490..9674327244 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7264,7 +7264,8 @@ export class AppStore extends TypedBaseStore { } const { allBranches, recentBranches } = branchesState - const { imageDiffType, selectedExternalEditor } = this.getState() + const { imageDiffType, selectedExternalEditor, showSideBySideDiff } = + this.getState() this._showPopup({ type: PopupType.StartPullRequest, @@ -7279,6 +7280,7 @@ export class AppStore extends TypedBaseStore { commitSHAs.length > 0 && !localCommitSHAs.includes(commitSHAs[0]) ? commitSHAs[0] : null, + showSideBySideDiff, }) } diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index dfca4a6a28..57cc87c866 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -370,4 +370,5 @@ export type Popup = recentBranches: ReadonlyArray repository: Repository nonLocalCommitSHA: string | null + showSideBySideDiff: boolean } diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 8bb82c098a..d6cd421e39 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -2259,11 +2259,8 @@ export class App extends React.Component { return null } - const { - pullRequestFilesListWidth, - hideWhitespaceInPullRequestDiff, - showSideBySideDiff, - } = this.state + const { pullRequestFilesListWidth, hideWhitespaceInPullRequestDiff } = + this.state const { allBranches, @@ -2274,6 +2271,7 @@ export class App extends React.Component { nonLocalCommitSHA, recentBranches, repository, + showSideBySideDiff, } = popup return ( diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index a41d6c9d31..e8ca091104 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -59,13 +59,23 @@ interface IPullRequestFilesChangedProps { readonly nonLocalCommitSHA: string | null } +interface IPullRequestFilesChangedState { + readonly showSideBySideDiff: boolean +} + /** * A component for viewing the file changes for a pull request. */ export class PullRequestFilesChanged extends React.Component< IPullRequestFilesChangedProps, - {} + IPullRequestFilesChangedState > { + public constructor(props: IPullRequestFilesChangedProps) { + super(props) + + this.state = { showSideBySideDiff: props.showSideBySideDiff } + } + private onOpenFile = (path: string) => { const fullPath = Path.join(this.props.repository.path, path) this.onOpenBinaryFile(fullPath) @@ -90,7 +100,7 @@ export class PullRequestFilesChanged extends React.Component< } private onShowSideBySideDiffChanged = (showSideBySideDiff: boolean) => { - this.props.dispatcher.onShowSideBySideDiffChanged(showSideBySideDiff) + this.setState({ showSideBySideDiff }) } private onDiffOptionsOpened = () => { @@ -215,7 +225,8 @@ export class PullRequestFilesChanged extends React.Component< } private renderHeader() { - const { hideWhitespaceInDiff, showSideBySideDiff } = this.props + const { hideWhitespaceInDiff } = this.props + const { showSideBySideDiff } = this.state return (
@@ -262,13 +273,9 @@ export class PullRequestFilesChanged extends React.Component< return } - const { - diff, - repository, - imageDiffType, - hideWhitespaceInDiff, - showSideBySideDiff, - } = this.props + const { diff, repository, imageDiffType, hideWhitespaceInDiff } = this.props + + const { showSideBySideDiff } = this.state return ( Date: Mon, 26 Sep 2022 13:01:55 -0400 Subject: [PATCH 35/84] Use MacOs/Windows Sentence casing --- app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index c6991954b0..f55546f465 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -134,8 +134,9 @@ export class OpenPullRequestDialog extends React.Component From f6a72527cc6cc8f550aa96bb6355a5d23b812b8c Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Mon, 26 Sep 2022 13:02:16 -0400 Subject: [PATCH 36/84] Add Enterprise label --- .../ui/open-pull-request/open-pull-request-dialog.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index f55546f465..4627d438f7 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { IConstrainedValue, IPullRequestState } from '../../lib/app-state' +import { getDotComAPIEndpoint } from '../../lib/api' import { Branch } from '../../models/branch' import { ImageDiffType } from '../../models/diff' import { Repository } from '../../models/repository' @@ -131,12 +132,20 @@ export class OpenPullRequestDialog extends React.Component From cad3813389608fd11b53cbc2e13268fc94f2a57e Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 08:41:50 -0400 Subject: [PATCH 37/84] Add no changes div --- .../open-pull-request-dialog.tsx | 17 ++++++++++++++++- .../pull-request-files-changed.tsx | 1 - 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index c6991954b0..fe449d15a9 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -93,6 +93,7 @@ export class OpenPullRequestDialog extends React.Component + {this.renderNoChanges()} {this.renderFilesChanged()}
) @@ -110,9 +111,13 @@ export class OpenPullRequestDialog extends React.Component No changes!
+ } + private renderFooter() { return ( diff --git a/app/src/ui/open-pull-request/pull-request-files-changed.tsx b/app/src/ui/open-pull-request/pull-request-files-changed.tsx index d08e9a30a9..02d02e48be 100644 --- a/app/src/ui/open-pull-request/pull-request-files-changed.tsx +++ b/app/src/ui/open-pull-request/pull-request-files-changed.tsx @@ -267,7 +267,6 @@ export class PullRequestFilesChanged extends React.Component< } public render() { - // TODO: handle empty change set return (
{this.renderHeader()} From cec67105a1849417f8e788edb09717cdb02effe6 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 08:41:56 -0400 Subject: [PATCH 38/84] Center no changes content --- app/styles/ui/dialogs/_open-pull-request.scss | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index 2c6f174137..6cdbb91e7f 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -22,4 +22,13 @@ .open-pull-request-content { padding: var(--spacing); } + + .open-pull-request-no-changes { + height: 100%; + display: flex; + align-items: center; + text-align: center; + justify-content: center; + padding: var(--spacing-double); + } } From 9a3c29b5b8031ea7271d2b9d822cffd1471fe68d Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Wed, 28 Sep 2022 09:04:53 -0400 Subject: [PATCH 39/84] Add no changes verbiage --- .../open-pull-request-dialog.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index fe449d15a9..95fb620209 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -5,6 +5,9 @@ import { ImageDiffType } from '../../models/diff' import { Repository } from '../../models/repository' import { DialogFooter, OkCancelButtonGroup, Dialog } from '../dialog' import { Dispatcher } from '../dispatcher' +import { Ref } from '../lib/ref' +import { Octicon } from '../octicons' +import * as OcticonSymbol from '../octicons/octicons.generated' import { OpenPullRequestDialogHeader } from './open-pull-request-header' import { PullRequestFilesChanged } from './pull-request-files-changed' @@ -136,13 +139,24 @@ export class OpenPullRequestDialog extends React.Component No changes!
+ return ( +
+
+ +

There are no changes.

+ {baseBranch.name} is up to date with all commits from{' '} + {currentBranch.name}. +
+
+ ) } private renderFooter() { From c9d74f4a775608b0042167176a879458d0e2d5e4 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:15:37 -0400 Subject: [PATCH 40/84] Update app/src/lib/stores/app-store.ts Co-authored-by: Sergio Padrino --- app/src/lib/stores/app-store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 9674327244..008e6f27b9 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -352,7 +352,7 @@ const hideWhitespaceInChangesDiffKey = 'hide-whitespace-in-changes-diff' const hideWhitespaceInHistoryDiffDefault = false const hideWhitespaceInHistoryDiffKey = 'hide-whitespace-in-diff' const hideWhitespaceInPullRequestDiffDefault = false -const hideWhitespaceInPullRequestDiffKey = 'hide-whitespace-in-diff' +const hideWhitespaceInPullRequestDiffKey = 'hide-whitespace-in-pull-request-diff' const commitSpellcheckEnabledDefault = true const commitSpellcheckEnabledKey = 'commit-spellcheck-enabled' From 21d0a60c05152efbf05ec1cde7f656edc2479944 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:21:50 -0400 Subject: [PATCH 41/84] Don't need this to be a promise? --- app/src/ui/diff/diff-options.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/diff/diff-options.tsx b/app/src/ui/diff/diff-options.tsx index f5791f5e44..9196dd9317 100644 --- a/app/src/ui/diff/diff-options.tsx +++ b/app/src/ui/diff/diff-options.tsx @@ -10,7 +10,7 @@ interface IDiffOptionsProps { readonly hideWhitespaceChanges: boolean readonly onHideWhitespaceChangesChanged: ( hideWhitespaceChanges: boolean - ) => Promise | void + ) => void readonly showSideBySideDiff: boolean readonly onShowSideBySideDiffChanged: (showSideBySideDiff: boolean) => void From 42cd43b6d96aaddf5b95d23adbdf44aaf6462b8d Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:25:45 -0400 Subject: [PATCH 42/84] Linter.. --- app/src/lib/stores/app-store.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 008e6f27b9..a38313233c 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -352,7 +352,8 @@ const hideWhitespaceInChangesDiffKey = 'hide-whitespace-in-changes-diff' const hideWhitespaceInHistoryDiffDefault = false const hideWhitespaceInHistoryDiffKey = 'hide-whitespace-in-diff' const hideWhitespaceInPullRequestDiffDefault = false -const hideWhitespaceInPullRequestDiffKey = 'hide-whitespace-in-pull-request-diff' +const hideWhitespaceInPullRequestDiffKey = + 'hide-whitespace-in-pull-request-diff' const commitSpellcheckEnabledDefault = true const commitSpellcheckEnabledKey = 'commit-spellcheck-enabled' From cc69b05956d100aff772051e945f98657f71f0b5 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Mon, 26 Sep 2022 11:25:24 -0400 Subject: [PATCH 43/84] Add update method chain to app-store --- app/src/lib/stores/app-store.ts | 1 + app/src/ui/dispatcher/dispatcher.ts | 4 ++++ app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 6 ++++++ app/src/ui/open-pull-request/open-pull-request-header.tsx | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index a38313233c..caec31e2d3 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7377,6 +7377,7 @@ export class AppStore extends TypedBaseStore { return Promise.resolve() } + public _updatePullRequestBaseBranch(repository: Repository, branch: Branch) {} } /** diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index dec5515def..2641f3cfc1 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -4001,4 +4001,8 @@ export class Dispatcher { public resetPullRequestFileListWidth(): Promise { return this.appStore._resetPullRequestFileListWidth() } + + public updatePullRequestBaseBranch(repository: Repository, branch: Branch) { + this.appStore._updatePullRequestBaseBranch(repository, branch) + } } diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index c6991954b0..53ffd5fcf5 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -68,6 +68,11 @@ export class OpenPullRequestDialog extends React.Component { + const { repository } = this.props + this.props.dispatcher.updatePullRequestBaseBranch(repository, branch) + } + private renderHeader() { const { currentBranch, @@ -85,6 +90,7 @@ export class OpenPullRequestDialog extends React.Component ) diff --git a/app/src/ui/open-pull-request/open-pull-request-header.tsx b/app/src/ui/open-pull-request/open-pull-request-header.tsx index e6b6045308..b9e376387b 100644 --- a/app/src/ui/open-pull-request/open-pull-request-header.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-header.tsx @@ -30,6 +30,9 @@ interface IOpenPullRequestDialogHeaderProps { /** The count of commits of the pull request */ readonly commitCount: number + /** When the branch selection changes */ + readonly onBranchChange: (branch: Branch) => void + /** * Event triggered when the dialog is dismissed by the user in the * ways described in the dismissable prop. @@ -54,6 +57,7 @@ export class OpenPullRequestDialogHeader extends React.Component< allBranches, recentBranches, commitCount, + onBranchChange, onDismissed, } = this.props const commits = `${commitCount} commit${commitCount > 1 ? 's' : ''}` @@ -74,6 +78,7 @@ export class OpenPullRequestDialogHeader extends React.Component< currentBranch={currentBranch} allBranches={allBranches} recentBranches={recentBranches} + onChange={onBranchChange} />{' '} from {currentBranch.name}.
From c4d549387635072b0cb1d0bee2f067415f77f833 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:48:29 -0400 Subject: [PATCH 44/84] Repeat pr start for new base branch ( move duplicate logic to new method) --- app/src/lib/stores/app-store.ts | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index caec31e2d3..5ab929bc3d 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7215,12 +7215,19 @@ export class AppStore extends TypedBaseStore { if (defaultBranch === null || tip.kind !== TipState.Valid) { return } - const currentBranch = tip.branch + this._initializePullRequestPreview(repository, defaultBranch, currentBranch) + } + + private async _initializePullRequestPreview( + repository: Repository, + baseBranch: Branch, + currentBranch: Branch + ) { const gitStore = this.gitStoreCache.get(repository) const pullRequestCommits = await gitStore.getCommitsBetweenBranches( - defaultBranch, + baseBranch, currentBranch ) @@ -7233,7 +7240,7 @@ export class AppStore extends TypedBaseStore { ? await gitStore.performFailableOperation(() => getBranchMergeBaseChangedFiles( repository, - defaultBranch.name, + baseBranch.name, currentBranch.name, commitSHAs[0] ) @@ -7245,7 +7252,7 @@ export class AppStore extends TypedBaseStore { } this.repositoryStateCache.initializePullRequestState(repository, { - baseBranch: defaultBranch, + baseBranch, commitSHAs, commitSelection: { shas: commitSHAs, @@ -7257,6 +7264,8 @@ export class AppStore extends TypedBaseStore { }, }) + this.emitUpdate() + if (changesetData.files.length > 0) { await this._changePullRequestFileSelection( repository, @@ -7377,7 +7386,27 @@ export class AppStore extends TypedBaseStore { return Promise.resolve() } - public _updatePullRequestBaseBranch(repository: Repository, branch: Branch) {} + + public _updatePullRequestBaseBranch( + repository: Repository, + baseBranch: Branch + ) { + const { branchesState, pullRequestState } = + this.repositoryStateCache.get(repository) + const { tip } = branchesState + + if (tip.kind !== TipState.Valid) { + return + } + + if (pullRequestState === null) { + // This would mean the user submitted PR after requesting base branch + // update. + return + } + + this._initializePullRequestPreview(repository, baseBranch, tip.branch) + } } /** From bf9e2422e719f5b2b77a280a87df5bb02586dbb7 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 29 Sep 2022 10:40:07 -0400 Subject: [PATCH 45/84] Fix update from dev changes --- app/src/lib/stores/app-store.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 5ab929bc3d..7dea0b780d 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7208,8 +7208,7 @@ export class AppStore extends TypedBaseStore { } public async _startPullRequest(repository: Repository) { - const { branchesState, localCommitSHAs } = - this.repositoryStateCache.get(repository) + const { branchesState } = this.repositoryStateCache.get(repository) const { defaultBranch, tip } = branchesState if (defaultBranch === null || tip.kind !== TipState.Valid) { @@ -7224,6 +7223,8 @@ export class AppStore extends TypedBaseStore { baseBranch: Branch, currentBranch: Branch ) { + const { branchesState, localCommitSHAs } = + this.repositoryStateCache.get(repository) const gitStore = this.gitStoreCache.get(repository) const pullRequestCommits = await gitStore.getCommitsBetweenBranches( @@ -7273,7 +7274,7 @@ export class AppStore extends TypedBaseStore { ) } - const { allBranches, recentBranches } = branchesState + const { allBranches, recentBranches, defaultBranch } = branchesState const { imageDiffType, selectedExternalEditor, showSideBySideDiff } = this.getState() From 1b76c6fc8c93e1dd026b6abbbd5d3cd9aa827238 Mon Sep 17 00:00:00 2001 From: Rebecca Miller-Webster Date: Thu, 29 Sep 2022 15:52:37 -0500 Subject: [PATCH 46/84] Update setup.md Update expected node, yarn, and python versions --- docs/contributing/setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/contributing/setup.md b/docs/contributing/setup.md index 2b1f3d7020..05a6819e98 100644 --- a/docs/contributing/setup.md +++ b/docs/contributing/setup.md @@ -19,13 +19,13 @@ versions look similar to the below output: ```shellsession $ node -v -v10.15.4 +v16.13.0 $ yarn -v -1.15.2 +1.21.1 $ python --version -Python 2.7.15 +Python 3.9.x ``` There are also [additional resources](tooling.md) to configure your favorite From f18ce24e9695a99d34ee68dee93a1d233b182dde Mon Sep 17 00:00:00 2001 From: Tsvetilian Yankov Date: Fri, 30 Sep 2022 12:49:38 +0300 Subject: [PATCH 47/84] Add discard stash toggle option to the prompt --- app/src/ui/app.tsx | 3 +++ app/src/ui/stashing/confirm-discard-stash.tsx | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 6609225ced..306899a670 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -1850,6 +1850,9 @@ export class App extends React.Component { void } interface IConfirmDiscardStashState { readonly isDiscarding: boolean + readonly confirmDiscardStash: boolean } /** * Dialog to confirm dropping a stash @@ -28,6 +31,7 @@ export class ConfirmDiscardStashDialog extends React.Component< this.state = { isDiscarding: false, + confirmDiscardStash: props.askForConfirmationOnDiscardStash, } } @@ -46,6 +50,17 @@ export class ConfirmDiscardStashDialog extends React.Component< > Are you sure you want to discard these stashed changes? + + + @@ -54,6 +69,14 @@ export class ConfirmDiscardStashDialog extends React.Component< ) } + private onAskForConfirmationOnDiscardStashChanged = ( + event: React.FormEvent + ) => { + const value = !event.currentTarget.checked + + this.setState({ confirmDiscardStash: value }) + } + private onSubmit = async () => { const { dispatcher, repository, stash, onDismissed } = this.props @@ -62,6 +85,7 @@ export class ConfirmDiscardStashDialog extends React.Component< }) try { + dispatcher.setConfirmDiscardStashSetting(this.state.confirmDiscardStash) await dispatcher.dropStash(repository, stash) } finally { this.setState({ From 73fcceb2f42136f89b0e009a875ae966901d2415 Mon Sep 17 00:00:00 2001 From: Sathvik Shanmugam Date: Sun, 2 Oct 2022 16:05:37 +0530 Subject: [PATCH 48/84] Adding new levels in zooming --- app/src/main-process/menu/build-default-menu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main-process/menu/build-default-menu.ts b/app/src/main-process/menu/build-default-menu.ts index b01d63f30c..2186d80500 100644 --- a/app/src/main-process/menu/build-default-menu.ts +++ b/app/src/main-process/menu/build-default-menu.ts @@ -640,7 +640,7 @@ function emit(name: MenuEvent): ClickHandler { } /** The zoom steps that we support, these factors must sorted */ -const ZoomInFactors = [1, 1.1, 1.25, 1.5, 1.75, 2] +const ZoomInFactors = [0.5, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2] const ZoomOutFactors = ZoomInFactors.slice().reverse() /** From 6ad7ec70b8b9ee42f10ee3a07d03a3bf4f07342e Mon Sep 17 00:00:00 2001 From: Sathvik Shanmugam Date: Sun, 2 Oct 2022 16:44:40 +0530 Subject: [PATCH 49/84] Adding levels to get sync with the browser standards --- app/src/main-process/menu/build-default-menu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main-process/menu/build-default-menu.ts b/app/src/main-process/menu/build-default-menu.ts index 2186d80500..a661eaa78a 100644 --- a/app/src/main-process/menu/build-default-menu.ts +++ b/app/src/main-process/menu/build-default-menu.ts @@ -640,7 +640,7 @@ function emit(name: MenuEvent): ClickHandler { } /** The zoom steps that we support, these factors must sorted */ -const ZoomInFactors = [0.5, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2] +const ZoomInFactors = [0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2] const ZoomOutFactors = ZoomInFactors.slice().reverse() /** From 55f994e7f3ed92cd1a90d17b62c2f0894f8f9fe2 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Mon, 3 Oct 2022 07:46:04 -0400 Subject: [PATCH 50/84] Make look like a button - add label --- app/src/ui/branches/branch-select.tsx | 40 +++++++++++++-------------- app/src/ui/lib/popover-dropdown.tsx | 4 ++- app/styles/ui/_branch-select.scss | 9 ------ app/styles/ui/_popover-dropdown.scss | 23 +++------------ 4 files changed, 26 insertions(+), 50 deletions(-) diff --git a/app/src/ui/branches/branch-select.tsx b/app/src/ui/branches/branch-select.tsx index 4cde775e46..e79b5c6742 100644 --- a/app/src/ui/branches/branch-select.tsx +++ b/app/src/ui/branches/branch-select.tsx @@ -80,27 +80,25 @@ export class BranchSelect extends React.Component< const { filterText, selectedBranch } = this.state return ( -
- base: - - - -
+ + + ) } } diff --git a/app/src/ui/lib/popover-dropdown.tsx b/app/src/ui/lib/popover-dropdown.tsx index d2e18518d1..7ba6233617 100644 --- a/app/src/ui/lib/popover-dropdown.tsx +++ b/app/src/ui/lib/popover-dropdown.tsx @@ -12,6 +12,7 @@ interface IPopoverDropdownProps { readonly className?: string readonly contentTitle: string readonly buttonContent: JSX.Element | string + readonly label: string } interface IPopoverDropdownState { @@ -112,7 +113,7 @@ export class PopoverDropdown extends React.Component< } public render() { - const { className, buttonContent } = this.props + const { className, buttonContent, label } = this.props const cn = classNames('popover-dropdown-component', className) return ( @@ -121,6 +122,7 @@ export class PopoverDropdown extends React.Component< onClick={this.togglePopover} onButtonRef={this.onInvokeButtonRef} > + {label} {buttonContent} diff --git a/app/styles/ui/_branch-select.scss b/app/styles/ui/_branch-select.scss index c0ae93fd27..e69de29bb2 100644 --- a/app/styles/ui/_branch-select.scss +++ b/app/styles/ui/_branch-select.scss @@ -1,9 +0,0 @@ -.branch-select-component { - display: inline; - - .base-label { - font-weight: var(--font-weight-semibold); - color: var(--text-secondary-color); - margin: 0 var(--spacing-half); - } -} diff --git a/app/styles/ui/_popover-dropdown.scss b/app/styles/ui/_popover-dropdown.scss index 178674cb77..6a0ccdba23 100644 --- a/app/styles/ui/_popover-dropdown.scss +++ b/app/styles/ui/_popover-dropdown.scss @@ -1,25 +1,10 @@ .popover-dropdown-component { display: inline-flex; - button { - border: none; - background-color: inherit; - border: none; - padding: 0; - margin: 0; - color: var(--link-button-color); - font-weight: bold; - text-decoration: underline; - - &.button-component { - overflow: visible; - - &:hover, - &:focus { - border: none; - box-shadow: none; - } - } + .popover-dropdown-button-label { + font-weight: var(--font-weight-semibold); + color: var(--text-secondary-color); + margin: 0 var(--spacing-half); } .popover-dropdown-popover { From 3ea43eb5a6ea8428d2a06100d4110e31b3c6c621 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 15:28:11 +0000 Subject: [PATCH 51/84] Bump peter-evans/create-pull-request from 4.1.2 to 4.1.3 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v4.1.2...v4.1.3) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/release-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 3b3811a498..c6daccbcec 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -37,7 +37,7 @@ jobs: private_key: ${{ secrets.DESKTOP_RELEASES_APP_PRIVATE_KEY }} - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v4.1.2 + uses: peter-evans/create-pull-request@v4.1.3 if: | startsWith(github.ref, 'refs/heads/releases/') && !contains(github.ref, 'test') with: From d689c2592668886d9bab7168c2390136552b917e Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Mon, 3 Oct 2022 12:07:13 -0400 Subject: [PATCH 52/84] Semi bold button text --- app/styles/ui/_popover-dropdown.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/styles/ui/_popover-dropdown.scss b/app/styles/ui/_popover-dropdown.scss index 6a0ccdba23..6b8b20dafb 100644 --- a/app/styles/ui/_popover-dropdown.scss +++ b/app/styles/ui/_popover-dropdown.scss @@ -1,8 +1,12 @@ .popover-dropdown-component { display: inline-flex; + .button-content, .popover-dropdown-button-label { font-weight: var(--font-weight-semibold); + } + + .popover-dropdown-button-label { color: var(--text-secondary-color); margin: 0 var(--spacing-half); } From 26b981b1ad37cca8afec15943d607bf6f0f0ccae Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 08:18:49 -0400 Subject: [PATCH 53/84] Use undo commit key --- app/src/lib/stores/app-store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 7dea0b780d..8f8541a540 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -5261,7 +5261,7 @@ export class AppStore extends TypedBaseStore { public _setConfirmUndoCommitSetting(value: boolean): Promise { this.confirmUndoCommit = value - setBoolean(confirmForcePushKey, value) + setBoolean(confirmUndoCommitKey, value) this.emitUpdate() From f9365ef957c582e19622ec24ae7909f454b9b7d1 Mon Sep 17 00:00:00 2001 From: Tsvetilian Yankov Date: Tue, 4 Oct 2022 23:26:23 +0300 Subject: [PATCH 54/84] Fix typo Co-authored-by: Sergio Padrino --- app/src/lib/app-state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index d7277a281f..19a1cce3f9 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -194,7 +194,7 @@ export interface IAppState { /** Whether we should show a confirmation dialog */ readonly askForConfirmationOnDiscardChangesPermanently: boolean - /** Should the app propt the user to confirm a discard stash */ + /** Should the app prompt the user to confirm a discard stash */ readonly askForConfirmationOnDiscardStash: boolean /** Should the app prompt the user to confirm a force push? */ From bc5e8e918e432cf012b2113d4499acf49b96e987 Mon Sep 17 00:00:00 2001 From: Sathvik Shanmugam Date: Thu, 6 Oct 2022 10:53:40 +0530 Subject: [PATCH 55/84] Addressing review comments --- app/src/main-process/menu/build-default-menu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main-process/menu/build-default-menu.ts b/app/src/main-process/menu/build-default-menu.ts index a661eaa78a..5da9141700 100644 --- a/app/src/main-process/menu/build-default-menu.ts +++ b/app/src/main-process/menu/build-default-menu.ts @@ -640,7 +640,7 @@ function emit(name: MenuEvent): ClickHandler { } /** The zoom steps that we support, these factors must sorted */ -const ZoomInFactors = [0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2] +const ZoomInFactors = [0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2] const ZoomOutFactors = ZoomInFactors.slice().reverse() /** From 7a9ac0f2f987ac7fafd0f9f652cab0c28c118f12 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 08:13:30 -0400 Subject: [PATCH 56/84] Add merge status to pull request state --- app/src/lib/app-state.ts | 3 ++ app/src/lib/stores/app-store.ts | 66 +++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index 1dd95f3a39..08ead91bc3 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -974,4 +974,7 @@ export interface IPullRequestState { * diff between the latest commit and the earliest commits parent. */ readonly commitSelection: ICommitSelection + + /** The result of merging the pull request branch into the base branch */ + readonly mergeStatus: MergeTreeResult | null } diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index f58777362c..8c8ea53bf2 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -473,6 +473,7 @@ export class AppStore extends TypedBaseStore { private repositoryFilterText: string = '' private currentMergeTreePromise: Promise | null = null + private currentPRMergeTreePromise: Promise | null = null /** The function to resolve the current Open in Desktop flow. */ private resolveOpenInDesktop: @@ -1480,6 +1481,40 @@ export class AppStore extends TypedBaseStore { } } + private setupMergabilityPromise( + repository: Repository, + baseBranch: Branch, + compareBranch: Branch, + onLoad: (mergeTreeResult: MergeTreeResult | null) => void, + cleanup: () => void + ) { + const mergeTreePromise = promiseWithMinimumTimeout( + () => determineMergeability(repository, baseBranch, compareBranch), + 500 + ) + .catch(err => { + log.warn( + `Error occurred while trying to merge ${baseBranch.name} (${baseBranch.tip.sha}) and ${compareBranch.name} (${compareBranch.tip.sha})`, + err + ) + return null + }) + .then(mergeStatus => { + this.repositoryStateCache.updateCompareState(repository, () => ({ + mergeStatus, + })) + + this.emitUpdate() + }) + .finally(() => { + this.currentMergeTreePromise = null + }) + + this.currentMergeTreePromise = mergeTreePromise + + return this.currentMergeTreePromise + } + /** This shouldn't be called directly. See `Dispatcher`. */ public _updateCompareForm( repository: Repository, @@ -7281,10 +7316,15 @@ export class AppStore extends TypedBaseStore { file: null, diff: null, }, + mergeStatus: { + kind: ComputedAction.Loading, + }, }) this.emitUpdate() + this.setupPRMergeTreePromise(repository, baseBranch, currentBranch) + if (changesetData.files.length > 0) { await this._changePullRequestFileSelection( repository, @@ -7426,6 +7466,32 @@ export class AppStore extends TypedBaseStore { this._initializePullRequestPreview(repository, baseBranch, tip.branch) } + + private setupPRMergeTreePromise( + repository: Repository, + baseBranch: Branch, + compareBranch: Branch + ) { + // Not sure why we do this..following pattern from compare branch setup + if (this.currentPRMergeTreePromise != null) { + return + } + + this.currentPRMergeTreePromise = this.setupMergabilityPromise( + repository, + baseBranch, + compareBranch, + (mergeStatus: MergeTreeResult | null) => { + this.repositoryStateCache.updatePullRequestState(repository, () => ({ + mergeStatus, + })) + this.emitUpdate() + }, + () => { + this.currentPRMergeTreePromise = null + } + ) + } } /** From 00edd315a145ff1a632a7396bd34955b9406c220 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 11:54:01 -0400 Subject: [PATCH 57/84] Create pull-request-merge-status.tsx --- .../pull-request-merge-status.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/src/ui/open-pull-request/pull-request-merge-status.tsx diff --git a/app/src/ui/open-pull-request/pull-request-merge-status.tsx b/app/src/ui/open-pull-request/pull-request-merge-status.tsx new file mode 100644 index 0000000000..b928724e04 --- /dev/null +++ b/app/src/ui/open-pull-request/pull-request-merge-status.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' +import { MergeResult } from '../../lib/git' + +interface IPullRequestMergeStatusProps { + /** The result of merging the pull request branch into the base branch */ + readonly mergeStatus: MergeResult +} + +/** The component to display message about the result of merging the pull + * request. */ +export class PullRequestMergeStatus extends React.Component { + public render() { + return
Merge Status
+ } +} From 20c666b1d9c2068ff95bfa500fdfa57dd517f823 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 12:45:07 -0400 Subject: [PATCH 58/84] Add merge status component to dialog --- app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 3 +++ .../ui/open-pull-request/pull-request-merge-status.tsx | 6 +++--- app/styles/ui/dialogs/_open-pull-request.scss | 8 ++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index b9d09a4441..3e82257375 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -11,6 +11,7 @@ import { Octicon } from '../octicons' import * as OcticonSymbol from '../octicons/octicons.generated' import { OpenPullRequestDialogHeader } from './open-pull-request-header' import { PullRequestFilesChanged } from './pull-request-files-changed' +import { PullRequestMergeStatus } from './pull-request-merge-status' interface IOpenPullRequestDialogProps { readonly repository: Repository @@ -167,6 +168,7 @@ export class OpenPullRequestDialog extends React.Component + { public render() { - return
Merge Status
+ return
Merge Status
} } diff --git a/app/styles/ui/dialogs/_open-pull-request.scss b/app/styles/ui/dialogs/_open-pull-request.scss index 6cdbb91e7f..7534652ca0 100644 --- a/app/styles/ui/dialogs/_open-pull-request.scss +++ b/app/styles/ui/dialogs/_open-pull-request.scss @@ -31,4 +31,12 @@ justify-content: center; padding: var(--spacing-double); } + + .dialog-footer { + flex-direction: row; + } + + .pull-request-merge-status { + flex-grow: 1; + } } From 77ae9dc249baa4c249b9c5a59ef8762dd866baab Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:37:27 -0400 Subject: [PATCH 59/84] Make it work.. --- app/src/lib/stores/app-store.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 8c8ea53bf2..d19e9f5db4 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -1488,7 +1488,7 @@ export class AppStore extends TypedBaseStore { onLoad: (mergeTreeResult: MergeTreeResult | null) => void, cleanup: () => void ) { - const mergeTreePromise = promiseWithMinimumTimeout( + return promiseWithMinimumTimeout( () => determineMergeability(repository, baseBranch, compareBranch), 500 ) @@ -1500,19 +1500,11 @@ export class AppStore extends TypedBaseStore { return null }) .then(mergeStatus => { - this.repositoryStateCache.updateCompareState(repository, () => ({ - mergeStatus, - })) - - this.emitUpdate() + onLoad(mergeStatus) }) .finally(() => { - this.currentMergeTreePromise = null + cleanup() }) - - this.currentMergeTreePromise = mergeTreePromise - - return this.currentMergeTreePromise } /** This shouldn't be called directly. See `Dispatcher`. */ From 099c0b1bcf771e987b373acb42d26113fbe9cc2c Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:37:49 -0400 Subject: [PATCH 60/84] No need to check merge status if no changes --- app/src/lib/stores/app-store.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index d19e9f5db4..9a13667b9b 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7308,14 +7308,19 @@ export class AppStore extends TypedBaseStore { file: null, diff: null, }, - mergeStatus: { - kind: ComputedAction.Loading, - }, + mergeStatus: + commitSHAs.length > 0 + ? { + kind: ComputedAction.Loading, + } + : null, }) this.emitUpdate() - this.setupPRMergeTreePromise(repository, baseBranch, currentBranch) + if (commitSHAs.length > 0) { + this.setupPRMergeTreePromise(repository, baseBranch, currentBranch) + } if (changesetData.files.length > 0) { await this._changePullRequestFileSelection( From 1c7623648e647218f02f2000402ff08c5e4b9f19 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:38:20 -0400 Subject: [PATCH 61/84] Add messages for each merge status kind Copying dotcom verbiage --- .../pull-request-merge-status.tsx | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/app/src/ui/open-pull-request/pull-request-merge-status.tsx b/app/src/ui/open-pull-request/pull-request-merge-status.tsx index 9662ddf653..41f4ab8b90 100644 --- a/app/src/ui/open-pull-request/pull-request-merge-status.tsx +++ b/app/src/ui/open-pull-request/pull-request-merge-status.tsx @@ -1,5 +1,9 @@ import * as React from 'react' +import { assertNever } from '../../lib/fatal-error' +import { ComputedAction } from '../../models/computed-action' import { MergeTreeResult } from '../../models/merge' +import { Octicon } from '../octicons' +import * as OcticonSymbol from '../octicons/octicons.generated' interface IPullRequestMergeStatusProps { /** The result of merging the pull request branch into the base branch */ @@ -9,7 +13,56 @@ interface IPullRequestMergeStatusProps { /** The component to display message about the result of merging the pull * request. */ export class PullRequestMergeStatus extends React.Component { + private getMergeStatusDescription = () => { + const { mergeStatus } = this.props + if (mergeStatus === null) { + return '' + } + + const { kind } = mergeStatus + switch (kind) { + case ComputedAction.Loading: + return ( + + Checking mergeability… Don’t worry, you can + still create the pull request. + + ) + case ComputedAction.Invalid: + return ( + + Error checking merge status. Don’t worry, you can + still create the pull request. + + ) + case ComputedAction.Clean: + return ( + + + Able to merge. + {' '} + These branches can be automatically merged. + + ) + case ComputedAction.Conflicts: + return ( + + + Can't automatically merge. + {' '} + Don’t worry, you can still create the pull request. + + ) + default: + return assertNever(kind, `Unknown merge status kind of ${kind}.`) + } + } + public render() { - return
Merge Status
+ return ( +
+ {this.getMergeStatusDescription()} +
+ ) } } From fca7928f7324c5db5ff2c61e63fd9fa877d28d96 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:02:28 -0400 Subject: [PATCH 62/84] Style the messages --- app/styles/_ui.scss | 1 + app/styles/ui/_pull-request-merge-status.scss | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 app/styles/ui/_pull-request-merge-status.scss diff --git a/app/styles/_ui.scss b/app/styles/_ui.scss index 53c78ec973..1122e15c7d 100644 --- a/app/styles/_ui.scss +++ b/app/styles/_ui.scss @@ -102,3 +102,4 @@ @import 'ui/_branch-select'; @import 'ui/_popover-dropdown'; @import 'ui/_pull-request-files-changed'; +@import 'ui/_pull-request-merge-status'; diff --git a/app/styles/ui/_pull-request-merge-status.scss b/app/styles/ui/_pull-request-merge-status.scss new file mode 100644 index 0000000000..09cb1edb1c --- /dev/null +++ b/app/styles/ui/_pull-request-merge-status.scss @@ -0,0 +1,31 @@ +.pull-request-merge-status { + flex-grow: 1; + color: var(--text-secondary-color); + + .octicon { + vertical-align: text-bottom; + } + + strong { + font-weight: var(--font-weight-semibold); + } + + .pr-merge-status-loading { + strong { + color: var(--warning-badge-icon-color); + } + } + + .pr-merge-status-invalid, + .pr-merge-status-conflicts { + strong { + color: var(--status-error-color); + } + } + + .pr-merge-status-clean { + strong { + color: var(--status-success-color); + } + } +} From c4e751f6e17da3daac02fee63439ed1095b9bbcd Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:13:26 -0400 Subject: [PATCH 63/84] Reuse new method for existing logic --- app/src/lib/stores/app-store.ts | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 9a13667b9b..2fdf777074 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -1442,34 +1442,21 @@ export class AppStore extends TypedBaseStore { } if (tip.kind === TipState.Valid && aheadBehind.behind > 0) { - const mergeTreePromise = promiseWithMinimumTimeout( - () => determineMergeability(repository, tip.branch, action.branch), - 500 - ) - .catch(err => { - log.warn( - `Error occurred while trying to merge ${tip.branch.name} (${tip.branch.tip.sha}) and ${action.branch.name} (${action.branch.tip.sha})`, - err - ) - return null - }) - .then(mergeStatus => { + this.currentMergeTreePromise = this.setupMergabilityPromise( + repository, + tip.branch, + action.branch, + mergeStatus => { this.repositoryStateCache.updateCompareState(repository, () => ({ mergeStatus, })) this.emitUpdate() - }) - - const cleanup = () => { - this.currentMergeTreePromise = null - } - - // TODO: when we have Promise.prototype.finally available we - // should use that here to make this intent clearer - mergeTreePromise.then(cleanup, cleanup) - - this.currentMergeTreePromise = mergeTreePromise + }, + () => { + this.currentMergeTreePromise = null + } + ) return this.currentMergeTreePromise } else { From 5a3056fc720e5e5d3391589a4e4460a998deee21 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:18:22 -0400 Subject: [PATCH 64/84] Remove copied stuff non applicable to my use case --- app/src/lib/stores/app-store.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 2fdf777074..66a52a425d 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -473,7 +473,6 @@ export class AppStore extends TypedBaseStore { private repositoryFilterText: string = '' private currentMergeTreePromise: Promise | null = null - private currentPRMergeTreePromise: Promise | null = null /** The function to resolve the current Open in Desktop flow. */ private resolveOpenInDesktop: @@ -1473,7 +1472,7 @@ export class AppStore extends TypedBaseStore { baseBranch: Branch, compareBranch: Branch, onLoad: (mergeTreeResult: MergeTreeResult | null) => void, - cleanup: () => void + cleanup?: () => void ) { return promiseWithMinimumTimeout( () => determineMergeability(repository, baseBranch, compareBranch), @@ -1490,7 +1489,7 @@ export class AppStore extends TypedBaseStore { onLoad(mergeStatus) }) .finally(() => { - cleanup() + cleanup?.() }) } @@ -7456,12 +7455,7 @@ export class AppStore extends TypedBaseStore { baseBranch: Branch, compareBranch: Branch ) { - // Not sure why we do this..following pattern from compare branch setup - if (this.currentPRMergeTreePromise != null) { - return - } - - this.currentPRMergeTreePromise = this.setupMergabilityPromise( + this.setupMergabilityPromise( repository, baseBranch, compareBranch, @@ -7470,9 +7464,6 @@ export class AppStore extends TypedBaseStore { mergeStatus, })) this.emitUpdate() - }, - () => { - this.currentPRMergeTreePromise = null } ) } From d8bc8464f9521d7ae5726a4daf5590a9f6c2c1b9 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:25:25 -0400 Subject: [PATCH 65/84] More legible warning color --- app/styles/ui/_pull-request-merge-status.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/ui/_pull-request-merge-status.scss b/app/styles/ui/_pull-request-merge-status.scss index 09cb1edb1c..f9d3377ae6 100644 --- a/app/styles/ui/_pull-request-merge-status.scss +++ b/app/styles/ui/_pull-request-merge-status.scss @@ -12,7 +12,7 @@ .pr-merge-status-loading { strong { - color: var(--warning-badge-icon-color); + color: var(--file-warning-color); } } From 596aa1a991bc3cc73624c75559ec49480aa0c9a2 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 08:31:56 -0400 Subject: [PATCH 66/84] Use a promise like your supposed to.. --- app/src/lib/stores/app-store.ts | 42 ++++++++++++--------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 66a52a425d..8e6a9cf361 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -1444,18 +1444,18 @@ export class AppStore extends TypedBaseStore { this.currentMergeTreePromise = this.setupMergabilityPromise( repository, tip.branch, - action.branch, - mergeStatus => { + action.branch + ) + .then(mergeStatus => { this.repositoryStateCache.updateCompareState(repository, () => ({ mergeStatus, })) this.emitUpdate() - }, - () => { + }) + .finally(() => { this.currentMergeTreePromise = null - } - ) + }) return this.currentMergeTreePromise } else { @@ -1470,27 +1470,18 @@ export class AppStore extends TypedBaseStore { private setupMergabilityPromise( repository: Repository, baseBranch: Branch, - compareBranch: Branch, - onLoad: (mergeTreeResult: MergeTreeResult | null) => void, - cleanup?: () => void + compareBranch: Branch ) { return promiseWithMinimumTimeout( () => determineMergeability(repository, baseBranch, compareBranch), 500 - ) - .catch(err => { - log.warn( - `Error occurred while trying to merge ${baseBranch.name} (${baseBranch.tip.sha}) and ${compareBranch.name} (${compareBranch.tip.sha})`, - err - ) - return null - }) - .then(mergeStatus => { - onLoad(mergeStatus) - }) - .finally(() => { - cleanup?.() - }) + ).catch(err => { + log.warn( + `Error occurred while trying to merge ${baseBranch.name} (${baseBranch.tip.sha}) and ${compareBranch.name} (${compareBranch.tip.sha})`, + err + ) + return null + }) } /** This shouldn't be called directly. See `Dispatcher`. */ @@ -7455,10 +7446,7 @@ export class AppStore extends TypedBaseStore { baseBranch: Branch, compareBranch: Branch ) { - this.setupMergabilityPromise( - repository, - baseBranch, - compareBranch, + this.setupMergabilityPromise(repository, baseBranch, compareBranch).then( (mergeStatus: MergeTreeResult | null) => { this.repositoryStateCache.updatePullRequestState(repository, () => ({ mergeStatus, From 6a4a279c7d6d36ca22d7c01d708f5a797d96cf04 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:03:15 -0400 Subject: [PATCH 67/84] Handle no merge base --- app/src/lib/git/diff.ts | 20 ++++++++++++-------- app/src/lib/stores/app-store.ts | 4 ++-- app/test/unit/git/diff-test.ts | 29 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/app/src/lib/git/diff.ts b/app/src/lib/git/diff.ts index 8878a0af03..0f7f0fcb4d 100644 --- a/app/src/lib/git/diff.ts +++ b/app/src/lib/git/diff.ts @@ -254,7 +254,7 @@ export async function getBranchMergeBaseChangedFiles( baseBranchName: string, comparisonBranchName: string, latestComparisonBranchCommitRef: string -): Promise { +): Promise { const baseArgs = [ 'diff', '--merge-base', @@ -268,22 +268,26 @@ export async function getBranchMergeBaseChangedFiles( '--', ] - const result = await git( - baseArgs, - repository.path, - 'getBranchMergeBaseChangedFiles' - ) - const mergeBaseCommit = await getMergeBase( repository, baseBranchName, comparisonBranchName ) + if (mergeBaseCommit === null) { + return null + } + + const result = await git( + baseArgs, + repository.path, + 'getBranchMergeBaseChangedFiles' + ) + return parseRawLogWithNumstat( result.combinedOutput, `${latestComparisonBranchCommitRef}`, - mergeBaseCommit ?? NullTreeSHA + mergeBaseCommit ) } diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 8e6a9cf361..04888116ef 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7281,7 +7281,7 @@ export class AppStore extends TypedBaseStore { shas: commitSHAs, shasInDiff: commitSHAs, isContiguous: true, - changesetData, + changesetData: changesetData !== null ? changesetData : emptyChangeSet, file: null, diff: null, }, @@ -7299,7 +7299,7 @@ export class AppStore extends TypedBaseStore { this.setupPRMergeTreePromise(repository, baseBranch, currentBranch) } - if (changesetData.files.length > 0) { + if (changesetData !== null && changesetData.files.length > 0) { await this._changePullRequestFileSelection( repository, changesetData.files[0] diff --git a/app/test/unit/git/diff-test.ts b/app/test/unit/git/diff-test.ts index 4ba2f5d8fd..8e1a2f198d 100644 --- a/app/test/unit/git/diff-test.ts +++ b/app/test/unit/git/diff-test.ts @@ -575,9 +575,38 @@ describe('git/diff', () => { 'feature-branch', 'irrelevantToTest' ) + + expect(changesetData).not.toBeNull() + if (changesetData === null) { + return + } + expect(changesetData.files).toHaveLength(1) expect(changesetData.files[0].path).toBe('feature.md') }) + + it('returns null for unrelated histories', async () => { + // create a second branch that's orphaned from our current branch + await GitProcess.exec( + ['checkout', '--orphan', 'orphaned-branch'], + repository.path + ) + + // add a commit to this new branch + await GitProcess.exec( + ['commit', '--allow-empty', '-m', `first commit on gh-pages`], + repository.path + ) + + const changesetData = await getBranchMergeBaseChangedFiles( + repository, + 'master', + 'feature-branch', + 'irrelevantToTest' + ) + + expect(changesetData).toBeNull() + }) }) describe('getBranchMergeBaseDiff', () => { From fbd5def4a345057e0c3a454d8b2978c2750a7823 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:05:08 -0400 Subject: [PATCH 68/84] Update invalid to represent unrelated histories --- app/src/ui/open-pull-request/pull-request-merge-status.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/ui/open-pull-request/pull-request-merge-status.tsx b/app/src/ui/open-pull-request/pull-request-merge-status.tsx index 41f4ab8b90..beebe4ddfe 100644 --- a/app/src/ui/open-pull-request/pull-request-merge-status.tsx +++ b/app/src/ui/open-pull-request/pull-request-merge-status.tsx @@ -31,8 +31,8 @@ export class PullRequestMergeStatus extends React.Component - Error checking merge status. Don’t worry, you can - still create the pull request. + Error checking merge status. Unable to merge + unrelated histories in this repository ) case ComputedAction.Clean: From 7d1ecec457cf1ed06bcd2ae17da8e5950705f05e Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:21:08 -0400 Subject: [PATCH 69/84] Don't bother with mergeability check if no mergebase --- app/src/lib/stores/app-store.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 04888116ef..afed3ee5c9 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -7254,18 +7254,18 @@ export class AppStore extends TypedBaseStore { currentBranch ) - const commitSHAs = pullRequestCommits.map(c => c.sha) + const commitsBetweenBranches = pullRequestCommits.map(c => c.sha) // A user may compare two branches with no changes between them. const emptyChangeSet = { files: [], linesAdded: 0, linesDeleted: 0 } const changesetData = - commitSHAs.length > 0 + commitsBetweenBranches.length > 0 ? await gitStore.performFailableOperation(() => getBranchMergeBaseChangedFiles( repository, baseBranch.name, currentBranch.name, - commitSHAs[0] + commitsBetweenBranches[0] ) ) : emptyChangeSet @@ -7274,6 +7274,11 @@ export class AppStore extends TypedBaseStore { return } + const hasMergeBase = changesetData !== null + // We don't care how many commits exist on the unrelated history that + // can't be merged. + const commitSHAs = hasMergeBase ? commitsBetweenBranches : [] + this.repositoryStateCache.initializePullRequestState(repository, { baseBranch, commitSHAs, @@ -7281,14 +7286,16 @@ export class AppStore extends TypedBaseStore { shas: commitSHAs, shasInDiff: commitSHAs, isContiguous: true, - changesetData: changesetData !== null ? changesetData : emptyChangeSet, + changesetData: changesetData ?? emptyChangeSet, file: null, diff: null, }, mergeStatus: - commitSHAs.length > 0 + commitSHAs.length > 0 || !hasMergeBase ? { - kind: ComputedAction.Loading, + kind: hasMergeBase + ? ComputedAction.Loading + : ComputedAction.Invalid, } : null, }) From 55f4d561d5b56800127e182fb28e10dd749ddf30 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:21:23 -0400 Subject: [PATCH 70/84] Disable create pull request button for no changes --- app/src/ui/open-pull-request/open-pull-request-dialog.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 3e82257375..10f0c7856a 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -168,7 +168,7 @@ export class OpenPullRequestDialog extends React.Component
) From c2232a52c31153bc6870c4cec22e67a2aaa15e1c Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:26:56 -0400 Subject: [PATCH 71/84] Add message about unrelated commit histories to no changes view --- .../open-pull-request-dialog.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx index 10f0c7856a..4a470907dd 100644 --- a/app/src/ui/open-pull-request/open-pull-request-dialog.tsx +++ b/app/src/ui/open-pull-request/open-pull-request-dialog.tsx @@ -12,6 +12,7 @@ import * as OcticonSymbol from '../octicons/octicons.generated' import { OpenPullRequestDialogHeader } from './open-pull-request-header' import { PullRequestFilesChanged } from './pull-request-files-changed' import { PullRequestMergeStatus } from './pull-request-merge-status' +import { ComputedAction } from '../../models/computed-action' interface IOpenPullRequestDialogProps { readonly repository: Repository @@ -148,20 +149,30 @@ export class OpenPullRequestDialog extends React.Component + {baseBranch.name} is up to date with all commits from{' '} + {currentBranch.name}. + + ) : ( + <> + {baseBranch.name} and {currentBranch.name} are + entirely different commit histories. + + ) return (

There are no changes.

- {baseBranch.name} is up to date with all commits from{' '} - {currentBranch.name}. + {message}
) From 6eefbc96c95426fdf7d7cf156d8a90f25799c31f Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 10:56:42 -0400 Subject: [PATCH 72/84] Release 3.1.2-beta1 --- app/package.json | 2 +- app/src/lib/feature-flag.ts | 2 +- changelog.json | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 17b1c3d945..9273708c62 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,7 @@ "productName": "GitHub Desktop", "bundleID": "com.github.GitHubClient", "companyName": "GitHub, Inc.", - "version": "3.1.1", + "version": "3.1.2-beta1", "main": "./main.js", "repository": { "type": "git", diff --git a/app/src/lib/feature-flag.ts b/app/src/lib/feature-flag.ts index dccc1a383d..f411e68b1a 100644 --- a/app/src/lib/feature-flag.ts +++ b/app/src/lib/feature-flag.ts @@ -110,5 +110,5 @@ export function enableSubmoduleDiff(): boolean { /** Should we enable starting pull requests? */ export function enableStartingPullRequests(): boolean { - return enableDevelopmentFeatures() + return enableBetaFeatures() } diff --git a/changelog.json b/changelog.json index fd84fb588e..8333912851 100644 --- a/changelog.json +++ b/changelog.json @@ -1,5 +1,11 @@ { "releases": { + "3.1.2-beta1": [ + "[Added] You can preview the changes a pull request from your current branch would make - #11517", + "[Fixed] App correctly remembers undo commit prompt setting - #15408", + "[Improved] Added support zooming out for the 67%, 75%, 80% and 90% zoom levels - #15401. Thanks @sathvikrijo!", + "[Improved] Add option to disable discard stash confirmation - #15379. Thanks @tsvetilian-ty!" + ], "3.1.1": [ "[Fixed] App correctly remembers undo commit prompt setting - #15408" ], From bccec59c0849896978f578f7e95d5578e6bedb14 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 6 Oct 2022 10:58:28 -0400 Subject: [PATCH 73/84] Update changelog.json --- changelog.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.json b/changelog.json index 8333912851..4a57665760 100644 --- a/changelog.json +++ b/changelog.json @@ -3,7 +3,7 @@ "3.1.2-beta1": [ "[Added] You can preview the changes a pull request from your current branch would make - #11517", "[Fixed] App correctly remembers undo commit prompt setting - #15408", - "[Improved] Added support zooming out for the 67%, 75%, 80% and 90% zoom levels - #15401. Thanks @sathvikrijo!", + "[Improved] Added support for zooming out at the 67%, 75%, 80% and 90% zoom levels - #15401. Thanks @sathvikrijo!", "[Improved] Add option to disable discard stash confirmation - #15379. Thanks @tsvetilian-ty!" ], "3.1.1": [ From 397a12b5786b7fed522ede9103285605a76404c5 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Mon, 10 Oct 2022 10:40:23 +0200 Subject: [PATCH 74/84] Update changelog.json --- changelog.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.json b/changelog.json index 4a57665760..f53274b243 100644 --- a/changelog.json +++ b/changelog.json @@ -3,7 +3,7 @@ "3.1.2-beta1": [ "[Added] You can preview the changes a pull request from your current branch would make - #11517", "[Fixed] App correctly remembers undo commit prompt setting - #15408", - "[Improved] Added support for zooming out at the 67%, 75%, 80% and 90% zoom levels - #15401. Thanks @sathvikrijo!", + "[Improved] Add support for zooming out at the 67%, 75%, 80% and 90% zoom levels - #15401. Thanks @sathvikrijo!", "[Improved] Add option to disable discard stash confirmation - #15379. Thanks @tsvetilian-ty!" ], "3.1.1": [ From 4dbcf07b3817dd31fb6ef92a10aa3b1dc3b98d58 Mon Sep 17 00:00:00 2001 From: Niko-O Date: Mon, 10 Oct 2022 16:26:45 +0200 Subject: [PATCH 75/84] Add link to build instructions to README.md Those instructions are otherwise buried behind 2 links. That is, I first have to see the link to CONTRIBUTING.md, then find the tiny "Set Up Your Machine" section in there. In my case, I wasn't even going at it from the perspective of trying to contribute; I just wanted to build the program. So I had a very hard time finding this information. Adding this link here would make finding this infromation a lot easier. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 663a8dfedf..6a2a683452 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ resources relevant to the project. If you're looking for something to work on, check out the [help wanted](https://github.com/desktop/desktop/issues?q=is%3Aissue+is%3Aopen+label%3A%22help%20wanted%22) label. +## Building Desktop + +To get your development environment set up for building Desktop, see [setup.md](./docs/contributing/setup.md). + ## More Resources See [desktop.github.com](https://desktop.github.com) for more product-oriented From f3e32e8e59f85e0704a43730f84d957b5f6ed057 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 11 Oct 2022 18:21:18 +0200 Subject: [PATCH 76/84] Fix cmd/control + Enter shortcut while amending a commit --- app/src/ui/changes/commit-message.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/changes/commit-message.tsx b/app/src/ui/changes/commit-message.tsx index 24c3355a1c..e3a9c38899 100644 --- a/app/src/ui/changes/commit-message.tsx +++ b/app/src/ui/changes/commit-message.tsx @@ -351,7 +351,7 @@ export class CommitMessage extends React.Component< if ( isShortcutKey && event.key === 'Enter' && - this.canCommit() && + (this.canCommit() || this.canAmend()) && this.canExcecuteCommitShortcut() ) { this.createCommit() From 581567d64b2f847b33a0d22b55986fda72210a17 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 12 Oct 2022 10:45:56 +0200 Subject: [PATCH 77/84] Make sure Squirrel.Windows isn't affected by partially or completely disabled releases --- script/package.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/script/package.ts b/script/package.ts index 7f8566adb2..8cfd8f03c7 100644 --- a/script/package.ts +++ b/script/package.ts @@ -102,7 +102,11 @@ function packageWindows() { } if (shouldMakeDelta()) { - options.remoteReleases = getUpdatesURL() + const url = new URL(getUpdatesURL()) + // Make sure Squirrel.Windows isn't affected by partially or completely + // disabled releases. + url.searchParams.set('bypassStaggeredRelease', '1') + options.remoteReleases = url.toString() } if (isAppveyor() || isGitHubActions()) { From 8675ea638b54b95784067858e3cf2aa60823634d Mon Sep 17 00:00:00 2001 From: Angus Date: Sat, 15 Oct 2022 01:49:44 +0100 Subject: [PATCH 78/84] Fix avatar tooltip does not wrap properly in some cases --- app/styles/ui/window/_tooltips.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/styles/ui/window/_tooltips.scss b/app/styles/ui/window/_tooltips.scss index 97282eda85..27f84b7439 100644 --- a/app/styles/ui/window/_tooltips.scss +++ b/app/styles/ui/window/_tooltips.scss @@ -11,6 +11,7 @@ body > .tooltip, max-width: 300px; word-wrap: break-word; + word-break: break-word; overflow-wrap: break-word; background-color: var(--tooltip-background-color); From 56e965cb10142dbbe06e2f1e1914ba22493f3f99 Mon Sep 17 00:00:00 2001 From: Angus Date: Sat, 15 Oct 2022 20:35:02 +0100 Subject: [PATCH 79/84] Fix issue #13636 - Tooltip position is (0,0) if mouse is not moved The tooltip position is referenced to mouse position set in mousemove event. If the tooltip is triggered by events other than mousemove (e.g. scroll the list with mousewheel or keyboard arrow keys, or click the Fetch Origin button without moving the mouse), the mouse position is not set (0,0). The fix is to set the mouse position in mouseenter event as well --- app/src/ui/lib/tooltip.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/ui/lib/tooltip.tsx b/app/src/ui/lib/tooltip.tsx index 6e4b05abbf..5d47f02ae4 100644 --- a/app/src/ui/lib/tooltip.tsx +++ b/app/src/ui/lib/tooltip.tsx @@ -300,6 +300,8 @@ export class Tooltip extends React.Component< } private onTargetMouseEnter = (event: MouseEvent) => { + this.mouseRect = new DOMRect(event.clientX - 10, event.clientY - 10, 20, 20) + this.mouseOverTarget = true this.cancelHideTooltip() if (!this.state.show) { From 9ffb2041679feafd668f536ccaa4f745b4a70330 Mon Sep 17 00:00:00 2001 From: Angus Date: Sun, 16 Oct 2022 00:35:25 +0100 Subject: [PATCH 80/84] Issue 11953 Progress bar during cloning partially hidden Close the repository list when clone starts --- app/src/ui/clone-repository/clone-repository.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/ui/clone-repository/clone-repository.tsx b/app/src/ui/clone-repository/clone-repository.tsx index d89646a093..cfca9408fc 100644 --- a/app/src/ui/clone-repository/clone-repository.tsx +++ b/app/src/ui/clone-repository/clone-repository.tsx @@ -3,6 +3,7 @@ import * as React from 'react' import { Dispatcher } from '../dispatcher' import { getDefaultDir, setDefaultDir } from '../lib/default-dir' import { Account } from '../../models/account' +import { FoldoutType } from '../../lib/app-state' import { IRepositoryIdentifier, parseRepositoryIdentifier, @@ -728,6 +729,7 @@ export class CloneRepository extends React.Component< const { url, defaultBranch } = cloneInfo + this.props.dispatcher.closeFoldout(FoldoutType.Repository) try { this.cloneImpl(url.trim(), path, defaultBranch) } catch (e) { From 2c6cae8c1cace54eb1df91c71347718cdc8f3c34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 16:08:50 +0000 Subject: [PATCH 81/84] Bump peter-evans/create-pull-request from 4.1.3 to 4.1.4 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.3 to 4.1.4. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v4.1.3...v4.1.4) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/release-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index c6daccbcec..c9a249428b 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -37,7 +37,7 @@ jobs: private_key: ${{ secrets.DESKTOP_RELEASES_APP_PRIVATE_KEY }} - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v4.1.3 + uses: peter-evans/create-pull-request@v4.1.4 if: | startsWith(github.ref, 'refs/heads/releases/') && !contains(github.ref, 'test') with: From ab9f11909e89de8f6660bad270a172063d775ac9 Mon Sep 17 00:00:00 2001 From: Angus Date: Mon, 17 Oct 2022 17:14:27 +0100 Subject: [PATCH 82/84] Refactoring extract the code to set this.mouseRect to rememberMousePosition --- app/src/ui/lib/tooltip.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/ui/lib/tooltip.tsx b/app/src/ui/lib/tooltip.tsx index 5d47f02ae4..1f65055187 100644 --- a/app/src/ui/lib/tooltip.tsx +++ b/app/src/ui/lib/tooltip.tsx @@ -299,8 +299,12 @@ export class Tooltip extends React.Component< } } - private onTargetMouseEnter = (event: MouseEvent) => { + private rememberMousePosition = (event: MouseEvent) => { this.mouseRect = new DOMRect(event.clientX - 10, event.clientY - 10, 20, 20) + } + + private onTargetMouseEnter = (event: MouseEvent) => { + this.rememberMousePosition(event) this.mouseOverTarget = true this.cancelHideTooltip() @@ -310,7 +314,7 @@ export class Tooltip extends React.Component< } private onTargetMouseMove = (event: MouseEvent) => { - this.mouseRect = new DOMRect(event.clientX - 10, event.clientY - 10, 20, 20) + this.rememberMousePosition(event) } private onTargetMouseDown = (event: MouseEvent) => { From afc2fac6255217adad816972412c2198d3b32718 Mon Sep 17 00:00:00 2001 From: Angus Date: Mon, 17 Oct 2022 18:29:44 +0100 Subject: [PATCH 83/84] Fix menu items are disabled if close the rebase conflict dialog onDismissed didn't reset IAppState. currentPopup so the menu is disabled. Need to call closePopup in onInvokeConflictsDialogDismissed "Abort Rebase" works properly since it calls onFlowEnded() --- .../ui/multi-commit-operation/base-multi-commit-operation.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/ui/multi-commit-operation/base-multi-commit-operation.tsx b/app/src/ui/multi-commit-operation/base-multi-commit-operation.tsx index aed59470f6..e3266ea7fe 100644 --- a/app/src/ui/multi-commit-operation/base-multi-commit-operation.tsx +++ b/app/src/ui/multi-commit-operation/base-multi-commit-operation.tsx @@ -93,6 +93,8 @@ export abstract class BaseMultiCommitOperation extends React.Component{targetBranch.name} : null} ) + + this.props.dispatcher.closePopup(PopupType.MultiCommitOperation) return dispatcher.onConflictsFoundBanner( repository, operationDescription, From eddd8b9f5a579c3f969fb3b485cd9b1139ad1326 Mon Sep 17 00:00:00 2001 From: Angus Date: Tue, 18 Oct 2022 07:32:49 +0100 Subject: [PATCH 84/84] Update function name to updateMouseRect --- app/src/ui/lib/tooltip.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/ui/lib/tooltip.tsx b/app/src/ui/lib/tooltip.tsx index 1f65055187..a724608423 100644 --- a/app/src/ui/lib/tooltip.tsx +++ b/app/src/ui/lib/tooltip.tsx @@ -299,12 +299,12 @@ export class Tooltip extends React.Component< } } - private rememberMousePosition = (event: MouseEvent) => { + private updateMouseRect = (event: MouseEvent) => { this.mouseRect = new DOMRect(event.clientX - 10, event.clientY - 10, 20, 20) } private onTargetMouseEnter = (event: MouseEvent) => { - this.rememberMousePosition(event) + this.updateMouseRect(event) this.mouseOverTarget = true this.cancelHideTooltip() @@ -314,7 +314,7 @@ export class Tooltip extends React.Component< } private onTargetMouseMove = (event: MouseEvent) => { - this.rememberMousePosition(event) + this.updateMouseRect(event) } private onTargetMouseDown = (event: MouseEvent) => {