<commit_before>'use strict';

const _ = require('lodash');
const React = require('react');
const ReactNative = require('react-native');
const flattenStyle = require('flattenStyle');
const ImageCacheProvider = require('./ImageCacheProvider');

const {
    Image,
    ActivityIndicator,
    NetInfo,
    Platform
} = ReactNative;

const {
    StyleSheet
} = ReactNative;

const styles = StyleSheet.create({
    image: {
        backgroundColor: 'transparent'
    },
    loader: {
        backgroundColor: 'transparent',
    },
    loaderPlaceholder: {
        backgroundColor: 'transparent',
        alignItems: 'center',
        justifyContent: 'center'
    }
});

function getImageProps(props) {
    return _.omit(props, ['source', 'defaultSource', 'activityIndicatorProps', 'style', 'useQueryParamsInCacheKey', 'renderImage']);
}

const CACHED_IMAGE_REF = 'cachedImage';

const CachedImage = React.createClass({
    propTypes: {
        renderImage: React.PropTypes.func.isRequired,
        activityIndicatorProps: React.PropTypes.object.isRequired,
        useQueryParamsInCacheKey: React.PropTypes.oneOfType([
            React.PropTypes.bool,
            React.PropTypes.array
        ]).isRequired
    },

    getDefaultProps() {
        return {
            renderImage: props => (<Image ref={CACHED_IMAGE_REF} {...props}/>),
            activityIndicatorProps: {},
            useQueryParamsInCacheKey: false
        };
    },

    setNativeProps(nativeProps) {
        try {
            this.refs[CACHED_IMAGE_REF].setNativeProps(nativeProps);
        } catch (e) {
            console.error(e);
        }
    },

    getInitialState() {
        this._isMounted = false;
        return {
            isCacheable: false,
            cachedImagePath: null,
            networkAvailable: true
        };
    },

    safeSetState(newState) {
        if (!this._isMounted) {
            return;
        }
        return this.setState(newState);
    },

    componentWillMount() {
        this._isMounted = true;
        NetInfo.isConnected.addEventListener('change', this.handleConnectivityChange);
        // initial
        NetInfo.isConnected.fetch()
            .then(isConnected => {
                this.safeSetState({
                    networkAvailable: isConnected
                });
            });

        this.processSource(this.props.source);
    },

    componentWillUnmount() {
        this._isMounted = false;
        NetInfo.isConnected.removeEventListener('change', this.handleConnectivityChange);
    },

    componentWillReceiveProps(nextProps) {
        if (!_.isEqual(this.props.source, nextProps.source)) {
            this.processSource(nextProps.source);
        }
    },

    handleConnectivityChange(isConnected) {
        this.safeSetState({
            networkAvailable: isConnected
        });
    },

    processSource(source) {
        const url = _.get(source, ['uri'], null);
        if (ImageCacheProvider.isCacheable(url)) {
            const options = _.pick(this.props, ['useQueryParamsInCacheKey', 'cacheGroup']);
            // try to get the image path from cache
            ImageCacheProvider.getCachedImagePath(url, options)
                // try to put the image in cache if
                .catch(() => ImageCacheProvider.cacheImage(url, options))
                .then(cachedImagePath => {
                    this.safeSetState({
                        cachedImagePath
                    });
                })
                .catch(err => {
                    this.safeSetState({
                        cachedImagePath: null
                    });
                });
            this.safeSetState({
                isCacheable: true
            });
        } else {
            this.safeSetState({
                isCacheable: false
            });
        }
    },

    render() {
        if (this.state.isCacheable && !this.state.cachedImagePath) {
            return this.renderLoader();
        }
        const props = getImageProps(this.props);
        const style = this.props.style || styles.image;
        const source = this.state.cachedImagePath ? {
                uri: 'file://' + this.state.cachedImagePath
            } : this.props.source;
        return this.props.renderImage({
            ...props,
            style,
            source
        });
    },

    renderLoader() {
        const imageProps = getImageProps(this.props);
        const imageStyle = [this.props.style, styles.loaderPlaceholder];

        const activityIndicatorProps = _.omit(this.props.activityIndicatorProps, ['style']);
        const activityIndicatorStyle = this.props.activityIndicatorProps.style || styles.loader;

        const source = this.props.defaultSource;

        // if the imageStyle has borderRadius it will break the loading image view on android
        // so we only show the ActivityIndicator
        if (Platform.OS === 'android' && flattenStyle(imageStyle).borderRadius) {
            return (
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={[imageStyle, activityIndicatorStyle]}/>
            );
        }
        // otherwise render an image with the defaultSource with the ActivityIndicator on top of it
        return (
            <Image
                {...imageProps}
                source={source}
                style={imageStyle}>
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={activityIndicatorStyle}/>
            </Image>
        );
    }
});

/**
 * Same as ReactNaive.Image.getSize only it will not download the image if it has a cached version
 * @param uri
 * @param success
 * @param failure
 * @param options
 */
CachedImage.getSize = function getSize(uri, success, failure, options) {
    if (ImageCacheProvider.isCacheable(uri)) {
        ImageCacheProvider.getCachedImagePath(uri, options)
            .then(imagePath => {
                if (Platform.OS === 'android') {
                    imagePath = 'file://' + imagePath;
                }
                Image.getSize(imagePath, success, failure);
            })
            .catch(err => {
                Image.getSize(uri, success, failure);
            });
    } else {
        Image.getSize(uri, success, failure);
    }
};

module.exports = CachedImage;
<commit_msg>Posible fix for "Unable to resolve module flattenStyle"<commit_after>'use strict';

const _ = require('lodash');
const React = require('react');
const ReactNative = require('react-native');
const flattenStyle = React.StyleSheet.flatten;
const ImageCacheProvider = require('./ImageCacheProvider');

const {
    Image,
    ActivityIndicator,
    NetInfo,
    Platform
} = ReactNative;

const {
    StyleSheet
} = ReactNative;

const styles = StyleSheet.create({
    image: {
        backgroundColor: 'transparent'
    },
    loader: {
        backgroundColor: 'transparent',
    },
    loaderPlaceholder: {
        backgroundColor: 'transparent',
        alignItems: 'center',
        justifyContent: 'center'
    }
});

function getImageProps(props) {
    return _.omit(props, ['source', 'defaultSource', 'activityIndicatorProps', 'style', 'useQueryParamsInCacheKey', 'renderImage']);
}

const CACHED_IMAGE_REF = 'cachedImage';

const CachedImage = React.createClass({
    propTypes: {
        renderImage: React.PropTypes.func.isRequired,
        activityIndicatorProps: React.PropTypes.object.isRequired,
        useQueryParamsInCacheKey: React.PropTypes.oneOfType([
            React.PropTypes.bool,
            React.PropTypes.array
        ]).isRequired
    },

    getDefaultProps() {
        return {
            renderImage: props => (<Image ref={CACHED_IMAGE_REF} {...props}/>),
            activityIndicatorProps: {},
            useQueryParamsInCacheKey: false
        };
    },

    setNativeProps(nativeProps) {
        try {
            this.refs[CACHED_IMAGE_REF].setNativeProps(nativeProps);
        } catch (e) {
            console.error(e);
        }
    },

    getInitialState() {
        this._isMounted = false;
        return {
            isCacheable: false,
            cachedImagePath: null,
            networkAvailable: true
        };
    },

    safeSetState(newState) {
        if (!this._isMounted) {
            return;
        }
        return this.setState(newState);
    },

    componentWillMount() {
        this._isMounted = true;
        NetInfo.isConnected.addEventListener('change', this.handleConnectivityChange);
        // initial
        NetInfo.isConnected.fetch()
            .then(isConnected => {
                this.safeSetState({
                    networkAvailable: isConnected
                });
            });

        this.processSource(this.props.source);
    },

    componentWillUnmount() {
        this._isMounted = false;
        NetInfo.isConnected.removeEventListener('change', this.handleConnectivityChange);
    },

    componentWillReceiveProps(nextProps) {
        if (!_.isEqual(this.props.source, nextProps.source)) {
            this.processSource(nextProps.source);
        }
    },

    handleConnectivityChange(isConnected) {
        this.safeSetState({
            networkAvailable: isConnected
        });
    },

    processSource(source) {
        const url = _.get(source, ['uri'], null);
        if (ImageCacheProvider.isCacheable(url)) {
            const options = _.pick(this.props, ['useQueryParamsInCacheKey', 'cacheGroup']);
            // try to get the image path from cache
            ImageCacheProvider.getCachedImagePath(url, options)
                // try to put the image in cache if
                .catch(() => ImageCacheProvider.cacheImage(url, options))
                .then(cachedImagePath => {
                    this.safeSetState({
                        cachedImagePath
                    });
                })
                .catch(err => {
                    this.safeSetState({
                        cachedImagePath: null
                    });
                });
            this.safeSetState({
                isCacheable: true
            });
        } else {
            this.safeSetState({
                isCacheable: false
            });
        }
    },

    render() {
        if (this.state.isCacheable && !this.state.cachedImagePath) {
            return this.renderLoader();
        }
        const props = getImageProps(this.props);
        const style = this.props.style || styles.image;
        const source = this.state.cachedImagePath ? {
                uri: 'file://' + this.state.cachedImagePath
            } : this.props.source;
        return this.props.renderImage({
            ...props,
            style,
            source
        });
    },

    renderLoader() {
        const imageProps = getImageProps(this.props);
        const imageStyle = [this.props.style, styles.loaderPlaceholder];

        const activityIndicatorProps = _.omit(this.props.activityIndicatorProps, ['style']);
        const activityIndicatorStyle = this.props.activityIndicatorProps.style || styles.loader;

        const source = this.props.defaultSource;

        // if the imageStyle has borderRadius it will break the loading image view on android
        // so we only show the ActivityIndicator
        if (Platform.OS === 'android' && flattenStyle(imageStyle).borderRadius) {
            return (
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={[imageStyle, activityIndicatorStyle]}/>
            );
        }
        // otherwise render an image with the defaultSource with the ActivityIndicator on top of it
        return (
            <Image
                {...imageProps}
                source={source}
                style={imageStyle}>
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={activityIndicatorStyle}/>
            </Image>
        );
    }
});

