<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
  Button, Header, Form, Input, Divider, Segment,
  Message, List, Checkbox, Grid, Icon, Label,
} from 'semantic-ui-react';
import * as _ from 'lodash';
import * as note from '../../util/notificationManagement';
import {mergeState, mgrUpdateGen} from '../../util/localStateOperations';
import {doValidation, referrerDomain} from './helpers';
import {NotificationList} from '../Notifications';
import {exception} from '../../util/dev';
import {fieldSplit} from '../../util/names';
import {fieldIsInError} from '../../util/commonComponentHelpers';

class AccountForm extends Component {

  constructor(props) {
    super(props);

    const {accountForm} = props;

    const init = {
      ephemeral: {
        submitting: false,
        accountExists: false,
        passwordType: 'password',
      },
      fields: {...accountForm.fields},
    };
    this.state = note.newManagers(init, ['account']);
    this.handlePasswordVisibility = this.handlePasswordVisibility.bind(this);
		console.log('state', this.state);
		console.log('accountForm', accountForm);
  }

  handleFieldChange = (event) => {
    // N.B. this function *must* be quick and early so that user doesn't get laggy input
    const [segment, fieldName] = fieldSplit(event.target.name);

    let fieldType = event.target.name.split('.')[event.target.name.split('.').length - 1];
    let fieldValue = event.target.value;
    const accountFormTemplate = `{"fields":{"account":{"${fieldType}":"${fieldValue}"}}}`;
    this.setState(mergeState(this.state, JSON.parse(accountFormTemplate)));

    // TODO: instead of waiting on validation here to set the input text state, return a validationResult immediately with the 'input' field set to the updated value and then have a promise resolution entail updating the validation result with other detail

    doValidation(segment, fieldName, event.target.value)
      .then((validationResult) => {
        if (!validationResult.isError()) {
          // clear these early, let further submits create new ones if necessary
          const newMgr = note.segmentMgr(this.state.notificationMgrs, 'account').fns.clearDs('errors');
          this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
        }

        // handleValidationResult always returns a properly-updated state object
        this.setState(note.handleValidationResult(this.state, validationResult));
      });
  }

  handleInputBlur = (event) => {
    const {accountFormFieldChange} = this.props;
    const [segment, fieldName] = fieldSplit(event.target.name);

    // a mgr is specific to a segment
    const mgr = note.segmentMgr(this.state.notificationMgrs, segment);
    const validationResult = mgr.fns.fieldValidationResult(fieldName);

    // validationResult can be null if there was never a change in the field
    if (validationResult !== null) {
      if (validationResult.isError()) {
        console.log('skipping action dispatch on event', event, 'b/c field is in error. Msg', validationResult.errorMsg);
      } else {
        // save in store; N.B.! Important that we use the value from the mgr b/c it contains the validation outcome with a possibly typed or sanitized value

        accountFormFieldChange(segment, fieldName, validationResult.value);
      }
    }
  }

  handleSubmit = (expectExistingAccount) => {
    const {configuration, accountFormDataSubmit, device, accountForm, accountFormFieldChange, router} = this.props;

		this.setState(mergeState(this.state, {ephemeral: { submitting: true }}));

    const submitMgr = note.segmentMgr(this.state.notificationMgrs, 'account');
    const allErrors = _.flatMap(_.omit(this.state.notificationMgrs, ['account']), (mgr) => { return mgr.fns.fieldErrorMsgs();});

    if (!_.isEmpty(allErrors)) {
      const newMgr = submitMgr.fns.error('submit', 'Please resolve field errors and submit again.');
      this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
    } else {
      accountFormDataSubmit(configuration.exchange_api, device.id, accountForm, expectExistingAccount).then((success) => {
				accountFormFieldChange('account', 'password', '');
        router.push('/setup');
      }).catch((err) => {
        const newMgr = submitMgr.fns.error('account', `Account data submission error. ${err.msg}`);
        this.setState(mergeState(this.state, {ephemeral: { submitting: false }}));
        this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
      });
    }
	}

// TODO: update
  handlePasswordReset = (event) => {
    const {configuration, accountFormNotification, accountFormPasswordReset, accountForm} = this.props;

		const mgr = note.segmentMgr(this.state.notificationMgrs, 'account');

    if (this.state.fields.account.username === '') {
			const newMgr = mgr.fns.error('account', 'Form incomplete.');
			this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
    } else {
			accountFormPasswordReset(configuration.exchange_api, accountForm.fields.account.username)
				.then(() => {
					const newMgr = mgr.fns.notification('account', 'Succeeded issuing password reset, please check your email inbox for a password reset message.');
					this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
				})
					.catch((err) => {
					console.log('Password reset failed', err);
					const newMgr = mgr.fns.error('account', `Reset error. ${err.msg}.`);
					this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
				});
			}
  }

  // handler for semantic checkbox toggle between new account and
  //  existing account
  handleAccountToggle = (event, checkboxProps) => {
    const newMgr = note.segmentMgr(this.state.notificationMgrs, 'account').fns.clearDs('fieldValidationResults');
    this.setState(mergeState(this.state, { ephemeral: { accountExists: checkboxProps.checked }}));
    this.setState(mergeState(this.state, mgrUpdateGen(newMgr)), function() {
      this.setState(mergeState(this.state, { ephemeral: { accountExists: checkboxProps.checked }}));
    });
  }

  handlePasswordVisibility(evt) {
    console.log('evt', evt);
    if (this.state.ephemeral.passwordType === 'password') {
      this.setState(mergeState(this.state, {
        ephemeral: {
          passwordType: 'text',
        }
      }));
    } else {
      this.setState(mergeState(this.state, {
        ephemeral: {
          passwordType: 'password',
        }
      }));
    }

  }

  componentWillMount() {
    document.title += ' - Account Setup';

    const {device, router} = this.props;

    if ('account' in device) {
      console.log('redirecting to dashboard');
      // user has already registered, send 'em to the dash!
      router.push('/dashboard');
    }
  }

  render() {
    // TODO: make sure returning to this page after reg (like if user hits the back button), causes redirection to dashboard

    let accountForm;

    !this.state.ephemeral.accountExists ? accountForm =
      <Form className="attached fluid segment" onSubmit={(event) => {event.preventDefault();} } id='account'>
        <Form.Input fluid focus label='Organization' name='account.organization' value={this.state.fields.account.organization} placeholder='Organization - Enter `public` for default' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.organization')} onBlur={this.handleInputBlur} />
        <Form.Input fluid focus label='Username' name='account.username' value={this.state.fields.account.username} placeholder='Username' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.username')} onBlur={this.handleInputBlur} />
        <Form.Input
          fluid
          label='Password'
          name='account.password'
          type={this.state.ephemeral.passwordType}
          value={this.state.fields.account.password}
          placeholder='Password'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.password')}
          placeholder="Password" onBlur={this.handleInputBlur}
          icon={<Icon
            name="eye"
            link
            onClick={this.handlePasswordVisibility}
          />}
        />
        <Form.Input fluid label='Email' name='account.email' value={this.state.fields.account.email} placeholder='Email address' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.email')} placeholder='Email address' onBlur={this.handleInputBlur} />
        <Form.Input fluid focus
          label={Device Name - Enter a name for device {this.props.device.id} that you will easily recognize.}
          name='account.devicename'
          value={this.state.fields.account.devicename}
          placeholder='Device Name'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.devicename')}
          onBlur={this.handleInputBlur}
        />
        <Button primary color="blue" onClick={() => {this.handleSubmit(false);}} loading={this.state.ephemeral.submitting} disabled={this.state.ephemeral.submitting}>Register Device with New Account</Button>
      </Form>
      : accountForm =
      <Form className="attached fluid segment" onSubmit={(event) => {event.preventDefault();} } id='account'>
        <Form.Input fluid focus label='Organization' name='account.organization' value={this.state.fields.account.organization} placeholder='Organization - Default is `public`' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.organization')} onBlur={this.handleInputBlur} />
        <Form.Input fluid focus label='Username' name='account.username' value={this.state.fields.account.username} placeholder='Username' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.username')} onBlur={this.handleInputBlur} />
        <Form.Input
          fluid
          label='Password'
          name='account.password'
          type={this.state.ephemeral.passwordType}
          value={this.state.fields.account.password}
          placeholder='Password'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.password')}
          placeholder="Password"
          onBlur={this.handleInputBlur}
          icon={<Icon
            name="eye"
            link
            onClick={this.handlePasswordVisibility}
          />}
        />
        <Form.Input fluid focus
          label={Device Name - Enter a name for device {this.props.device.id} that you will easily recognize.}
          name='account.devicename'
          value={this.state.fields.account.devicename}
          placeholder='Device Name'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.devicename')}
          onBlur={this.handleInputBlur}
        />
        <Button primary color="blue" onClick={() => {this.handleSubmit(true);}} loading={this.state.ephemeral.submitting} disabled={this.state.ephemeral.submitting}>Register Device with Existing Account</Button>
        <Button basic onClick={this.handlePasswordReset}>Reset Password</Button>
      </Form>;
    return (

        Account Setup
        <Segment padded raised>

Register this device with an existing Blue Horizon Exchange user account or create a new account and register this device to it.

          <Checkbox
            toggle
            onChange={this.handleAccountToggle}
            label={I have an account with Horizon.}
          />

					<NotificationList attached={true} mgr={note.segmentMgr(this.state.notificationMgrs, 'account')} notificationHeader='Account Setup' errHeader='Account Data Error' />
          {accountForm}
        </Segment>

    );
  }
}

export default AccountForm;
<commit_msg>set the existing account expectations<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
  Button, Header, Form, Input, Divider, Segment,
  Message, List, Checkbox, Grid, Icon, Label,
} from 'semantic-ui-react';
import * as _ from 'lodash';
import * as note from '../../util/notificationManagement';
import {mergeState, mgrUpdateGen} from '../../util/localStateOperations';
import {doValidation, referrerDomain} from './helpers';
import {NotificationList} from '../Notifications';
import {exception} from '../../util/dev';
import {fieldSplit} from '../../util/names';
import {fieldIsInError} from '../../util/commonComponentHelpers';

class AccountForm extends Component {

