1
0
mirror of https://github.com/desktop/desktop synced 2024-06-30 22:54:41 +00:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Jorge Pedroso
67c25095df
Merge 9d7df2847a into d2c6ddb164 2024-06-27 11:39:38 +02:00
Markus Olsson
d2c6ddb164
Merge pull request #18887 from desktop/args-args-everywhere
Inline argument conditionals
2024-06-27 09:27:16 +02:00
Markus Olsson
95f263a23d Set --progress and --recurse-submodules inline when necessary 2024-06-24 13:44:30 +02:00
Markus Olsson
10c3d47706 Set --progress and --recurse-submodules inline when necessary 2024-06-24 13:44:13 +02:00
Markus Olsson
8d86091ae3 🎨 Easier to read this way IMO 2024-06-24 13:43:48 +02:00
Markus Olsson
d8873cb08d Add --recurse-submodules and --progress inline when necessary 2024-06-24 13:43:14 +02:00
Markus Olsson
a404a3f251 Add --progress inline when necesary 2024-06-24 13:40:51 +02:00
Jorge Pedroso
9d7df2847a
New ToolboxDropdown.foldoutStyleOverrides property
Introduce the new property to avoid changing behavior of the existing `foldoutStyle` property.

Whereas `foldoutStyle` replaces default style entirely, `foldoutStyleOverrides` is used to add to or override the default style properties.
2024-05-10 13:28:55 +03:00
Jorge Pedroso
d4f7558f54
Use foldoutStyle to control min and max width 2024-05-10 13:28:55 +03:00
Jorge Pedroso
66570530d8
Remove max width 65% for branch names
Branch names can expand to the available width in  `.branches-list-item`.
2024-05-10 09:33:28 +03:00
Jorge Pedroso
5f233d65d8
Documentation for Branch dropdown dispatchers 2024-05-10 09:33:28 +03:00
Jorge Pedroso
5e0b5cf1de
Add vertical spacing around branches and pr list empty states
With the empty states centered on the container, their imagery would get uncomfortably close to the top. This introduces some spacing on top and bottom to make layout more balanced.
2024-05-10 09:33:28 +03:00
Jorge Pedroso
9724c3131b
Set min width for the branches container
Prevents the branches dropdown container from becoming too narrow when branch names are not long enough.
2024-05-10 09:33:28 +03:00
Jorge Pedroso
b247c49a82
Center empty states in branches and pull requests container
When there are no branches or pull requests to show, the corresponding empty states are centered on the container with a fixed width of 365px.

For the branches empty state container, the fixed width replaces `flex: 1` to prevent it from filling the container and make the Create Branch button too wide.
2024-05-10 09:33:28 +03:00
Jorge Pedroso
cce104e7c5
Make push pull toolbar button resizable 2024-05-10 09:33:27 +03:00
Jorge Pedroso
32dbe77260
Rename vars related to push/pull button
More consistent with the `PushPullButton` type they relate to.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
e9360f8935
Fix typo in documentation 2024-05-10 09:33:27 +03:00
Jorge Pedroso
3ed52eb84e
Use a constant for the push/fetch button width
Replace the inline hardcoded value with a constant defined closer the other toolbar constants.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
4f87f44c53
Rename toolbarButtonsWidth to toolbarButtonsMinWidth
This local var needs to reflect that some of the toolbar buttons are now resizable, and what is represents the total min width of those buttons.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
da8d0cc358
Use branch dropdown's constrained value min and max in resizable
Instead of using a hardcoded max width of 600 and the default min width of 200, the branch dropdown resizable now uses the min and max that are provided with the constrained value.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
ac6a9a2c8c
Update the max width available for the branch dropdown
Set a new constrained value for the branch dropdown so it can only be as wide as the available space after taking the sidebar and pull fetch button widths.

The minimum size remains constant at its default width.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
20a3fdbd13
Avoid shrink on toolbar-dropdown-arrow-button
Prevents the dropdown arrow button from shrinking when the window or toolbar items are resized.
2024-05-10 09:33:27 +03:00
Jorge Pedroso
91d0fca84a
Make toolbar branch dropdown button resizable 2024-05-10 09:33:26 +03:00
14 changed files with 269 additions and 101 deletions

View File