/**
 * Same as ReactNaive.Image.getSize only it will not download the image if it has a cached version
 * @param uri
 * @param success
 * @param failure
 * @param options
 */
CachedImage.getSize = function getSize(uri, success, failure, options) {
    if (ImageCacheProvider.isCacheable(uri)) {
        ImageCacheProvider.getCachedImagePath(uri, options)
            .then(imagePath => {
                if (Platform.OS === 'android') {
                    imagePath = 'file://' + imagePath;
                }
                Image.getSize(imagePath, success, failure);
            })
            .catch(err => {
                Image.getSize(uri, success, failure);
            });
    } else {
        Image.getSize(uri, success, failure);
    }
};

module.exports = CachedImage;
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const React = require('react');
const ReactNative = require('react-native');
const flattenStyle = ReactNative.StyleSheet.flatten;
const ImageCacheProvider = require('./ImageCacheProvider');

const {
    Image,
    ActivityIndicator,
    NetInfo,
    Platform
} = ReactNative;

const {
    StyleSheet
} = ReactNative;

const styles = StyleSheet.create({
    image: {
        backgroundColor: 'transparent'
    },
    loader: {
        backgroundColor: 'transparent',
    },
    loaderPlaceholder: {
        backgroundColor: 'transparent',
        alignItems: 'center',
        justifyContent: 'center'
    }
});

function getImageProps(props) {
    return _.omit(props, ['source', 'defaultSource', 'fallbackSource', 'loadingIndicator', 'activityIndicatorProps', 'style', 'useQueryParamsInCacheKey', 'renderImage', 'resolveHeaders']);
}

const CACHED_IMAGE_REF = 'cachedImage';

const CachedImage = React.createClass({
    propTypes: {
        renderImage: React.PropTypes.func.isRequired,
        activityIndicatorProps: React.PropTypes.object.isRequired,
        useQueryParamsInCacheKey: React.PropTypes.oneOfType([
            React.PropTypes.bool,
            React.PropTypes.array
        ]).isRequired,
        resolveHeaders: React.PropTypes.func
    },

    getDefaultProps() {
        return {
            renderImage: props => (<Image ref={CACHED_IMAGE_REF} {...props}/>),
            activityIndicatorProps: {},
            useQueryParamsInCacheKey: false,
            resolveHeaders: () => Promise.resolve({})
        };
    },

    setNativeProps(nativeProps) {
        try {
            this.refs[CACHED_IMAGE_REF].setNativeProps(nativeProps);
        } catch (e) {
            console.error(e);
        }
    },

    getInitialState() {
        this._isMounted = false;
        return {
            isCacheable: false,
            cachedImagePath: null,
            networkAvailable: true
        };
    },

    safeSetState(newState) {
        if (!this._isMounted) {
            return;
        }
        return this.setState(newState);
    },

    componentWillMount() {
        this._isMounted = true;
        NetInfo.isConnected.addEventListener('change', this.handleConnectivityChange);
        // initial
        NetInfo.isConnected.fetch()
            .then(isConnected => {
                this.safeSetState({
                    networkAvailable: isConnected
                });
            });

        this.processSource(this.props.source);
    },

    componentWillUnmount() {
        this._isMounted = false;
        NetInfo.isConnected.removeEventListener('change', this.handleConnectivityChange);
    },

    componentWillReceiveProps(nextProps) {
        if (!_.isEqual(this.props.source, nextProps.source)) {
            this.processSource(nextProps.source);
        }
    },

    handleConnectivityChange(isConnected) {
        this.safeSetState({
            networkAvailable: isConnected
        });
    },

    processSource(source) {
        const url = _.get(source, ['uri'], null);
        if (ImageCacheProvider.isCacheable(url)) {
            const options = _.pick(this.props, ['useQueryParamsInCacheKey', 'cacheGroup']);
            // try to get the image path from cache
            ImageCacheProvider.getCachedImagePath(url, options)
                // try to put the image in cache if
                .catch(() => ImageCacheProvider.cacheImage(url, options, this.props.resolveHeaders))
                .then(cachedImagePath => {
                    this.safeSetState({
                        cachedImagePath
                    });
                })
                .catch(err => {
                    this.safeSetState({
                        cachedImagePath: null,
                        isCacheable: false
                    });
                });
            this.safeSetState({
                isCacheable: true
            });
        } else {
            this.safeSetState({
                isCacheable: false
            });
        }
    },

    render() {
        if (this.state.isCacheable && !this.state.cachedImagePath) {
            return this.renderLoader();
        }
        const props = getImageProps(this.props);
        const style = this.props.style || styles.image;
        const source = (this.state.isCacheable && this.state.cachedImagePath) ? {
                uri: 'file://' + this.state.cachedImagePath
            } : this.props.source;
        if (!this.state.cachedImagePath) {
          return this.props.renderImage({
              ...props,
              key: `${props.key || source.uri}error`,
              style,
              source: this.props.fallbackSource
          });
        }
        return this.props.renderImage({
            ...props,
            key: props.key || source.uri,
            style,
            source
        });
    },

    renderLoader() {
        const imageProps = getImageProps(this.props);
        const imageStyle = [this.props.style, styles.loaderPlaceholder];

        const activityIndicatorProps = _.omit(this.props.activityIndicatorProps, ['style']);
        const activityIndicatorStyle = this.props.activityIndicatorProps.style || styles.loader;

        const loadingIndicator = this.props.loadingIndicator;

        const source = this.props.defaultSource;

        // if the imageStyle has borderRadius it will break the loading image view on android
        // so we only show the ActivityIndicator
        if (!source || (Platform.OS === 'android' && flattenStyle(imageStyle).borderRadius)) {
            if (loadingIndicator) {
              return loadingIndicator();
            }
            return (
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={[imageStyle, activityIndicatorStyle]}/>
            );
        }
        // otherwise render an image with the defaultSource with the ActivityIndicator on top of it
        return this.props.renderImage({
            ...imageProps,
            style: imageStyle,
            key: source.uri,
            source,
            children: (
                typeof loadingIndicator === 'function'
                  ? loadingIndicator()
                  : <ActivityIndicator
                      {...activityIndicatorProps}
                      style={activityIndicatorStyle}/>
            )
        });
    }
});

/**
 * Same as ReactNaive.Image.getSize only it will not download the image if it has a cached version
 * @param uri
 * @param success
 * @param failure
 * @param options
 */
CachedImage.getSize = function getSize(uri, success, failure, options) {
    if (ImageCacheProvider.isCacheable(uri)) {
        ImageCacheProvider.getCachedImagePath(uri, options)
            .then(imagePath => {
                if (Platform.OS === 'android') {
                    imagePath = 'file://' + imagePath;
                }
                Image.getSize(imagePath, success, failure);
            })
            .catch(err => {
                Image.getSize(uri, success, failure);
            });
    } else {
        Image.getSize(uri, success, failure);
    }
};

module.exports = CachedImage;
<commit_msg>modify loadingIndicator type<commit_after>'use strict';

const _ = require('lodash');
const React = require('react');
const ReactNative = require('react-native');
const flattenStyle = ReactNative.StyleSheet.flatten;
const ImageCacheProvider = require('./ImageCacheProvider');

const {
    Image,
    ActivityIndicator,
    NetInfo,
    Platform
} = ReactNative;

const {
    StyleSheet
} = ReactNative;

const styles = StyleSheet.create({
    image: {
        backgroundColor: 'transparent'
    },
    loader: {
        backgroundColor: 'transparent',
    },
    loaderPlaceholder: {
        backgroundColor: 'transparent',
        alignItems: 'center',
        justifyContent: 'center'
    }
});

function getImageProps(props) {
    return _.omit(props, ['source', 'defaultSource', 'fallbackSource', 'loadingIndicator', 'activityIndicatorProps', 'style', 'useQueryParamsInCacheKey', 'renderImage', 'resolveHeaders']);
}

const CACHED_IMAGE_REF = 'cachedImage';