  constructor(props) {
    super(props);

    const {accountForm} = props;

    const init = {
      ephemeral: {
        submitting: false,
        accountExists: false,
        passwordType: 'password',
      },
      fields: {...accountForm.fields},
    };
    this.state = note.newManagers(init, ['account']);
    this.handlePasswordVisibility = this.handlePasswordVisibility.bind(this);
		console.log('state', this.state);
		console.log('accountForm', accountForm);
  }

  handleFieldChange = (event) => {
    // N.B. this function *must* be quick and early so that user doesn't get laggy input
    const [segment, fieldName] = fieldSplit(event.target.name);

    let fieldType = event.target.name.split('.')[event.target.name.split('.').length - 1];
    let fieldValue = event.target.value;
    const accountFormTemplate = `{"fields":{"account":{"${fieldType}":"${fieldValue}"}}}`;
    this.setState(mergeState(this.state, JSON.parse(accountFormTemplate)));

    // TODO: instead of waiting on validation here to set the input text state, return a validationResult immediately with the 'input' field set to the updated value and then have a promise resolution entail updating the validation result with other detail

    doValidation(segment, fieldName, event.target.value)
      .then((validationResult) => {
        if (!validationResult.isError()) {
          // clear these early, let further submits create new ones if necessary
          const newMgr = note.segmentMgr(this.state.notificationMgrs, 'account').fns.clearDs('errors');
          this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
        }

        // handleValidationResult always returns a properly-updated state object
        this.setState(note.handleValidationResult(this.state, validationResult));
      });
  }

  handleInputBlur = (event) => {
    const {accountFormFieldChange} = this.props;
    const [segment, fieldName] = fieldSplit(event.target.name);

    // a mgr is specific to a segment
    const mgr = note.segmentMgr(this.state.notificationMgrs, segment);
    const validationResult = mgr.fns.fieldValidationResult(fieldName);

    // validationResult can be null if there was never a change in the field
    if (validationResult !== null) {
      if (validationResult.isError()) {
        console.log('skipping action dispatch on event', event, 'b/c field is in error. Msg', validationResult.errorMsg);
      } else {
        // save in store; N.B.! Important that we use the value from the mgr b/c it contains the validation outcome with a possibly typed or sanitized value

        accountFormFieldChange(segment, fieldName, validationResult.value);
      }
    }
  }

  handleSubmit = (expectExistingAccount) => {
    const {configuration, accountFormDataSubmit, device, accountForm, accountFormFieldChange, router, setExpectExistingAccount} = this.props;

        // .then(() => {
        //   router.push('/setup');
        // })
        // .catch((err) => {
        //   const newMgr = submitMgr.fns.error('account', `Error in setting account existance expectations. ${err.msg}`);
        // })

		this.setState(mergeState(this.state, {ephemeral: { submitting: true }}));

    const submitMgr = note.segmentMgr(this.state.notificationMgrs, 'account');
    const allErrors = _.flatMap(_.omit(this.state.notificationMgrs, ['account']), (mgr) => { return mgr.fns.fieldErrorMsgs();});

    if (!_.isEmpty(allErrors)) {
      const newMgr = submitMgr.fns.error('submit', 'Please resolve field errors and submit again.');
      this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
    } else {
      setExpectExistingAccount(expectExistingAccount);
      this.setState(mergeState(this.state, {ephemeral: { submitting: false }}));
      router.push('/setup');
      // accountFormDataSubmit(configuration.exchange_api, device.id, accountForm, expectExistingAccount).then((success) => {
			// 	accountFormFieldChange('account', 'password', '');
      //   router.push('/setup');
      // }).catch((err) => {
      //   const newMgr = submitMgr.fns.error('account', `Account data submission error. ${err.msg}`);
      //   this.setState(mergeState(this.state, {ephemeral: { submitting: false }}));
      //   this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
      // });
    }
	}

// TODO: update
  handlePasswordReset = (event) => {
    const {configuration, accountFormNotification, accountFormPasswordReset, accountForm} = this.props;

		const mgr = note.segmentMgr(this.state.notificationMgrs, 'account');

    if (this.state.fields.account.username === '') {
			const newMgr = mgr.fns.error('account', 'Form incomplete.');
			this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
    } else {
			accountFormPasswordReset(configuration.exchange_api, accountForm.fields.account.username)
				.then(() => {
					const newMgr = mgr.fns.notification('account', 'Succeeded issuing password reset, please check your email inbox for a password reset message.');
					this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
				})
					.catch((err) => {
					console.log('Password reset failed', err);
					const newMgr = mgr.fns.error('account', `Reset error. ${err.msg}.`);
					this.setState(mergeState(this.state, mgrUpdateGen(newMgr)));
				});
			}
  }

  // handler for semantic checkbox toggle between new account and
  //  existing account
  handleAccountToggle = (event, checkboxProps) => {
    const newMgr = note.segmentMgr(this.state.notificationMgrs, 'account').fns.clearDs('fieldValidationResults');
    this.setState(mergeState(this.state, { ephemeral: { accountExists: checkboxProps.checked }}));
    this.setState(mergeState(this.state, mgrUpdateGen(newMgr)), function() {
      this.setState(mergeState(this.state, { ephemeral: { accountExists: checkboxProps.checked }}));
    });
  }

  handlePasswordVisibility(evt) {
    console.log('evt', evt);
    if (this.state.ephemeral.passwordType === 'password') {
      this.setState(mergeState(this.state, {
        ephemeral: {
          passwordType: 'text',
        }
      }));
    } else {
      this.setState(mergeState(this.state, {
        ephemeral: {
          passwordType: 'password',
        }
      }));
    }

  }

  componentWillMount() {
    document.title += ' - Account Setup';

    const {device, router} = this.props;

    if ('account' in device) {
      console.log('redirecting to dashboard');
      // user has already registered, send 'em to the dash!
      router.push('/dashboard');
    }
  }

  render() {
    // TODO: make sure returning to this page after reg (like if user hits the back button), causes redirection to dashboard

    let accountForm;

    !this.state.ephemeral.accountExists ? accountForm =
      <Form className="attached fluid segment" onSubmit={(event) => {event.preventDefault();} } id='account'>
        <Form.Input fluid focus label='Organization' name='account.organization' value={this.state.fields.account.organization} placeholder='Organization - Enter `public` for default' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.organization')} onBlur={this.handleInputBlur} />
        <Form.Input fluid focus label='Username' name='account.username' value={this.state.fields.account.username} placeholder='Username' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.username')} onBlur={this.handleInputBlur} />
        <Form.Input
          fluid
          label='Password'
          name='account.password'
          type={this.state.ephemeral.passwordType}
          value={this.state.fields.account.password}
          placeholder='Password'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.password')}
          placeholder="Password" onBlur={this.handleInputBlur}
          icon={<Icon
            name="eye"
            link
            onClick={this.handlePasswordVisibility}
          />}
        />
        <Form.Input fluid label='Email' name='account.email' value={this.state.fields.account.email} placeholder='Email address' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.email')} placeholder='Email address' onBlur={this.handleInputBlur} />
        <Form.Input fluid focus
          label={Device Name - Enter a name for device {this.props.device.id} that you will easily recognize.}
          name='account.devicename'
          value={this.state.fields.account.devicename}
          placeholder='Device Name'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.devicename')}
          onBlur={this.handleInputBlur}
        />
        <Button primary color="blue" onClick={() => {this.handleSubmit(false);}} loading={this.state.ephemeral.submitting} disabled={this.state.ephemeral.submitting}>Continue</Button>
      </Form>
      : accountForm =
      <Form className="attached fluid segment" onSubmit={(event) => {event.preventDefault();} } id='account'>
        <Form.Input fluid focus label='Organization' name='account.organization' value={this.state.fields.account.organization} placeholder='Organization - Default is `public`' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.organization')} onBlur={this.handleInputBlur} />
        <Form.Input fluid focus label='Username' name='account.username' value={this.state.fields.account.username} placeholder='Username' onChange={this.handleFieldChange} error={fieldIsInError(this, 'account.username')} onBlur={this.handleInputBlur} />
        <Form.Input
          fluid
          label='Password'
          name='account.password'
          type={this.state.ephemeral.passwordType}
          value={this.state.fields.account.password}
          placeholder='Password'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.password')}
          placeholder="Password"
          onBlur={this.handleInputBlur}
          icon={<Icon
            name="eye"
            link
            onClick={this.handlePasswordVisibility}
          />}
        />
        <Form.Input fluid focus
          label={Device Name - Enter a name for device {this.props.device.id} that you will easily recognize.}
          name='account.devicename'
          value={this.state.fields.account.devicename}
          placeholder='Device Name'
          onChange={this.handleFieldChange}
          error={fieldIsInError(this, 'account.devicename')}
          onBlur={this.handleInputBlur}
        />
        <Button primary color="blue" onClick={() => {this.handleSubmit(true);}} loading={this.state.ephemeral.submitting} disabled={this.state.ephemeral.submitting}>Continue</Button>
        <Button basic onClick={this.handlePasswordReset}>Reset Password</Button>
      </Form>;
    return (

        Account Setup
        <Segment padded raised>

Register this device with an existing Blue Horizon Exchange user account or create a new account and register this device to it.

          <Checkbox
            toggle
            onChange={this.handleAccountToggle}
            label={I have an account with Horizon.}
          />

					<NotificationList attached={true} mgr={note.segmentMgr(this.state.notificationMgrs, 'account')} notificationHeader='Account Setup' errHeader='Account Data Error' />
          {accountForm}
        </Segment>

    );
  }
}

export default AccountForm;
<|endoftext|>


<commit_before>
// Test declaring deferred values.

// Change the configuration directory for testing
process.env.NODE_CONFIG_DIR = __dirname + '/3-config';

// Hardcode $NODE_ENV=test for testing
process.env.NODE_ENV='test';

// Test for multi-instance applications
process.env.NODE_APP_INSTANCE='defer';

// Because require'ing config creates and caches a global singleton,
// We have to invalidate the cache to build new object based on the environment variables above
var CONFIG = requireUncached('../lib/config');

// Dependencies
var vows = require('vows'),
    assert = require('assert');

