Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.
59 changes: 38 additions & 21 deletions lib/controllers/git-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import StatusBar from '../views/status-bar';
import Panel from '../views/panel';
import PaneItem from '../views/pane-item';
import Resizer from '../views/resizer';
import Tabs from '../views/tabs';
import Commands, {Command} from '../views/commands';
import FilePatchController from './file-patch-controller';
import GitPanelController from './git-panel-controller';
Expand All @@ -31,10 +32,12 @@ export default class GitController extends React.Component {
repository: React.PropTypes.object,
statusBar: React.PropTypes.object,
savedState: React.PropTypes.object,
githubEnabled: React.PropTypes.bool,
}

static defaultProps = {
savedState: {},
githubEnabled: false,
}

serialize() {
Expand All @@ -51,6 +54,7 @@ export default class GitController extends React.Component {
amending: false,
gitPanelActive: !!props.savedState.gitPanelActive,
panelSize: props.savedState.panelSize || 400,
activeTab: 0,
};

this.repositoryStateRegistry = new ModelStateRegistry(GitController, {
Expand Down Expand Up @@ -123,27 +127,36 @@ export default class GitController extends React.Component {
size={this.state.panelSize}
onChange={this.handlePanelResize}
className="github-PanelResizer">
<EtchWrapper
ref={c => { this.gitPanelController = c; }}
className="github-PanelEtchWrapper"
reattachDomNode={false}>
<GitPanelController
workspace={this.props.workspace}
commandRegistry={this.props.commandRegistry}
notificationManager={this.props.notificationManager}
repository={this.props.repository}
isAmending={this.state.amending}
didSelectFilePath={this.showFilePatchForPath}
didDiveIntoFilePath={this.diveIntoFilePatchForPath}
didSelectMergeConflictFile={this.showMergeConflictFileForPath}
didDiveIntoMergeConflictPath={this.diveIntoMergeConflictFileForPath}
didChangeAmending={this.didChangeAmending}
focusFilePatchView={this.focusFilePatchView}
ensureGitPanel={this.ensureGitPanel}
openFiles={this.openFiles}
discardWorkDirChangesForPaths={this.discardWorkDirChangesForPaths}
/>
</EtchWrapper>
<Tabs activeIndex={this.state.activeTab} onChange={this.handleChangeTab} className="sidebar-tabs">
<Tabs.Panel title="Git">
<EtchWrapper
ref={c => { this.gitPanelController = c; }}
className="github-PanelEtchWrapper"
reattachDomNode={false}>
<GitPanelController
workspace={this.props.workspace}
commandRegistry={this.props.commandRegistry}
notificationManager={this.props.notificationManager}
repository={this.props.repository}
isAmending={this.state.amending}
didSelectFilePath={this.showFilePatchForPath}
didDiveIntoFilePath={this.diveIntoFilePatchForPath}
didSelectMergeConflictFile={this.showMergeConflictFileForPath}
didDiveIntoMergeConflictPath={this.diveIntoMergeConflictFileForPath}
didChangeAmending={this.didChangeAmending}
focusFilePatchView={this.focusFilePatchView}
ensureGitPanel={this.ensureGitPanel}
openFiles={this.openFiles}
discardWorkDirChangesForPaths={this.discardWorkDirChangesForPaths}
/>
</EtchWrapper>
</Tabs.Panel>
{this.props.githubEnabled && (
<Tabs.Panel title="Hub">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hee hee, I still think that's great.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, let's leave it for a bit longer. 😂

Hello from Hub
</Tabs.Panel>
)}
</Tabs>
</Resizer>
</Panel>
);
Expand Down Expand Up @@ -315,4 +328,8 @@ export default class GitController extends React.Component {
return this.props.repository.discardWorkDirChangesForPaths(filePaths);
}

@autobind
handleChangeTab(activeTab) {
this.setState({activeTab});
}
}
1 change: 1 addition & 0 deletions lib/git-shell-out-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default class GitShellOutStrategy {
processCallback: child => {
child.on('error', err => {
console.error('Error executing: ' + formattedArgs);

console.error(err.stack);
});
child.stdin.on('error', err => {
Expand Down
6 changes: 5 additions & 1 deletion lib/github-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import FilePatchController from './controllers/file-patch-controller';
import GitController from './controllers/git-controller';

export default class GithubPackage {
constructor(workspace, project, commandRegistry, notificationManager) {
constructor(workspace, project, commandRegistry, notificationManager, config) {
this.workspace = workspace;
this.project = project;
this.commandRegistry = commandRegistry;
this.notificationManager = notificationManager;
this.config = config;
this.repositoriesAndChangeObserversByProjectPath = new Map();
this.activeRepository = null;
this.subscriptions = new CompositeDisposable();
Expand All @@ -33,6 +34,7 @@ export default class GithubPackage {
this.subscriptions.add(
this.project.onDidChangePaths(this.didChangeProjectPaths),
this.workspace.onDidChangeActivePaneItem(this.didChangeActivePaneItem),
this.config.onDidChange('github.githubEnabled', this.rerender),
);
if (state.activeRepositoryPath) {
const repository = await this.getRepositoryForWorkdirPath(state.activeRepositoryPath);
Expand All @@ -51,6 +53,7 @@ export default class GithubPackage {
};
}

@autobind
rerender() {
if (!this.element) {
this.element = document.createElement('div');
Expand All @@ -69,6 +72,7 @@ export default class GithubPackage {
repository={this.getActiveRepository()}
statusBar={this.statusBar}
savedState={this.savedState.gitController}
githubEnabled={this.config.get('github.githubEnabled')}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feature flags ftw ✨

/>, this.element,
);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ function startPackage() {
var GithubPackage = require('./github-package').default;

return new GithubPackage(
atom.workspace, atom.project, atom.commands, atom.notifications,
atom.workspace, atom.project, atom.commands, atom.notifications, atom.config,
);
}
95 changes: 95 additions & 0 deletions lib/views/tabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';
import cx from 'classnames';
import {autobind} from 'core-decorators';

function getClasses(staticClasses, active) {
return cx(...staticClasses, {
inactive: !active,
active,
});
}

class TabsNavigationItem extends React.Component {
static propTypes = {
title: React.PropTypes.node,
tabIndex: React.PropTypes.number.isRequired,
active: React.PropTypes.bool,
onClick: React.PropTypes.func,
}

render() {
const classes = getClasses(['github-Tabs-NavigationItem'], this.props.active);
return (
<div className={classes} onClick={this.handleClick}>
{this.props.title}
</div>
);
}

@autobind
handleClick() {
this.props.onClick(this.props.tabIndex);
}
}

export default class Tabs extends React.Component {
static propTypes = {
className: React.PropTypes.string,
activeIndex: React.PropTypes.number.isRequired,
children: React.PropTypes.node,
onChange: React.PropTypes.func,
}

static defaultProps = {
className: '',
onChange: () => {},
}

render() {
const children = React.Children.toArray(this.props.children).filter(v => !!v);
return (
<div className={cx('github-Tabs', this.props.className)} data-tabs-count={children.length}>
<nav className="github-Tabs-NavigationContainer">
{children.map((child, i) => child && (
<TabsNavigationItem
key={i}
title={child.props.title}
active={this.props.activeIndex === i}
tabIndex={i}
onClick={this.props.onChange}
/>
))}
</nav>
<section className="github-Tabs-PanelContainer">
{children.map((child, i) => child && (
React.cloneElement(child, {active: i === this.props.activeIndex})
))}
</section>
</div>
);
}
}

Tabs.Panel = class TabPanel extends React.Component {
static propTypes = {
className: React.PropTypes.string,
active: React.PropTypes.bool,
children: React.PropTypes.node,
title: React.PropTypes.node,
}

static defaultProps = {
className: '',
active: false,
}

render() {
// eslint-disable-next-line no-unused-vars
const {active, children, className, title, ...others} = this.props;
return (
<div className={getClasses(['github-Tabs-Panel', className], this.props.active)} {...others}>
{this.props.children}
</div>
);
}
};
5 changes: 0 additions & 5 deletions styles/git-panel.less
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
@import "variables";

.github-PanelResizer {
// ok, yeah, magic number.. err color
background-color: mix(@base-background-color, @tool-panel-background-color);
}

.github-PanelEtchWrapper {
height: 100%;
}
Expand Down
82 changes: 82 additions & 0 deletions styles/tabs.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@import "variables";

// General Styles
.github-Tabs {
&-Panel {
&.active {
display: block;
}

&.inactive {
display: none;
}
}
}

// App-specific styles
.github-Tabs.sidebar-tabs {
height: 100%;
display: flex;
flex-direction: column;

.github-Tabs-NavigationContainer {
display: flex;
flex-direction: row;
padding: @component-padding;

.github-Tabs-NavigationItem {
flex: 1;
text-align: center;
cursor: pointer;
background-color: @button-background-color;
color: contrast(@button-background-color, hsla(0,0%,0%,.6), hsla(0,0%,100%,.6));
border: 1px solid @button-border-color;
padding: .25em .5em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

& + .github-Tabs-NavigationItem {
border-left: none;
}

&.active {
background-color: @button-background-color-selected;
color: contrast(@button-background-color-selected, hsla(0,0%,0%,1), hsla(0,0%,100%,1));
}

&:first-child {
border-top-left-radius: @component-border-radius;
border-bottom-left-radius: @component-border-radius;
}

&:last-child {
border-top-right-radius: @component-border-radius;
border-bottom-right-radius: @component-border-radius;
}
}

}

&[data-tabs-count="1"] {
.github-Tabs-NavigationContainer {
display: none;
}
}

.github-Tabs-PanelContainer {
flex: 1;
display: flex;
flex-direction: column;
}

.github-Tabs-Panel {
flex: 1;

&.active {
}

&.inactive {
}
}
}
5 changes: 3 additions & 2 deletions test/github-package.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import {cloneRepository} from './helpers';
import GithubPackage from '../lib/github-package';

describe('GithubPackage', function() {
let atomEnv, workspace, project, commandRegistry, notificationManager, githubPackage;
let atomEnv, workspace, project, commandRegistry, notificationManager, config, githubPackage;

beforeEach(function() {
atomEnv = global.buildAtomEnvironment();
workspace = atomEnv.workspace;
project = atomEnv.project;
commandRegistry = atomEnv.commands;
notificationManager = atomEnv.notifications;
githubPackage = new GithubPackage(workspace, project, commandRegistry, notificationManager);
config = atomEnv.config;
githubPackage = new GithubPackage(workspace, project, commandRegistry, notificationManager, config);
});

afterEach(async function() {
Expand Down