const CachedImage = React.createClass({
    propTypes: {
        renderImage: React.PropTypes.func.isRequired,
        activityIndicatorProps: React.PropTypes.object.isRequired,
        useQueryParamsInCacheKey: React.PropTypes.oneOfType([
            React.PropTypes.bool,
            React.PropTypes.array
        ]).isRequired,
        resolveHeaders: React.PropTypes.func
    },

    getDefaultProps() {
        return {
            renderImage: props => (<Image ref={CACHED_IMAGE_REF} {...props}/>),
            activityIndicatorProps: {},
            useQueryParamsInCacheKey: false,
            resolveHeaders: () => Promise.resolve({})
        };
    },

    setNativeProps(nativeProps) {
        try {
            this.refs[CACHED_IMAGE_REF].setNativeProps(nativeProps);
        } catch (e) {
            console.error(e);
        }
    },

    getInitialState() {
        this._isMounted = false;
        return {
            isCacheable: false,
            cachedImagePath: null,
            networkAvailable: true
        };
    },

    safeSetState(newState) {
        if (!this._isMounted) {
            return;
        }
        return this.setState(newState);
    },

    componentWillMount() {
        this._isMounted = true;
        NetInfo.isConnected.addEventListener('change', this.handleConnectivityChange);
        // initial
        NetInfo.isConnected.fetch()
            .then(isConnected => {
                this.safeSetState({
                    networkAvailable: isConnected
                });
            });

        this.processSource(this.props.source);
    },

    componentWillUnmount() {
        this._isMounted = false;
        NetInfo.isConnected.removeEventListener('change', this.handleConnectivityChange);
    },

    componentWillReceiveProps(nextProps) {
        if (!_.isEqual(this.props.source, nextProps.source)) {
            this.processSource(nextProps.source);
        }
    },

    handleConnectivityChange(isConnected) {
        this.safeSetState({
            networkAvailable: isConnected
        });
    },

    processSource(source) {
        const url = _.get(source, ['uri'], null);
        if (ImageCacheProvider.isCacheable(url)) {
            const options = _.pick(this.props, ['useQueryParamsInCacheKey', 'cacheGroup']);
            // try to get the image path from cache
            ImageCacheProvider.getCachedImagePath(url, options)
                // try to put the image in cache if
                .catch(() => ImageCacheProvider.cacheImage(url, options, this.props.resolveHeaders))
                .then(cachedImagePath => {
                    this.safeSetState({
                        cachedImagePath
                    });
                })
                .catch(err => {
                    this.safeSetState({
                        cachedImagePath: null,
                        isCacheable: false
                    });
                });
            this.safeSetState({
                isCacheable: true
            });
        } else {
            this.safeSetState({
                isCacheable: false
            });
        }
    },

    render() {
        if (this.state.isCacheable && !this.state.cachedImagePath) {
            return this.renderLoader();
        }
        const props = getImageProps(this.props);
        const style = this.props.style || styles.image;
        const source = (this.state.isCacheable && this.state.cachedImagePath) ? {
                uri: 'file://' + this.state.cachedImagePath
            } : this.props.source;
        if (!this.state.cachedImagePath) {
          return this.props.renderImage({
              ...props,
              key: `${props.key || source.uri}error`,
              style,
              source: this.props.fallbackSource
          });
        }
        return this.props.renderImage({
            ...props,
            key: props.key || source.uri,
            style,
            source
        });
    },

    renderLoader() {
        const imageProps = getImageProps(this.props);
        const imageStyle = [this.props.style, styles.loaderPlaceholder];

        const activityIndicatorProps = _.omit(this.props.activityIndicatorProps, ['style']);
        const activityIndicatorStyle = this.props.activityIndicatorProps.style || styles.loader;

        const loadingIndicator = this.props.loadingIndicator;

        const source = this.props.defaultSource;

        // if the imageStyle has borderRadius it will break the loading image view on android
        // so we only show the ActivityIndicator
        if (!source || (Platform.OS === 'android' && flattenStyle(imageStyle).borderRadius)) {
            if (loadingIndicator) {
              return (
                <loadingIndicator
                  {...activityIndicatorProps}
                  style={[imageStyle, activityIndicatorStyle]} />
              );
            }
            return (
                <ActivityIndicator
                    {...activityIndicatorProps}
                    style={[imageStyle, activityIndicatorStyle]}/>
            );
        }
        // otherwise render an image with the defaultSource with the ActivityIndicator on top of it
        return this.props.renderImage({
            ...imageProps,
            style: imageStyle,
            key: source.uri,
            source,
            children: (
                typeof loadingIndicator === 'function'
                  ? <loadingIndicator
                      {...activityIndicatorProps}
                      style={activityIndicatorStyle} />
                  : <ActivityIndicator
                      {...activityIndicatorProps}
                      style={activityIndicatorStyle}/>
            )
        });
    }
});

/**
 * Same as ReactNaive.Image.getSize only it will not download the image if it has a cached version
 * @param uri
 * @param success
 * @param failure
 * @param options
 */
CachedImage.getSize = function getSize(uri, success, failure, options) {
    if (ImageCacheProvider.isCacheable(uri)) {
        ImageCacheProvider.getCachedImagePath(uri, options)
            .then(imagePath => {
                if (Platform.OS === 'android') {
                    imagePath = 'file://' + imagePath;
                }
                Image.getSize(imagePath, success, failure);
            })
            .catch(err => {
                Image.getSize(uri, success, failure);
            });
    } else {
        Image.getSize(uri, success, failure);
    }
};

module.exports = CachedImage;
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var PropTypes = require('ReactPropTypes');
var Dimensions = require('Dimensions');
var moment = require('moment');

var {
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View
} = React;

var
  MAX_COLUMNS = 7,
  MAX_ROWS = 7,
  DEVICE_WIDTH = Dimensions.get('window').width,
  VIEW_INDEX = 2;

var Calendar = React.createClass({
  propTypes: {
    dayHeadings: PropTypes.array,
    onDateSelect: PropTypes.func,
    scrollEnabled: PropTypes.bool,
    showControls: PropTypes.bool,
    prevButtonText: PropTypes.string,
    nextButtonText: PropTypes.string,
    titleFormat: PropTypes.string,
    onSwipeNext: PropTypes.func,
    onSwipePrev: PropTypes.func,
    onTouchNext: PropTypes.func,
    onTouchPrev: PropTypes.func,
  },

  getDefaultProps() {
    return {
      scrollEnabled: false,
      showControls: false,
      prevButtonText: 'Prev',
      nextButtonText: 'Next',
      titleFormat: 'MMMM YYYY',
      dayHeadings: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
    }
  },

  getInitialState() {
    return {
      calendarDates: this.getInitialStack(),
      selectedDate: null,
      currentMonth: moment().format()
    };
  },

  componentDidMount() {
    this._scrollToItem(VIEW_INDEX);
  },

  getInitialStack() {
    return([
      moment().subtract(2, 'month').format(),
      moment().subtract(1, 'month').format(),
      moment().format(),
      moment().add(1, 'month').format(),
      moment().add(2, 'month').format()
    ])
  },

  renderTopBar(date) {
    if(this.props.showControls) {
      return (
        <View style={styles.calendarControls}>
          <TouchableOpacity style={styles.controlButton} onPress={this._onPrev}>
            <Text style={styles.controlButtonText}>{this.props.prevButtonText}</Text>
          </TouchableOpacity>
          <Text style={styles.title}>
            {moment(this.state.currentMonth).format(this.props.titleFormat)}
          </Text>
          <TouchableOpacity style={styles.controlButton} onPress={this._onNext}>
            <Text style={styles.controlButtonText}>{this.props.nextButtonText}</Text>
          </TouchableOpacity>
        </View>
      )
    } else {
      return (
        <View style={styles.calendarControls}>
          <Text style={styles.title}>{moment(this.state.currentMonth).format(this.props.titleFormat)}</Text>
        </View>
      )
    }
  },

  renderHeading() {
    return (
      <View style={styles.calendarHeading}>
        {this.props.dayHeadings.map((day) => { return (<Text style={styles.dayHeading}>{day}</Text>) })}
      </View>
    )
  },

  renderMonthView(date) {
    var dayStart = moment(date).startOf('month').format(),
      daysInMonth = moment(dayStart).daysInMonth(),
      offset = moment(dayStart).get('day'),
      preFiller = 0,
      currentDay = 0,
      weekRows = [];

    for (var i = 0; i < MAX_COLUMNS; i++) {
      var days = [];
      for (var j = 0; j < MAX_ROWS; j++) {
        if (preFiller < offset) {
          days.push(<TouchableWithoutFeedback><View style={styles.dayButton}></View></TouchableWithoutFeedback>);
        } else {
          if(currentDay < daysInMonth) {
            var newDay = moment(dayStart).set('date', currentDay + 1);
            var isToday = (moment().isSame(newDay, 'month') && moment().isSame(newDay, 'day')) ? true : false;

            days.push((
              <TouchableOpacity
                onPress={this._selectDate.bind(this, newDay)}>
                  <View style={styles.dayButton}>
                    <Text style={[styles.day, isToday && styles.currentDay]}>{currentDay + 1}</Text>
                    <View style={styles.dayDot}></View>
                  </View>
              </TouchableOpacity>
            ));
            currentDay++;
          }
        }
        preFiller++;
      } // row

      if(days.length > 0 && days.length < 7) {
        for (var x = days.length; x < 7; x++) {
          days.push(<TouchableWithoutFeedback><View style={styles.dayButton}></View></TouchableWithoutFeedback>);
        }
        weekRows.push(<View key={weekRows.length} style={styles.weekRow}>{days}</View>);
      } else {
        weekRows.push(<View key={weekRows.length} style={styles.weekRow}>{days}</View>);
      }
    } // column
    return (<View key={moment(newDay).month()} style={styles.calendarContainer}>{weekRows}</View>);
  },

  _prependMonth() {
    var calendarDates = this.state.calendarDates;
    calendarDates.unshift(moment(calendarDates[0]).subtract(1, 'month').format());
    calendarDates.pop();
    this.setState({
      calendarDates: calendarDates,
      currentMonth: calendarDates[VIEW_INDEX]
    });
  },

  _appendMonth(){
    var calendarDates = this.state.calendarDates;
    calendarDates.push(moment(calendarDates[calendarDates.length - 1]).add(1, 'month').format());
    calendarDates.shift();
    this.setState({
      calendarDates: calendarDates,
      currentMonth: calendarDates[VIEW_INDEX]
    });
  },

  _selectDate(date) {
    this.props.onDateSelect && this.props.onDateSelect(date.format());
  },

  _onPrev(){
    this._prependMonth();
    this._scrollToItem(VIEW_INDEX);
    this.props.onTouchPrev && this.props.onTouchPrev();
  },

  _onNext(){
    this._appendMonth();
    this._scrollToItem(VIEW_INDEX);
    this.props.onTouchNext && this.props.onTouchNext();
  },

  _scrollToItem(itemIndex) {
      var scrollToX = itemIndex * DEVICE_WIDTH;
      this.refs.calendar.scrollWithoutAnimationTo(0, scrollToX);
  },

  _scrollEnded(event) {
    var position = event.nativeEvent.contentOffset.x;
    var currentPage = position / DEVICE_WIDTH;

    if (currentPage < VIEW_INDEX) {
      this._prependMonth();
      this._scrollToItem(VIEW_INDEX);
      this.props.onSwipePrev && this.props.onSwipePrev();
    } else if (currentPage > VIEW_INDEX) {
        this._appendMonth();
        this._scrollToItem(VIEW_INDEX);
        this.props.onSwipeNext() && this.props.onSwipeNext();
    } else {
        return false;
    }
  },

  render() {
    return (
      <View>
        {this.renderTopBar()}
        {this.renderHeading(this.props.titleFormat)}
        <ScrollView
          ref='calendar'
          horizontal={true}
          scrollEnabled={this.props.scrollEnabled}
          pagingEnabled={true}
          removeClippedSubviews={true}
          scrollEventThrottle={600}
          showsHorizontalScrollIndicator={false}
          onMomentumScrollEnd={(event) => this._scrollEnded(event)}>
          {this.state.calendarDates.map((date) => { return this.renderMonthView(date) })}
        </ScrollView>
      </View>
    )
  }
});