exports.DeferredTest = vows.describe('Tests for deferred values').addBatch({
  'Configuration file Tests': {
    topic: function() {
      return CONFIG;
    },

    'Using deferConfig() in a config file causes value to be evaluated at the end': function() {
        // The deferred function was declared in default-defer.js
        // Then local-defer.js is located which overloads the siteTitle mentioned in the function
        // Finally the deferred configurations, now referencing the 'local' siteTitle
        assert.equal(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!');
    },

    'values which are functions remain untouched unless they are instance of DeferredConfig': function() {
        // If this had been treated as a deferred config value it would blow-up.
        assert.equal(CONFIG.welcomeEmail.aFunc(), 'Still just a function.');
    },

    // This defer function didn't use args, but relied 'this' being bound to the main config object
    "defer functions can simply refer to 'this'" : function () {
        assert.equal(CONFIG.welcomeEmail.justThis, 'Welcome to this New Instance!');
    }

  }
});

function requireUncached(module){
   delete require.cache[require.resolve(module)];
   return require(module);
}
<commit_msg>Remove the 'topic' block. Turns out it was dead code.<commit_after>
// Test declaring deferred values.

// Change the configuration directory for testing
process.env.NODE_CONFIG_DIR = __dirname + '/3-config';

// Hardcode $NODE_ENV=test for testing
process.env.NODE_ENV='test';

// Test for multi-instance applications
process.env.NODE_APP_INSTANCE='defer';

// Because require'ing config creates and caches a global singleton,
// We have to invalidate the cache to build new object based on the environment variables above
var CONFIG = requireUncached('../lib/config');

// Dependencies
var vows = require('vows'),
    assert = require('assert');

exports.DeferredTest = vows.describe('Tests for deferred values').addBatch({
  'Configuration file Tests': {
    'Using deferConfig() in a config file causes value to be evaluated at the end': function() {
        // The deferred function was declared in default-defer.js
        // Then local-defer.js is located which overloads the siteTitle mentioned in the function
        // Finally the deferred configurations, now referencing the 'local' siteTitle
        assert.equal(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!');
    },

    'values which are functions remain untouched unless they are instance of DeferredConfig': function() {
        // If this had been treated as a deferred config value it would blow-up.
        assert.equal(CONFIG.welcomeEmail.aFunc(), 'Still just a function.');
    },

    // This defer function didn't use args, but relied 'this' being bound to the main config object
    "defer functions can simply refer to 'this'" : function () {
        assert.equal(CONFIG.welcomeEmail.justThis, 'Welcome to this New Instance!');
    }

  }
});

function requireUncached(module){
   delete require.cache[require.resolve(module)];
   return require(module);
}
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var {
  PropTypes,
  requireNativeComponent,
  View,
} = React;

class BarcodeScannerView extends React.Component {
  constructor() {
    super();
    this.onChange = this.onChange.bind(this);
  }

  onChange(event) {
    if (!this.props.onBarCodeRead) {
      return;
    }

    this.props.onBarCodeRead({
      type: event.nativeEvent.type,
      data: event.nativeEvent.data,
    });
  }

  render() {
    return (
      <RNBarcodeScannerView {...this.props} onChange={this.onChange} />
    );
  }
}

BarcodeScannerView.propTypes = {
  ...View.propTypes,
  viewFinderBackgroundColor: PropTypes.string,
  viewFinderBorderColor: PropTypes.string,
  viewFinderBorderWidth: PropTypes.number,
  viewFinderBorderLength: PropTypes.number,
  viewFinderDrawLaser: PropTypes.bool,
  viewFinderLaserColor: PropTypes.string,
  torchMode: PropTypes.string,
  cameraType: PropTypes.string,
  onBarCodeRead: PropTypes.func,
  rotation: PropTypes.number,
  scaleX: PropTypes.number,
  scaleY: PropTypes.number,
  translateX: PropTypes.number,
  translateY: PropTypes.number,
};

var RNBarcodeScannerView = requireNativeComponent('RNBarcodeScannerView', BarcodeScannerView, {
  nativeOnly: {onChange: true}
});

module.exports = BarcodeScannerView;
<commit_msg>add required "props" to constructor<commit_after>'use strict';

var React = require('react-native');
var {
  PropTypes,
  requireNativeComponent,
  View,
} = React;

class BarcodeScannerView extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
  }

  onChange(event) {
    if (!this.props.onBarCodeRead) {
      return;
    }

    this.props.onBarCodeRead({
      type: event.nativeEvent.type,
      data: event.nativeEvent.data,
    });
  }

  render() {
    return (
      <RNBarcodeScannerView {...this.props} onChange={this.onChange} />
    );
  }
}

BarcodeScannerView.propTypes = {
  ...View.propTypes,
  viewFinderBackgroundColor: PropTypes.string,
  viewFinderBorderColor: PropTypes.string,
  viewFinderBorderWidth: PropTypes.number,
  viewFinderBorderLength: PropTypes.number,
  viewFinderDrawLaser: PropTypes.bool,
  viewFinderLaserColor: PropTypes.string,
  torchMode: PropTypes.string,
  cameraType: PropTypes.string,
  onBarCodeRead: PropTypes.func,
  rotation: PropTypes.number,
  scaleX: PropTypes.number,
  scaleY: PropTypes.number,
  translateX: PropTypes.number,
  translateY: PropTypes.number,
};

var RNBarcodeScannerView = requireNativeComponent('RNBarcodeScannerView', BarcodeScannerView, {
  nativeOnly: {onChange: true}
});

module.exports = BarcodeScannerView;
<|endoftext|>


<commit_before>'use strict'

// ===================================================================

var Bluebird = require('bluebird')
var Collection = require('xo-collection').default
var forEach = require('lodash.foreach')
var Index = require('xo-collection/index')
var isString = require('lodash.isstring')
var startsWith = require('lodash.startswith')
var UniqueIndex = require('xo-collection/unique-index')

var Api = require('./api')
var BackOff = require('./back-off')
var ConnectionError = require('./connection-error')
var SessionError = require('./session-error')

// ===================================================================

// function bind (fn, thisArg) {
//   if (!fn) {
//     return fn
//   }

//   return function () {
//     return fn.apply(thisArg, arguments)
//   }
// }

function makeStandaloneDeferred () {
  var resolve, reject

  var promise = new Bluebird(function (resolve_, reject_) {
    resolve = resolve_
    reject = reject_
  })
  promise.resolve = resolve
  promise.reject = reject

  return promise
}

function noop () {}

// var trace =
//   bind(console.trace, console) ||
//   bind(console.log, console) ||
//   noop

// -------------------------------------------------------------------

var defineProperty = Object.defineProperty

function getDeprecatedUUID () {
  // trace('.UUID is deprecated, use .id instead')

  return this.id
}

function defineDeprecatedUUID (object) {
  defineProperty(object, 'UUID', {
    get: getDeprecatedUUID
  })
}

// var LINK_RE = /^(.*)\$link\$$/
// function createAutoLinks (collection, object) {
//   var all = collection.all

//   forEach(object, function resolveObject (value, key, object) {
//     var matches = key.match(LINK_RE)
//     if (!matches) {
//       return
//     }

//     defineProperty(object, matches[1], {
//       get: function () {
//         return all[value]
//       }
//     })
//   })
// }

function setMultiple (collection, items) {
  var messages = collection.indexes.messagesByObject

  forEach(items, function (item, key) {
    defineDeprecatedUUID(item)
    // createAutoLinks(collection, item)

    defineProperty(item, 'messages', {
      get: function () {
        return messages[key]
      }
    })

    collection.set(key, item)
  })
}

function unsetMultiple (collection, items) {
  forEach(items, function (_, key) {
    if (collection.has(key)) {
      collection.remove(key)
    }
  })
}

// ===================================================================

function Xo (opts) {
  if (!opts) {
    opts = {}
  } else if (isString(opts)) {
    opts = {
      url: opts
    }
  }

  // -----------------------------------------------------------------

  var api = new Api(opts.url)

  api.on('connected', function () {
    this._backOff.reset()
    this.status = 'connected'

    this._tryToOpenSession()
  }.bind(this))

  api.on('disconnected', function () {
    this._closeSession()
    this._connect()
  }.bind(this))

  api.on('notification', function (notification) {
    if (notification.method !== 'all') {
      return
    }

    var method = notification.params.type === 'exit' ?
      unsetMultiple :
      setMultiple

    method(this.objects, notification.params.items)
  }.bind(this))

  // -----------------------------------------------------------------

  var objects = this.objects = new Collection()
  objects.createIndex('ref', new UniqueIndex('ref'))
  objects.createIndex('type', new Index('type'))
  objects.createIndex('messagesByObject', new Index(function (obj) {
    if (obj.type === 'message') {
      return obj.$object
    }
  }))

  this.status = 'disconnected'
  this.user = null

  this._api = api
  this._backOff = new BackOff()
  this._credentials = opts.creadentials
  this._session = makeStandaloneDeferred()
  this._signIn = null

  // -----------------------------------------------------------------

  this._connect()
}

Xo.prototype.call = function (method, params) {
  // Prevent session.*() from being because it may interfere
  // with this class session management.
  if (startsWith(method, 'session.')) {
    return Bluebird.reject(
      new Error('session.*() methods are disabled from this interface')
    )
  }

  return this._session.bind(this).then(function () {
    return this._api.call(method, params)
  }).catch(ConnectionError, SessionError, function () {
    // Automatically requeue this call.
    return this.call(method, params)
  })
}

Xo.prototype.signIn = function (credentials) {
  this.signOut()

  this._credentials = credentials
  this._signIn = makeStandaloneDeferred()

  this._tryToOpenSession()

  return this._signIn
}

Xo.prototype.signOut = function () {
  this._closeSession()
  this._credentials = null

  var signIn = this._signIn
  if (signIn && signIn.isPending()) {
    signIn.reject(new SessionError('sign in aborted'))
  }

  return this.status === 'connected' ?

    // Attempt to sign out and ignore any return values and errors.
    this._api.call('session.signOut').then(noop, noop) :

    // Always return a promise.
    Bluebird.resolve()
}

Xo.prototype._connect = function _connect () {
  this.status = 'connecting'

  return this._api.connect().bind(this).catch(function (error) {
    console.warn('could not connect:', error)

    return this._backOff.wait().bind(this).then(_connect)
  })
}

Xo.prototype._closeSession = function () {
  if (!this._session.isPending()) {
    this._session = makeStandaloneDeferred()
  }

  this.user = null
}