@ -185,6 +185,12 @@ export interface IAppState {
/** The width of the files list in the pull request files changed view */
readonly pullRequestFilesListWidth: IConstrainedValue
/** The width of the resizable branch drop down button in the toolbar. */
readonly branchDropdownWidth: IConstrainedValue
/** The width of the resizable push/pull button in the toolbar. */
readonly pushPullButtonWidth: IConstrainedValue
/**
* Used to highlight access keys throughout the app when the
* Alt key is pressed. Only applicable on non-macOS platforms.

View File

@ -20,28 +20,22 @@ import { IRemote } from '../../models/remote'
export type ProgressCallback = (progress: ICheckoutProgress) => void
function getCheckoutArgs(progressCallback?: ProgressCallback) {
return progressCallback != null
? [...gitNetworkArguments(), 'checkout', '--progress']
: [...gitNetworkArguments(), 'checkout']
return [
...gitNetworkArguments(),
'checkout',
...(progressCallback ? ['--progress'] : []),
]
}
async function getBranchCheckoutArgs(branch: Branch) {
const baseArgs: ReadonlyArray<string> = []
if (enableRecurseSubmodulesFlag()) {
return branch.type === BranchType.Remote
? baseArgs.concat(
branch.name,
'-b',
branch.nameWithoutRemote,
'--recurse-submodules',
'--'
)
: baseArgs.concat(branch.name, '--recurse-submodules', '--')
}
return branch.type === BranchType.Remote
? baseArgs.concat(branch.name, '-b', branch.nameWithoutRemote, '--')
: baseArgs.concat(branch.name, '--')
return [
branch.name,
...(branch.type === BranchType.Remote
? ['-b', branch.nameWithoutRemote]
: []),
...(enableRecurseSubmodulesFlag() ? ['--recurse-submodules'] : []),
'--',
]
}
async function getCheckoutOpts(

View File

@ -485,8 +485,7 @@ export function gitRebaseArguments() {
// uses the merge backend even if the user has the apply backend
// configured, since this is the only one supported.
// This can go away once git deprecates the apply backend.
'-c',
'rebase.backend=merge',
...['-c', 'rebase.backend=merge'],
]
}

View File

@ -11,28 +11,16 @@ async function getFetchArgs(
remote: string,
progressCallback?: (progress: IFetchProgress) => void
) {
if (enableRecurseSubmodulesFlag()) {
return progressCallback != null
? [
...gitNetworkArguments(),
'fetch',
'--progress',
'--prune',
'--recurse-submodules=on-demand',
remote,
]
: [
...gitNetworkArguments(),
'fetch',
'--prune',
'--recurse-submodules=on-demand',
remote,
]
} else {
return progressCallback != null
? [...gitNetworkArguments(), 'fetch', '--progress', '--prune', remote]
: [...gitNetworkArguments(), 'fetch', '--prune', remote]
}
return [
...gitNetworkArguments(),
'fetch',
...(progressCallback ? ['--progress'] : []),
'--prune',
...(enableRecurseSubmodulesFlag()
? ['--recurse-submodules=on-demand']
: []),
remote,
]
}
/**

View File

@ -19,28 +19,15 @@ async function getPullArgs(
remote: string,
progressCallback?: (progress: IPullProgress) => void
) {
const divergentPathArgs = await getDefaultPullDivergentBranchArguments(
repository
)
const args = [
return [
...gitNetworkArguments(),
...gitRebaseArguments(),
'pull',
...divergentPathArgs,
...(await getDefaultPullDivergentBranchArguments(repository)),
...(enableRecurseSubmodulesFlag() ? ['--recurse-submodules'] : []),
...(progressCallback ? ['--progress'] : []),
remote,
]
if (enableRecurseSubmodulesFlag()) {
args.push('--recurse-submodules')
}
if (progressCallback != null) {
args.push('--progress')
}
args.push(remote)
return args
}
/**

View File

@ -360,6 +360,12 @@ const stashedFilesWidthConfigKey: string = 'stashed-files-width'
const defaultPullRequestFileListWidth: number = 250
const pullRequestFileListConfigKey: string = 'pull-request-files-width'
const defaultBranchDropdownWidth: number = 230
const branchDropdownWidthConfigKey: string = 'branch-dropdown-width'
const defaultPushPullButtonWidth: number = 230
const pushPullButtonWidthConfigKey: string = 'push-pull-button-width'
const askToMoveToApplicationsFolderDefault: boolean = true
const confirmRepoRemovalDefault: boolean = true
const showCommitLengthWarningDefault: boolean = false
@ -480,6 +486,8 @@ export class AppStore extends TypedBaseStore<IAppState> {
private commitSummaryWidth = constrain(defaultCommitSummaryWidth)
private stashedFilesWidth = constrain(defaultStashedFilesWidth)
private pullRequestFileListWidth = constrain(defaultPullRequestFileListWidth)
private branchDropdownWidth = constrain(defaultBranchDropdownWidth)
private pushPullButtonWidth = constrain(defaultPushPullButtonWidth)
private windowState: WindowState | null = null
private windowZoomFactor: number = 1
@ -1000,6 +1008,8 @@ export class AppStore extends TypedBaseStore<IAppState> {
focusCommitMessage: this.focusCommitMessage,
emoji: this.emoji,
sidebarWidth: this.sidebarWidth,
branchDropdownWidth: this.branchDropdownWidth,
pushPullButtonWidth: this.pushPullButtonWidth,
commitSummaryWidth: this.commitSummaryWidth,
stashedFilesWidth: this.stashedFilesWidth,
pullRequestFilesListWidth: this.pullRequestFileListWidth,
@ -2120,6 +2130,12 @@ export class AppStore extends TypedBaseStore<IAppState> {
this.pullRequestFileListWidth = constrain(
getNumber(pullRequestFileListConfigKey, defaultPullRequestFileListWidth)
)
this.branchDropdownWidth = constrain(
getNumber(branchDropdownWidthConfigKey, defaultBranchDropdownWidth)
)
this.pushPullButtonWidth = constrain(
getNumber(pushPullButtonWidthConfigKey, defaultPushPullButtonWidth)
)
this.updateResizableConstraints()
// TODO: Initiliaze here for now... maybe move to dialog mounting
@ -2257,11 +2273,12 @@ export class AppStore extends TypedBaseStore<IAppState> {
* dimensions change.
*/
private updateResizableConstraints() {
// The combined width of the branch dropdown and the push pull fetch button
// The combined width of the branch dropdown and the push/pull/fetch button
// Since the repository list toolbar button width is tied to the width of
// the sidebar we can't let it push the branch, and push/pull/fetch buttons
// the sidebar we can't let it push the branch, and push/pull/fetch button
// off screen.
const toolbarButtonsWidth = 460
const toolbarButtonsMinWidth =
defaultPushPullButtonWidth + defaultBranchDropdownWidth
// Start with all the available width
let available = window.innerWidth
@ -2272,7 +2289,7 @@ export class AppStore extends TypedBaseStore<IAppState> {
// 220 was determined as the minimum value since it is the smallest width
// that will still fit the placeholder text in the branch selector textbox
// of the history tab
const maxSidebarWidth = available - toolbarButtonsWidth
const maxSidebarWidth = available - toolbarButtonsMinWidth
this.sidebarWidth = constrain(this.sidebarWidth, 220, maxSidebarWidth)
// Now calculate the width we have left to distribute for the other panes
@ -2288,6 +2305,23 @@ export class AppStore extends TypedBaseStore<IAppState> {
this.commitSummaryWidth = constrain(this.commitSummaryWidth, 100, filesMax)
this.stashedFilesWidth = constrain(this.stashedFilesWidth, 100, filesMax)
// Update the maximum width available for the branch dropdown resizable.
// The branch dropdown can only be as wide as the available space
// after taking the sidebar and pull/push/fetch button widths.
const branchDropdownMax = available - defaultPushPullButtonWidth
this.branchDropdownWidth = constrain(
this.branchDropdownWidth,
defaultBranchDropdownWidth,
branchDropdownMax
)
const pushPullButtonMaxWidth = available - this.branchDropdownWidth.value
this.pushPullButtonWidth = constrain(
this.pushPullButtonWidth,
defaultPushPullButtonWidth,
pushPullButtonMaxWidth
)
}
/**
@ -5153,6 +5187,48 @@ export class AppStore extends TypedBaseStore<IAppState> {
return Promise.resolve()
}
public _setBranchDropdownWidth(width: number): Promise<void> {
this.branchDropdownWidth = { ...this.branchDropdownWidth, value: width }
setNumber(branchDropdownWidthConfigKey, width)
this.updateResizableConstraints()
this.emitUpdate()
return Promise.resolve()
}
public _resetBranchDropdownWidth(): Promise<void> {
this.branchDropdownWidth = {
...this.branchDropdownWidth,
value: defaultBranchDropdownWidth,
}
localStorage.removeItem(branchDropdownWidthConfigKey)
this.updateResizableConstraints()
this.emitUpdate()
return Promise.resolve()
}
public _setPushPullButtonWidth(width: number): Promise<void> {
this.pushPullButtonWidth = { ...this.pushPullButtonWidth, value: width }
setNumber(pushPullButtonWidthConfigKey, width)
this.updateResizableConstraints()
this.emitUpdate()
return Promise.resolve()
}
public _resetPushPullButtonWidth(): Promise<void> {
this.pushPullButtonWidth = {
...this.pushPullButtonWidth,
value: defaultPushPullButtonWidth,
}
localStorage.removeItem(pushPullButtonWidthConfigKey)
this.updateResizableConstraints()
this.emitUpdate()
return Promise.resolve()
}
public _setCommitSummaryWidth(width: number): Promise<void> {
this.commitSummaryWidth = { ...this.commitSummaryWidth, value: width }
setNumber(commitSummaryWidthConfigKey, width)

View File

@ -3113,6 +3113,7 @@ export class App extends React.Component<IAppProps, IAppState> {
askForConfirmationOnForcePush={this.state.askForConfirmationOnForcePush}
onDropdownStateChanged={this.onPushPullDropdownStateChanged}
enableFocusTrap={enableFocusTrap}
pushPullButtonWidth={this.state.pushPullButtonWidth}
/>
)
}
@ -3216,6 +3217,7 @@ export class App extends React.Component<IAppProps, IAppState> {
<BranchDropdown
dispatcher={this.props.dispatcher}
isOpen={isOpen}
branchDropdownWidth={this.state.branchDropdownWidth}
onDropDownStateChanged={this.onBranchDropdownStateChanged}
repository={repository}
repositoryState={selection.state}

View File

@ -950,6 +950,41 @@ export class Dispatcher {
return this.appStore._setSidebarWidth(width)
}
/**
* Set the width of the Branch toolbar button to the given value.
* This affects the toolbar button and its dropdown element.
*
* @param width The value for the width of Branch button
*/
public setBranchDropdownWidth(width: number): Promise<void> {
return this.appStore._setBranchDropdownWidth(width)
}
/**
* Reset the width of the Branch toolbar button to its default value.
*/
public resetBranchDropdownWidth(): Promise<void> {
return this.appStore._resetBranchDropdownWidth()
}
/**
* Set the width of the Push/Push toolbar button to the given value.
* This affects the toolbar button and its dropdown element.
*
* @param width The value for the width of Push/Pull button
*/
public setPushPullButtonWidth(width: number): Promise<void> {
return this.appStore._setPushPullButtonWidth(width)
}
/**
* Reset the width of the Push/Pull toolbar button to its default
* value.
*/
public resetPushPullButtonWidth(): Promise<void> {
return this.appStore._resetPushPullButtonWidth()
}
/**
* Set the update banner's visibility
*/

View File

@ -3,10 +3,12 @@ import { Dispatcher } from '../dispatcher'
import * as octicons from '../octicons/octicons.generated'
import { OcticonSymbol, syncClockwise } from '../octicons'
import { Repository } from '../../models/repository'
import { Resizable } from '../resizable'
import { TipState } from '../../models/tip'
import { ToolbarDropdown, DropdownState } from './dropdown'
import {
FoldoutType,
IConstrainedValue,
IRepositoryState,
isRebaseConflictState,
} from '../../lib/app-state'
@ -33,6 +35,9 @@ interface IBranchDropdownProps {
/** The current repository state as derived from AppState */
readonly repositoryState: IRepositoryState
/** The width of the resizable branch dropdown button, as derived from AppState. */
readonly branchDropdownWidth: IConstrainedValue
/** Whether or not the branch dropdown is currently open */
readonly isOpen: boolean
@ -188,35 +193,61 @@ export class BranchDropdown extends React.Component<IBranchDropdownProps> {
'nudge-arrow-up': this.props.shouldNudge,
})
// Properties to override the default foldout style for the branch dropdown.
// The min width of the foldout is different from `branchDropdownWidth.min`
// because the branches list foldout min width we want set to 365px instead.
const foldoutStyleOverrides: React.CSSProperties = {
width: this.props.branchDropdownWidth.value,
maxWidth: this.props.branchDropdownWidth.max,
minWidth: 365,
}
return (
<>
<ToolbarDropdown
className="branch-button"
icon={icon}
iconClassName={iconClassName}
title={title}
description={description}
onContextMenu={this.onBranchToolbarButtonContextMenu}
tooltip={isOpen ? undefined : tooltip}
onDropdownStateChanged={this.onDropDownStateChanged}
dropdownContentRenderer={this.renderBranchFoldout}
dropdownState={currentState}
disabled={disabled}
showDisclosureArrow={canOpen}
progressValue={progressValue}
buttonClassName={buttonClassName}
onMouseEnter={this.onMouseEnter}
onlyShowTooltipWhenOverflowed={true}
isOverflowed={isDescriptionOverflowed}
enableFocusTrap={enableFocusTrap}
<Resizable
width={this.props.branchDropdownWidth.value}
onReset={this.onReset}
onResize={this.onResize}
maximumWidth={this.props.branchDropdownWidth.max}
minimumWidth={this.props.branchDropdownWidth.min}
>
{this.renderPullRequestInfo()}
</ToolbarDropdown>
{this.props.showCIStatusPopover && this.renderPopover()}
<ToolbarDropdown
className="branch-button"
icon={icon}
iconClassName={iconClassName}
title={title}
description={description}
foldoutStyleOverrides={foldoutStyleOverrides}
onContextMenu={this.onBranchToolbarButtonContextMenu}
tooltip={isOpen ? undefined : tooltip}
onDropdownStateChanged={this.onDropDownStateChanged}
dropdownContentRenderer={this.renderBranchFoldout}
dropdownState={currentState}
disabled={disabled}
showDisclosureArrow={canOpen}
progressValue={progressValue}
buttonClassName={buttonClassName}
onMouseEnter={this.onMouseEnter}
onlyShowTooltipWhenOverflowed={true}
isOverflowed={isDescriptionOverflowed}
enableFocusTrap={enableFocusTrap}
>
{this.renderPullRequestInfo()}
</ToolbarDropdown>
{this.props.showCIStatusPopover && this.renderPopover()}
</Resizable>
</>
)
}
private onResize = (width: number) => {
this.props.dispatcher.setBranchDropdownWidth(width)
}
private onReset = () => {
this.props.dispatcher.resetBranchDropdownWidth()
}
/**
* Method to capture when the mouse is over the branch dropdown button.
*

View File

@ -124,11 +124,24 @@ export interface IToolbarDropdownProps {
readonly enableFocusTrap?: boolean
/**
* Sets the styles for the dropdown's foldout. Useful for custom positioning
* and sizes.
* Sets the styles for the dropdown's foldout, replacing the defaults.
* Useful for custom positioning and sizes.
*
* Note: If this property is set, the default positioning, size, and
* `foldoutStyleOverrides` property are all ignored.
*/
readonly foldoutStyle?: React.CSSProperties
/**
* Sets additional styles that add to or override the default foldout style.
*
* Use as an alternative to `foldoutStyle`, when only certain properties need
* to be customized and the default style and placement should still apply.
*
* Note: If `foldoutStyle` is set, this property is ignored.
*/
readonly foldoutStyleOverrides?: React.CSSProperties
/**
* Whether the button should displays its disclosure arrow. Defaults to true.
*/
@ -352,7 +365,7 @@ export class ToolbarDropdown extends React.Component<
}
return {
position: 'absolute',
position: 'fixed',
top: rect.bottom,
left: 0,
width: '100%',
@ -361,6 +374,7 @@ export class ToolbarDropdown extends React.Component<
}
private getFoldoutStyle(): React.CSSProperties | undefined {
// if `foldoutStyle` is set, ignore default style and `foldoutStyleOverrides`
if (this.props.foldoutStyle) {
return this.props.foldoutStyle
}
@ -375,11 +389,15 @@ export class ToolbarDropdown extends React.Component<
? { maxHeight: '100%', width: rect.width }
: { height: '100%', minWidth: rect.width }
const overrides: React.CSSProperties =
this.props.foldoutStyleOverrides ?? {}
return {
position: 'absolute',
marginLeft: rect.left,
top: 0,
...heightStyle,
...overrides,
}
}

View File

@ -5,6 +5,7 @@ import { Repository } from '../../models/repository'
import { IAheadBehind } from '../../models/branch'
import { TipState } from '../../models/tip'
import { FetchType } from '../../models/fetch'
import { Resizable } from '../resizable'
import { Dispatcher } from '../dispatcher'
import {
@ -24,7 +25,7 @@ import {
ToolbarDropdown,
ToolbarDropdownStyle,
} from './dropdown'
import { FoldoutType } from '../../lib/app-state'
import { FoldoutType, IConstrainedValue } from '../../lib/app-state'
import { ForcePushBranchState } from '../../lib/rebase'
import { PushPullButtonDropDown } from './push-pull-button-dropdown'
import { AriaLiveContainer } from '../accessibility/aria-live-container'
@ -95,6 +96,9 @@ interface IPushPullButtonProps {
*/
readonly enableFocusTrap: boolean
/** The width of the resizable push/pull button, as derived from AppState. */
readonly pushPullButtonWidth: IConstrainedValue
/**
* An event handler for when the drop down is opened, or closed, by a pointer
* event or by pressing the space or enter key while focused.
@ -359,6 +363,24 @@ export class PushPullButton extends React.Component<
)
}
/**
* Handler called when the width of the push/pull button has changed
* through an explicit resize event to the given width.
*
* @param width The new width of resizable button.
*/
private onResize = (width: number) => {
this.props.dispatcher.setPushPullButtonWidth(width)
}
/**
* Handler called when the resizable push/pull button has been
* asked to restore its original width.
*/
private onReset = () => {
this.props.dispatcher.resetPushPullButtonWidth()
}
private getDropdownContentRenderer(
itemTypes: ReadonlyArray<DropdownItemType>
) {
@ -380,10 +402,18 @@ export class PushPullButton extends React.Component<
public render() {
return (
<>
{this.renderButton()}
<span id="push-pull-button-state">
<AriaLiveContainer message={this.state.screenReaderStateMessage} />
</span>
<Resizable
width={this.props.pushPullButtonWidth.value}
onReset={this.onReset}
onResize={this.onResize}
maximumWidth={this.props.pushPullButtonWidth.max}
minimumWidth={this.props.pushPullButtonWidth.min}
>
{this.renderButton()}
<span id="push-pull-button-state">
<AriaLiveContainer message={this.state.screenReaderStateMessage} />
</span>
</Resizable>
</>
)
}

View File

@ -4,14 +4,14 @@
height: 100%;
display: flex;
flex-direction: column;
width: 365px;
width: 100%;
& > .tab-bar {
border-top: var(--base-border);
}
.branches-list {
width: 365px;
width: 100%;
min-height: 0;
}
@ -173,7 +173,6 @@
.name {
flex-grow: 2;
@include ellipsis;
max-width: 65%;
margin-right: var(--spacing-half);
/* Used to highlight substring matches in filtered lists */
@ -198,6 +197,7 @@
.no-pull-requests {
width: 365px;
margin: var(--spacing) auto;
display: flex;
flex-direction: column;

View File

@ -1,6 +1,7 @@
.no-branches {
width: 365px;
margin: var(--spacing) auto;
display: flex;
flex: 1;
flex-direction: column;
align-items: center;
text-align: center;

View File

@ -33,19 +33,20 @@
.toolbar-button {
&.push-pull-button {
width: 230px;
width: 100%;
}
}
.toolbar-button {
&.branch-toolbar-button {
width: 230px;
width: 100%;
}
&.revert-progress {
width: 230px;
}
&.toolbar-dropdown-arrow-button {
width: 39px;
flex-shrink: 0;
}
}
}