var styles = StyleSheet.create({
  calendarContainer: {
    width: DEVICE_WIDTH
  },
  calendarControls: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    margin: 10,
    marginTop: 30
  },
  controlButton: {
    flex: 1,
    padding: 5,
  },
  controlButtonText: {
    fontSize: 15,
  },
  title: {
    flex: 1,
    textAlign: 'center',
    fontSize: 15,
  },
  calendarHeading: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    borderTopWidth: 1,
    borderBottomWidth: 1
  },
  dayHeading: {
    padding: 5,
    flex: 1,
    textAlign: 'center',
    fontSize: 15,
    justifyContent: 'flex-start',
  },
  weekRow: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
  },
  dayButton: {
    padding: 5,
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
  },
  day: {
    fontSize: 20,
  },
  dayDot: {
    marginTop: 10,
    borderColor: '#cccccc',
    borderLeftWidth: 4,
    borderTopWidth: 4,
    borderBottomWidth: 4,
    borderRightWidth: 4,
    backgroundColor: '#cccccc',
    borderTopLeftRadius: 4,
    borderTopRightRadius: 4,
    borderBottomLeftRadius: 4,
    borderBottomRightRadius: 4,
  },
  currentDay: {
    color: 'red',
  }
});

module.exports = Calendar;
<commit_msg>Renaming "dayDot" style to "eventIndicator"<commit_after>'use strict';

var React = require('react-native');
var PropTypes = require('ReactPropTypes');
var Dimensions = require('Dimensions');
var moment = require('moment');

var {
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View
} = React;

var
  MAX_COLUMNS = 7,
  MAX_ROWS = 7,
  DEVICE_WIDTH = Dimensions.get('window').width,
  VIEW_INDEX = 2;

var Calendar = React.createClass({
  propTypes: {
    dayHeadings: PropTypes.array,
    onDateSelect: PropTypes.func,
    scrollEnabled: PropTypes.bool,
    showControls: PropTypes.bool,
    prevButtonText: PropTypes.string,
    nextButtonText: PropTypes.string,
    titleFormat: PropTypes.string,
    onSwipeNext: PropTypes.func,
    onSwipePrev: PropTypes.func,
    onTouchNext: PropTypes.func,
    onTouchPrev: PropTypes.func,
  },

  getDefaultProps() {
    return {
      scrollEnabled: false,
      showControls: false,
      prevButtonText: 'Prev',
      nextButtonText: 'Next',
      titleFormat: 'MMMM YYYY',
      dayHeadings: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
    }
  },

  getInitialState() {
    return {
      calendarDates: this.getInitialStack(),
      selectedDate: null,
      currentMonth: moment().format()
    };
  },

  componentDidMount() {
    this._scrollToItem(VIEW_INDEX);
  },

  getInitialStack() {
    return([
      moment().subtract(2, 'month').format(),
      moment().subtract(1, 'month').format(),
      moment().format(),
      moment().add(1, 'month').format(),
      moment().add(2, 'month').format()
    ])
  },

  renderTopBar(date) {
    if(this.props.showControls) {
      return (
        <View style={styles.calendarControls}>
          <TouchableOpacity style={styles.controlButton} onPress={this._onPrev}>
            <Text style={styles.controlButtonText}>{this.props.prevButtonText}</Text>
          </TouchableOpacity>
          <Text style={styles.title}>
            {moment(this.state.currentMonth).format(this.props.titleFormat)}
          </Text>
          <TouchableOpacity style={styles.controlButton} onPress={this._onNext}>
            <Text style={styles.controlButtonText}>{this.props.nextButtonText}</Text>
          </TouchableOpacity>
        </View>
      )
    } else {
      return (
        <View style={styles.calendarControls}>
          <Text style={styles.title}>{moment(this.state.currentMonth).format(this.props.titleFormat)}</Text>
        </View>
      )
    }
  },

  renderHeading() {
    return (
      <View style={styles.calendarHeading}>
        {this.props.dayHeadings.map((day) => { return (<Text style={styles.dayHeading}>{day}</Text>) })}
      </View>
    )
  },

  renderMonthView(date) {
    var dayStart = moment(date).startOf('month').format(),
      daysInMonth = moment(dayStart).daysInMonth(),
      offset = moment(dayStart).get('day'),
      preFiller = 0,
      currentDay = 0,
      weekRows = [];

    for (var i = 0; i < MAX_COLUMNS; i++) {
      var days = [];
      for (var j = 0; j < MAX_ROWS; j++) {
        if (preFiller < offset) {
          days.push(<TouchableWithoutFeedback><View style={styles.dayButton}></View></TouchableWithoutFeedback>);
        } else {
          if(currentDay < daysInMonth) {
            var newDay = moment(dayStart).set('date', currentDay + 1);
            var isToday = (moment().isSame(newDay, 'month') && moment().isSame(newDay, 'day')) ? true : false;

            days.push((
              <TouchableOpacity
                onPress={this._selectDate.bind(this, newDay)}>
                  <View style={styles.dayButton}>
                    <Text style={[styles.day, isToday && styles.currentDay]}>{currentDay + 1}</Text>
                    <View style={styles.eventIndicator}></View>
                  </View>
              </TouchableOpacity>
            ));
            currentDay++;
          }
        }
        preFiller++;
      } // row

      if(days.length > 0 && days.length < 7) {
        for (var x = days.length; x < 7; x++) {
          days.push(<TouchableWithoutFeedback><View style={styles.dayButton}></View></TouchableWithoutFeedback>);
        }
        weekRows.push(<View key={weekRows.length} style={styles.weekRow}>{days}</View>);
      } else {
        weekRows.push(<View key={weekRows.length} style={styles.weekRow}>{days}</View>);
      }
    } // column
    return (<View key={moment(newDay).month()} style={styles.calendarContainer}>{weekRows}</View>);
  },

  _prependMonth() {
    var calendarDates = this.state.calendarDates;
    calendarDates.unshift(moment(calendarDates[0]).subtract(1, 'month').format());
    calendarDates.pop();
    this.setState({
      calendarDates: calendarDates,
      currentMonth: calendarDates[VIEW_INDEX]
    });
  },

  _appendMonth(){
    var calendarDates = this.state.calendarDates;
    calendarDates.push(moment(calendarDates[calendarDates.length - 1]).add(1, 'month').format());
    calendarDates.shift();
    this.setState({
      calendarDates: calendarDates,
      currentMonth: calendarDates[VIEW_INDEX]
    });
  },

  _selectDate(date) {
    this.props.onDateSelect && this.props.onDateSelect(date.format());
  },

  _onPrev(){
    this._prependMonth();
    this._scrollToItem(VIEW_INDEX);
    this.props.onTouchPrev && this.props.onTouchPrev();
  },

  _onNext(){
    this._appendMonth();
    this._scrollToItem(VIEW_INDEX);
    this.props.onTouchNext && this.props.onTouchNext();
  },

  _scrollToItem(itemIndex) {
      var scrollToX = itemIndex * DEVICE_WIDTH;
      this.refs.calendar.scrollWithoutAnimationTo(0, scrollToX);
  },

  _scrollEnded(event) {
    var position = event.nativeEvent.contentOffset.x;
    var currentPage = position / DEVICE_WIDTH;

    if (currentPage < VIEW_INDEX) {
      this._prependMonth();
      this._scrollToItem(VIEW_INDEX);
      this.props.onSwipePrev && this.props.onSwipePrev();
    } else if (currentPage > VIEW_INDEX) {
        this._appendMonth();
        this._scrollToItem(VIEW_INDEX);
        this.props.onSwipeNext() && this.props.onSwipeNext();
    } else {
        return false;
    }
  },

  render() {
    return (
      <View>
        {this.renderTopBar()}
        {this.renderHeading(this.props.titleFormat)}
        <ScrollView
          ref='calendar'
          horizontal={true}
          scrollEnabled={this.props.scrollEnabled}
          pagingEnabled={true}
          removeClippedSubviews={true}
          scrollEventThrottle={600}
          showsHorizontalScrollIndicator={false}
          onMomentumScrollEnd={(event) => this._scrollEnded(event)}>
          {this.state.calendarDates.map((date) => { return this.renderMonthView(date) })}
        </ScrollView>
      </View>
    )
  }
});

var styles = StyleSheet.create({
  calendarContainer: {
    width: DEVICE_WIDTH
  },
  calendarControls: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    margin: 10,
    marginTop: 30
  },
  controlButton: {
    flex: 1,
    padding: 5,
  },
  controlButtonText: {
    fontSize: 15,
  },
  title: {
    flex: 1,
    textAlign: 'center',
    fontSize: 15,
  },
  calendarHeading: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    borderTopWidth: 1,
    borderBottomWidth: 1
  },
  dayHeading: {
    padding: 5,
    flex: 1,
    textAlign: 'center',
    fontSize: 15,
    justifyContent: 'flex-start',
  },
  weekRow: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
  },
  dayButton: {
    padding: 5,
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
  },
  day: {
    fontSize: 20,
  },
  eventIndicator: {
    marginTop: 10,
    borderColor: '#cccccc',
    borderLeftWidth: 4,
    borderTopWidth: 4,
    borderBottomWidth: 4,
    borderRightWidth: 4,
    backgroundColor: '#cccccc',
    borderTopLeftRadius: 4,
    borderTopRightRadius: 4,
    borderBottomLeftRadius: 4,
    borderBottomRightRadius: 4,
  },
  currentDay: {
    color: 'red',
  }
});

module.exports = Calendar;
<|endoftext|>