Xo.prototype._tryToOpenSession = function () {
  var credentials = this._credentials
  if (!credentials || this.status !== 'connected') {
    return
  }

  this._api.call(
    credentials.token ?
      'session.signInWithToken' :
      'session.signInWithPassword',
    credentials
  ).bind(this).then(
    function (user) {
      this.user = user

      this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
        this.objects.clear()
        setMultiple(this.objects, objects)
      })

      // Validate the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.resolve()
      }

      // Open the session.
      this._session.resolve()
    },

    function (error) {
      // Reject the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.reject(error)
      }
    }
  )
}

// ===================================================================

module.exports = Xo
<commit_msg>Always use session.signIn().<commit_after>'use strict'

// ===================================================================

var Bluebird = require('bluebird')
var Collection = require('xo-collection').default
var forEach = require('lodash.foreach')
var Index = require('xo-collection/index')
var isString = require('lodash.isstring')
var startsWith = require('lodash.startswith')
var UniqueIndex = require('xo-collection/unique-index')

var Api = require('./api')
var BackOff = require('./back-off')
var ConnectionError = require('./connection-error')
var SessionError = require('./session-error')

// ===================================================================

// function bind (fn, thisArg) {
//   if (!fn) {
//     return fn
//   }

//   return function () {
//     return fn.apply(thisArg, arguments)
//   }
// }

function makeStandaloneDeferred () {
  var resolve, reject

  var promise = new Bluebird(function (resolve_, reject_) {
    resolve = resolve_
    reject = reject_
  })
  promise.resolve = resolve
  promise.reject = reject

  return promise
}

function noop () {}

// var trace =
//   bind(console.trace, console) ||
//   bind(console.log, console) ||
//   noop

// -------------------------------------------------------------------

var defineProperty = Object.defineProperty

function getDeprecatedUUID () {
  // trace('.UUID is deprecated, use .id instead')

  return this.id
}

function defineDeprecatedUUID (object) {
  defineProperty(object, 'UUID', {
    get: getDeprecatedUUID
  })
}

// var LINK_RE = /^(.*)\$link\$$/
// function createAutoLinks (collection, object) {
//   var all = collection.all

//   forEach(object, function resolveObject (value, key, object) {
//     var matches = key.match(LINK_RE)
//     if (!matches) {
//       return
//     }

//     defineProperty(object, matches[1], {
//       get: function () {
//         return all[value]
//       }
//     })
//   })
// }

function setMultiple (collection, items) {
  var messages = collection.indexes.messagesByObject

  forEach(items, function (item, key) {
    defineDeprecatedUUID(item)
    // createAutoLinks(collection, item)

    defineProperty(item, 'messages', {
      get: function () {
        return messages[key]
      }
    })

    collection.set(key, item)
  })
}

function unsetMultiple (collection, items) {
  forEach(items, function (_, key) {
    if (collection.has(key)) {
      collection.remove(key)
    }
  })
}

// ===================================================================

function Xo (opts) {
  if (!opts) {
    opts = {}
  } else if (isString(opts)) {
    opts = {
      url: opts
    }
  }

  // -----------------------------------------------------------------

  var api = new Api(opts.url)

  api.on('connected', function () {
    this._backOff.reset()
    this.status = 'connected'

    this._tryToOpenSession()
  }.bind(this))

  api.on('disconnected', function () {
    this._closeSession()
    this._connect()
  }.bind(this))

  api.on('notification', function (notification) {
    if (notification.method !== 'all') {
      return
    }

    var method = notification.params.type === 'exit' ?
      unsetMultiple :
      setMultiple

    method(this.objects, notification.params.items)
  }.bind(this))

  // -----------------------------------------------------------------

  var objects = this.objects = new Collection()
  objects.createIndex('ref', new UniqueIndex('ref'))
  objects.createIndex('type', new Index('type'))
  objects.createIndex('messagesByObject', new Index(function (obj) {
    if (obj.type === 'message') {
      return obj.$object
    }
  }))

  this.status = 'disconnected'
  this.user = null

  this._api = api
  this._backOff = new BackOff()
  this._credentials = opts.creadentials
  this._session = makeStandaloneDeferred()
  this._signIn = null

  // -----------------------------------------------------------------

  this._connect()
}

Xo.prototype.call = function (method, params) {
  // Prevent session.*() from being because it may interfere
  // with this class session management.
  if (startsWith(method, 'session.')) {
    return Bluebird.reject(
      new Error('session.*() methods are disabled from this interface')
    )
  }

  return this._session.bind(this).then(function () {
    return this._api.call(method, params)
  }).catch(ConnectionError, SessionError, function () {
    // Automatically requeue this call.
    return this.call(method, params)
  })
}

Xo.prototype.signIn = function (credentials) {
  this.signOut()

  this._credentials = credentials
  this._signIn = makeStandaloneDeferred()

  this._tryToOpenSession()

  return this._signIn
}

Xo.prototype.signOut = function () {
  this._closeSession()
  this._credentials = null

  var signIn = this._signIn
  if (signIn && signIn.isPending()) {
    signIn.reject(new SessionError('sign in aborted'))
  }

  return this.status === 'connected' ?

    // Attempt to sign out and ignore any return values and errors.
    this._api.call('session.signOut').then(noop, noop) :

    // Always return a promise.
    Bluebird.resolve()
}

Xo.prototype._connect = function _connect () {
  this.status = 'connecting'

  return this._api.connect().bind(this).catch(function (error) {
    console.warn('could not connect:', error)

    return this._backOff.wait().bind(this).then(_connect)
  })
}

Xo.prototype._closeSession = function () {
  if (!this._session.isPending()) {
    this._session = makeStandaloneDeferred()
  }

  this.user = null
}

Xo.prototype._tryToOpenSession = function () {
  var credentials = this._credentials
  if (!credentials || this.status !== 'connected') {
    return
  }

  this._api.call('session.signIn', credentials).bind(this).then(
    function (user) {
      this.user = user

      this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
        this.objects.clear()
        setMultiple(this.objects, objects)
      })

      // Validate the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.resolve()
      }

      // Open the session.
      this._session.resolve()
    },

    function (error) {
      // Reject the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.reject(error)
      }
    }
  )
}

// ===================================================================

module.exports = Xo
<|endoftext|>


<commit_before>module.exports = function(users, experiments, schema) {
    const parse = require('co-body');
    const status = require('http-status');
    const _ = require('lodash');

    return {
        updateProjectFavorites,
        updateUserSettings,
        createAccount
    };

    function* updateProjectFavorites(next) {
        let attrs = yield parse(this);
        this.body = yield users.updateProjectFavorites(this.reqctx.user.id, this.params.project_id, attrs);
        this.status = 200;
        yield next;
    }

    function* updateUserSettings(next) {
        let args = yield parse(this);
        let errors = yield validateUserSettingsArgs(args, this.reqctx.user.id);
        if (errors != null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let settingArgs = {
                default_project: args.default_project,
                default_experiment: args.default_experiment
            };
            let rv = yield users.updateUserSettings(this.reqctx.user.id, settingArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                this.body = rv.val;
            }
        }
        yield next;
    }

    function* validateUserSettingsArgs(args, userId) {
        if (!args.default_project || !_.isString(args.default_project)) {
            return {error: `Bad argument for default_project`};
        }

        let isValidProject = yield users.userHasProjectAccess(userId, args.default_project);
        if (!isValidProject) {
            return {error: `No such project: ${args.default_project}`};
        }

        if (args.default_experiment && !_.isString(args.default_experiment)) {
            return {error: `Bad argument for default_experiment`};
        }

        if (args.default_experiment) {
            let experimentInProject = yield experiments.experimentExistsInProject(args.default_project, args.default_experiment);
            if (!experimentInProject) {
                return {error: `No such experiment ${args.default_experiment} in project ${args.default_project}`};
            }
        } else {
            args.default_experiment = '';
        }

        return null;
    }

    function* createAccount(next) {
        let accountArgs = yield parse(this);
        schema.prepare(schema.userAccountSchema, accountArgs);
        let errors = yield validateCreateAccount(accountArgs);
        if (errors !== null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let rv = yield users.createUnverifiedAccount(accountArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                let evl = yield emailValidationLink(rv.val);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = evl.val;
                }
            }
        }
        yield next;
    }

    function* validateCreateAccount(accountArgs) {
        return yield schema.validate(schema.userAccountSchema, accountArgs);
    }

    function* emailValidationLink(userData) {
        console.log("emailValidation 01");
        var nodemailer = require('nodemailer');

        console.log("emailValidation 02");

        // create reusable transporter object using the default SMTP transport
        var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass@smtp.gmail.com');

        console.log("emailValidation 03");

        // setup e-mail data with unicode symbols
        var mailOptions = {
            from: '"Fred Foo 👥" <foo@blurdybloop.com>', // sender address
            to: 'bar@blurdybloop.com, baz@blurdybloop.com', // list of receivers
            subject: 'Hello ✔', // Subject line
            text: 'Hello world 🐴', // plaintext body
            html: 'Hello world 🐴' // html body
        };

        console.log("emailValidation 04");

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return console.log('Send error: ' + error);
            }
            console.log('Message sent: ' + info.response);
        });

        console.log("emailValidation 05");

        return {val: userData}
    }
};
<commit_msg>Send verifification link to user; based on gmail account as defined by environmental varialbes<commit_after>module.exports = function(users, experiments, schema) {
    const parse = require('co-body');
    const status = require('http-status');
    const _ = require('lodash');

    return {
        updateProjectFavorites,
        updateUserSettings,
        createAccount
    };

    function* updateProjectFavorites(next) {
        let attrs = yield parse(this);
        this.body = yield users.updateProjectFavorites(this.reqctx.user.id, this.params.project_id, attrs);
        this.status = 200;
        yield next;
    }

    function* updateUserSettings(next) {
        let args = yield parse(this);
        let errors = yield validateUserSettingsArgs(args, this.reqctx.user.id);
        if (errors != null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let settingArgs = {
                default_project: args.default_project,
                default_experiment: args.default_experiment
            };
            let rv = yield users.updateUserSettings(this.reqctx.user.id, settingArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                this.body = rv.val;
            }
        }
        yield next;
    }

    function* validateUserSettingsArgs(args, userId) {
        if (!args.default_project || !_.isString(args.default_project)) {
            return {error: `Bad argument for default_project`};
        }

        let isValidProject = yield users.userHasProjectAccess(userId, args.default_project);
        if (!isValidProject) {
            return {error: `No such project: ${args.default_project}`};
        }

        if (args.default_experiment && !_.isString(args.default_experiment)) {
            return {error: `Bad argument for default_experiment`};
        }

        if (args.default_experiment) {
            let experimentInProject = yield experiments.experimentExistsInProject(args.default_project, args.default_experiment);
            if (!experimentInProject) {
                return {error: `No such experiment ${args.default_experiment} in project ${args.default_project}`};
            }
        } else {
            args.default_experiment = '';
        }

        return null;
    }

    function* createAccount(next) {
        let accountArgs = yield parse(this);
        schema.prepare(schema.userAccountSchema, accountArgs);
        let errors = yield validateCreateAccount(accountArgs);
        if (errors !== null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let rv = yield users.createUnverifiedAccount(accountArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                let evl = yield emailValidationLink(rv.val);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = evl.val;
                }
            }
        }
        yield next;
    }

    function* validateCreateAccount(accountArgs) {
        return yield schema.validate(schema.userAccountSchema, accountArgs);
    }

    function* emailValidationLink(userData) {
        var nodemailer = require('nodemailer');

        var fromEmailAddress = process.env.MC_VERIFY_EMAIL;
        var fromEmailPass = process.env.MC_VERIFY_PASS;
        var mailURL = 'smtps://' + fromEmailAddress + ':' + fromEmailPass + '@smtp.gmail.com';
        console.log(mailURL);
        var transporter = nodemailer.createTransport(mailURL);

        var sendTo = userData.id;
        var validationLink = "http://mctest.localhost/validate/" + userData.validate_uuid;
        var planTextBody = "Validate with the URL: " + validationLink;
        var htmlBody = "Validate with this link: " + validationLink;

        var mailOptions = {
            from: fromEmailAddress,
            to: sendTo,
            subject: 'MaterialCommons - login verification',
            text: planTextBody,
            html: htmlBody
        };

        console.log("emailValidation: " + sendTo);

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                console.log('Send error: ' + error);
                return error;
            }
            console.log('Message sent: ' + info.response);
        });

        return {val: userData}
    }
};
<|endoftext|>


