Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Enable Avatar OnClick Actions #2348

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/containers/git-tab-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import yubikiri from 'yubikiri';
import {autobind} from '../helpers';
import {nullCommit} from '../models/commit';
import {nullBranch} from '../models/branch';
import {nullAuthor} from '../models/author';
import ObserveModel from '../views/observe-model';
import GitTabController from '../controllers/git-tab-controller';

const DEFAULT_REPO_DATA = {
lastCommit: nullCommit,
recentCommits: [],
committer: nullAuthor,
isMerging: false,
isRebasing: false,
hasUndoHistory: false,
Expand Down Expand Up @@ -38,6 +40,7 @@ export default class GitTabContainer extends React.Component {
return yubikiri({
lastCommit: repository.getLastCommit(),
recentCommits: repository.getRecentCommits({max: 10}),
committer: repository.getCommitter(),
isMerging: repository.isMerging(),
isRebasing: repository.isRebasing(),
hasUndoHistory: repository.hasDiscardHistory(),
Expand Down
7 changes: 5 additions & 2 deletions lib/containers/github-tab-header-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export default class GithubTabHeaderContainer extends React.Component {
getCurrentWorkDirs: PropTypes.func.isRequired,

// Event Handlers
handleWorkDirSelect: PropTypes.func,
onDidChangeWorkDirs: PropTypes.func,
handleWorkDirSelect: PropTypes.func.isRequired,
onDidChangeWorkDirs: PropTypes.func.isRequired,
onDidClickAvatar: PropTypes.func.isRequired,
}

render() {
Expand Down Expand Up @@ -83,6 +84,7 @@ export default class GithubTabHeaderContainer extends React.Component {
// Event Handlers
handleWorkDirSelect={this.props.handleWorkDirSelect}
onDidChangeWorkDirs={this.props.onDidChangeWorkDirs}
onDidClickAvatar={this.props.onDidClickAvatar}
/>
);
}
Expand All @@ -99,6 +101,7 @@ export default class GithubTabHeaderContainer extends React.Component {
// Event Handlers
handleWorkDirSelect={this.props.handleWorkDirSelect}
onDidChangeWorkDirs={this.props.onDidChangeWorkDirs}
onDidClickAvatar={() => {}}
/>
);
}
Expand Down
8 changes: 7 additions & 1 deletion lib/controllers/git-tab-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import GitTabView from '../views/git-tab-view';
import UserStore from '../models/user-store';
import RefHolder from '../models/ref-holder';
import {
CommitPropType, BranchPropType, FilePatchItemPropType, MergeConflictItemPropType, RefHolderPropType,
AuthorPropType, CommitPropType, BranchPropType, FilePatchItemPropType, MergeConflictItemPropType, RefHolderPropType,
} from '../prop-types';
import {autobind} from '../helpers';

Expand All @@ -22,6 +22,7 @@ export default class GitTabController extends React.Component {

lastCommit: CommitPropType.isRequired,
recentCommits: PropTypes.arrayOf(CommitPropType).isRequired,
committer: AuthorPropType.isRequired,
isMerging: PropTypes.bool.isRequired,
isRebasing: PropTypes.bool.isRequired,
hasUndoHistory: PropTypes.bool.isRequired,
Expand Down Expand Up @@ -74,6 +75,7 @@ export default class GitTabController extends React.Component {

this.state = {
selectedCoAuthors: [],
showIntroduction: false,
};

this.userStore = new UserStore({
Expand All @@ -92,9 +94,11 @@ export default class GitTabController extends React.Component {

isLoading={this.props.fetchInProgress}
repository={this.props.repository}
showIntroduction={this.state.showIntroduction}

lastCommit={this.props.lastCommit}
recentCommits={this.props.recentCommits}
committer={this.props.committer}
isMerging={this.props.isMerging}
isRebasing={this.props.isRebasing}
hasUndoHistory={this.props.hasUndoHistory}
Expand Down Expand Up @@ -125,6 +129,8 @@ export default class GitTabController extends React.Component {
changeWorkingDirectory={this.props.changeWorkingDirectory}
getCurrentWorkDirs={this.props.getCurrentWorkDirs}
onDidChangeWorkDirs={this.props.onDidChangeWorkDirs}
onDidClickAvatar={() => this.setState({showIntroduction: true})}
onDidCancelIntroduction={() => this.setState({showIntroduction: false})}

attemptFileStageOperation={this.attemptFileStageOperation}
attemptStageAllOperation={this.attemptStageAllOperation}
Expand Down
38 changes: 9 additions & 29 deletions lib/controllers/git-tab-header-controller.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import {CompositeDisposable} from 'atom';
import {nullAuthor} from '../models/author';
import {AuthorPropType} from '../prop-types';
import GitTabHeaderView from '../views/git-tab-header-view';

export default class GitTabHeaderController extends React.Component {
static propTypes = {
getCommitter: PropTypes.func.isRequired,
committer: AuthorPropType.isRequired,

// Workspace
currentWorkDir: PropTypes.string,
Expand All @@ -15,14 +15,12 @@ export default class GitTabHeaderController extends React.Component {
// Event Handlers
handleWorkDirSelect: PropTypes.func.isRequired,
onDidChangeWorkDirs: PropTypes.func.isRequired,
onDidUpdateRepo: PropTypes.func.isRequired,
onDidClickAvatar: PropTypes.func.isRequired,
}

constructor(props) {
super(props);
this._isMounted = false;
this.state = {currentWorkDirs: [], committer: nullAuthor};
this.disposable = new CompositeDisposable();
this.state = {currentWorkDirs: []};
}

static getDerivedStateFromProps(props, state) {
Expand All @@ -32,38 +30,28 @@ export default class GitTabHeaderController extends React.Component {
}

componentDidMount() {
this._isMounted = true;
this.disposable.add(this.props.onDidChangeWorkDirs(this.resetWorkDirs));
this.disposable.add(this.props.onDidUpdateRepo(this.updateCommitter));
this.updateCommitter();
this.disposable = this.props.onDidChangeWorkDirs(this.resetWorkDirs);
}

componentDidUpdate(prevProps) {
if (
prevProps.onDidChangeWorkDirs !== this.props.onDidChangeWorkDirs
|| prevProps.onDidUpdateRepo !== this.props.onDidUpdateRepo
) {
if (prevProps.onDidChangeWorkDirs !== this.props.onDidChangeWorkDirs) {
this.disposable.dispose();
this.disposable = new CompositeDisposable();
this.disposable.add(this.props.onDidChangeWorkDirs(this.resetWorkDirs));
this.disposable.add(this.props.onDidUpdateRepo(this.updateCommitter));
}
if (prevProps.getCommitter !== this.props.getCommitter) {
this.updateCommitter();
this.disposable = this.props.onDidChangeWorkDirs(this.resetWorkDirs);
}
}

render() {
return (
<GitTabHeaderView
committer={this.state.committer}
committer={this.props.committer}

// Workspace
workdir={this.props.currentWorkDir}
workdirs={this.state.currentWorkDirs}

// Event Handlers
handleWorkDirSelect={this.props.handleWorkDirSelect}
onDidClickAvatar={this.props.onDidClickAvatar}
/>
);
}
Expand All @@ -74,15 +62,7 @@ export default class GitTabHeaderController extends React.Component {
}));
}

updateCommitter = async () => {
const committer = await this.props.getCommitter() || nullAuthor;
if (this._isMounted) {
this.setState({committer});
}
}

componentWillUnmount() {
this._isMounted = false;
this.disposable.dispose();
}
}
10 changes: 10 additions & 0 deletions lib/controllers/github-tab-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export default class GitHubTabController extends React.Component {
openGitTab: PropTypes.func.isRequired,
}

constructor(props) {
super(props);
this.state = {
showLogin: false,
}
}

render() {
const gitHubRemotes = this.props.allRemotes.filter(remote => remote.isGithubRepo());
const currentBranch = this.props.branches.getHeadBranch();
Expand All @@ -48,6 +55,7 @@ export default class GitHubTabController extends React.Component {
<GitHubTabView
// Connection
loginModel={this.props.loginModel}
showLogin={this.state.showLogin}

workspace={this.props.workspace}
refresher={this.props.refresher}
Expand All @@ -73,6 +81,8 @@ export default class GitHubTabController extends React.Component {
openBoundPublishDialog={this.openBoundPublishDialog}
openCloneDialog={this.props.openCloneDialog}
openGitTab={this.props.openGitTab}
onDidClickAvatar={() => this.setState({showLogin: true})}
onCancelLogin={() => this.setState({showLogin: false})}
/>
);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/controllers/github-tab-header-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class GithubTabHeaderController extends React.Component {
// Event Handlers
handleWorkDirSelect: PropTypes.func.isRequired,
onDidChangeWorkDirs: PropTypes.func.isRequired,
onDidClickAvatar: PropTypes.func.isRequired,
}

constructor(props) {
Expand Down Expand Up @@ -51,6 +52,8 @@ export default class GithubTabHeaderController extends React.Component {

// Event Handlers
handleWorkDirSelect={this.props.handleWorkDirSelect}
onDidChangeWorkDirs={this.props.onDidChangeWorkDirs}
onDidClickAvatar={this.props.onDidClickAvatar}
/>
);
}
Expand Down
123 changes: 123 additions & 0 deletions lib/views/git-introduction-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React from 'react';
import PropTypes from 'prop-types';
import {AuthorPropType} from '../prop-types';

import RefHolder from '../models/ref-holder';

import Author from '../models/author';
import Commands, {Command} from '../atom/commands';

export default class GitIntroductionView extends React.Component {
static propTypes = {
commands: PropTypes.object.isRequired,
identity: AuthorPropType.isRequired,
onSave: PropTypes.func.isRequired,
onCancel: PropTypes.func,
};

constructor(props) {
super(props);

this.refRoot = new RefHolder();

this.state = {
name: '',
email: '',
saveDisabled: true,
};
}

render() {
return (
<div className='git-Introduction native-key-bindings' ref={this.refRoot.setter}>
<Commands registry={this.props.commands} target={this.refRoot}>
<Command command="core:cancel" callback={this.cancel} />
<Command command="core:confirm" callback={this.confirm} />
</Commands>
{this.renderIndentity()}
<div className='git-Introduction-options'>
<p className='git-Introduction-context'>Add your name and email that will be used to identify your commits.</p>
<input
type="text"
placeholder={this.props.identity.getFullName()}
ref={e => (this.nameInput = e)}
className="input-text git-Introduction-input"
value={this.state.name}
onChange={this.onNameChange}
tabIndex="1"
/>
<input
type="email"
placeholder={this.props.identity.getEmail()}
ref={e => (this.emailInput = e)}
className="input-text git-Introduction-input"
value={this.state.email}
onChange={this.onEmailChange}
tabIndex="2"
/>
<div className='git-Introduction-row'>
<button className="btn btn-primary" disabled={this.state.saveDisabled} tabIndex="3" onClick={this.confirm}>
Save
</button>
<button className="btn" tabIndex="4" onClick={this.cancel}>Cancel</button>
</div>
</div>
<p className='git-Introduction-explanation'>
This will only modify/overwrite your local (repository)&nbsp;
<span className='git-Introduction-keyword'>user.name</span> and&nbsp;
<span className='git-Introduction-keyword'>user.email</span>.
</p>
</div>
);
}

renderIndentity() {
return (
<div className='git-Introduction-header'>
<h1 className='git-Introduction-heading'>Your Current Identity</h1>
<img className='git-Introduction-avatar' src={this.props.identity.getAvatarUrl() || 'atom://github/img/avatar.svg'} />
<h3 className='git-Introduction-name'>{this.props.identity.getFullName()}</h3>
<h3 className='git-Introduction-email'>{this.props.identity.getEmail()}</h3>
</div>
);
}

confirm = () => {
if (this.isInputValid()) {
this.props.onSave(
new Author(
this.state.email || this.props.identity.getEmail(),
this.state.name || this.props.identity.getFullName()
)
);
}
}

cancel = () => {
this.props.onCancel();
}

onNameChange = e => {
this.setState({name: e.target.value}, this.validate);
}

onEmailChange = e => {
this.setState({email: e.target.value}, this.validate);
}

validate = () => {
this.setState({saveDisabled: !this.isInputValid()});
}

isInputValid = () => {
// email validation with regex has a LOT of corner cases, dawg.
// https://stackoverflow.com/questions/48055431/can-it-cause-harm-to-validate-email-addresses-with-a-regex
// to avoid bugs for users with nonstandard email addresses,
// just check to make sure email address contains `@` and move on with our lives.
return !!(
(this.state.name || this.state.email.includes('@'))
&& (this.state.name || this.props.identity.getFullName())
&& (this.state.email.includes('@') || this.props.identity.getEmail())
);
}
}
6 changes: 4 additions & 2 deletions lib/views/git-tab-header-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export default class GitTabHeaderView extends React.Component {
workdirs: PropTypes.shape({[Symbol.iterator]: PropTypes.func.isRequired}).isRequired,

// Event Handlers
handleWorkDirSelect: PropTypes.func,
handleWorkDirSelect: PropTypes.func.isRequired,
onDidClickAvatar: PropTypes.func.isRequired,
}

render() {
Expand All @@ -21,7 +22,7 @@ export default class GitTabHeaderView extends React.Component {
{this.renderCommitter()}
<select className="github-Project-path input-select"
value={this.props.workdir ? path.normalize(this.props.workdir) : undefined}
onChange={this.props.handleWorkDirSelect ? this.props.handleWorkDirSelect : () => {}}>
onChange={this.props.handleWorkDirSelect}>
{this.renderWorkDirs()}
</select>
</header>
Expand All @@ -46,6 +47,7 @@ export default class GitTabHeaderView extends React.Component {
src={avatarUrl || 'atom://github/img/avatar.svg'}
title={`${name} ${email}`}
alt={`${name}'s avatar`}
onClick={this.props.onDidClickAvatar}
/>
);
}
Expand Down
Loading