<commit_before>// Write a JavaScript function that takes a sentence as an argument and determines which word in that sentence has the greatest number of repeated letters (the repeated letters do not have to be consecutive).
      //
      // If the sentence has multiple words with the same max of repeated letters, return them all in an Array.
      //
      // Test Case
      //
      // Would select the words:
      // wordSelector("I attribute my success to this: I never gave or took any excuse. –Florence Nightingale")
      //
      // ["attribute", "success"]

      function wordSelector(sentence) {

          // split sentence to array
          // How to: Use split or match Method
          // match method is more useful one line of code parssing token such as  ".", "–"
          var array = sentence.match(/[a-z]+/ig);

          var arrayReturn = [];
          var highistRepeat = 1;

          for (var i = 0; i < array.length; i++) {

              //["I","attribute","my","success","to"...]
              var arrayLetter = array[i];
              // Repeat letter counter
              var wordRepeats = repeatLetterCounter(arrayLetter);

              if (wordRepeats > highistRepeat) {
                  arrayReturn = []; // reset array
                  arrayReturn.push(arrayLetter);

                  highistRepeat = wordRepeats;
              }
              else if (highistRepeat === wordRepeats) {
                  arrayReturn.push(arrayLetter);
              }
          }

          return arrayReturn;
      }

      function repeatLetterCounter(arrayLetter) {

          var uniqueTokenLetter = "";
          var repeatLetterCount = 2;

          for (var i = 0; i < arrayLetter.length; i++) {

              if (uniqueTokenLetter.indexOf(arrayLetter.charAt(i)) === -1) {

                  // pattern genarated format example: /s/gi
                  var pattern = RegExp(arrayLetter[i], "gi");

                  // return matching letter "sucess" ==> ["s", "s", "s"]
                  var arrayMatchingLetter = arrayLetter.match(pattern);

                  if (arrayMatchingLetter.length > repeatLetterCount) {
                      repeatLetterCount = arrayMatchingLetter.length;
                  }

                  uniqueTokenLetter += arrayLetter.charAt(i);
              }
          }

          return repeatLetterCount;

      }

       console.log(wordSelector("I attribute my success to this: I never gave or took any excuse. –Florence Nightingale"));
<commit_msg>Code clean up<commit_after>// Write a JavaScript function that takes a sentence as an argument and determines which word in that sentence has the greatest number of repeated letters (the repeated letters do not have to be consecutive).
//
// If the sentence has multiple words with the same max of repeated letters, return them all in an Array.
//
// Test Case
//
// Would select the words:
// wordSelector("I attribute my success to this: I never gave or took any excuse. –Florence Nightingale")
//
// ["attribute", "success"]

function wordSelector(sentence) {

    // split sentence to array
    // How to: Use split or match Method
    // match method is more useful one line of code parssing token such as  ".", "–"
    var array = sentence.match(/[a-z]+/ig);

    var arrayReturn = [];
    var highistRepeat = 1;

    for (var i = 0; i < array.length; i++) {

        //["I","attribute","my","success","to"...]
        var arrayLetter = array[i];
        // Repeat letter counter
        var wordRepeats = repeatLetterCounter(arrayLetter);

        if (wordRepeats > highistRepeat) {
            arrayReturn = []; // reset array
            arrayReturn.push(arrayLetter);

            highistRepeat = wordRepeats;
        }
        else if (highistRepeat === wordRepeats) {
            arrayReturn.push(arrayLetter);
        }
    }

    return arrayReturn;
}

function repeatLetterCounter(arrayLetter) {

    var uniqueTokenLetter = "";
    var repeatLetterCount = 2;

    for (var i = 0; i < arrayLetter.length; i++) {

        if (uniqueTokenLetter.indexOf(arrayLetter.charAt(i)) === -1) {

            // pattern genarated format example: /s/gi
            var pattern = RegExp(arrayLetter[i], "gi");

            // return matching letter "sucess" ==> ["s", "s", "s"]
            var arrayMatchingLetter = arrayLetter.match(pattern);

            if (arrayMatchingLetter.length > repeatLetterCount) {
                repeatLetterCount = arrayMatchingLetter.length;
            }

            uniqueTokenLetter += arrayLetter.charAt(i);
        }
    }

    return repeatLetterCount;

}

 console.log(wordSelector("I attribute my success to this: I never gave or took any excuse. –Florence Nightingale"));
<|endoftext|>


<commit_before>/**
 * ListPopover - Popover rendered with a selectable list.
 */
"use strict";

import React from 'react';
import {
  ListView,
  PropTypes,
  StyleSheet,
  Text,
  Dimensions,
  TouchableOpacity,
  View
} from 'react-native';
var SCREEN_HEIGHT = Dimensions.get('window').height;
var noop = () => {};
var ds = new ListView.DataSource({rowHasChanged: (r1,r2)=>(r1!==r2)});

var ListPopover = React.createClass({
  propTypes: {
    list: PropTypes.array.isRequired,
    isVisible: PropTypes.bool,
    onClick: PropTypes.func,
    onClose: PropTypes.func,
  },
  getDefaultProps: function() {
    return {
      list: [""],
      isVisible: false,
      onClick: noop,
      onClose: noop
    };
  },
  getInitialState: function() {
    return {
      dataSource: ds.cloneWithRows(this.props.list)
    };
  },
  componentWillReceiveProps: function(nextProps:any) {
    if (nextProps.list !== this.props.list) {
      this.setState({dataSource: ds.cloneWithRows(nextProps.list)});
    }
  },
  handleClick: function(data) {
    this.props.onClick(data);
    this.props.onClose();
  },
  renderRow: function(rowData) {
    var separatorStyle = this.props.separatorStyle || DefaultStyles.separator;
    var rowTextStyle = this.props.rowText || DefaultStyles.rowText;

    var separator = <View style={separatorStyle}/>;
    if (rowData === this.props.list[0]) {
      separator = null;
    }

    var row = <Text style={rowTextStyle}>{rowData}</Text>
    if (this.props.renderRow) {
      row = this.props.renderRow(rowData);
    }

    return (
      <View>
        {separator}
        <TouchableOpacity onPress={() => this.handleClick(rowData)}>
          {row}
        </TouchableOpacity>
      </View>
    );
  },
  renderList: function() {
    var styles = this.props.style || DefaultStyles;
    var maxHeight = {};
    if (this.props.list.length > 12) {
      maxHeight = {height: SCREEN_HEIGHT * 3/4};
    }
    return (
      <ListView
        style={maxHeight}
        dataSource={this.state.dataSource}
        renderRow={(rowData) => this.renderRow(rowData)}
        automaticallyAdjustContentInsets={false}
      />
    );
  },
  render: function() {
    var containerStyle = this.props.containerStyle || DefaultStyles.container;
    var popoverStyle = this.props.popoverStyle || DefaultStyles.popover;

    if (this.props.isVisible) {
      return (
        <TouchableOpacity onPress={this.props.onClose}>
          <View style={containerStyle}>
            <View style={popoverStyle}>
              {this.renderList()}
            </View>
          </View>
        </TouchableOpacity>
      );
    } else {
      return (<View/>);
    }
  }
});

var DefaultStyles = StyleSheet.create({
  container: {
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    position: 'absolute',
    justifyContent: 'center',
    backgroundColor: 'transparent',
  },
  popover: {
    margin: 10,
    borderRadius: 3,
    padding: 3,
    backgroundColor: '#ffffff',
  },
  rowText: {
    padding: 10,
  },
  separator: {
    height: 0.5,
    marginLeft: 8,
    marginRight: 8,
    backgroundColor: '#CCC',
  },
});

module.exports = ListPopover;
<commit_msg>upgrade to RN 0.25<commit_after>/**
 * ListPopover - Popover rendered with a selectable list.
 */
"use strict";

import React, {PropTypes} from 'react';
import {
  ListView,
  StyleSheet,
  Text,
  Dimensions,
  TouchableOpacity,
  View
} from 'react-native';
var SCREEN_HEIGHT = Dimensions.get('window').height;
var noop = () => {};
var ds = new ListView.DataSource({rowHasChanged: (r1,r2)=>(r1!==r2)});

var ListPopover = React.createClass({
  propTypes: {
    list: PropTypes.array.isRequired,
    isVisible: PropTypes.bool,
    onClick: PropTypes.func,
    onClose: PropTypes.func,
  },
  getDefaultProps: function() {
    return {
      list: [""],
      isVisible: false,
      onClick: noop,
      onClose: noop
    };
  },
  getInitialState: function() {
    return {
      dataSource: ds.cloneWithRows(this.props.list)
    };
  },
  componentWillReceiveProps: function(nextProps:any) {
    if (nextProps.list !== this.props.list) {
      this.setState({dataSource: ds.cloneWithRows(nextProps.list)});
    }
  },
  handleClick: function(data) {
    this.props.onClick(data);
    this.props.onClose();
  },
  renderRow: function(rowData) {
    var separatorStyle = this.props.separatorStyle || DefaultStyles.separator;
    var rowTextStyle = this.props.rowText || DefaultStyles.rowText;

    var separator = <View style={separatorStyle}/>;
    if (rowData === this.props.list[0]) {
      separator = null;
    }

    var row = <Text style={rowTextStyle}>{rowData}</Text>
    if (this.props.renderRow) {
      row = this.props.renderRow(rowData);
    }

    return (
      <View>
        {separator}
        <TouchableOpacity onPress={() => this.handleClick(rowData)}>
          {row}
        </TouchableOpacity>
      </View>
    );
  },
  renderList: function() {
    var styles = this.props.style || DefaultStyles;
    var maxHeight = {};
    if (this.props.list.length > 12) {
      maxHeight = {height: SCREEN_HEIGHT * 3/4};
    }
    return (
      <ListView
        style={maxHeight}
        dataSource={this.state.dataSource}
        renderRow={(rowData) => this.renderRow(rowData)}
        automaticallyAdjustContentInsets={false}
      />
    );
  },
  render: function() {
    var containerStyle = this.props.containerStyle || DefaultStyles.container;
    var popoverStyle = this.props.popoverStyle || DefaultStyles.popover;

    if (this.props.isVisible) {
      return (
        <TouchableOpacity onPress={this.props.onClose}>
          <View style={containerStyle}>
            <View style={popoverStyle}>
              {this.renderList()}
            </View>
          </View>
        </TouchableOpacity>
      );
    } else {
      return (<View/>);
    }
  }
});