<commit_before>/**
 * @module ogs.vgl
 */

/**
 * Create a new instance of class renderState
 *
 * @class vglModule.renderState
 * @returns {vglModule.renderState}
 */
vglModule.renderState = function() {
  this.m_modelViewMatrix = mat4.create();
  this.m_projectionMatrix = null;
  this.m_material = null;
  this.m_mapper = null;
};

/**
 * Create a new instance of class renderer
 *
 * @class vglModule.renderer
 * @returns {vglModule.renderer}
 */
vglModule.renderer = function() {

  if (!(this instanceof vglModule.renderer)) {
    return new vglModule.renderer();
  }
  vglModule.object.call(this);

  /** @private */
  var m_backgroundColor = [1.0, 1.0, 1.0, 1.0];

  /** @private */
  var m_sceneRoot = new vglModule.groupNode();

  /** @private */
  var m_camera = new vglModule.camera();
  m_camera.addChild(m_sceneRoot);

  /**
   * Get background color
   */
  this.backgroundColor = function() {
    return m_backgroundColor;
  };

  /**
   * Set background color
   */
  this.setBackgroundColor = function(r, g, b, a) {
    m_backgroundColor[0] = r;
    m_backgroundColor[1] = g;
    m_backgroundColor[2] = b;
    m_backgroundColor[3] = a;

    this.modified();
  }

  /**
   * Get scene root
   */
  this.sceneRoot = function() {
    return m_sceneRoot;
  };

  /**
   * Get main camera of the renderer
   */
  this.camera = function() {
    return m_camera;
  };

  /**
   * Render the scene
   */
  this.render = function() {
    gl.clearColor(m_backgroundColor[0], m_backgroundColor[1],
      m_backgroundColor[2], m_backgroundColor[3]);
    gl.enable(gl.DEPTH_TEST);
    gl.depthFunc(gl.LEQUAL);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    perspectiveMatrix = m_camera.projectionMatrix();

    var renSt = new vglModule.renderState();
    renSt.m_projectionMatrix = perspectiveMatrix;
    var children = m_sceneRoot.children();
    for ( var i = 0; i < children.length; ++i) {
      var actor = children[i];
      actor.computeBounds();
      if (actor.visible() === false) {
        continue;
      }

      mat4.multiply(renSt.m_modelViewMatrix, m_camera.viewMatrix(),
                    actor.matrix());
      renSt.m_material = actor.material();
      renSt.m_mapper = actor.mapper();

      // TODO Fix this shortcut

      renSt.m_material.render(renSt);
      renSt.m_mapper.render(renSt);
      renSt.m_material.remove(renSt);
    }
  };

  /**
   * Automatically set up the camera based on visible actors
   */
  this.resetCamera = function() {
    m_camera.computeBounds();

    var vn = m_camera.directionOfProjection();
    var visibleBounds = m_camera.bounds();

    // console.log('visibleBounds ', visibleBounds);

    var center = [
      (visibleBounds[0] + visibleBounds[1]) / 2.0,
      (visibleBounds[2] + visibleBounds[3]) / 2.0,
      (visibleBounds[4] + visibleBounds[5]) / 2.0];

    // console.log('center ', center);

    var diagonals = [
      visibleBounds[1] - visibleBounds[0],
      visibleBounds[3] - visibleBounds[2],
      visibleBounds[5] - visibleBounds[4],
    ];

    var radius = 0.0;
    if (diagonals[0] > diagonals[1]) {
      if (diagonals[0] > diagonals[2]) {
        radius = diagonals[0] / 2.0;
      } else {
        radius = diagonals[2] / 2.0;
      }
    } else {
      if (diagonals[1] > diagonals[2]) {
        radius = diagonals[1] / 2.0;
      } else {
        radius = diagonals[2] / 2.0;
      }
    }

    var aspect = m_camera.viewAspect();
    var angle = m_camera.viewAngle();

    // @todo Need to figure out what's happening here
    if (aspect >= 1.0) {
      angle = 2.0 * Math.atan(Math.tan(angle * 0.5) / aspect);
    } else {
      angle = 2.0 * Math.atan(Math.tan(angle * 0.5) * aspect);
    }

    var distance =  radius / Math.sin(angle * 0.5);

    var vup = m_camera.viewUpDirection();

    if (Math.abs(vec3.dot(vup, vn)) > 0.999) {
      m_camera.setViewDirection(-vup[2], vup[0], vup[1]);
    }

    m_camera.setFocalPoint(center[0], center[1], center[2]);
    m_camera.setPosition(center[0] + distance * -vn[0],
      center[1] + distance * -vn[1], center[2] + distance * -vn[2]);
  };

  /**
   * Recalculate camera's clipping range
   */
  this.resetCameraClippingRange = function() {
    // TODO
  };

  /**
   * Resize viewport given a width and height
   */
  this.resize = function(width, height) {
    this.positionAndResize(m_x, m_y, width, height);
  };

  /**
   * Resize viewport given a position, width and height
   */
  this.positionAndResize = function(x, y, width, height) {
    // TODO move this code to camera
    gl.viewport(x, y, width, height);
    m_camera.setViewAspect(width / height);
    this.modified();
  };

  /**
   * Add new actor to the collection
   */
  this.addActor = function(actor) {
    if (actor instanceof vglModule.actor) {
      m_sceneRoot.addChild(actor);
      this.modified();
      return true;
    }

    return false;
  };

  /**
   * Remove the actor from the collection
   */
  this.removeActor = function(actor) {
    if (m_sceneRoot.children().indexOf(actor) !== -1) {
      m_sceneRoot.removeChild(actor);
      this.modified();
      return true;
    }

    return false;
  };

  /**
   * Transform a point in the world space to display space
   */
  this.worldToDisplay = function(worldPt, viewMatrix, projectionMatrix, width,
                                 height) {
    var viewProjectionMatrix = mat4.create();
    mat4.multiply(viewProjectionMatrix, projectionMatrix, viewMatrix);

    // Transform world to clipping coordinates
    var clipPt = vec4.create();
    vec4.transformMat4(clipPt, worldPt, viewProjectionMatrix);

    if (clipPt[3] !== 0.0) {
      clipPt[0] = clipPt[0] / clipPt[3];
      clipPt[1] = clipPt[1] / clipPt[3];
      clipPt[2] = clipPt[2] / clipPt[3];
      clipPt[3] = 1.0;
    }

    var winX = Math.round((((clipPt[0]) + 1) / 2.0) * width);
    // / We calculate -point3D.getY() because the screen Y axis is
    // / oriented top->down
    var winY = Math.round(((1 - clipPt[1]) / 2.0) * height);
    var winZ = clipPt[2];
    var winW = clipPt[3];

    return vec4.fromValues(winX, winY, winZ, winW);
  };

  /**
   * Transform a point in display space to world space
   */
  this.displayToWorld = function(displayPt, viewMatrix, projectionMatrix,
                                 width, height) {
    var x = (2.0 * displayPt[0] / width) - 1;
    var y = -(2.0 * displayPt[1] / height) + 1;
    var z = displayPt[2];

    var viewProjectionInverse = mat4.create();
    mat4.multiply(viewProjectionInverse, projectionMatrix, viewMatrix);
    mat4.invert(viewProjectionInverse, viewProjectionInverse);

    var worldPt = vec4.fromValues(x, y, z, 1);
    var myvec = vec4.create();
    vec4.transformMat4(worldPt, worldPt, viewProjectionInverse);
    if (worldPt[3] !== 0.0) {
      worldPt[0] = worldPt[0] / worldPt[3];
      worldPt[1] = worldPt[1] / worldPt[3];
      worldPt[2] = worldPt[2] / worldPt[3];
      worldPt[3] = 1.0;
    }

    return worldPt;
  };

  return this;
};

inherit(vglModule.renderer, vglModule.object);
<commit_msg>Re-added methods to get width and height of the renderer<commit_after>/**
 * @module ogs.vgl
 */

/**
 * Create a new instance of class renderState
 *
 * @class vglModule.renderState
 * @returns {vglModule.renderState}
 */
vglModule.renderState = function() {
  this.m_modelViewMatrix = mat4.create();
  this.m_projectionMatrix = null;
  this.m_material = null;
  this.m_mapper = null;
};

