-
Notifications
You must be signed in to change notification settings - Fork 405
Move "Undo Discard" button behind context menu #1702
Changes from all commits
0d73036
b82e732
0f1b6f5
0b834a0
dee888e
ddb7c46
71abb97
9baccc1
36f51ed
7505f9b
46c8240
dca63d6
08900af
8336eee
22ec1fe
636ccf0
8cba2f8
3fabe7c
7f03c66
32b0ada
f759c78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import RefHolder from '../models/ref-holder'; | |
import FilePatchController from '../controllers/file-patch-controller'; | ||
import Commands, {Command} from '../atom/commands'; | ||
import {autobind} from '../helpers'; | ||
import {addEvent} from '../reporter-proxy'; | ||
|
||
const debounce = (fn, wait) => { | ||
let timeout; | ||
|
@@ -82,9 +83,8 @@ export default class StagingView extends React.Component { | |
'dblclickOnItem', 'contextMenuOnItem', 'mousedownOnItem', 'mousemoveOnItem', 'mouseup', 'registerItemElement', | ||
'renderBody', 'openFile', 'discardChanges', 'activateNextList', 'activatePreviousList', 'activateLastList', | ||
'stageAll', 'unstageAll', 'stageAllMergeConflicts', 'discardAll', 'confirmSelectedItems', 'selectAll', | ||
'selectFirst', 'selectLast', 'diveIntoSelection', 'showDiffView', 'showBulkResolveMenu', | ||
'selectFirst', 'selectLast', 'diveIntoSelection', 'showDiffView', 'showBulkResolveMenu', 'showActionsMenu', | ||
'resolveCurrentAsOurs', 'resolveCurrentAsTheirs', 'quietlySelectItem', 'didChangeSelectedItems', | ||
'undoLastDiscard', | ||
); | ||
|
||
this.subs = new CompositeDisposable( | ||
|
@@ -194,9 +194,12 @@ export default class StagingView extends React.Component { | |
<header className="github-StagingView-header"> | ||
<span className="icon icon-list-unordered" /> | ||
<span className="github-StagingView-title">Unstaged Changes</span> | ||
{this.props.unstagedChanges.length ? this.renderStageAllButton() : null} | ||
{this.renderActionsMenu()} | ||
<button | ||
className="github-StagingView-headerButton icon icon-move-down" | ||
disabled={this.props.unstagedChanges.length === 0} | ||
onClick={this.stageAll}>Stage All</button> | ||
</header> | ||
{this.props.hasUndoHistory ? this.renderUndoButton() : null} | ||
<div className="github-StagingView-list github-FilePatchListView github-StagingView-unstaged"> | ||
{ | ||
this.state.unstagedChanges.map(filePatch => ( | ||
|
@@ -222,7 +225,9 @@ export default class StagingView extends React.Component { | |
<span className="github-StagingView-title"> | ||
Staged Changes | ||
</span> | ||
{ this.props.stagedChanges.length ? this.renderUnstageAllButton() : null } | ||
<button className="github-StagingView-headerButton icon icon-move-up" | ||
disabled={this.props.stagedChanges.length === 0} | ||
onClick={this.unstageAll}>Unstage All</button> | ||
</header> | ||
<div className="github-StagingView-list github-FilePatchListView github-StagingView-staged"> | ||
{ | ||
|
@@ -267,38 +272,62 @@ export default class StagingView extends React.Component { | |
<Command command="github:open-file" callback={this.openFile} /> | ||
<Command command="github:resolve-file-as-ours" callback={this.resolveCurrentAsOurs} /> | ||
<Command command="github:resolve-file-as-theirs" callback={this.resolveCurrentAsTheirs} /> | ||
<Command command="github:discard-changes-in-selected-files" callback={this.discardChanges} /> | ||
<Command command="core:undo" callback={this.undoLastDiscard} /> | ||
<Command command="github:discard-changes-in-selected-files" callback={this.discardChangesFromCommand} /> | ||
<Command command="core:undo" callback={this.undoLastDiscardFromCoreUndo} /> | ||
</Commands> | ||
<Commands registry={this.props.commandRegistry} target="atom-workspace"> | ||
<Command command="github:stage-all-changes" callback={this.stageAll} /> | ||
<Command command="github:unstage-all-changes" callback={this.unstageAll} /> | ||
<Command command="github:discard-all-changes" callback={this.discardAll} /> | ||
<Command command="github:undo-last-discard-in-git-tab" callback={this.undoLastDiscard} /> | ||
<Command command="github:discard-all-changes" callback={this.discardAllFromCommand} /> | ||
<Command command="github:undo-last-discard-in-git-tab" | ||
callback={this.undoLastDiscardFromCommand} | ||
/> | ||
</Commands> | ||
</Fragment> | ||
); | ||
} | ||
|
||
renderStageAllButton() { | ||
return ( | ||
<button | ||
className="github-StagingView-headerButton icon icon-move-down" | ||
onClick={this.stageAll}>Stage All</button> | ||
); | ||
undoLastDiscardFromCoreUndo = () => { | ||
this.undoLastDiscard({eventSource: {command: 'core:undo'}}); | ||
} | ||
|
||
renderUnstageAllButton() { | ||
return ( | ||
<button className="github-StagingView-headerButton icon icon-move-up" | ||
onClick={this.unstageAll}>Unstage All</button> | ||
); | ||
undoLastDiscardFromCommand = () => { | ||
this.undoLastDiscard({eventSource: {command: 'github:undo-last-discard-in-git-tab'}}); | ||
} | ||
|
||
undoLastDiscardFromButton = () => { | ||
this.undoLastDiscard({eventSource: 'button'}); | ||
} | ||
|
||
undoLastDiscardFromHeaderMenu = () => { | ||
this.undoLastDiscard({eventSource: 'header-menu'}); | ||
} | ||
|
||
discardChangesFromCommand = () => { | ||
this.discardChanges({eventSource: {command: 'github:discard-changes-in-selected-files'}}); | ||
} | ||
|
||
discardAllFromCommand = () => { | ||
this.discardAll({eventSource: {command: 'github:discard-all-changes'}}); | ||
} | ||
|
||
renderActionsMenu() { | ||
if (this.props.unstagedChanges.length || this.props.hasUndoHistory) { | ||
return ( | ||
<button | ||
className="github-StagingView-headerButton github-StagingView-headerButton--iconOnly icon icon-ellipses" | ||
onClick={this.showActionsMenu} | ||
/> | ||
); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
renderUndoButton() { | ||
return ( | ||
<button className="github-StagingView-headerButton github-StagingView-headerButton--fullWidth icon icon-history" | ||
onClick={this.undoLastDiscard}>Undo Discard</button> | ||
onClick={this.undoLastDiscardFromButton}>Undo Discard</button> | ||
); | ||
} | ||
|
||
|
@@ -377,20 +406,31 @@ export default class StagingView extends React.Component { | |
this.subs.dispose(); | ||
} | ||
|
||
getSelectedItemFilePaths() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 for refactoring this out. |
||
return Array.from(this.state.selection.getSelectedItems(), item => item.filePath); | ||
} | ||
|
||
getSelectedConflictPaths() { | ||
if (this.state.selection.getActiveListKey() !== 'conflicts') { | ||
return []; | ||
} | ||
return Array.from(this.state.selection.getSelectedItems(), item => item.filePath); | ||
return this.getSelectedItemFilePaths(); | ||
} | ||
|
||
openFile() { | ||
const filePaths = Array.from(this.state.selection.getSelectedItems(), item => item.filePath); | ||
const filePaths = this.getSelectedItemFilePaths(); | ||
return this.props.openFiles(filePaths); | ||
} | ||
|
||
discardChanges() { | ||
const filePaths = Array.from(this.state.selection.getSelectedItems(), item => item.filePath); | ||
discardChanges({eventSource} = {}) { | ||
const filePaths = this.getSelectedItemFilePaths(); | ||
addEvent('discard-unstaged-changes', { | ||
annthurium marked this conversation as resolved.
Show resolved
Hide resolved
|
||
package: 'github', | ||
component: 'StagingView', | ||
fileCount: filePaths.length, | ||
type: 'selected', | ||
eventSource, | ||
}); | ||
return this.props.discardWorkDirChangesForPaths(filePaths); | ||
} | ||
|
||
|
@@ -457,14 +497,21 @@ export default class StagingView extends React.Component { | |
return this.props.attemptFileStageOperation(filePaths, 'unstaged'); | ||
} | ||
|
||
discardAll() { | ||
discardAll({eventSource} = {}) { | ||
if (this.props.unstagedChanges.length === 0) { return null; } | ||
const filePaths = this.props.unstagedChanges.map(filePatch => filePatch.filePath); | ||
addEvent('discard-unstaged-changes', { | ||
package: 'github', | ||
component: 'StagingView', | ||
fileCount: filePaths.length, | ||
type: 'all', | ||
eventSource, | ||
}); | ||
return this.props.discardWorkDirChangesForPaths(filePaths); | ||
} | ||
|
||
confirmSelectedItems = async () => { | ||
const itemPaths = Array.from(this.state.selection.getSelectedItems(), item => item.filePath); | ||
const itemPaths = this.getSelectedItemFilePaths(); | ||
await this.props.attemptFileStageOperation(itemPaths, this.state.selection.getActiveListKey()); | ||
await new Promise(resolve => { | ||
this.setState(prevState => ({selection: prevState.selection.coalesce()}), resolve); | ||
|
@@ -586,6 +633,35 @@ export default class StagingView extends React.Component { | |
menu.popup(remote.getCurrentWindow()); | ||
} | ||
|
||
showActionsMenu(event) { | ||
event.preventDefault(); | ||
|
||
const menu = new Menu(); | ||
|
||
const selectedItemCount = this.state.selection.getSelectedItems().size; | ||
const pluralization = selectedItemCount > 1 ? 's' : ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we ever i18n our package, all our hard coded pluralization is going to be fun to convert.... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yuuuup 😕 |
||
|
||
menu.append(new MenuItem({ | ||
label: 'Discard All Changes', | ||
click: () => this.discardAll({eventSource: 'header-menu'}), | ||
enabled: this.props.unstagedChanges.length > 0, | ||
})); | ||
|
||
menu.append(new MenuItem({ | ||
label: 'Discard Changes in Selected File' + pluralization, | ||
click: () => this.discardChanges({eventSource: 'header-menu'}), | ||
enabled: !!(this.props.unstagedChanges.length && selectedItemCount), | ||
})); | ||
|
||
menu.append(new MenuItem({ | ||
label: 'Undo Last Discard', | ||
click: () => this.undoLastDiscard({eventSource: 'header-menu'}), | ||
enabled: this.props.hasUndoHistory, | ||
})); | ||
|
||
menu.popup(remote.getCurrentWindow()); | ||
} | ||
|
||
resolveCurrentAsOurs() { | ||
this.props.resolveAsOurs(this.getSelectedConflictPaths()); | ||
} | ||
|
@@ -792,11 +868,17 @@ export default class StagingView extends React.Component { | |
} | ||
} | ||
|
||
undoLastDiscard() { | ||
undoLastDiscard({eventSource} = {}) { | ||
if (!this.props.hasUndoHistory) { | ||
return; | ||
} | ||
|
||
addEvent('undo-last-discard', { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as above - would recommend refactoring this so that you're logging menu views as a ui interaction. |
||
package: 'github', | ||
component: 'StagingView', | ||
eventSource, | ||
}); | ||
|
||
this.props.undoLastDiscard(); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yess metrics