var DefaultStyles = StyleSheet.create({
  container: {
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    position: 'absolute',
    justifyContent: 'center',
    backgroundColor: 'transparent',
  },
  popover: {
    margin: 10,
    borderRadius: 3,
    padding: 3,
    backgroundColor: '#ffffff',
  },
  rowText: {
    padding: 10,
  },
  separator: {
    height: 0.5,
    marginLeft: 8,
    marginRight: 8,
    backgroundColor: '#CCC',
  },
});

module.exports = ListPopover;
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var {
  ActivityIndicatorIOS,
  ListView,
  Platform,
  ProgressBarAndroid,
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableHighlight,
  Alert,
} = React;

var dismissKeyboard = require('dismissKeyboard');

var Base64 = require('./Base64.js');
var EVENTICK_TOKEN_URL='https://www.eventick.com.br/api/v1/tokens.json';
var EventsScreen = require('./EventsScreen.js');

var LoginScreen = React.createClass({
  getInitialState: function() {
    return {
      emailText: '',
      passwordText: '',
      isLoading: false
    };
  },

  loadEventsScreen: function(eventickToken) {
    eventickToken = 'Basic ' + Base64.encode(eventickToken + ':');
    if (Platform.OS === 'ios') {
      this.props.navigator.push({
        title: 'Events List',
        component: EventsScreen,
        passProps: {eventickToken},
      });
    } else {
      dismissKeyboard();
      this.props.navigator.push({
        title: 'Events List',
        name: 'events',
        eventickToken: eventickToken,
      });
    }
  },

  onLoginPressed: function() {
    this.setState({ isLoading: true });

    var accessToken = 'Basic ' + Base64.encode(this.state.emailText + ':' + this.state.passwordText);

    fetch(EVENTICK_TOKEN_URL, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': accessToken,
      },
    })
    .then(res => res.json())
    .catch(err => {
      this.setState({ isLoading: false });

      displayAlert('Error', err.message);
    })
    .then(json => {
      this.setState({ isLoading: false });
      this.loadEventsScreen(json.token);
    });
  },

  displayAlert: function(title, message) {
    Alert.alert(
      title,
      message,
      [
        {text: 'OK', onPress: () => console.log('OK Pressed')},
      ]
    )
  },

  render: function() {
    var spinner;
    if(this.state.isLoading) {
      if (Platform.OS === 'ios') {
        spinner = ( <ActivityIndicatorIOS hidden='true' size='large' /> );
      } else {
        spinner = (
          <View  style={{alignItems: 'center'}}>
            <ProgressBarAndroid styleAttr="Large" />
          </View>
        );
      }
    }

    return (
      <View style={styles.container}>
        <TextInput
          style={styles.textInput}
          onChangeText={(emailText) => this.setState({emailText})}
          value={this.state.emailText}
          placeholder="email"
          autoCorrect={false}
          keyboardType="email-address"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.textInput}
          onChangeText={(passwordText) => this.setState({passwordText})}
          value={this.state.passwordText}
          placeholder="password"
          autoCorrect={false}
          secureTextEntry={true}
        />
        <TouchableHighlight style={styles.button}
          underlayColor='#99d9f4'
          onPress={this.onLoginPressed}>
          <Text style={styles.buttonText}>Login</Text>
        </TouchableHighlight>
        {spinner}
      </View>
    );
  },
});

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
    padding: 20,
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  textInput: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    padding: 10,
    margin: 10
  },
  buttonText: {
    fontSize: 18,
    color: 'white',
    alignSelf: 'center'
  },
  button: {
    height: 36,
    backgroundColor: '#48BBEC',
    borderColor: '#48BBEC',
    borderWidth: 1,
    borderRadius: 8,
    marginBottom: 10,
    alignSelf: 'stretch',
    justifyContent: 'center'
  },
});

module.exports = LoginScreen;<commit_msg>Fix displayAlert on LoginScreen<commit_after>'use strict';

var React = require('react-native');
var {
  ActivityIndicatorIOS,
  ListView,
  Platform,
  ProgressBarAndroid,
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableHighlight,
  Alert,
} = React;

var dismissKeyboard = require('dismissKeyboard');

var Base64 = require('./Base64.js');
var EVENTICK_TOKEN_URL='https://www.eventick.com.br/api/v1/tokens.json';
var EventsScreen = require('./EventsScreen.js');

var LoginScreen = React.createClass({
  getInitialState: function() {
    return {
      emailText: '',
      passwordText: '',
      isLoading: false
    };
  },

  loadEventsScreen: function(eventickToken) {
    eventickToken = 'Basic ' + Base64.encode(eventickToken + ':');
    if (Platform.OS === 'ios') {
      this.props.navigator.push({
        title: 'Events List',
        component: EventsScreen,
        passProps: {eventickToken},
      });
    } else {
      dismissKeyboard();
      this.props.navigator.push({
        title: 'Events List',
        name: 'events',
        eventickToken: eventickToken,
      });
    }
  },

  onLoginPressed: function() {
    this.setState({ isLoading: true });

    var accessToken = 'Basic ' + Base64.encode(this.state.emailText + ':' + this.state.passwordText);

    fetch(EVENTICK_TOKEN_URL, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': accessToken,
      },
    })
    .then(res => res.json())
    .catch(err => {
      this.setState({ isLoading: false });

      this.displayAlert('Error', err.message);
    })
    .then(json => {
      this.setState({ isLoading: false });
      this.loadEventsScreen(json.token);
    });
  },

  displayAlert: function(title, message) {
    Alert.alert(
      title,
      message,
      [
        {text: 'OK', onPress: () => console.log('OK Pressed')},
      ]
    )
  },

  render: function() {
    var spinner;
    if(this.state.isLoading) {
      if (Platform.OS === 'ios') {
        spinner = ( <ActivityIndicatorIOS hidden='true' size='large' /> );
      } else {
        spinner = (
          <View  style={{alignItems: 'center'}}>
            <ProgressBarAndroid styleAttr="Large" />
          </View>
        );
      }
    }

    return (
      <View style={styles.container}>
        <TextInput
          style={styles.textInput}
          onChangeText={(emailText) => this.setState({emailText})}
          value={this.state.emailText}
          placeholder="email"
          autoCorrect={false}
          keyboardType="email-address"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.textInput}
          onChangeText={(passwordText) => this.setState({passwordText})}
          value={this.state.passwordText}
          placeholder="password"
          autoCorrect={false}
          secureTextEntry={true}
        />
        <TouchableHighlight style={styles.button}
          underlayColor='#99d9f4'
          onPress={this.onLoginPressed}>
          <Text style={styles.buttonText}>Login</Text>
        </TouchableHighlight>
        {spinner}
      </View>
    );
  },
});

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
    padding: 20,
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  textInput: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    padding: 10,
    margin: 10
  },
  buttonText: {
    fontSize: 18,
    color: 'white',
    alignSelf: 'center'
  },
  button: {
    height: 36,
    backgroundColor: '#48BBEC',
    borderColor: '#48BBEC',
    borderWidth: 1,
    borderRadius: 8,
    marginBottom: 10,
    alignSelf: 'stretch',
    justifyContent: 'center'
  },
});

module.exports = LoginScreen;<|endoftext|>


<commit_before><commit_msg>prof module<commit_after><|endoftext|>


<commit_before>'use strict';

const bodyParser = require('body-parser');
const express = require('express');
const request = require('request');
var path = require('path');
var nus = require( path.resolve( __dirname, "./nusmod.js" ) );

// Webserver parameter
const PORT = process.env.PORT || 8445;

// Messenger API parameters
const FB_PAGE_ID = process.env.FB_PAGE_ID;
if (!FB_PAGE_ID) {
  throw new Error('missing FB_PAGE_ID');
}
const FB_PAGE_TOKEN = process.env.FB_PAGE_TOKEN;
if (!FB_PAGE_TOKEN) {
  throw new Error('missing FB_PAGE_TOKEN');
}
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;

const sessions = {};
const findOrCreateSession = (fbid) => {
  let sessionId;
  // Let's see if we already have a session for the user fbid
  Object.keys(sessions).forEach(k => {
    if (sessions[k].fbid === fbid) {
      // Yep, got it!
      sessionId = k;
    }
  });
  if (!sessionId) {
    // No session found for user fbid, let's create a new one
    sessionId = new Date().toISOString();
    sessions[sessionId] = {fbid: fbid, context: {}};
  }
  return sessionId;
};

// Messenger API specific code

// See the Send API reference
// https://developers.facebook.com/docs/messenger-platform/send-api-reference
const fbReq = request.defaults({
  uri: 'https://graph.facebook.com/me/messages',
  method: 'POST',
  json: true,
  qs: { access_token: FB_PAGE_TOKEN },
  headers: {'Content-Type': 'application/json'},
});

const fbMessage = (recipientId, msg, cb) => {
  const opts = {
    form: {
      recipient: {
        id: recipientId,
      },
      message: {
        text: msg,
      },
    },
  };
  fbReq(opts, (err, resp, data) => {
    if (cb) {
      cb(err || data.error && data.error.message, data);
    }
  });
};

const fbMessageWithButtons = (recipientId, msg, cb) => {
  const opts = {
    form: {
      recipient: {
        id: recipientId,
      },
      message: {
        'attachment': {
        	'type': 'template',
        	'payload': {
        		'template_type': 'button',
        		'text': msg,
        		'buttons': [
        		{
        			'type': 'postback',
        			'title': 'Thank you',
        			'payload': 'yay'
        		},
        		{
        			'type': 'postback',
        			'title': 'Err no',
        			'payload': 'nay'
        		}
        		]
        	}
      },
    },
  },
};
  fbReq(opts, (err, resp, data) => {
    if (cb) {
      cb(err || data.error && data.error.message, data);
    }
  });
};

// See the Webhook reference
// https://developers.facebook.com/docs/messenger-platform/webhook-reference
// const getFirstMessagingEntry = (body) => {
//   const val = body.object == 'page' &&
//     body.entry &&
//     Array.isArray(body.entry) &&
//     body.entry.length > 0 &&
//     body.entry[0] &&
//     body.entry[0].id === FB_PAGE_ID &&
//     body.entry[0].messaging &&
//     Array.isArray(body.entry[0].messaging) &&
//     body.entry[0].messaging.length > 0 &&
//     body.entry[0].messaging[0]
//   ;
//   return val || null;
// };