/**
 * Create a new instance of class renderer
 *
 * @class vglModule.renderer
 * @returns {vglModule.renderer}
 */
vglModule.renderer = function() {

  if (!(this instanceof vglModule.renderer)) {
    return new vglModule.renderer();
  }
  vglModule.object.call(this);

  /** @private */
  var m_backgroundColor = [1.0, 1.0, 1.0, 1.0];

  /** @private */
  var m_sceneRoot = new vglModule.groupNode();

  /** @private */
  var m_camera = new vglModule.camera();
  m_camera.addChild(m_sceneRoot);

  /** @private */
  var m_width = 0;

  /** @private */
  var m_height = 0;

  /**
   * Get width of the renderer
   */
  this.width = function() {
    return m_width;
  }

  /**
   * Get height of the renderer
   */
  this.height = function() {
    return m_height;
  }

  /**
   * Get background color
   */
  this.backgroundColor = function() {
    return m_backgroundColor;
  };

  /**
   * Set background color
   */
  this.setBackgroundColor = function(r, g, b, a) {
    m_backgroundColor[0] = r;
    m_backgroundColor[1] = g;
    m_backgroundColor[2] = b;
    m_backgroundColor[3] = a;

    this.modified();
  }

  /**
   * Get scene root
   */
  this.sceneRoot = function() {
    return m_sceneRoot;
  };

  /**
   * Get main camera of the renderer
   */
  this.camera = function() {
    return m_camera;
  };

  /**
   * Render the scene
   */
  this.render = function() {
    gl.clearColor(m_backgroundColor[0], m_backgroundColor[1],
      m_backgroundColor[2], m_backgroundColor[3]);
    gl.enable(gl.DEPTH_TEST);
    gl.depthFunc(gl.LEQUAL);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    perspectiveMatrix = m_camera.projectionMatrix();

    var renSt = new vglModule.renderState();
    renSt.m_projectionMatrix = perspectiveMatrix;
    var children = m_sceneRoot.children();
    for ( var i = 0; i < children.length; ++i) {
      var actor = children[i];
      actor.computeBounds();
      if (actor.visible() === false) {
        continue;
      }

      mat4.multiply(renSt.m_modelViewMatrix, m_camera.viewMatrix(),
                    actor.matrix());
      renSt.m_material = actor.material();
      renSt.m_mapper = actor.mapper();

      // TODO Fix this shortcut

      renSt.m_material.render(renSt);
      renSt.m_mapper.render(renSt);
      renSt.m_material.remove(renSt);
    }
  };

  /**
   * Automatically set up the camera based on visible actors
   */
  this.resetCamera = function() {
    m_camera.computeBounds();

    var vn = m_camera.directionOfProjection();
    var visibleBounds = m_camera.bounds();

    // console.log('visibleBounds ', visibleBounds);

    var center = [
      (visibleBounds[0] + visibleBounds[1]) / 2.0,
      (visibleBounds[2] + visibleBounds[3]) / 2.0,
      (visibleBounds[4] + visibleBounds[5]) / 2.0];

    // console.log('center ', center);

    var diagonals = [
      visibleBounds[1] - visibleBounds[0],
      visibleBounds[3] - visibleBounds[2],
      visibleBounds[5] - visibleBounds[4],
    ];

    var radius = 0.0;
    if (diagonals[0] > diagonals[1]) {
      if (diagonals[0] > diagonals[2]) {
        radius = diagonals[0] / 2.0;
      } else {
        radius = diagonals[2] / 2.0;
      }
    } else {
      if (diagonals[1] > diagonals[2]) {
        radius = diagonals[1] / 2.0;
      } else {
        radius = diagonals[2] / 2.0;
      }
    }

    var aspect = m_camera.viewAspect();
    var angle = m_camera.viewAngle();

    // @todo Need to figure out what's happening here
    if (aspect >= 1.0) {
      angle = 2.0 * Math.atan(Math.tan(angle * 0.5) / aspect);
    } else {
      angle = 2.0 * Math.atan(Math.tan(angle * 0.5) * aspect);
    }

    var distance =  radius / Math.sin(angle * 0.5);

    var vup = m_camera.viewUpDirection();

    if (Math.abs(vec3.dot(vup, vn)) > 0.999) {
      m_camera.setViewDirection(-vup[2], vup[0], vup[1]);
    }

    m_camera.setFocalPoint(center[0], center[1], center[2]);
    m_camera.setPosition(center[0] + distance * -vn[0],
      center[1] + distance * -vn[1], center[2] + distance * -vn[2]);
  };

  /**
   * Recalculate camera's clipping range
   */
  this.resetCameraClippingRange = function() {
    // TODO
  };

  /**
   * Resize viewport given a width and height
   */
  this.resize = function(width, height) {
    this.positionAndResize(m_x, m_y, width, height);
  };

  /**
   * Resize viewport given a position, width and height
   */
  this.positionAndResize = function(x, y, width, height) {
    // TODO move this code to camera
    gl.viewport(x, y, width, height);
    m_camera.setViewAspect(width / height);
    this.modified();
  };

  /**
   * Add new actor to the collection
   */
  this.addActor = function(actor) {
    if (actor instanceof vglModule.actor) {
      m_sceneRoot.addChild(actor);
      this.modified();
      return true;
    }

    return false;
  };

  /**
   * Remove the actor from the collection
   */
  this.removeActor = function(actor) {
    if (m_sceneRoot.children().indexOf(actor) !== -1) {
      m_sceneRoot.removeChild(actor);
      this.modified();
      return true;
    }

    return false;
  };

  /**
   * Transform a point in the world space to display space
   */
  this.worldToDisplay = function(worldPt, viewMatrix, projectionMatrix, width,
                                 height) {
    var viewProjectionMatrix = mat4.create();
    mat4.multiply(viewProjectionMatrix, projectionMatrix, viewMatrix);

    // Transform world to clipping coordinates
    var clipPt = vec4.create();
    vec4.transformMat4(clipPt, worldPt, viewProjectionMatrix);

    if (clipPt[3] !== 0.0) {
      clipPt[0] = clipPt[0] / clipPt[3];
      clipPt[1] = clipPt[1] / clipPt[3];
      clipPt[2] = clipPt[2] / clipPt[3];
      clipPt[3] = 1.0;
    }

    var winX = Math.round((((clipPt[0]) + 1) / 2.0) * width);
    // / We calculate -point3D.getY() because the screen Y axis is
    // / oriented top->down
    var winY = Math.round(((1 - clipPt[1]) / 2.0) * height);
    var winZ = clipPt[2];
    var winW = clipPt[3];

    return vec4.fromValues(winX, winY, winZ, winW);
  };

  /**
   * Transform a point in display space to world space
   */
  this.displayToWorld = function(displayPt, viewMatrix, projectionMatrix,
                                 width, height) {
    var x = (2.0 * displayPt[0] / width) - 1;
    var y = -(2.0 * displayPt[1] / height) + 1;
    var z = displayPt[2];

    var viewProjectionInverse = mat4.create();
    mat4.multiply(viewProjectionInverse, projectionMatrix, viewMatrix);
    mat4.invert(viewProjectionInverse, viewProjectionInverse);

    var worldPt = vec4.fromValues(x, y, z, 1);
    var myvec = vec4.create();
    vec4.transformMat4(worldPt, worldPt, viewProjectionInverse);
    if (worldPt[3] !== 0.0) {
      worldPt[0] = worldPt[0] / worldPt[3];
      worldPt[1] = worldPt[1] / worldPt[3];
      worldPt[2] = worldPt[2] / worldPt[3];
      worldPt[3] = 1.0;
    }

    return worldPt;
  };

  return this;
};

inherit(vglModule.renderer, vglModule.object);
<|endoftext|>


<commit_before>import React from 'react';
import uuid from 'uuid';
import { connect } from 'react-redux';
import { Form, Grid, FormControl, Button, Glyphicon, Row, Col, FormGroup } from 'react-bootstrap';
import { translate } from 'react-i18next';
// FIXME: we should maybe pick one? :)
import R from 'ramda';
import _ from 'lodash';

import { ListActions } from '../../actions';
import { ListItem, ShareList } from '../../components';

const mapStateToProps = (state) => {
  return {
    todos: state.todo.lists,
  };
};

@translate(['common', 'todo'])
@connect(mapStateToProps)
export default class CreateList extends React.Component {

  static contextTypes = {
    router: React.PropTypes.object,
  };

  static propTypes = {
    t: React.PropTypes.func.isRequired,
    dispatch: React.PropTypes.func.isRequired,
    params: React.PropTypes.shape({
      listId: React.PropTypes.string,
    }),
    todos: React.PropTypes.array,
  };

  static defaultProps = {
    params: {},
    todos: [],
  }

  constructor(props) {
    super(props);
    this.state = {
      listTitle: '',
      itemTitle: '',
      items: [],
      existingItem: false,
    };
  }

  saveDisabled() {
    return !(this.state.listTitle &&
    this.state.items.length !== 0);
  }

  componentDidMount() {
    if (this.props.params) {
      const itemId = this.props.params.listId;
      const existingItem = R.find(obj=> String(obj.id) === itemId, this.props.todos);
      if (!existingItem) return;
      this.setState({
        listTitle: existingItem.title,
        existingItem: existingItem,
        items: existingItem.items,
      });
    }
  }

  navigateTo(url) {
    this.context.router.push(url);
  }

  // Fixes an issue with controllable/uncontrollable inputs. You might
  // wanna check if there's better way of doing this
  getListTitle() {
    return this.state.listTitle || '';
  }

  handleSaveButton() {
    var items = this.state.items;
    var title = this.state.listTitle;
    var { dispatch } = this.props;
    var data = { title, items };

    if (this.state.existingItem) {
      const id = this.state.existingItem.id;
      ListActions(dispatch).modifyList(id, data).then(() => {
        this.navigateTo('/');
      });
    } else {
      ListActions(dispatch).createList(data).then(() => {
        this.navigateTo('/');
      });
    }
  }

  handleAddItemButton(title) {
    if (title) {
      var item = {
        title,
        id: uuid.v1(),
      };
      this.setState({
        items: R.append(item, this.state.items),
      });
    }

    this.setState({ itemTitle: '' });
  }

