<commit_before>import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { signToken, wrapToken } from 'blockstack-profiles'
import { PrivateKeychain, PublicKeychain } from 'blockstack-keychains'

import {
  InputGroup, SaveButton, ProfileEditingSidebar, PageHeader
} from '../../components/index'
import { IdentityActions } from '../../store/identities'
import { getNameParts, uploadProfile, uploadPhoto } from '../../utils/index'

import BasicInfoTab      from './tabs/BasicInfoTab'
import PhotosTab         from './tabs/PhotosTab'
import SocialAccountsTab from './tabs/SocialAccountsTab'
import PublicKeysTab     from './tabs/PublicKeysTab'
import PrivateInfoTab    from './tabs/PrivateInfoTab'

function mapStateToProps(state) {
  return {
    localIdentities: state.identities.localIdentities,
    api: state.settings.api,
    identityKeypairs: state.account.identityAccount.keypairs,
    analyticsId: state.account.analyticsId
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(IdentityActions, dispatch)
}

class EditProfilePage extends Component {
  static propTypes = {
    updateProfile: PropTypes.func.isRequired,
    localIdentities: PropTypes.object.isRequired,
    api: PropTypes.object.isRequired,
    identityKeypairs: PropTypes.array.isRequired,
    analyticsId: PropTypes.string.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      domainName: null,
      profile: null,
      profileJustSaved: false,
      verifications: [],
      tabName: "Basic Info"
    }

    this.saveProfile = this.saveProfile.bind(this)
    this.changeTabs = this.changeTabs.bind(this)
    this.uploadProfilePhoto = this.uploadProfilePhoto.bind(this)
  }

  componentHasNewLocalIdentities(props) {
    const profileIndex = this.props.routeParams.index,
          newDomainName = props.localIdentities[profileIndex].domainName,
          newProfile = props.localIdentities[profileIndex].profile
    if (profileIndex) {
      this.setState({
        domainName: newDomainName,
        profile: newProfile
      })
    }
  }

  componentWillMount() {
    this.componentHasNewLocalIdentities(this.props)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.localIdentities !== this.props.localIdentities) {
      this.componentHasNewLocalIdentities(nextProps)
    }
  }

  componentWillUnmount() {
    this.saveProfile(this.state.profile)
  }

  saveProfile(newProfile) {
    this.props.updateProfile(this.props.routeParams.index, newProfile)
    const analyticsId = this.props.analyticsId
    mixpanel.track('Save profile', { distinct_id: analyticsId })
    mixpanel.track('Perform action', { distinct_id: analyticsId })

    const filename = this.state.domainName + '.json'

    const keypair = this.props.identityKeypairs[0],
          privateKey = keypair.key,
          publicKey = keypair.keyID

    const token = signToken(this.state.profile, privateKey, {publicKey: publicKey}),
          tokenRecord = wrapToken(token),
          tokenRecords = [tokenRecord]
    const data = JSON.stringify(tokenRecords, null, 2)

    uploadProfile(this.props.api, this.state.domainName, data).catch((err) => {
        console.error(err)
        console.error('profile not uploaded ')
    })

  }


  uploadProfilePhoto(file, index) {

    const analyticsId = this.props.analyticsId
    mixpanel.track('Upload photo', { distinct_id: analyticsId })
    mixpanel.track('Perform action', { distinct_id: analyticsId })
    const name = this.state.domainName
    return uploadPhoto(this.props.api, name, file, index)

  }

  changeTabs(tabName) {
    this.setState({tabName: tabName})
  }

  render() {
    return (
      <div className="body-inner body-inner-white">
        <PageHeader title="Edit Profile" subtitle={this.state.tabName} />
        <div className="container">
          <div className="row"><commit_msg>resolved spacing issues on edit profile<commit_after>import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { signToken, wrapToken } from 'blockstack-profiles'
import { PrivateKeychain, PublicKeychain } from 'blockstack-keychains'

import {
  InputGroup, SaveButton, ProfileEditingSidebar, PageHeader
} from '../../components/index'
import { IdentityActions } from '../../store/identities'
import { getNameParts, uploadProfile, uploadPhoto } from '../../utils/index'

import BasicInfoTab      from './tabs/BasicInfoTab'
import PhotosTab         from './tabs/PhotosTab'
import SocialAccountsTab from './tabs/SocialAccountsTab'
import PublicKeysTab     from './tabs/PublicKeysTab'
import PrivateInfoTab    from './tabs/PrivateInfoTab'

function mapStateToProps(state) {
  return {
    localIdentities: state.identities.localIdentities,
    api: state.settings.api,
    identityKeypairs: state.account.identityAccount.keypairs,
    analyticsId: state.account.analyticsId
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(IdentityActions, dispatch)
}

class EditProfilePage extends Component {
  static propTypes = {
    updateProfile: PropTypes.func.isRequired,
    localIdentities: PropTypes.object.isRequired,
    api: PropTypes.object.isRequired,
    identityKeypairs: PropTypes.array.isRequired,
    analyticsId: PropTypes.string.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      domainName: null,
      profile: null,
      profileJustSaved: false,
      verifications: [],
      tabName: "Basic Info"
    }

    this.saveProfile = this.saveProfile.bind(this)
    this.changeTabs = this.changeTabs.bind(this)
    this.uploadProfilePhoto = this.uploadProfilePhoto.bind(this)
  }

  componentHasNewLocalIdentities(props) {
    const profileIndex = this.props.routeParams.index,
          newDomainName = props.localIdentities[profileIndex].domainName,
          newProfile = props.localIdentities[profileIndex].profile
    if (profileIndex) {
      this.setState({
        domainName: newDomainName,
        profile: newProfile
      })
    }
  }

  componentWillMount() {
    this.componentHasNewLocalIdentities(this.props)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.localIdentities !== this.props.localIdentities) {
      this.componentHasNewLocalIdentities(nextProps)
    }
  }

  componentWillUnmount() {
    this.saveProfile(this.state.profile)
  }

  saveProfile(newProfile) {
    this.props.updateProfile(this.props.routeParams.index, newProfile)
    const analyticsId = this.props.analyticsId
    mixpanel.track('Save profile', { distinct_id: analyticsId })
    mixpanel.track('Perform action', { distinct_id: analyticsId })

    const filename = this.state.domainName + '.json'

    const keypair = this.props.identityKeypairs[0],
          privateKey = keypair.key,
          publicKey = keypair.keyID

    const token = signToken(this.state.profile, privateKey, {publicKey: publicKey}),
          tokenRecord = wrapToken(token),
          tokenRecords = [tokenRecord]
    const data = JSON.stringify(tokenRecords, null, 2)

    uploadProfile(this.props.api, this.state.domainName, data).catch((err) => {
        console.error(err)
        console.error('profile not uploaded ')
    })

  }


  uploadProfilePhoto(file, index) {

    const analyticsId = this.props.analyticsId
    mixpanel.track('Upload photo', { distinct_id: analyticsId })
    mixpanel.track('Perform action', { distinct_id: analyticsId })
    const name = this.state.domainName
    return uploadPhoto(this.props.api, name, file, index)

  }

  changeTabs(tabName) {
    this.setState({tabName: tabName})
  }

  render() {
    return (
      <div className="body-inner-white">
        <PageHeader title="Edit Profile"/>
        <div className="container vertical-split-content">
          <div className="row">
{'fraction_non_alphanumeric': 0.10892207303300289, 'fraction_numerical': 0.0005019450370184465, 'mean_word_length': 3.652656158785756, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '354936', 'n_tokens_mistral': 2327, 'n_tokens_neox': 2293, 'n_words': 451}