// Starting our webserver and putting it all together
const app = express();
app.set('port', PORT);
app.listen(app.get('port'));
app.use(bodyParser.json());

// Webhook setup
app.get('/fb', (req, res) => {
  if (!FB_VERIFY_TOKEN) {
    throw new Error('missing FB_VERIFY_TOKEN');
  }
  if (req.query['hub.mode'] === 'subscribe' &&
    req.query['hub.verify_token'] === FB_VERIFY_TOKEN) {
    res.send(req.query['hub.challenge']);
  } else {
    res.sendStatus(400);
  }
});

// Message handler
app.post('/fb', (req, res) => {
  // Parsing the Messenger API response

  // const messaging = getFirstMessagingEntry(req.body);
  // if (messaging && messaging.message && messaging.recipient.id === FB_PAGE_ID) {
  //   // Yay! We got a new message!

  //   // We retrieve the Facebook user ID of the sender

  //   const sender = messaging.sender.id;

  //   // We retrieve the message content
  //   const msg = messaging.message.text.toUpperCase();
  //   const atts = messaging.message.attachments;
  //   // const payload = messaging.postback;

  //   if (atts) {
  //     // We received an attachment

  //     // Let's reply with an automatic message

  //     fbMessage(
  //       sender,
  //       'What a nice photo!'
  //     );
  //   } else if (msg) {

  //     execute(sender, msg);

  //   } else if (payload){
  //   	console.log('fine');
  //   }
  //   // } else if (payload) {

  //   //   // Handle a payload from this sender
  //   //   console.log(payload);
  //   // }
  // }

  let messaging_events = req.body.entry[0].messaging
	for (let i = 0; i < messaging_events.length; i++) {

		let event = req.body.entry[0].messaging[i]
		let sender = event.sender.id
		const sessionId = findOrCreateSession(sender);

		if (event.message && event.message.text) {
			let text = event.message.text.toUpperCase()
			// sessions[sessionId].context.parameter = execute(sender,text);
			// fbMessage(sender,sessions[sessionId].context.parameter);
			execute(sender,text);
		}
		if (event.postback) {
			if (event.postback.payload == 'yay' ) {
				fbMessage(sender,'It is my pleasure!');
				delete sessions[sessionId];
				console.log('session terminated');
			} else {
				fbMessage(sender,'Too bad!');
				delete sessions[sessionId];
				console.log('session terminated');
			}
		}
	}

  res.sendStatus(200);
});

//function to check text

var execute = (sender, msg ) => {

	var intent = nus.findKey(msg);
	var module = nus.findModule(msg);

	// var module = nusmod.findModule(msg);

	switch(intent){
		case "unsure":

		fbMessage(sender,"Do you wish to find class location or examination detail?");
		break;

		case "no intent":

		fbMessage(sender,"We are not ready for this sh*t");
		break;

		case "class":

		if (module !== -1) {
		var result = {};
		nus.getModule("2015-2016",module).then(function(res){
				result = Object.assign(result,res);
		}).catch(function(err){
			console.log(err);
		})
		// blah blah
		var messageToSend = "This is the message to send";
		fbMessage(sender,messageToSend);
		} else
			fbMessage(sender,'There is either no module indicated or we cannot find that module. Please indicate again');
		break;

		case "exam":

		if (module !== -1) {
			var result = {};

			nus.getModule(nus.findModule(msg)).then(function(res){
				// console.log(nus.findModule(msg));
				// console.log(res);
				result = Object.assign(result,res);
        // console.log(result);

        var messageToSend = "The time of examination of module " + nus.findModule(msg) + " is at " + nus.convertTime(result.ExamDate) + ", it will last for " + nus.convertPeriod(result.ExamDuration) +
        " and it will be held in " + result.ExamVenue + ".";
        console.log(nus.convertTime(result.ExamDate));
        fbMessageWithButtons(sender,messageToSend);
		// delete sessions[sessionId];
		console.log("Waiting for other messages");

		}).catch(function(value){
			// console.log(err);

			var messageToSend = "Sorry we cannot find your module. Is it " + value + "?";
			fbMessage(sender,messageToSend);
			console.log("Waiting for other messages");

		});
		} else
			fbMessage(sender,'There is either no module indicated or we cannot find that module. Please indicate again');

	}
	// return intent || module;

}

<commit_msg>fixing bugs<commit_after>'use strict';

const bodyParser = require('body-parser');
const express = require('express');
const request = require('request');
var path = require('path');
var nus = require( path.resolve( __dirname, "./nusmod.js" ) );

// Webserver parameter
const PORT = process.env.PORT || 8445;

// Messenger API parameters
const FB_PAGE_ID = process.env.FB_PAGE_ID;
if (!FB_PAGE_ID) {
  throw new Error('missing FB_PAGE_ID');
}
const FB_PAGE_TOKEN = process.env.FB_PAGE_TOKEN;
if (!FB_PAGE_TOKEN) {
  throw new Error('missing FB_PAGE_TOKEN');
}
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;

const sessions = {};
const findOrCreateSession = (fbid) => {
  let sessionId;
  // Let's see if we already have a session for the user fbid
  Object.keys(sessions).forEach(k => {
    if (sessions[k].fbid === fbid) {
      // Yep, got it!
      sessionId = k;
    }
  });
  if (!sessionId) {
    // No session found for user fbid, let's create a new one
    sessionId = new Date().toISOString();
    sessions[sessionId] = {fbid: fbid, context: {}};
  }
  return sessionId;
};

// Messenger API specific code

// See the Send API reference
// https://developers.facebook.com/docs/messenger-platform/send-api-reference
const fbReq = request.defaults({
  uri: 'https://graph.facebook.com/me/messages',
  method: 'POST',
  json: true,
  qs: { access_token: FB_PAGE_TOKEN },
  headers: {'Content-Type': 'application/json'},
});

const fbMessage = (recipientId, msg, cb) => {
  const opts = {
    form: {
      recipient: {
        id: recipientId,
      },
      message: {
        text: msg,
      },
    },
  };
  fbReq(opts, (err, resp, data) => {
    if (cb) {
      cb(err || data.error && data.error.message, data);
    }
  });
};

const fbMessageWithButtons = (recipientId, msg, cb) => {
  const opts = {
    form: {
      recipient: {
        id: recipientId,
      },
      message: {
        'attachment': {
        	'type': 'template',
        	'payload': {
        		'template_type': 'button',
        		'text': msg,
        		'buttons': [
        		{
        			'type': 'postback',
        			'title': 'Thank you',
        			'payload': 'yay'
        		},
        		{
        			'type': 'postback',
        			'title': 'Err no',
        			'payload': 'nay'
        		}
        		]
        	}
      },
    },
  },
};
  fbReq(opts, (err, resp, data) => {
    if (cb) {
      cb(err || data.error && data.error.message, data);
    }
  });
};

// See the Webhook reference
// https://developers.facebook.com/docs/messenger-platform/webhook-reference
// const getFirstMessagingEntry = (body) => {
//   const val = body.object == 'page' &&
//     body.entry &&
//     Array.isArray(body.entry) &&
//     body.entry.length > 0 &&
//     body.entry[0] &&
//     body.entry[0].id === FB_PAGE_ID &&
//     body.entry[0].messaging &&
//     Array.isArray(body.entry[0].messaging) &&
//     body.entry[0].messaging.length > 0 &&
//     body.entry[0].messaging[0]
//   ;
//   return val || null;
// };

// Starting our webserver and putting it all together
const app = express();
app.set('port', PORT);
app.listen(app.get('port'));
app.use(bodyParser.json());

// Webhook setup
app.get('/fb', (req, res) => {
  if (!FB_VERIFY_TOKEN) {
    throw new Error('missing FB_VERIFY_TOKEN');
  }
  if (req.query['hub.mode'] === 'subscribe' &&
    req.query['hub.verify_token'] === FB_VERIFY_TOKEN) {
    res.send(req.query['hub.challenge']);
  } else {
    res.sendStatus(400);
  }
});

// Message handler
app.post('/fb', (req, res) => {
  // Parsing the Messenger API response

  // const messaging = getFirstMessagingEntry(req.body);
  // if (messaging && messaging.message && messaging.recipient.id === FB_PAGE_ID) {
  //   // Yay! We got a new message!

  //   // We retrieve the Facebook user ID of the sender

  //   const sender = messaging.sender.id;

  //   // We retrieve the message content
  //   const msg = messaging.message.text.toUpperCase();
  //   const atts = messaging.message.attachments;
  //   // const payload = messaging.postback;

  //   if (atts) {
  //     // We received an attachment

  //     // Let's reply with an automatic message

  //     fbMessage(
  //       sender,
  //       'What a nice photo!'
  //     );
  //   } else if (msg) {

  //     execute(sender, msg);

  //   } else if (payload){
  //   	console.log('fine');
  //   }
  //   // } else if (payload) {

  //   //   // Handle a payload from this sender
  //   //   console.log(payload);
  //   // }
  // }

  let messaging_events = req.body.entry[0].messaging
	for (let i = 0; i < messaging_events.length; i++) {

		let event = req.body.entry[0].messaging[i]
		let sender = event.sender.id
		const sessionId = findOrCreateSession(sender);

		if (event.message && event.message.text) {
			let text = event.message.text.toUpperCase()
			// sessions[sessionId].context.parameter = execute(sender,text);
			// fbMessage(sender,sessions[sessionId].context.parameter);
			execute(sender,text);
		}
		if (event.postback) {
			if (event.postback.payload == 'yay' ) {
				fbMessage(sender,'It is my pleasure!');
				delete sessions[sessionId];
				console.log('session terminated');
			} else {
				fbMessage(sender,'Too bad!');
				delete sessions[sessionId];
				console.log('session terminated');
			}
		}
	}

  res.sendStatus(200);
});

//function to check text