  handleItemRemoval(itemId) {
    const tempItems = this.state.items;
    _.remove(tempItems, tempItem => tempItem.id === itemId);

    this.setState({
      items: tempItems,
    });
  }

  renderTodoListItem(item) {
    return (
      <ListItem
        key={item.id}
        date={item.updatedAt}
        allowNavigation
        removeFn={()=>this.handleItemRemoval(item.id)}
      >
        {item.title}
      </ListItem>
    );
  }

  render() {
    const { t, params } = this.props;
    const { items, listTitle } = this.state;
    const pageTitle = params.listId ? t('edit_list') + ' ' + (listTitle || '') : t('add_new_list');

    return (

        <Grid>

{pageTitle}

          <Form>
            <FormGroup>
              <Row>
                <Col xs={12}>
                  <FormControl
                    value={this.getListTitle()}
                    type="text"
                    placeholder={t('enter_title')}
                    onChange={e => this.setState({ listTitle: e.target.value })}
                  />
                </Col>
              </Row>

              <Row className="todo-create-list-add-item-container">
                <Col xs={12}>
                  <FormControl
                    value={this.state.itemTitle}
                    type="text"
                    placeholder={t('item_title')}
                    onChange={e => this.setState({ itemTitle: e.target.value })}
                  />
                  <Button
                    className="todo-create-list-add-item-button"
                    disabled={!this.state.itemTitle}
                    onClick={() => this.handleAddItemButton(this.state.itemTitle)}
                  >
                    <Glyphicon glyph="plus" />
                  </Button>
                </Col>
              </Row>
              {items.length > 0 ?

                  {
                    items && items.map ?
                    items.map(item => this.renderTodoListItem(item)) : null
                  }

                : null }
              <Row className="todo-create-list-control-buttons">
                <Col xs={12}>
                  <Button
                    className="todo-button"
                    onClick={() => this.handleSaveButton()}
                    disabled={this.saveDisabled()}
                  >

                    <Glyphicon glyph="save" />{t('save')}</Button>
                  <ShareList />
                </Col>
              </Row>
            </FormGroup>
          </Form>
        </Grid>

    );
  }
}
<commit_msg>Createlist: code cleanup<commit_after>import React from 'react';
import uuid from 'uuid';
import { connect } from 'react-redux';
import { Form, Grid, FormControl, Button, Glyphicon, Row, Col, FormGroup } from 'react-bootstrap';
import { translate } from 'react-i18next';
// FIXME: we should maybe pick one? :)
import R from 'ramda';
import _ from 'lodash';

import { ListActions } from '../../actions';
import { ListItem, ShareList } from '../../components';

const mapStateToProps = (state) => {
  return {
    todos: state.todo.lists,
  };
};

@translate(['common', 'todo'])
@connect(mapStateToProps)
export default class CreateList extends React.Component {

  static contextTypes = {
    router: React.PropTypes.object,
  };

  static propTypes = {
    t: React.PropTypes.func.isRequired,
    dispatch: React.PropTypes.func.isRequired,
    params: React.PropTypes.shape({
      listId: React.PropTypes.string,
    }),
    todos: React.PropTypes.array,
  };

  static defaultProps = {
    params: {},
    todos: [],
  }

  constructor(props) {
    super(props);
    this.state = {
      listTitle: '',
      itemTitle: '',
      items: [],
      existingItem: false,
    };
  }

  saveDisabled() {
    return !(this.state.listTitle &&
    this.state.items.length !== 0);
  }

  componentDidMount() {
    if (this.props.params) {
      const itemId = this.props.params.listId;
      const existingItem = R.find(obj=> String(obj.id) === itemId, this.props.todos);
      if (!existingItem) return;
      this.setState({
        listTitle: existingItem.title,
        existingItem: existingItem,
        items: existingItem.items,
      });
    }
  }

  navigateTo(url) {
    this.context.router.push(url);
  }

  // Fixes an issue with controllable/uncontrollable inputs. You might
  // wanna check if there's better way of doing this
  getListTitle() {
    return this.state.listTitle || '';
  }

  handleSaveButton() {
    const items = this.state.items;
    const title = this.state.listTitle;
    const { dispatch } = this.props;
    const data = { title, items };
    let promise = null;

    if (this.state.existingItem) {
      const id = this.state.existingItem.id;
      promise = ListActions(dispatch).modifyList(id, data);
    } else {
      promise = ListActions(dispatch).createList(data);
    }

    promise.then(() => {
        this.navigateTo('/');
      });
  }

  handleAddItemButton(title) {
    if (title) {
      var item = {
        title,
        id: uuid.v1(),
      };
      this.setState({
        items: R.append(item, this.state.items),
      });
    }

    this.setState({ itemTitle: '' });
  }

  handleItemRemoval(itemId) {
    const tempItems = this.state.items;
    _.remove(tempItems, tempItem => tempItem.id === itemId);

    this.setState({
      items: tempItems,
    });
  }

  renderTodoListItem(item) {
    return (
      <ListItem
        key={item.id}
        date={item.updatedAt}
        allowNavigation
        removeFn={()=>this.handleItemRemoval(item.id)}
      >
        {item.title}
      </ListItem>
    );
  }

  render() {
    const { t, params } = this.props;
    const { items, listTitle } = this.state;
    const pageTitle = params.listId ? t('edit_list') + ' ' + (listTitle || '') : t('add_new_list');

    return (

        <Grid>

{pageTitle}

          <Form>
            <FormGroup>
              <Row>
                <Col xs={12}>
                  <FormControl
                    value={this.getListTitle()}
                    type="text"
                    placeholder={t('enter_title')}
                    onChange={e => this.setState({ listTitle: e.target.value })}
                  />
                </Col>
              </Row>

              <Row className="todo-create-list-add-item-container">
                <Col xs={12}>
                  <FormControl
                    value={this.state.itemTitle}
                    type="text"
                    placeholder={t('item_title')}
                    onChange={e => this.setState({ itemTitle: e.target.value })}
                  />
                  <Button
                    className="todo-create-list-add-item-button"
                    disabled={!this.state.itemTitle}
                    onClick={() => this.handleAddItemButton(this.state.itemTitle)}
                  >
                    <Glyphicon glyph="plus" />
                  </Button>
                </Col>
              </Row>
              {items.length > 0 ?

                  {
                    items && items.map ?
                    items.map(item => this.renderTodoListItem(item)) : null
                  }

                : null }
              <Row className="todo-create-list-control-buttons">
                <Col xs={12}>
                  <Button
                    className="todo-button"
                    onClick={() => this.handleSaveButton()}
                    disabled={this.saveDisabled()}
                  >

                    <Glyphicon glyph="save" />{t('save')}</Button>
                  <ShareList />
                </Col>
              </Row>
            </FormGroup>
          </Form>
        </Grid>

    );
  }
}
<|endoftext|>


<commit_before>
TestCase("UserTest", {
    "test setting user's first name": function() {

        var u = new User();
        u.set("firstname", "Bill");
        assertEquals("Bill" , u.get("firstname"));
    }
, "test if subtitle is first and last name for humans": function() {

    var u = new User();
    u.set("firstname", "Ed");
    u.set("lastname", "Sapir");
    assertEquals("Bill Sapir", u.subtitle());
}

,"test for login": function() {

    var u = new User();
    u.set("username", "esapir");
    u.set("password", "wharf");
    assertTrue( u.login("esapir" , "wharf" ));
}
});<commit_msg>changed Bill's name to Ed<commit_after>
TestCase("UserTest", {
    "test setting user's first name": function() {

        var u = new User();
        u.set("firstname", "Bill");
        assertEquals("Bill" , u.get("firstname"));
    }
, "test if subtitle is first and last name for humans": function() {

    var u = new User();
    u.set("firstname", "Ed");
    u.set("lastname", "Sapir");
    assertEquals("Ed Sapir", u.subtitle());
}

,"test for login": function() {

    var u = new User();
    u.set("username", "esapir");
    u.set("password", "wharf");
    assertTrue( u.login("esapir" , "wharf" ));
}
});<|endoftext|>


<commit_before>'use strict'

// ===================================================================

var Bluebird = require('bluebird')
var Collection = require('xo-collection').default
var forEach = require('lodash.foreach')
var Index = require('xo-collection/index')
var isString = require('lodash.isstring')
var startsWith = require('lodash.startswith')

var Api = require('./api')
var BackOff = require('./back-off')
var ConnectionError = require('./connection-error')
var SessionError = require('./session-error')

// ===================================================================

function makeStandaloneDeferred () {
  var resolve, reject

  var promise = new Bluebird(function (resolve_, reject_) {
    resolve = resolve_
    reject = reject_
  })
  promise.resolve = resolve
  promise.reject = reject

  return promise
}

function noop () {}

function setMultiple (collection, items) {
  forEach(items, function (item) {
    collection.set(item)
  })
}

function unsetMultiple (collection, items) {
  forEach(items, function (item) {
    collection.unset(item)
  })
}

// ===================================================================

function Xo (opts) {
  if (!opts) {
    opts = {}
  } else if (isString(opts)) {
    opts = {
      url: opts
    }
  }

  // -----------------------------------------------------------------

  var api = new Api(opts.url)

  api.on('connected', function () {
    this._backOff.reset()
    this.status = 'connected'

    this._tryToOpenSession()
  }.bind(this))

  api.on('disconnected', function () {
    this._closeSession()
    this._connect()
  }.bind(this))

  api.on('notification', function (notification) {
    if (notification.method !== 'all') {
      return
    }

    var method = notification.params.type === 'exit' ?
      unsetMultiple :
      setMultiple

    method(this.objects, notification.params.items)
  }.bind(this))

  // -----------------------------------------------------------------

  var objects = this.objects = new Collection()
  objects.getKey = function (item) {
    return item.UUID || item.ref || 'undefined'
  }
  objects.createIndex('ref', new Index('ref'))
  objects.createIndex('type', new Index('type'))
  objects.createIndex('UUID', new Index('UUID'))

  this.status = 'disconnected'
  this.user = null

  this._api = api
  this._backOff = new BackOff()
  this._credentials = opts.creadentials
  this._session = makeStandaloneDeferred()
  this._signIn = null

  // -----------------------------------------------------------------

  this._connect()
}

Xo.prototype.call = function (method, params) {
  // Prevent session.*() from being because it may interfere
  // with this class session management.
  if (startsWith(method, 'session.')) {
    return Bluebird.reject(
      new Error('session.*() methods are disabled from this interface')
    )
  }

  return this._session.bind(this).then(function () {
    return this._api.call(method, params)
  }).catch(ConnectionError, SessionError, function () {
    // Automatically requeue this call.
    return this.call(method, params)
  })
}

Xo.prototype.signIn = function (credentials) {
  this.signOut()

  this._credentials = credentials
  this._signIn = makeStandaloneDeferred()

  this._tryToOpenSession()

  return this._signIn
}

Xo.prototype.signOut = function () {
  this._closeSession()
  this._credentials = null

  var signIn = this._signIn
  if (signIn && signIn.isPending()) {
    signIn.reject(new SessionError('sign in aborted'))
  }

  return this.status === 'connected' ?

    // Attempt to sign out and ignore any return values and errors.
    this._api.call('session.signOut').then(noop, noop) :

    // Always return a promise.
    Bluebird.resolve()
}

Xo.prototype._connect = function _connect () {
  this.status = 'connecting'

  return this._api.connect().bind(this).catch(function (error) {
    console.warn('could not connect:', error)

    return this._backOff.wait().bind(this).then(_connect)
  })
}

Xo.prototype._closeSession = function () {
  if (!this._session.isPending()) {
    this._session = makeStandaloneDeferred()
  }

  this.user = null
}

Xo.prototype._tryToOpenSession = function () {
  var credentials = this._credentials
  if (!credentials || this.status !== 'connected') {
    return
  }

  this._api.call(
    credentials.token ?
      'session.signInWithToken' :
      'session.signInWithPassword',
    credentials
  ).bind(this).then(
    function (user) {
      this.user = user

      this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
        this.objects.clear()
        setMultiple(this.objects, objects)
      })

      // Validate the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.resolve()
      }

      // Open the session.
      this._session.resolve()
    },

    function (error) {
      // Reject the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.reject(error)
      }
    }
  )
}

// ===================================================================

module.exports = Xo
<commit_msg>Auto links.<commit_after>'use strict'

// ===================================================================

var Bluebird = require('bluebird')
var Collection = require('xo-collection').default
var forEach = require('lodash.foreach')
var Index = require('xo-collection/index')
var isString = require('lodash.isstring')
var startsWith = require('lodash.startswith')

var Api = require('./api')
var BackOff = require('./back-off')
var ConnectionError = require('./connection-error')
var SessionError = require('./session-error')

// ===================================================================

function makeStandaloneDeferred () {
  var resolve, reject

  var promise = new Bluebird(function (resolve_, reject_) {
    resolve = resolve_
    reject = reject_
  })
  promise.resolve = resolve
  promise.reject = reject

  return promise
}

function noop () {}

// -------------------------------------------------------------------

var defineProperty = Object.defineProperty

var LINK_RE = /^(.*)\$link\$$/

function createAutoLinks (collection, object) {
  forEach(object, function resolveObject (value, key, object) {
    var matches = key.match(LINK_RE)
    if (!matches) {
      return
    }

    defineProperty(object, matches[1], {
      get: function () {
        return collection[value]
      }
    })
  })
}

function setMultiple (collection, items) {
  forEach(items, function (item) {
    createAutoLinks(item)

    collection.set(item)
  })
}

function unsetMultiple (collection, items) {
  forEach(items, function (item) {
    collection.unset(item)
  })
}

// ===================================================================

function Xo (opts) {
  if (!opts) {
    opts = {}
  } else if (isString(opts)) {
    opts = {
      url: opts
    }
  }

  // -----------------------------------------------------------------

  var api = new Api(opts.url)

  api.on('connected', function () {
    this._backOff.reset()
    this.status = 'connected'

    this._tryToOpenSession()
  }.bind(this))

  api.on('disconnected', function () {
    this._closeSession()
    this._connect()
  }.bind(this))

  api.on('notification', function (notification) {
    if (notification.method !== 'all') {
      return
    }

    var method = notification.params.type === 'exit' ?
      unsetMultiple :
      setMultiple

    method(this.objects, notification.params.items)
  }.bind(this))

  // -----------------------------------------------------------------

  var objects = this.objects = new Collection()
  objects.getKey = function (item) {
    return item.UUID || item.ref || 'undefined'
  }
  objects.createIndex('ref', new Index('ref'))
  objects.createIndex('type', new Index('type'))
  objects.createIndex('uuid', new Index('uuid'))

  this.status = 'disconnected'
  this.user = null

  this._api = api
  this._backOff = new BackOff()
  this._credentials = opts.creadentials
  this._session = makeStandaloneDeferred()
  this._signIn = null

  // -----------------------------------------------------------------

  this._connect()
}

Xo.prototype.call = function (method, params) {
  // Prevent session.*() from being because it may interfere
  // with this class session management.
  if (startsWith(method, 'session.')) {
    return Bluebird.reject(
      new Error('session.*() methods are disabled from this interface')
    )
  }

  return this._session.bind(this).then(function () {
    return this._api.call(method, params)
  }).catch(ConnectionError, SessionError, function () {
    // Automatically requeue this call.
    return this.call(method, params)
  })
}

Xo.prototype.signIn = function (credentials) {
  this.signOut()

  this._credentials = credentials
  this._signIn = makeStandaloneDeferred()

  this._tryToOpenSession()

  return this._signIn
}

Xo.prototype.signOut = function () {
  this._closeSession()
  this._credentials = null

  var signIn = this._signIn
  if (signIn && signIn.isPending()) {
    signIn.reject(new SessionError('sign in aborted'))
  }

  return this.status === 'connected' ?

    // Attempt to sign out and ignore any return values and errors.
    this._api.call('session.signOut').then(noop, noop) :

    // Always return a promise.
    Bluebird.resolve()
}

Xo.prototype._connect = function _connect () {
  this.status = 'connecting'

  return this._api.connect().bind(this).catch(function (error) {
    console.warn('could not connect:', error)

    return this._backOff.wait().bind(this).then(_connect)
  })
}

Xo.prototype._closeSession = function () {
  if (!this._session.isPending()) {
    this._session = makeStandaloneDeferred()
  }

  this.user = null
}

Xo.prototype._tryToOpenSession = function () {
  var credentials = this._credentials
  if (!credentials || this.status !== 'connected') {
    return
  }

  this._api.call(
    credentials.token ?
      'session.signInWithToken' :
      'session.signInWithPassword',
    credentials
  ).bind(this).then(
    function (user) {
      this.user = user

      this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
        this.objects.clear()
        setMultiple(this.objects, objects)
      })

      // Validate the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.resolve()
      }

      // Open the session.
      this._session.resolve()
    },

    function (error) {
      // Reject the sign in.
      var signIn = this._signIn
      if (signIn) {
        signIn.reject(error)
      }
    }
  )
}

// ===================================================================

module.exports = Xo
<|endoftext|>


<commit_before>var Radium = new function ($) {
	"use strict";

	/**
	 * Initialise the ArkAdmin theme
	 * @param charts
	 */
	this.init = function (charts) {
		initControls();
		// initDatePickers();
		initMenus();
		// //init code highlighter
		// if (typeof prettyPrint === "function"){
		// 	prettyPrint();
		// }
		// initCharts(charts);
		updateContentHeight();
		$('body').resize(function (){
			updateContentHeight();
		});
	};

	/**
	 * Update the height of the content to match the window size
	 */
	function updateContentHeight(){
		var windowHeight = $(window).height();
		var navHeight = $('.navbar-main').height();
		$('.content').css('min-height', (windowHeight - navHeight-1) + "px");
	}

	/**
	 * Init toggle open menu functionality
	 */
	function initMenus() {
		function toggleMenu($menu){
			$menu.toggleClass('open');
		}
		$(document).on('click', '.menu .menu-toggle', function (event){
			event.preventDefault();
			toggleMenu($(this).parents('.menu').first());
		});
	}

	/**
	 * Init the form controls and other input functionality
	 */
	function initControls() {
		// set up textarea autosize
		$('textarea').autosize();
		// set up tooltips
		$('[data-toggle="tooltip"]').tooltip();
		// set up checkbox/radiobox styles
		$("input:checkbox, input:radio").uniform();

		// set up select2
		$('select').select2();
	}

}(jQuery);

/**
 * Radium Init method
 */
jQuery(function () {
	"use strict";
	Radium.init();
});<commit_msg>Added switching of content elements based on type.<commit_after>var Radium = new function ($) {
	"use strict";

	/**
	 * Initialise the ArkAdmin theme
	 * @param charts
	 */
	this.init = function (charts) {
		initControls();
		// initDatePickers();
		initMenus();
		initDataswitch();
		// //init code highlighter
		// if (typeof prettyPrint === "function"){
		// 	prettyPrint();
		// }
		// initCharts(charts);
		updateContentHeight();
		$('body').resize(function (){
			updateContentHeight();
		});
	};

	/**
	 * Update the height of the content to match the window size
	 */
	function updateContentHeight(){
		var windowHeight = $(window).height();
		var navHeight = $('.navbar-main').height();
		$('.content').css('min-height', (windowHeight - navHeight-1) + "px");
	}

	/**
	 * Init toggle open menu functionality
	 */
	function initMenus() {
		function toggleMenu($menu){
			$menu.toggleClass('open');
		}
		$(document).on('click', '.menu .menu-toggle', function (event){
			event.preventDefault();
			toggleMenu($(this).parents('.menu').first());
		});
	}

	/**
	 * Init the form controls and other input functionality
	 */
	function initControls() {
		// set up textarea autosize
		$('textarea').autosize();
		// set up tooltips
		$('[data-toggle="tooltip"]').tooltip();
		// set up checkbox/radiobox styles
		$("input:checkbox:visible, input:radio:visible").uniform();
		// set up select2
		$('select').select2();
	}

	function initDataswitch() {
		$('body').on('change', '[data-switch]', function(e){
			var name = $(this).attr('data-switch'),
				val = $(this).val(),
				target = name + '_' + val;

			$('[class*="' + name + '_"]').hide();
			if (this.value !== '') {
				$('div.'+target).show();
			}
		});
		$('[data-switch]').trigger('change');
	}

}(jQuery);

/**
 * Radium Init method
 */
jQuery(function () {
	"use strict";
	Radium.init();
});<|endoftext|>