var execute = (sender, msg ) => {

	var intent = nus.findKey(msg);
	var module = nus.findModule(msg);

	// var module = nusmod.findModule(msg);

	switch(intent){
		case "unsure":

		fbMessage(sender,"Do you wish to find class location or examination detail?");
		break;

		case "no intent":

		fbMessage(sender,"We are not ready for this sh*t");
		break;

		case "class":

		if (module !== -1) {
		var result = {};
		nus.getModule("2015-2016",module).then(function(res){
				result = Object.assign(result,res);
		}).catch(function(err){
			console.log(err);
		})
		// blah blah
		var messageToSend = "This is the message to send";
		fbMessage(sender,messageToSend);
		} else
			fbMessage(sender,'There is either no module indicated or we cannot find that module. Please indicate again');
		break;

		case "exam":

		if (module !== -1) {
			var result = {};

			nus.getModule(nus.findModule(msg)).then(function(res){
				// console.log(nus.findModule(msg));
				// console.log(res);
				result = Object.assign(result,res);
        // console.log(result);

        var messageToSend = "The time of examination of module " + nus.findModule(msg) + " is at " + nus.convertTime(result.ExamDate) + ", it will last for " + nus.convertPeriod(result.ExamDuration) +
        " and it will be held in " + result.ExamVenue + ".";
        console.log(nus.convertTime(result.ExamDate));
        fbMessageWithButtons(sender,messageToSend);
		// delete sessions[sessionId];
		console.log("Waiting for other messages");

		}).catch(function(err){
			console.log(err);

			var messageToSend = "Sorry we cannot find your module. Is it " + err + "?";
			fbMessage(sender,messageToSend);
			console.log("Waiting for other messages");

		});
		} else
			fbMessage(sender,'There is either no module indicated or we cannot find that module. Please indicate again');

	}
	// return intent || module;

}

<|endoftext|>


<commit_before>var plot, ymax,xmax;
$(function(){
  var graph = $('.plot');
  graph.height(graph.width()/2);
  updateGraph();

  $('.scaley').click(function(){
    $(this).toggleClass('success');
    $('.gymax').parents('.columns').toggleClass('invisible');
    if($('.gxmax').is(':visible')){
      $('.gymax').val(ymax);
    }
  });

  $('.scalex').click(function(){
    $(this).toggleClass('success');
    $('.gxmax').parents('.columns').toggleClass('invisible');
    if($('.gxmax').is(':visible')){
      $('.gxmax').val(xmax.toFixed(2));
    }
  });

  $('.update-graph').click(function(){
    updateGraph();
  });
});

function updateGraph(){
  var v0 = nanDefault(parseFloat($('.volt').val()),1);
  var res = nanDefault(parseFloat($('.res').val()),50);
  var ind = nanDefault(parseFloat($('.ind').val()),50)/1000;
  var cap = nanDefault(parseFloat($('.cap').val()),50)/1000000;
  var gymax = nanDefault(parseFloat($('.gymax').val()),0.05);
  var fmax = nanDefault(parseFloat($('.gxmax').val()),10000);
  var max_amp = (v0*1.0/res);
  var res_freq = (1/Math.sqrt(ind*cap));

  // Only scale if they've turned on autoscale
  var scaley = !$('.scaley').hasClass('success');
  var scalex = !$('.scalex').hasClass('success');
  var base = [];

  fmax = scalex ? fmax : res_freq*5;

  xmax = fmax;

  var step_size = fmax/50000.0;

  for(var i = 0; i < fmax; i += step_size){
    base.push([i,(v0)/(Math.sqrt(Math.pow(res,2)+Math.pow((i)*ind-1/((i)*cap),2)))]);
  }

  var options = {
    xaxes: [{
      axisLabel: 'ω (rad/s)',
      axisLabelPadding: 10,
      axisLabelUseCanvas: true,
      font: {size: 15, color: 'black'}
    }],
    yaxes: [{
      axisLabel: 'Amplitude of current (A)',
      axisLabelPadding: 10,
      axisLabelUseCanvas: true,
      font: {size: 15, color: 'black'},
      min: 0
    }],
    grid: {labelMargin: 10}
      };

  if(scaley){
    options.yaxes[0].max = gymax;
  }

  var max_res = [[res_freq,0],[res_freq,max_amp]];

  var plot = $.plot('.plot',[
      {data: max_res, color: 'red', shadowSize: 0, dashes: {show: true}},
      {data: base},
      ], options);
  ymax = plot.getAxes().yaxis.max;
  $('.note').text('Maximum amplitude of current is '+max_amp.toFixed(3)+' A at ω = '+res_freq.toFixed(2)+' rad/s.');
}

function nanDefault(value,def){
  return isNaN(value) ? def : value
}
<commit_msg>Fixing my oopsies<commit_after>var plot, ymax,xmax;
$(function(){
  var graph = $('.plot');
  graph.height(graph.width()/2);
  updateGraph();

  $('.scaley').click(function(){
    $(this).toggleClass('success');
    $('.gymax').parents('.columns').toggleClass('invisible');
    if($('.gxmax').is(':visible')){
      $('.gymax').val(ymax);
    }
  });

  $('.scalex').click(function(){
    $(this).toggleClass('success');
    $('.gxmax').parents('.columns').toggleClass('invisible');
    if($('.gxmax').is(':visible')){
      $('.gxmax').val(xmax.toFixed(2));
    }
  });

  $('.update-graph').click(function(){
    updateGraph();
  });
});

function updateGraph(){
  var v0 = nanDefault(parseFloat($('.volt').val()),1);
  var res = nanDefault(parseFloat($('.res').val()),50);
  var ind = nanDefault(parseFloat($('.ind').val()),50)/1000;
  var cap = nanDefault(parseFloat($('.cap').val()),50)/1000000;
  var gymax = nanDefault(parseFloat($('.gymax').val()),0.05);
  var fmax = nanDefault(parseFloat($('.gxmax').val()),10000);
  var max_amp = (v0*1.0/res);
  var res_freq = (1/Math.sqrt(ind*cap));

  // Only scale if they've turned on autoscale
  var scaley = !$('.scaley').hasClass('success');
  var scalex = !$('.scalex').hasClass('success');
  var base = [];

  fmax = scalex ? fmax : res_freq*5;

  xmax = fmax;

  var step_size = fmax/50000.0;

  for(var i = 0; i < fmax; i += step_size){
    base.push([i,(v0)/(Math.sqrt(Math.pow(res,2)+Math.pow((i)*ind-1/((i)*cap),2)))]);
  }

  var options = {
    xaxes: [{
      axisLabel: 'f (Hz)',
      axisLabelPadding: 10,
      axisLabelUseCanvas: true,
      font: {size: 15, color: 'black'}
    }],
    yaxes: [{
      axisLabel: 'Amplitude of current (A)',
      axisLabelPadding: 10,
      axisLabelUseCanvas: true,
      font: {size: 15, color: 'black'},
      min: 0
    }],
    grid: {labelMargin: 10}
      };

  if(scaley){
    options.yaxes[0].max = gymax;
  }

  var max_res = [[res_freq,0],[res_freq,max_amp]];

  var plot = $.plot('.plot',[
      {data: max_res, color: 'red', shadowSize: 0, dashes: {show: true}},
      {data: base},
      ], options);
  ymax = plot.getAxes().yaxis.max;
  $('.note').text('Maximum amplitude of current is '+max_amp.toFixed(3)+' A at ω = '+res_freq.toFixed(2)+' rad/s.');
}

function nanDefault(value,def){
  return isNaN(value) ? def : value
}
<|endoftext|>


<commit_before>import React from 'react';
import { mount } from 'enzyme';
import { RoomCard } from './index';

const roomMock = {
  _id: 1,
  topic: 'this is a topic',
  name: 'this is a name',
  creator: {
    username: 'Arno'
  }
};

test('<RoomCard /> mounts with no errors', () => {
  mount(<RoomCard room={ roomMock }></RoomCard>);
});

test('<RoomCard /> renders a title', () => {
  const wrapper = mount(<RoomCard room={roomMock}></RoomCard>);
  expect(wrapper.find('.room-title.title').exists()).toEqual(true);
  expect(wrapper.find('.room-title.title').text()).toEqual('this is a name');
});

test('<RoomCard /> renders a description', () => {
  const wrapper = mount(<RoomCard room={roomMock}></RoomCard>);
  expect(wrapper.find('.description').exists()).toEqual(true);
  expect(wrapper.find('.description').text()).toEqual(roomMock.topic);
});

test('<RoomCard /> renders a creator', () => {
  const wrapper = mount(<RoomCard room={roomMock}></RoomCard>);
  const creatorNode = (

      created by { roomMock.creator.username }

);
  expect(wrapper.containsMatchingElement(creatorNode)).toEqual(true);
});
<commit_msg>test(roomCard): roomCard should redirect to room<commit_after>import React from 'react';
import { mount } from 'enzyme';
import { RoomCard } from './index';

const roomMock = {
  _id: 1,
  topic: 'this is a topic',
  name: 'this is a name',
  creator: {
    username: 'Arno'
  }
};

test('<RoomCard /> mounts with no errors', () => {
  mount(<RoomCard room={ roomMock }></RoomCard>);
});

test('<RoomCard /> renders a title', () => {
  const wrapper = mount(<RoomCard room={ roomMock }></RoomCard>);
  expect(wrapper.find('.room-title.title').exists()).toEqual(true);
  expect(wrapper.find('.room-title.title').text()).toEqual('this is a name');
});

test('<RoomCard /> renders a description', () => {
  const wrapper = mount(<RoomCard room={ roomMock }></RoomCard>);
  expect(wrapper.find('.description').exists()).toEqual(true);
  expect(wrapper.find('.description').text()).toEqual(roomMock.topic);
});

test('<RoomCard /> renders a creator', () => {
  const wrapper = mount(<RoomCard room={ roomMock }></RoomCard>);
  const creatorNode = (

      created by { roomMock.creator.username }

);
  expect(wrapper.containsMatchingElement(creatorNode)).toEqual(true);
});

test('<RoomCard /> redirects to room', () => {
  const wrapper = mount(<RoomCard room={ roomMock }></RoomCard>);
  const roomCard = wrapper.find('.room').get(0);
  expect(roomCard.props.to).toEqual(`/broadcast/${roomMock._id}`);
});
<|endoftext|>