<commit_before>import React, {Component} from 'react';

import FlatButton from 'src/FlatButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';

import PropTypeDescTable from 'components/PropTypeDescTable';
import doc from 'assets/propTypes/FlatButton.json';

import 'scss/containers/app/modules/buttons/FlatButtonExamples.scss';

class FlatButtonExamples extends Component {

    constructor(props) {
        super(props);
    }

    render() {

        return (

Flat Button

                    Flat Button are used for general functions and reduce the amount of layering on the
                    screen, making it more readable.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Basic"/>

                                    Flat Button with default
                                    theme, success, warning
                                    , error and disabled props applied.

                                <FlatButton value="Default"/>

                                <FlatButton value="Primary"
                                            theme={FlatButton.Theme.PRIMARY}/>

                                <FlatButton value="Secondary"
                                            theme={FlatButton.Theme.SECONDARY}/>

                                <FlatButton value="Highlight"
                                            theme={FlatButton.Theme.HIGHLIGHT}/>

                                <FlatButton value="Info"
                                            theme={FlatButton.Theme.INFO}/>

                                <FlatButton value="Success"
                                            theme={FlatButton.Theme.SUCCESS}/>

                                <FlatButton value="Warning"
                                            theme={FlatButton.Theme.WARNING}/>

                                <FlatButton value="Error"
                                            theme={FlatButton.Theme.ERROR}/>

                                <FlatButton value="Disabled"
                                            disabled={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With border radius"/>

Set the isRounded property to true for button round corner.

                                <FlatButton value="Default"
                                            isRounded={true}/>

                                <FlatButton value="Primary"
                                            theme={FlatButton.Theme.PRIMARY}
                                            isRounded={true}/>

                                <FlatButton value="Secondary"
                                            theme={FlatButton.Theme.SECONDARY}
                                            isRounded={true}/>

                                <FlatButton value="Highlight"
                                            theme={FlatButton.Theme.HIGHLIGHT}
                                            isRounded={true}/>

                                <FlatButton value="Info"
                                            theme={FlatButton.Theme.INFO}
                                            isRounded={true}/>

                                <FlatButton value="Success"
                                            theme={FlatButton.Theme.SUCCESS}
                                            isRounded={true}/>

                                <FlatButton value="Warning"
                                            theme={FlatButton.Theme.WARNING}
                                            isRounded={true}/>

                                <FlatButton value="Error"
                                            theme={FlatButton.Theme.ERROR}
                                            isRounded={true}/>

                                <FlatButton value="Disabled"
                                            disabled={true}
                                            isRounded={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With icon"/>

Set the iconCls property for button left icon.And set the
                                    rightIconCls property for button right icon.

                                <FlatButton value="Reset"
                                            iconCls="fas fa-undo"/>

                                <FlatButton value="Add"
                                            theme={FlatButton.Theme.SUCCESS}
                                            iconCls="fas fa-plus"/>

                                <FlatButton value="Delete"
                                            theme={FlatButton.Theme.ERROR}
                                            iconCls="fas fa-trash-alt"/>

                                <FlatButton value="Next"
                                            theme={FlatButton.Theme.PRIMARY}
                                            rightIconCls="fas fa-angle-right"/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Use circle shape"/>

Set the isCircular property to true for circle shape flat button.

                                <FlatButton value="Primary"
                                            isCircular={true}/>

                                <FlatButton value="Success"
                                            theme={FlatButton.Theme.SUCCESS}
                                            isCircular={true}/>

                                <FlatButton value="Error"
                                            theme={FlatButton.Theme.ERROR}
                                            isCircular={true}/>

                                <FlatButton value="Warning"
                                            theme={FlatButton.Theme.WARNING}
                                            isCircular={true}/>

                </Widget>

Properties

                <PropTypeDescTable data={doc}/>

        );
    }
};

export default FlatButtonExamples;
<commit_msg>update FlatButtonExamples<commit_after>import React, {Component} from 'react';

import FlatButton from 'src/FlatButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';

import PropTypeDescTable from 'components/PropTypeDescTable';
import doc from 'assets/propTypes/FlatButton.json';

import 'scss/containers/app/modules/buttons/FlatButtonExamples.scss';

class FlatButtonExamples extends Component {

    constructor(props) {
        super(props);
    }

    render() {

        return (

Flat Button

                    Flat Button
                    are used for general functions and reduce the amount of layering on the
                    screen, making it more readable.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Basic"/>

                                    Flat Button with default
                                    theme, success, warning
                                    , error and disabled props applied.

                                <FlatButton value="Default"
                                            tip="Default"/>

                                <FlatButton value="Primary"
                                            tip="Primary"
                                            theme={FlatButton.Theme.PRIMARY}/>

                                <FlatButton value="Secondary"
                                            tip="Secondary"
                                            theme={FlatButton.Theme.SECONDARY}/>

                                <FlatButton value="Highlight"
                                            tip="Highlight"
                                            theme={FlatButton.Theme.HIGHLIGHT}/>

                                <FlatButton value="Info"
                                            tip="Info"
                                            theme={FlatButton.Theme.INFO}/>

                                <FlatButton value="Success"
                                            tip="Success"
                                            theme={FlatButton.Theme.SUCCESS}/>

                                <FlatButton value="Warning"
                                            tip="Warning"
                                            theme={FlatButton.Theme.WARNING}/>

                                <FlatButton value="Error"
                                            tip="Error"
                                            theme={FlatButton.Theme.ERROR}/>

                                <FlatButton value="Disabled"
                                            tip="Disabled"
                                            disabled={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With border radius"/>

Set the isRounded property to true for button round corner.

                                <FlatButton value="Default"
                                            isRounded={true}/>

                                <FlatButton value="Primary"
                                            theme={FlatButton.Theme.PRIMARY}
                                            isRounded={true}/>

                                <FlatButton value="Secondary"
                                            theme={FlatButton.Theme.SECONDARY}
                                            isRounded={true}/>

                                <FlatButton value="Highlight"
                                            theme={FlatButton.Theme.HIGHLIGHT}
                                            isRounded={true}/>

                                <FlatButton value="Info"
                                            theme={FlatButton.Theme.INFO}
                                            isRounded={true}/>

                                <FlatButton value="Success"
                                            theme={FlatButton.Theme.SUCCESS}
                                            isRounded={true}/>

                                <FlatButton value="Warning"
                                            theme={FlatButton.Theme.WARNING}
                                            isRounded={true}/>

                                <FlatButton value="Error"
                                            theme={FlatButton.Theme.ERROR}
                                            isRounded={true}/>

                                <FlatButton value="Disabled"
                                            disabled={true}
                                            isRounded={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With icon"/>

Set the iconCls property for button left icon.And set the
                                    rightIconCls property for button right icon.

                                <FlatButton value="Reset"
                                            iconCls="fas fa-undo"/>

                                <FlatButton value="Add"
                                            theme={FlatButton.Theme.SUCCESS}
                                            iconCls="fas fa-plus"/>

                                <FlatButton value="Delete"
                                            theme={FlatButton.Theme.ERROR}
                                            iconCls="fas fa-trash-alt"/>

                                <FlatButton value="Next"
                                            theme={FlatButton.Theme.PRIMARY}
                                            rightIconCls="fas fa-angle-right"/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Use circle shape"/>

Set the isCircular property to true for circle shape flat button.

                                <FlatButton value="Primary"
                                            isCircular={true}/>

                                <FlatButton value="Success"
                                            theme={FlatButton.Theme.SUCCESS}
                                            isCircular={true}/>

                                <FlatButton value="Error"
                                            theme={FlatButton.Theme.ERROR}
                                            isCircular={true}/>

                                <FlatButton value="Warning"
                                            theme={FlatButton.Theme.WARNING}
                                            isCircular={true}/>

                </Widget>

Properties

                <PropTypeDescTable data={doc}/>

        );
    }
};

export default FlatButtonExamples;
<|endoftext|>


<commit_before>'use strict';

const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const babelHelpers = require('./broccoli/babel-helpers');
const concatBundle = require('./lib/concat-bundle');
const testIndexHTML = require('./broccoli/test-index-html');
const testPolyfills = require('./broccoli/test-polyfills');
const rollupPackage = require('./broccoli/rollup-package');
const minify = require('./broccoli/minify');
const debugTree = require('broccoli-debug').buildDebugCallback('ember-source:ember-cli-build');

Error.stackTraceLimit = Infinity;

const {
  routerES,
  jquery,
  loader,
  qunit,
  handlebarsES,
  rsvpES,
  simpleHTMLTokenizerES,
  backburnerES,
  dagES,
  routeRecognizerES,
  glimmerES,
  glimmerCompilerES,
  emberVersionES,
  emberLicense,
  getPackagesES,
} = require('./broccoli/packages');

const { allSupportedBrowsers, modernBrowsers } = require('./config/browserlists');

const ENV = process.env.EMBER_ENV || 'development';
const SHOULD_ROLLUP = process.env.SHOULD_ROLLUP !== 'false';
const SHOULD_MINIFY = Boolean(process.env.SHOULD_MINIFY);

/**
 * There isn't a way for us to override targets through ember-cli-babel, and we
 * don't want to introduce that functionality for reasons. This is a quick and
 * dirty way for us to accomplish custom targets. This is specifically for:
 *
 * 1. The ember-template-compiler.js file, which should always be built for all
 *    of our supported browsers.
 * 2. The ember.debug.js file, which should always be built for modern browsers.
 *
 * This is not a recommended way of building standard Ember apps.
 */
function withTargets(project, fn) {
  return (tree, isProduction = ENV === 'production', { targets } = {}) => {
    let originalTargets = project.targets;
    if (targets !== undefined) project._targets = targets;

    let transpiled = fn(tree, isProduction);

    project._targets = originalTargets;

    return transpiled;
  };
}

module.exports = function ({ project }) {
  let emberSource = project.addons.find((a) => a.name === 'ember-source');

  let transpileTree = withTargets(project, emberSource.transpileTree.bind(emberSource));
  let emberBundles = withTargets(project, emberSource.buildEmberBundles.bind(emberSource));

  let packages = debugTree(
    new MergeTrees([
      // dynamically generated packages
      emberVersionES(),

      // packages/** (after typescript compilation)
      getPackagesES(),

      // externalized helpers
      babelHelpers(),
    ]),
    'packages:initial'
  );

  // Rollup
  if (SHOULD_ROLLUP) {
    packages = debugTree(
      new MergeTrees([
        new Funnel(packages, {
          exclude: [
            '@ember/-internals/browser-environment/index.js',
            '@ember/-internals/browser-environment/lib/**',
            '@ember/-internals/container/index.js',
            '@ember/-internals/container/lib/**',
            '@ember/-internals/environment/index.js',
            '@ember/-internals/environment/lib/**',
            '@ember/-internals/glimmer/index.js',
            '@ember/-internals/glimmer/lib/**',
            '@ember/-internals/metal/index.js',
            '@ember/-internals/metal/lib/**',
            '@ember/-internals/utils/index.js',
            '@ember/-internals/utils/lib/**',
          ],
        }),
        rollupPackage(packages, '@ember/-internals/browser-environment'),
        rollupPackage(packages, '@ember/-internals/environment'),
        rollupPackage(packages, '@ember/-internals/glimmer'),
        rollupPackage(packages, '@ember/-internals/metal'),
        rollupPackage(packages, '@ember/-internals/utils'),
        rollupPackage(packages, '@ember/-internals/container'),
      ]),
      'packages:rollup'
    );
  }

  let dist = debugTree(
    new MergeTrees([
      new Funnel(packages, {
        destDir: 'packages',
        exclude: [
          '**/package.json',
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
          'ember-template-compiler/**',
          'internal-test-helpers/**',
        ],
      }),
      new Funnel(emberHeaderFiles(), { destDir: 'header' }),
      new Funnel(emberDependencies(ENV), { destDir: 'dependencies' }),
    ]),
    'dist'
  );

  // Test builds, tests, and test harness
  let testFiles = debugTree(
    new Funnel(
      new MergeTrees([
        emberBundles(dist),
        testsBundle(packages, ENV, transpileTree),
        testHarness(),
      ]),
      {
        destDir: 'tests',
      }
    ),
    'testFiles'
  );

  let preBuilt = debugTree(
    new Funnel(emberBundles(dist, false, { targets: modernBrowsers, loose: false }), {
      getDestinationPath(path) {
        return path.replace('ember.', 'ember.debug.');
      },
    }),
    'preBuilt'
  );

  if (SHOULD_MINIFY) {
    preBuilt = minify(preBuilt);
  }

  return new MergeTrees([
    // Distributed files
    dist,

    // Pre-built bundles
    preBuilt,
    debugTree(templateCompilerBundle(packages, transpileTree), 'template-compiler'),

    testFiles,
  ]);
};

function emberDependencies(environment) {
  // generate "loose" ES<latest> modules...
  return debugTree(
    new MergeTrees([
      backburnerES(),
      rsvpES(),
      dagES(),
      routerES(),
      routeRecognizerES(),
      glimmerES(environment),
    ]),
    'dependencies'
  );
}

function testsBundle(emberPackages, env, transpileTree) {
  let exclude = env === 'production' ? ['@ember/debug/tests/**', 'ember-testing/tests/**'] : [];

  let emberTestsFiles = transpileTree(
    new MergeTrees([
      new Funnel(emberPackages, {
        include: [
          'internal-test-helpers/**',
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
          'ember-template-compiler/**',
        ],
        exclude,
      }),
    ])
  );

  return concatBundle(new MergeTrees([emberTestsFiles, emberHeaderFiles()]), {
    outputFile: 'ember-tests.js',
  });
}

function templateCompilerBundle(emberPackages, transpileTree) {
  let templateCompilerFiles = transpileTree(
    new MergeTrees([
      new Funnel(emberPackages, {
        include: [
          '@ember/-internals/utils/**',
          '@ember/-internals/environment/**',
          '@ember/-internals/browser-environment/**',
          '@ember/canary-features/**',
          '@ember/debug/**',
          '@ember/deprecated-features/**',
          '@ember/error/**',
          '@ember/polyfills/**',
          'ember/version.js',
          'ember-babel.js',
          'ember-template-compiler/**',
          'node-module/**',
        ],
        exclude: [
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
        ],
      }),
      templateCompilerDependencies(),
    ]),
    false,
    { targets: allSupportedBrowsers, loose: false }
  );

  return concatBundle(new MergeTrees([templateCompilerFiles, emberHeaderFiles()]), {
    outputFile: 'ember-template-compiler.js',
    footer:
      '(function (m) { if (typeof module === "object" && module.exports) { module.exports = m } }(require("ember-template-compiler")));',
  });
}

function testHarness() {
  return new MergeTrees([
    emptyTestem(),
    testPolyfills(),
    testIndexHTML(),
    loader(),
    qunit(),
    jquery(),
  ]);
}

function emptyTestem() {
  return new Funnel('tests', {
    files: ['testem.js'],
    destDir: '',
    annotation: 'tests/testem.js',
  });
}

function templateCompilerDependencies() {
  return new MergeTrees([simpleHTMLTokenizerES(), handlebarsES(), glimmerCompilerES()]);
}

function emberHeaderFiles() {
  return new MergeTrees([emberLicense(), loader()]);
}
<commit_msg>[fixes #19588] Don’t include type-tests in build<commit_after>'use strict';

const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const babelHelpers = require('./broccoli/babel-helpers');
const concatBundle = require('./lib/concat-bundle');
const testIndexHTML = require('./broccoli/test-index-html');
const testPolyfills = require('./broccoli/test-polyfills');
const rollupPackage = require('./broccoli/rollup-package');
const minify = require('./broccoli/minify');
const debugTree = require('broccoli-debug').buildDebugCallback('ember-source:ember-cli-build');

Error.stackTraceLimit = Infinity;

const {
  routerES,
  jquery,
  loader,
  qunit,
  handlebarsES,
  rsvpES,
  simpleHTMLTokenizerES,
  backburnerES,
  dagES,
  routeRecognizerES,
  glimmerES,
  glimmerCompilerES,
  emberVersionES,
  emberLicense,
  getPackagesES,
} = require('./broccoli/packages');

const { allSupportedBrowsers, modernBrowsers } = require('./config/browserlists');

const ENV = process.env.EMBER_ENV || 'development';
const SHOULD_ROLLUP = process.env.SHOULD_ROLLUP !== 'false';
const SHOULD_MINIFY = Boolean(process.env.SHOULD_MINIFY);

/**
 * There isn't a way for us to override targets through ember-cli-babel, and we
 * don't want to introduce that functionality for reasons. This is a quick and
 * dirty way for us to accomplish custom targets. This is specifically for:
 *
 * 1. The ember-template-compiler.js file, which should always be built for all
 *    of our supported browsers.
 * 2. The ember.debug.js file, which should always be built for modern browsers.
 *
 * This is not a recommended way of building standard Ember apps.
 */
function withTargets(project, fn) {
  return (tree, isProduction = ENV === 'production', { targets } = {}) => {
    let originalTargets = project.targets;
    if (targets !== undefined) project._targets = targets;

    let transpiled = fn(tree, isProduction);

    project._targets = originalTargets;

    return transpiled;
  };
}

module.exports = function ({ project }) {
  let emberSource = project.addons.find((a) => a.name === 'ember-source');

  let transpileTree = withTargets(project, emberSource.transpileTree.bind(emberSource));
  let emberBundles = withTargets(project, emberSource.buildEmberBundles.bind(emberSource));

  let packages = debugTree(
    new MergeTrees([
      // dynamically generated packages
      emberVersionES(),

      // packages/** (after typescript compilation)
      getPackagesES(),

      // externalized helpers
      babelHelpers(),
    ]),
    'packages:initial'
  );

  // Rollup
  if (SHOULD_ROLLUP) {
    packages = debugTree(
      new MergeTrees([
        new Funnel(packages, {
          exclude: [
            '@ember/-internals/browser-environment/index.js',
            '@ember/-internals/browser-environment/lib/**',
            '@ember/-internals/container/index.js',
            '@ember/-internals/container/lib/**',
            '@ember/-internals/environment/index.js',
            '@ember/-internals/environment/lib/**',
            '@ember/-internals/glimmer/index.js',
            '@ember/-internals/glimmer/lib/**',
            '@ember/-internals/metal/index.js',
            '@ember/-internals/metal/lib/**',
            '@ember/-internals/utils/index.js',
            '@ember/-internals/utils/lib/**',
          ],
        }),
        rollupPackage(packages, '@ember/-internals/browser-environment'),
        rollupPackage(packages, '@ember/-internals/environment'),
        rollupPackage(packages, '@ember/-internals/glimmer'),
        rollupPackage(packages, '@ember/-internals/metal'),
        rollupPackage(packages, '@ember/-internals/utils'),
        rollupPackage(packages, '@ember/-internals/container'),
      ]),
      'packages:rollup'
    );
  }

  let dist = debugTree(
    new MergeTrees([
      new Funnel(packages, {
        destDir: 'packages',
        exclude: [
          '**/package.json',
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
          '@ember/-internals/*/type-tests/**' /* internal packages */,
          '*/*/type-tests/**' /* scoped packages */,
          '*/type-tests/**' /* packages */,
          'ember-template-compiler/**',
          'internal-test-helpers/**',
        ],
      }),
      new Funnel(emberHeaderFiles(), { destDir: 'header' }),
      new Funnel(emberDependencies(ENV), { destDir: 'dependencies' }),
    ]),
    'dist'
  );

  // Test builds, tests, and test harness
  let testFiles = debugTree(
    new Funnel(
      new MergeTrees([
        emberBundles(dist),
        testsBundle(packages, ENV, transpileTree),
        testHarness(),
      ]),
      {
        destDir: 'tests',
      }
    ),
    'testFiles'
  );

  let preBuilt = debugTree(
    new Funnel(emberBundles(dist, false, { targets: modernBrowsers, loose: false }), {
      getDestinationPath(path) {
        return path.replace('ember.', 'ember.debug.');
      },
    }),
    'preBuilt'
  );

  if (SHOULD_MINIFY) {
    preBuilt = minify(preBuilt);
  }

  return new MergeTrees([
    // Distributed files
    dist,

    // Pre-built bundles
    preBuilt,
    debugTree(templateCompilerBundle(packages, transpileTree), 'template-compiler'),

    testFiles,
  ]);
};

function emberDependencies(environment) {
  // generate "loose" ES<latest> modules...
  return debugTree(
    new MergeTrees([
      backburnerES(),
      rsvpES(),
      dagES(),
      routerES(),
      routeRecognizerES(),
      glimmerES(environment),
    ]),
    'dependencies'
  );
}

function testsBundle(emberPackages, env, transpileTree) {
  let exclude = env === 'production' ? ['@ember/debug/tests/**', 'ember-testing/tests/**'] : [];

  let emberTestsFiles = transpileTree(
    new MergeTrees([
      new Funnel(emberPackages, {
        include: [
          'internal-test-helpers/**',
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
          'ember-template-compiler/**',
        ],
        exclude,
      }),
    ])
  );

  return concatBundle(new MergeTrees([emberTestsFiles, emberHeaderFiles()]), {
    outputFile: 'ember-tests.js',
  });
}

function templateCompilerBundle(emberPackages, transpileTree) {
  let templateCompilerFiles = transpileTree(
    new MergeTrees([
      new Funnel(emberPackages, {
        include: [
          '@ember/-internals/utils/**',
          '@ember/-internals/environment/**',
          '@ember/-internals/browser-environment/**',
          '@ember/canary-features/**',
          '@ember/debug/**',
          '@ember/deprecated-features/**',
          '@ember/error/**',
          '@ember/polyfills/**',
          'ember/version.js',
          'ember-babel.js',
          'ember-template-compiler/**',
          'node-module/**',
        ],
        exclude: [
          '@ember/-internals/*/tests/**' /* internal packages */,
          '*/*/tests/**' /* scoped packages */,
          '*/tests/**' /* packages */,
        ],
      }),
      templateCompilerDependencies(),
    ]),
    false,
    { targets: allSupportedBrowsers, loose: false }
  );

  return concatBundle(new MergeTrees([templateCompilerFiles, emberHeaderFiles()]), {
    outputFile: 'ember-template-compiler.js',
    footer:
      '(function (m) { if (typeof module === "object" && module.exports) { module.exports = m } }(require("ember-template-compiler")));',
  });
}

function testHarness() {
  return new MergeTrees([
    emptyTestem(),
    testPolyfills(),
    testIndexHTML(),
    loader(),
    qunit(),
    jquery(),
  ]);
}

function emptyTestem() {
  return new Funnel('tests', {
    files: ['testem.js'],
    destDir: '',
    annotation: 'tests/testem.js',
  });
}

function templateCompilerDependencies() {
  return new MergeTrees([simpleHTMLTokenizerES(), handlebarsES(), glimmerCompilerES()]);
}

function emberHeaderFiles() {
  return new MergeTrees([emberLicense(), loader()]);
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {
  attachStar,
  contentFeedLike,
  feedCommentDelete,
  feedCommentEdit,
  feedContentEdit,
  feedContentDelete,
  feedRewardCommentEdit,
  feedVideoStar,
  fetchMoreFeeds,
  fetchNewFeeds,
  fetchFeeds,
  fetchFeed,
  loadMoreFeedReplies,
  loadMoreFeedComments,
  clearFeeds,
  setCurrentSection,
  setDifficulty,
  showFeedComments,
  uploadFeedComment,
  uploadTargetContentComment
} from 'redux/actions/FeedActions';
import { toggleHideWatched } from 'redux/actions/UserActions';
import { resetNumNewPosts } from 'redux/actions/NotiActions';
import InputPanel from './InputPanel';
import ContentPanel from 'components/ContentPanel';
import LoadMoreButton from 'components/Buttons/LoadMoreButton';
import Loading from 'components/Loading';
import { connect } from 'react-redux';
import { addEvent, removeEvent } from 'helpers/listenerHelpers';
import Banner from 'components/Banner';
import ErrorBoundary from 'components/Wrappers/ErrorBoundary';
import { queryStringForArray } from 'helpers/stringHelpers';
import { loadNewFeeds } from 'helpers/requestHelpers';
import HomeFilter from './HomeFilter';

class Stories extends Component {
  static propTypes = {
    attachStar: PropTypes.func.isRequired,
    chatMode: PropTypes.bool,
    clearFeeds: PropTypes.func.isRequired,
    contentFeedLike: PropTypes.func.isRequired,
    feedCommentDelete: PropTypes.func.isRequired,
    feedContentDelete: PropTypes.func.isRequired,
    feedContentEdit: PropTypes.func.isRequired,
    feedCommentEdit: PropTypes.func.isRequired,
    feedRewardCommentEdit: PropTypes.func.isRequired,
    feedVideoStar: PropTypes.func.isRequired,
    fetchFeed: PropTypes.func.isRequired,
    fetchFeeds: PropTypes.func.isRequired,
    fetchMoreFeeds: PropTypes.func.isRequired,
    fetchNewFeeds: PropTypes.func.isRequired,
    hideWatched: PropTypes.bool,
    history: PropTypes.object.isRequired,
    loaded: PropTypes.bool.isRequired,
    loadMoreButton: PropTypes.bool.isRequired,
    loadMoreFeedComments: PropTypes.func.isRequired,
    loadMoreFeedReplies: PropTypes.func.isRequired,
    numNewPosts: PropTypes.number.isRequired,
    resetNumNewPosts: PropTypes.func.isRequired,
    selectedFilter: PropTypes.string.isRequired,
    setDifficulty: PropTypes.func,
    showFeedComments: PropTypes.func.isRequired,
    storyFeeds: PropTypes.array.isRequired,
    toggleHideWatched: PropTypes.func.isRequired,
    username: PropTypes.string,
    uploadFeedComment: PropTypes.func.isRequired,
    uploadTargetContentComment: PropTypes.func.isRequired,
    userId: PropTypes.number
  };

  clearingFeeds = false;
  scrollHeight = 0;

  categoryObj = {
    uploads: {
      filter: 'all',
      orderBy: 'lastInteraction'
    },
    challenges: {
      filter: 'post',
      orderBy: 'difficulty'
    },
    responses: {
      filter: 'comment',
      orderBy: 'totalStars'
    },
    videos: {
      filter: 'video',
      orderBy: 'totalViewDuration'
    }
  };

  state = {
    category: 'uploads',
    displayOrder: 'desc',
    loadingMore: false
  };

  body =
    typeof document !== 'undefined'
      ? document.scrollingElement || document.documentElement
      : {};

  async componentDidMount() {
    let {
      history,
      clearFeeds,
      fetchFeeds,
      loaded,
      resetNumNewPosts,
      setCurrentSection
    } = this.props;
    setCurrentSection('storyFeeds');
    addEvent(window, 'scroll', this.onScroll);
    addEvent(document.getElementById('App'), 'scroll', this.onScroll);
    resetNumNewPosts();
    if (history.action === 'PUSH' || !loaded) {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      fetchFeeds();
    }
  }

  componentDidUpdate(prevProps) {
    const { clearFeeds, fetchFeeds } = this.props;
    if (
      prevProps.hideWatched !== this.props.hideWatched &&
      this.state.category === 'videos'
    ) {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      fetchFeeds({
        order: 'desc',
        filter: this.categoryObj.videos.filter,
        orderBy: this.categoryObj.videos.orderBy
      });
    }
  }

  componentWillUnmount() {
    removeEvent(window, 'scroll', this.onScroll);
    removeEvent(document.getElementById('App'), 'scroll', this.onScroll);
  }

  render() {
    const {
      attachStar,
      contentFeedLike,
      feedCommentDelete,
      feedCommentEdit,
      feedContentDelete,
      feedContentEdit,
      feedVideoStar,
      feedRewardCommentEdit,
      fetchFeed,
      hideWatched,
      loadMoreButton,
      loadMoreFeedReplies,
      numNewPosts,
      userId,
      loaded,
      loadMoreFeedComments,
      selectedFilter,
      setDifficulty,
      showFeedComments,
      storyFeeds,
      toggleHideWatched,
      uploadTargetContentComment,
      username
    } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    return (
      <ErrorBoundary>

 {
            this.Container = ref;
          }}
          style={{ position: 'relative', width: '100%', paddingBottom: '1rem' }}
        >
          <HomeFilter
            category={category}
            changeCategory={this.changeCategory}
            displayOrder={displayOrder}
            hideWatched={hideWatched}
            selectedFilter={selectedFilter}
            applyFilter={this.applyFilter}
            setDisplayOrder={this.setDisplayOrder}
            toggleHideWatched={toggleHideWatched}
          />
          <InputPanel />

            {!loaded && <Loading text="Loading Feeds..." />}
            {loaded &&
              storyFeeds.length === 0 && (

                    {username
                      ? `Hello ${username}, be the first to post something`
                      : 'Hi there!'}

              )}
            {loaded &&
              storyFeeds.length > 0 && (
                <>
                  {numNewPosts > 0 && (
                    <Banner
                      gold
                      onClick={this.fetchNewFeeds}
                      style={{ marginBottom: '1rem' }}
                    >
                      Click to See {numNewPosts} new Post
                      {numNewPosts > 1 ? 's' : ''}
                    </Banner>
                  )}
                  {storyFeeds.map(feed => {
                    return (
                      <ContentPanel
                        key={feed.feedId}
                        commentsLoadLimit={5}
                        contentObj={feed}
                        inputAtBottom={feed.type === 'comment'}
                        onLoadContent={fetchFeed}
                        onAttachStar={attachStar}
                        onCommentSubmit={data =>
                          this.uploadFeedComment({ feed, data })
                        }
                        onDeleteComment={feedCommentDelete}
                        onDeleteContent={feedContentDelete}
                        onEditComment={feedCommentEdit}
                        onEditContent={feedContentEdit}
                        onEditRewardComment={feedRewardCommentEdit}
                        onLikeContent={contentFeedLike}
                        onLoadMoreComments={loadMoreFeedComments}
                        onLoadMoreReplies={loadMoreFeedReplies}
                        onReplySubmit={data =>
                          this.uploadFeedComment({ feed, data })
                        }
                        onSetDifficulty={setDifficulty}
                        onStarVideo={feedVideoStar}
                        onShowComments={showFeedComments}
                        onTargetCommentSubmit={uploadTargetContentComment}
                        selfLoadingDisabled={this.clearingFeeds}
                        userId={userId}
                      />
                    );
                  })}
                  {loadMoreButton && (
                    <LoadMoreButton
                      onClick={this.loadMoreFeeds}
                      loading={loadingMore}
                      filled
                      info
                    />
                  )}
                </>
              )}

      </ErrorBoundary>
    );
  }

  applyFilter = filter => {
    const { fetchFeeds, selectedFilter, clearFeeds } = this.props;
    if (filter === selectedFilter) return;
    clearFeeds();
    fetchFeeds({ filter });
    this.setState({ displayOrder: 'desc' });
  };

  loadMoreFeeds = async() => {
    const { storyFeeds, fetchMoreFeeds, selectedFilter } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    if (!loadingMore) {
      this.setState({ loadingMore: true });
      try {
        await fetchMoreFeeds({
          order: displayOrder,
          orderBy: this.categoryObj[category].orderBy,
          shownFeeds: queryStringForArray(storyFeeds, 'feedId', 'shownFeeds'),
          filter:
            category === 'uploads'
              ? selectedFilter
              : this.categoryObj[category].filter
        });
        this.setState({ loadingMore: false });
      } catch (error) {
        console.error(error);
      }
    }
  };

  onScroll = () => {
    const { chatMode, storyFeeds, loadMoreButton } = this.props;
    if (
      document.getElementById('App').scrollHeight > this.scrollHeight ||
      this.body.scrollTop > this.scrollHeight
    ) {
      this.scrollHeight = Math.max(
        document.getElementById('App').scrollHeight,
        this.body.scrollTop
      );
    }
    if (!chatMode && storyFeeds.length > 0 && this.scrollHeight !== 0) {
      this.setState(
        {
          scrollPosition: {
            desktop: document.getElementById('App').scrollTop,
            mobile: this.body.scrollTop
          }
        },
        () => {
          if (
            (this.state.scrollPosition.desktop >=
              this.scrollHeight - window.innerHeight - 400 ||
              this.state.scrollPosition.mobile >=
                this.scrollHeight - window.innerHeight - 400) &&
            loadMoreButton
          ) {
            this.loadMoreFeeds();
          }
        }
      );
    }
  };

  changeCategory = category => {
    const { clearFeeds, fetchFeeds } = this.props;
    this.clearingFeeds = true;
    clearFeeds();
    this.clearingFeeds = false;
    fetchFeeds({
      order: 'desc',
      filter: this.categoryObj[category].filter,
      orderBy: this.categoryObj[category].orderBy
    });
    this.setState({ displayOrder: 'desc', category });
    this.scrollHeight = 0;
  };

  fetchNewFeeds = async() => {
    const {
      clearFeeds,
      fetchFeeds,
      storyFeeds = [],
      resetNumNewPosts,
      fetchNewFeeds
    } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    if (category !== 'uploads' || displayOrder === 'asc') {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      resetNumNewPosts();
      return fetchFeeds();
    }
    if (!loadingMore) {
      this.setState({ loadingMore: true });
      resetNumNewPosts();
      const data = await loadNewFeeds({
        lastInteraction: storyFeeds[0] ? storyFeeds[0].lastInteraction : 0,
        shownFeeds: queryStringForArray(storyFeeds, 'feedId', 'shownFeeds')
      });
      if (data) fetchNewFeeds(data);
      this.setState({ loadingMore: false });
    }
  };

  setDisplayOrder = () => {
    const { clearFeeds, fetchFeeds, selectedFilter } = this.props;
    const { category, displayOrder } = this.state;
    const newDisplayOrder = displayOrder === 'desc' ? 'asc' : 'desc';
    this.clearingFeeds = true;
    clearFeeds();
    this.clearingFeeds = false;
    fetchFeeds({
      order: newDisplayOrder,
      orderBy: this.categoryObj[category].orderBy,
      filter:
        category === 'uploads'
          ? selectedFilter
          : this.categoryObj[category].filter
    });
    this.setState({ displayOrder: newDisplayOrder });
    this.scrollHeight = 0;
  };

  uploadFeedComment = ({ feed, data }) => {
    const { uploadFeedComment } = this.props;
    uploadFeedComment({
      data,
      type: feed.type,
      contentId: feed.contentId
    });
  };
}

export default connect(
  state => ({
    hideWatched: state.UserReducer.hideWatched,
    loadMoreButton: state.FeedReducer.storyFeedsLoadMoreButton,
    storyFeeds: state.FeedReducer.storyFeeds,
    loaded: state.FeedReducer.loaded,
    numNewPosts: state.NotiReducer.numNewPosts,
    userId: state.UserReducer.userId,
    username: state.UserReducer.username,
    selectedFilter: state.FeedReducer.selectedFilter,
    chatMode: state.ChatReducer.chatMode,
    noFeeds: state.FeedReducer.noFeeds
  }),
  {
    attachStar,
    contentFeedLike,
    fetchMoreFeeds,
    fetchFeed,
    fetchFeeds,
    fetchNewFeeds,
    feedCommentDelete,
    feedContentDelete,
    feedContentEdit,
    feedCommentEdit,
    feedRewardCommentEdit,
    feedVideoStar,
    loadMoreFeedComments,
    loadMoreFeedReplies,
    clearFeeds,
    resetNumNewPosts,
    setCurrentSection,
    setDifficulty,
    showFeedComments,
    toggleHideWatched,
    uploadFeedComment,
    uploadTargetContentComment
  }
)(Stories);
<commit_msg>minor bug fix<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {
  attachStar,
  contentFeedLike,
  feedCommentDelete,
  feedCommentEdit,
  feedContentEdit,
  feedContentDelete,
  feedRewardCommentEdit,
  feedVideoStar,
  fetchMoreFeeds,
  fetchNewFeeds,
  fetchFeeds,
  fetchFeed,
  loadMoreFeedReplies,
  loadMoreFeedComments,
  clearFeeds,
  setCurrentSection,
  setDifficulty,
  showFeedComments,
  uploadFeedComment,
  uploadTargetContentComment
} from 'redux/actions/FeedActions';
import { toggleHideWatched } from 'redux/actions/UserActions';
import { resetNumNewPosts } from 'redux/actions/NotiActions';
import InputPanel from './InputPanel';
import ContentPanel from 'components/ContentPanel';
import LoadMoreButton from 'components/Buttons/LoadMoreButton';
import Loading from 'components/Loading';
import { connect } from 'react-redux';
import { addEvent, removeEvent } from 'helpers/listenerHelpers';
import Banner from 'components/Banner';
import ErrorBoundary from 'components/Wrappers/ErrorBoundary';
import { queryStringForArray } from 'helpers/stringHelpers';
import { loadNewFeeds } from 'helpers/requestHelpers';
import HomeFilter from './HomeFilter';

class Stories extends Component {
  static propTypes = {
    attachStar: PropTypes.func.isRequired,
    chatMode: PropTypes.bool,
    clearFeeds: PropTypes.func.isRequired,
    contentFeedLike: PropTypes.func.isRequired,
    feedCommentDelete: PropTypes.func.isRequired,
    feedContentDelete: PropTypes.func.isRequired,
    feedContentEdit: PropTypes.func.isRequired,
    feedCommentEdit: PropTypes.func.isRequired,
    feedRewardCommentEdit: PropTypes.func.isRequired,
    feedVideoStar: PropTypes.func.isRequired,
    fetchFeed: PropTypes.func.isRequired,
    fetchFeeds: PropTypes.func.isRequired,
    fetchMoreFeeds: PropTypes.func.isRequired,
    fetchNewFeeds: PropTypes.func.isRequired,
    hideWatched: PropTypes.bool,
    history: PropTypes.object.isRequired,
    loaded: PropTypes.bool.isRequired,
    loadMoreButton: PropTypes.bool.isRequired,
    loadMoreFeedComments: PropTypes.func.isRequired,
    loadMoreFeedReplies: PropTypes.func.isRequired,
    numNewPosts: PropTypes.number.isRequired,
    resetNumNewPosts: PropTypes.func.isRequired,
    selectedFilter: PropTypes.string.isRequired,
    setDifficulty: PropTypes.func,
    showFeedComments: PropTypes.func.isRequired,
    storyFeeds: PropTypes.array.isRequired,
    toggleHideWatched: PropTypes.func.isRequired,
    username: PropTypes.string,
    uploadFeedComment: PropTypes.func.isRequired,
    uploadTargetContentComment: PropTypes.func.isRequired,
    userId: PropTypes.number
  };

  clearingFeeds = false;
  scrollHeight = 0;

  categoryObj = {
    uploads: {
      filter: 'all',
      orderBy: 'lastInteraction'
    },
    challenges: {
      filter: 'post',
      orderBy: 'difficulty'
    },
    responses: {
      filter: 'comment',
      orderBy: 'totalStars'
    },
    videos: {
      filter: 'video',
      orderBy: 'totalViewDuration'
    }
  };

  state = {
    category: 'uploads',
    displayOrder: 'desc',
    loadingMore: false
  };

  body =
    typeof document !== 'undefined'
      ? document.scrollingElement || document.documentElement
      : {};

  async componentDidMount() {
    let {
      history,
      clearFeeds,
      fetchFeeds,
      loaded,
      resetNumNewPosts,
      setCurrentSection
    } = this.props;
    setCurrentSection('storyFeeds');
    addEvent(window, 'scroll', this.onScroll);
    addEvent(document.getElementById('App'), 'scroll', this.onScroll);
    resetNumNewPosts();
    if (history.action === 'PUSH' || !loaded) {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      fetchFeeds();
    }
  }

  componentDidUpdate(prevProps) {
    const { clearFeeds, fetchFeeds } = this.props;
    if (
      prevProps.hideWatched !== this.props.hideWatched &&
      this.state.category === 'videos'
    ) {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      fetchFeeds({
        order: 'desc',
        filter: this.categoryObj.videos.filter,
        orderBy: this.categoryObj.videos.orderBy
      });
    }
  }

  componentWillUnmount() {
    removeEvent(window, 'scroll', this.onScroll);
    removeEvent(document.getElementById('App'), 'scroll', this.onScroll);
  }

  render() {
    const {
      attachStar,
      contentFeedLike,
      feedCommentDelete,
      feedCommentEdit,
      feedContentDelete,
      feedContentEdit,
      feedVideoStar,
      feedRewardCommentEdit,
      fetchFeed,
      hideWatched,
      loadMoreButton,
      loadMoreFeedReplies,
      numNewPosts,
      userId,
      loaded,
      loadMoreFeedComments,
      selectedFilter,
      setDifficulty,
      showFeedComments,
      storyFeeds,
      toggleHideWatched,
      uploadTargetContentComment,
      username
    } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    return (
      <ErrorBoundary>

 {
            this.Container = ref;
          }}
          style={{ position: 'relative', width: '100%', paddingBottom: '1rem' }}
        >
          <HomeFilter
            category={category}
            changeCategory={this.changeCategory}
            displayOrder={displayOrder}
            hideWatched={hideWatched}
            selectedFilter={selectedFilter}
            applyFilter={this.applyFilter}
            setDisplayOrder={this.setDisplayOrder}
            toggleHideWatched={toggleHideWatched}
          />
          <InputPanel />

            {!loaded && <Loading text="Loading Feeds..." />}
            {loaded &&
              storyFeeds.length === 0 && (

                    {username
                      ? `Hello ${username}, be the first to post something`
                      : 'Hi there!'}

              )}
            {loaded &&
              storyFeeds.length > 0 && (
                <>
                  {numNewPosts > 0 && (
                    <Banner
                      gold
                      onClick={this.fetchNewFeeds}
                      style={{ marginBottom: '1rem' }}
                    >
                      Click to See {numNewPosts} new Post
                      {numNewPosts > 1 ? 's' : ''}
                    </Banner>
                  )}
                  {storyFeeds.map(feed => {
                    return (
                      <ContentPanel
                        key={feed.feedId}
                        commentsLoadLimit={5}
                        contentObj={feed}
                        inputAtBottom={feed.type === 'comment'}
                        onLoadContent={fetchFeed}
                        onAttachStar={attachStar}
                        onCommentSubmit={data =>
                          this.uploadFeedComment({ feed, data })
                        }
                        onDeleteComment={feedCommentDelete}
                        onDeleteContent={feedContentDelete}
                        onEditComment={feedCommentEdit}
                        onEditContent={feedContentEdit}
                        onEditRewardComment={feedRewardCommentEdit}
                        onLikeContent={contentFeedLike}
                        onLoadMoreComments={loadMoreFeedComments}
                        onLoadMoreReplies={loadMoreFeedReplies}
                        onReplySubmit={data =>
                          this.uploadFeedComment({ feed, data })
                        }
                        onSetDifficulty={setDifficulty}
                        onStarVideo={feedVideoStar}
                        onShowComments={showFeedComments}
                        onTargetCommentSubmit={uploadTargetContentComment}
                        selfLoadingDisabled={this.clearingFeeds}
                        userId={userId}
                      />
                    );
                  })}
                  {loadMoreButton && (
                    <LoadMoreButton
                      onClick={this.loadMoreFeeds}
                      loading={loadingMore}
                      filled
                      info
                    />
                  )}
                </>
              )}

      </ErrorBoundary>
    );
  }

  applyFilter = filter => {
    const { fetchFeeds, selectedFilter, clearFeeds } = this.props;
    if (filter === selectedFilter) return;
    clearFeeds();
    fetchFeeds({ filter });
    this.setState({ displayOrder: 'desc' });
  };

  loadMoreFeeds = async() => {
    const { storyFeeds, fetchMoreFeeds, selectedFilter } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    if (!loadingMore) {
      this.setState({ loadingMore: true });
      try {
        await fetchMoreFeeds({
          order: displayOrder,
          orderBy: this.categoryObj[category].orderBy,
          shownFeeds: queryStringForArray(storyFeeds, 'feedId', 'shownFeeds'),
          filter:
            category === 'uploads'
              ? selectedFilter
              : this.categoryObj[category].filter
        });
        this.setState({ loadingMore: false });
      } catch (error) {
        console.error(error);
      }
    }
  };

  onScroll = () => {
    const { chatMode, storyFeeds, loadMoreButton } = this.props;
    if (
      document.getElementById('App').scrollHeight > this.scrollHeight ||
      this.body.scrollTop > this.scrollHeight
    ) {
      this.scrollHeight = Math.max(
        document.getElementById('App').scrollHeight,
        this.body.scrollTop
      );
    }
    if (!chatMode && storyFeeds.length > 0 && this.scrollHeight !== 0) {
      this.setState(
        {
          scrollPosition: {
            desktop: document.getElementById('App').scrollTop,
            mobile: this.body.scrollTop
          }
        },
        () => {
          if (
            (this.state.scrollPosition.desktop >=
              this.scrollHeight - window.innerHeight - 400 ||
              this.state.scrollPosition.mobile >=
                this.scrollHeight - window.innerHeight - 400) &&
            loadMoreButton
          ) {
            this.loadMoreFeeds();
          }
        }
      );
    }
  };

  changeCategory = category => {
    const { clearFeeds, fetchFeeds } = this.props;
    this.clearingFeeds = true;
    clearFeeds();
    this.clearingFeeds = false;
    fetchFeeds({
      order: 'desc',
      filter: this.categoryObj[category].filter,
      orderBy: this.categoryObj[category].orderBy
    });
    this.setState({ displayOrder: 'desc', category });
    this.scrollHeight = 0;
  };

  fetchNewFeeds = async() => {
    const {
      clearFeeds,
      fetchFeeds,
      storyFeeds = [],
      resetNumNewPosts,
      fetchNewFeeds
    } = this.props;
    const { category, displayOrder, loadingMore } = this.state;
    if (category !== 'uploads' || displayOrder === 'asc') {
      this.clearingFeeds = true;
      clearFeeds();
      this.clearingFeeds = false;
      resetNumNewPosts();
      this.setState({ category: 'uploads' });
      return fetchFeeds();
    }
    if (!loadingMore) {
      this.setState({ loadingMore: true });
      resetNumNewPosts();
      const data = await loadNewFeeds({
        lastInteraction: storyFeeds[0] ? storyFeeds[0].lastInteraction : 0,
        shownFeeds: queryStringForArray(storyFeeds, 'feedId', 'shownFeeds')
      });
      if (data) fetchNewFeeds(data);
      this.setState({ loadingMore: false });
    }
  };

  setDisplayOrder = () => {
    const { clearFeeds, fetchFeeds, selectedFilter } = this.props;
    const { category, displayOrder } = this.state;
    const newDisplayOrder = displayOrder === 'desc' ? 'asc' : 'desc';
    this.clearingFeeds = true;
    clearFeeds();
    this.clearingFeeds = false;
    fetchFeeds({
      order: newDisplayOrder,
      orderBy: this.categoryObj[category].orderBy,
      filter:
        category === 'uploads'
          ? selectedFilter
          : this.categoryObj[category].filter
    });
    this.setState({ displayOrder: newDisplayOrder });
    this.scrollHeight = 0;
  };

  uploadFeedComment = ({ feed, data }) => {
    const { uploadFeedComment } = this.props;
    uploadFeedComment({
      data,
      type: feed.type,
      contentId: feed.contentId
    });
  };
}

export default connect(
  state => ({
    hideWatched: state.UserReducer.hideWatched,
    loadMoreButton: state.FeedReducer.storyFeedsLoadMoreButton,
    storyFeeds: state.FeedReducer.storyFeeds,
    loaded: state.FeedReducer.loaded,
    numNewPosts: state.NotiReducer.numNewPosts,
    userId: state.UserReducer.userId,
    username: state.UserReducer.username,
    selectedFilter: state.FeedReducer.selectedFilter,
    chatMode: state.ChatReducer.chatMode,
    noFeeds: state.FeedReducer.noFeeds
  }),
  {
    attachStar,
    contentFeedLike,
    fetchMoreFeeds,
    fetchFeed,
    fetchFeeds,
    fetchNewFeeds,
    feedCommentDelete,
    feedContentDelete,
    feedContentEdit,
    feedCommentEdit,
    feedRewardCommentEdit,
    feedVideoStar,
    loadMoreFeedComments,
    loadMoreFeedReplies,
    clearFeeds,
    resetNumNewPosts,
    setCurrentSection,
    setDifficulty,
    showFeedComments,
    toggleHideWatched,
    uploadFeedComment,
    uploadTargetContentComment
  }
)(Stories);
<|endoftext|>


<commit_before>$(document).ready(function() {
    $.ajax({
        type: 'GET',
        crossDomain: true,
        contentType: "application/json; charset=utf-8",
        url: "https://protected-bayou-34428.herokuapp.com/health?echo=21",
        dataType: "jsonp"
    }).then(function(data) {
       $('.bearing').append(data.bearing);
       $('.size').append(data.size);
    });
});
<commit_msg>testing<commit_after>$(document).ready(function() {
    $.ajax({
        type: 'GET',
        crossDomain: true,
        contentType: "application/json; charset=utf-8",
        url: "https://protected-bayou-34428.herokuapp.com/health?echo=21",
        dataType: "jsonp"
        success: function(data){
              $('.bearing').append(data.bearing);
              $('.size').append(data.size);
            }
        }
        error : function(data){
                    console.log(data);
                   }
    })
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
/* eslint-disable no-case-declarations */
/* eslint-disable global-require */

const program = require('commander')
const { TerminalUtils } = require('constellate-dev-utils')
const { configureGracefulExit, loadEnvVars } = require('constellate-utils')

const rollbackRepo = require('../utils/rollbackRepo')
const packageJson = require('../../package.json')

const noop = () => undefined

TerminalUtils.header(`constellate v${packageJson.version || '0.0.0-develop'}`)

program.version(packageJson.version || '0.0.0-develop')

const ArgParsers = {
  list: val => val.split(','),
}

const createAction = ({
  defaultEnv = 'production',
  resolveScript,
  gracefulExit = noop,
  errorMsg,
  preScript,
}) => async (...originalArgs) => {
  try {
    configureGracefulExit({
      onExit: gracefulExit,
      name: 'constellate',
    })
    if (!process.env.NODE_ENV) {
      process.env.NODE_ENV = defaultEnv
    }
    loadEnvVars()
    if (preScript) {
      await preScript()
    }

    let options
    let args = []
    if (args.length === 1) {
      options = originalArgs[0]
    } else {
      args = originalArgs.slice(0, originalArgs.length - 1)
      options = originalArgs[originalArgs.length - 1]
    }

    const script = resolveScript(options, args)
    await script()
    process.exit(0)
  } catch (err) {
    TerminalUtils.error('Argh! An unexpected error has occurred', err)
    if (errorMsg) {
      TerminalUtils.error(errorMsg)
    }
    gracefulExit()
    process.exit(1)
  }
}

program.command('build').description('Builds the projects').action(
  createAction({
    resolveScript: () => require('../scripts/build'),
  }),
)

program
  .command('clean')
  .description('Deletes the build output and node_modules files for projects')
  .option(
    '-p, --projects <projects>',
    'Specify the projects to run the install for (defaults to all)',
    ArgParsers.list,
  )
  .option('-n, --node-modules', 'Removes node_modules for each project')
  .option('-l, --package-lock', 'Removes package-lock.json for each project')
  .option('-b, --build', 'Removes build output for each project')
  .action(
    createAction({
      resolveScript: options => () => require('../scripts/clean')(options),
    }),
  )

program.command('deploy').description('Deploys the projects').action(
  createAction({
    resolveScript: () => require('../scripts/deploy'),
    errorMsg: 'Your projects may not have been fully deployed. Please check your expected deployment targets.',
  }),
)

program
  .command('develop')
  .description('Runs a development environment for the projects')
  .action(
    createAction({
      defaultEnv: 'development',
      preScript: () => {
        TerminalUtils.title('Kickstarting development hyperengine...')
        console.log(`\n${require('../utils/getCarlSaganQuote')()}\n`)
        return new Promise(resolve => setTimeout(resolve, 3000))
      },
      resolveScript: () => require('../scripts/develop'),
    }),
  )

program
  .command('install')
  .description('Installs the dependencies for every project')
  .option(
    '-p, --projects <projects>',
    'Specify the projects to run the install for',
    ArgParsers.list,
  )
  .option('-c, --clean', 'Removes existing node_modules for each project')
  .option(
    '-h, --hard-clean',
    'Removes existing node_modules and package-lock.json for each project',
  )
  .action(
    createAction({
      // We should not use "production" as a NODE_ENV because then only our
      // production dependencies will get installed, i.e. no devDependencies
      defaultEnv: 'development',
      resolveScript: options => () => require('../scripts/install')(options),
    }),
  )

program
  .command('link-projects')
  .description('Links project(s) to a project')
  .action(
    createAction({
      resolveScript: () => require('../scripts/linkProjects'),
    }),
  )

program
  .command('release')
  .description(
    'Creates a new release, versioning the app, the changed projects, and published the changed projects to NPM',
  )
  .action(
    createAction({
      resolveScript: () => require('../scripts/release'),
      gracefulExit: rollbackRepo,
    }),
  )

/*
program
  .command('test [...passThroughArgs]')
  .description('Runs the tests')
  .action(
    createAction({
      defaultEnv: 'test',
      resolveScript: (options, args) => () =>
        require('../scripts/test')({
          passThroughArgs: args,
        }),
    }),
  )

program.command('exec').description('Executed a provided command').action(
  createAction({
    resolveScript: () => () =>
      require('../scripts/exec')({
        passThroughArgs: process.argv.slice(3),
      }),
  }),
)
*/

program
  .command('update')
  .description(
    'Runs an interactive dependency update process for every project',
  )
  .action(
    createAction({
      // We should not use "production" as a NODE_ENV because then only our
      // production dependencies will get installed, i.e. no devDependencies
      defaultEnv: 'development',
      resolveScript: () => require('../scripts/update'),
    }),
  )

// If the user passes no args, or an unknown arg then we will show the help
const showHelp = () => {
  program.outputHelp(x => console.log(x))
  process.exit(0)
}
program.command('*').action(showHelp)
if (!process.argv.slice(2).length) {
  showHelp()
}

const [cmd, args] = process.argv.slice(2)

if (cmd === 'test' || cmd === 'exec') {
  if (args.find(x => x === '--help' || x === '-h')) {
    // TODO: Print help.
  }
  const execScript = async (scriptThunk) => {
    loadEnvVars()
    await scriptThunk()
    process.exit(0)
  }

  switch (cmd) {
    case 'test': {
      execScript(() =>
        require('../scripts/test')({
          passThroughArgs: args,
        }),
      )
      break
    }
    case 'exec': {
      execScript(() =>
        require('../scripts/exec')({
          passThroughArgs: args,
        }),
      )
      break
    }
    default: {
      throw new Error('unkown')
    }
  }
} else {
  program.parse(process.argv)
}

// Prevent node process from exiting. (until CTRL + C or process.exit is called)
// We do this to allow our scripts to respont to process exit events and do
// cleaning up etc.
const preventScriptExit = () => {
  (function wait() {
    // eslint-disable-next-line no-constant-condition
    if (true) setTimeout(wait, 1000)
  }())
}
preventScriptExit()
<commit_msg>Trying to decrease test output noise.<commit_after>#!/usr/bin/env node
/* eslint-disable no-case-declarations */
/* eslint-disable global-require */

const program = require('commander')
const { TerminalUtils } = require('constellate-dev-utils')
const { configureGracefulExit, loadEnvVars } = require('constellate-utils')

const rollbackRepo = require('../utils/rollbackRepo')
const packageJson = require('../../package.json')

const noop = () => undefined

TerminalUtils.header(`constellate v${packageJson.version || '0.0.0-develop'}`)

program.version(packageJson.version || '0.0.0-develop')

const ArgParsers = {
  list: val => val.split(','),
}

const createAction = ({
  defaultEnv = 'production',
  resolveScript,
  gracefulExit = noop,
  errorMsg,
  preScript,
}) => async (...originalArgs) => {
  try {
    configureGracefulExit({
      onExit: gracefulExit,
      name: 'constellate',
    })
    if (!process.env.NODE_ENV) {
      process.env.NODE_ENV = defaultEnv
    }
    loadEnvVars()
    if (preScript) {
      await preScript()
    }

    let options
    let args = []
    if (args.length === 1) {
      options = originalArgs[0]
    } else {
      args = originalArgs.slice(0, originalArgs.length - 1)
      options = originalArgs[originalArgs.length - 1]
    }

    const script = resolveScript(options, args)
    await script()
    process.exit(0)
  } catch (err) {
    TerminalUtils.error('Argh! An unexpected error has occurred', err)
    if (errorMsg) {
      TerminalUtils.error(errorMsg)
    }
    gracefulExit()
    process.exit(1)
  }
}

program.command('build').description('Builds the projects').action(
  createAction({
    resolveScript: () => require('../scripts/build'),
  }),
)

program
  .command('clean')
  .description('Deletes the build output and node_modules files for projects')
  .option(
    '-p, --projects <projects>',
    'Specify the projects to run the install for (defaults to all)',
    ArgParsers.list,
  )
  .option('-n, --node-modules', 'Removes node_modules for each project')
  .option('-l, --package-lock', 'Removes package-lock.json for each project')
  .option('-b, --build', 'Removes build output for each project')
  .action(
    createAction({
      resolveScript: options => () => require('../scripts/clean')(options),
    }),
  )

program.command('deploy').description('Deploys the projects').action(
  createAction({
    resolveScript: () => require('../scripts/deploy'),
    errorMsg: 'Your projects may not have been fully deployed. Please check your expected deployment targets.',
  }),
)

program
  .command('develop')
  .description('Runs a development environment for the projects')
  .action(
    createAction({
      defaultEnv: 'development',
      preScript: () => {
        TerminalUtils.title('Kickstarting development hyperengine...')
        console.log(`\n${require('../utils/getCarlSaganQuote')()}\n`)
        return new Promise(resolve => setTimeout(resolve, 3000))
      },
      resolveScript: () => require('../scripts/develop'),
    }),
  )

program
  .command('install')
  .description('Installs the dependencies for every project')
  .option(
    '-p, --projects <projects>',
    'Specify the projects to run the install for',
    ArgParsers.list,
  )
  .option('-c, --clean', 'Removes existing node_modules for each project')
  .option(
    '-h, --hard-clean',
    'Removes existing node_modules and package-lock.json for each project',
  )
  .action(
    createAction({
      // We should not use "production" as a NODE_ENV because then only our
      // production dependencies will get installed, i.e. no devDependencies
      defaultEnv: 'development',
      resolveScript: options => () => require('../scripts/install')(options),
    }),
  )

program
  .command('link-projects')
  .description('Links project(s) to a project')
  .action(
    createAction({
      resolveScript: () => require('../scripts/linkProjects'),
    }),
  )

program
  .command('release')
  .description(
    'Creates a new release, versioning the app, the changed projects, and published the changed projects to NPM',
  )
  .action(
    createAction({
      resolveScript: () => require('../scripts/release'),
      gracefulExit: rollbackRepo,
    }),
  )

/*
program
  .command('test [...passThroughArgs]')
  .description('Runs the tests')
  .action(
    createAction({
      defaultEnv: 'test',
      resolveScript: (options, args) => () =>
        require('../scripts/test')({
          passThroughArgs: args,
        }),
    }),
  )

program.command('exec').description('Executed a provided command').action(
  createAction({
    resolveScript: () => () =>
      require('../scripts/exec')({
        passThroughArgs: process.argv.slice(3),
      }),
  }),
)
*/

program
  .command('update')
  .description(
    'Runs an interactive dependency update process for every project',
  )
  .action(
    createAction({
      // We should not use "production" as a NODE_ENV because then only our
      // production dependencies will get installed, i.e. no devDependencies
      defaultEnv: 'development',
      resolveScript: () => require('../scripts/update'),
    }),
  )

// If the user passes no args, or an unknown arg then we will show the help
const showHelp = () => {
  program.outputHelp(x => console.log(x))
  process.exit(0)
}
program.command('*').action(showHelp)
if (!process.argv.slice(2).length) {
  showHelp()
}

const [cmd, ...args] = process.argv.slice(2)

if (cmd === 'test' || cmd === 'exec') {
  if (args.find(x => x === '--help' || x === '-h')) {
    // TODO: Print help.
  }
  const execScript = async (scriptThunk) => {
    loadEnvVars()
    await scriptThunk()
    process.exit(0)
  }

  switch (cmd) {
    case 'test': {
      execScript(() =>
        require('../scripts/test')({
          passThroughArgs: args,
        }),
      )
      break
    }
    case 'exec': {
      execScript(() =>
        require('../scripts/exec')({
          passThroughArgs: args,
        }),
      )
      break
    }
    default: {
      throw new Error('unkown')
    }
  }
} else {
  program.parse(process.argv)
}

// Prevent node process from exiting. (until CTRL + C or process.exit is called)
// We do this to allow our scripts to respont to process exit events and do
// cleaning up etc.
const preventScriptExit = () => {
  (function wait() {
    // eslint-disable-next-line no-constant-condition
    if (true) setTimeout(wait, 1000)
  }())
}
preventScriptExit()
<|endoftext|>


<commit_before>var pk = pk || {};
(function (pk) {
    pk.carousel = function (opt) {

        var el = opt.element,
            options = opt.options || [],
            value=opt.value || 0;

        if (options.length === 0 && el.nodeName === "UL") {
            for (var i = 0; i < el.children.length; i++) {
                options.push(el.children[i].innerHTML);
            }
        }

        var tpl = "

", navEl=[], optionEl=[];
        for (var o=0;o<options.length;o++) {
            optionEl.push(pk.createEl("
" + options[o] + "
"));
            navEl.push(pk.createEl(""));
        }
        tpl += "

";

        el.innerHTML = '';
        el = pk.replaceEl(el, tpl);
        for (o=0;o<options.length;o++) {
            el.children[0].appendChild(optionEl[o]);
          	el.appendChild(navEl[o]);
        }
        for(var c in el.children){
            if(pk.attribute(el.children[c], 'data-nav')){
                  pk.bindEvent('click', el.children[c], clickHandler);
            }
        }
        function clickHandler(e){
            obj.value(pk.attribute(e.target, 'data-nav'));
        }
        var obj={
            value:function(val){
                val = val.toString();
                if(val===undefined){return value;}
                if(val.indexOf("-")!==-1){
                    value = value-parseInt(val.replace('-', ''),0) < 0 ? options.length-1 : --value;
                }else if(val.indexOf("+")!==-1){
                    value = value+parseInt(val.replace('+', ''),0) > options.length-1 ? 0 : ++value;
                }else{
                    value = parseInt(val.replace('=', ''),0);
                    value = value < 0 ? 0 : value > options.length-1 ? options.length-1 : value;
                }
                for (o=0;o<options.length;o++) {
                    if(parseInt(o, 0)===value){
                        pk.addClass(optionEl[o], 'pk-selected');
                        pk.addClass(navEl[o], 'pk-selected');
                    }else{
                        pk.removeClass(optionEl[o], 'pk-selected');
                        pk.removeClass(navEl[o], 'pk-selected');
                    }
                }
            }
        };
        obj.value(value);
        return obj;
    };
    return pk;
})(pk);
<commit_msg>Update carousel.js<commit_after>var pk = pk || {};
(function (pk) {
    pk.carousel = function (opt) {

        var el = opt.element,
            options = opt.options || [],
            value=opt.value || 0;

        if (options.length === 0 && el.nodeName === "UL") {
            for (var i = 0; i < el.children.length; i++) {
                options.push(el.children[i].innerHTML);
            }
        }

        var tpl = "

", navEl=[], optionEl=[];
        for (var o=0;o<options.length;o++) {
            optionEl.push(pk.createEl("
" + options[o] + "
"));
            navEl.push(pk.createEl(""));
        }
        tpl += "

";

        el.innerHTML = '';
        el = pk.replaceEl(el, tpl);
        for (o=0;o<options.length;o++) {
            el.children[0].appendChild(optionEl[o]);
          	el.appendChild(navEl[o]);
        }

        function clickHandler(e){
            obj.value(pk.attribute(e.target, 'data-nav'));
        }
        for(var c in el.children){
            if(pk.attribute(el.children[c], 'data-nav')){
                  pk.bindEvent('click', el.children[c], clickHandler);
            }
        }
        var obj={
            value:function(val){
                val = val.toString();
                if(val===undefined){return value;}
                if(val.indexOf("-")!==-1){
                    value = value-parseInt(val.replace('-', ''),0) < 0 ? options.length-1 : --value;
                }else if(val.indexOf("+")!==-1){
                    value = value+parseInt(val.replace('+', ''),0) > options.length-1 ? 0 : ++value;
                }else{
                    value = parseInt(val.replace('=', ''),0);
                    value = value < 0 ? 0 : value > options.length-1 ? options.length-1 : value;
                }
                for (o=0;o<options.length;o++) {
                    if(parseInt(o, 0)===value){
                        pk.addClass(optionEl[o], 'pk-selected');
                        pk.addClass(navEl[o], 'pk-selected');
                    }else{
                        pk.removeClass(optionEl[o], 'pk-selected');
                        pk.removeClass(navEl[o], 'pk-selected');
                    }
                }
            }
        };
        obj.value(value);
        return obj;
    };
    return pk;
})(pk);
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Titanium Appcelerator 3.3.0GA
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 * App Base Development Framework Team
 *
 *  Alejandro F.Carrera
 *  Carlos Blanco Vallejo
 *  Santiago Blanco Ventas
 *
 */

"use strict";

// Yaast Framework Init (Global Scope)
var Yaast = {
    "Log": function(msg, type, error, extra) {
        var self = {
            'name': 'W4TLog',
            'message': msg
        };
        if(error) {
            self.details = (extra) ? {
                'message': error.message,
                'info': extra
            } : error.message;
            self.source = error.sourceURL;
        }
        Ti.API[type](self);
        return self;
    },
    "FontAwesome": require('fonts/FontAwesome4'),
    "Sandbox": {
    	'currentView': null,
    }
};
Yaast.API = require('lib/API');

// Merge shortcut
Yaast["MergeObject"] = Yaast.API.SW.Utils.mergeObject;

(function() {

    if (Yaast.API.HW.System.isTablet()) {
        var Window = require('ui/window/appWindow');
        Window.window.open();
    }
    else  alert("Wirecloud4Tablet has not compatibility with Smartphone's'");

}());<commit_msg>Add screen Density test info messages<commit_after>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Titanium Appcelerator 3.3.0GA
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 * App Base Development Framework Team
 *
 *  Alejandro F.Carrera
 *  Carlos Blanco Vallejo
 *  Santiago Blanco Ventas
 *
 */

"use strict";

// Yaast Framework Init (Global Scope)
var Yaast = {
    "Log": function(msg, type, error, extra) {
        var self = {
            'name': 'W4TLog',
            'message': msg
        };
        if(error) {
            self.details = (extra) ? {
                'message': error.message,
                'info': extra
            } : error.message;
            self.source = error.sourceURL;
        }
        Ti.API[type](self);
        return self;
    },
    "FontAwesome": require('fonts/FontAwesome4'),
    "Sandbox": {
    	'currentView': null,
    }
};
Yaast.API = require('lib/API');

Ti.API.info('WELCOME 2 Wirecloud 4 Tablet!!!');
Ti.API.info('Screen Density: ' + Yaast.API.HW.UI.getDensityScreen());

// Merge shortcut
Yaast["MergeObject"] = Yaast.API.SW.Utils.mergeObject;

(function() {

    if (Yaast.API.HW.System.isTablet()) {
        var Window = require('ui/window/appWindow');
        Window.window.open();
    }
    else  alert("Wirecloud4Tablet has not compatibility with Smartphone's'");

}());<|endoftext|>


<commit_before>
uiModule.gis = function() {
  if (!(this instanceof uiModule.gis)) {
    return new uiModule.gis();
  }

  return this;
};

/**
 * Create a placeholder to display current layers
 *
 * @param rootId
 * @param heading
 */
uiModule.gis.createList = function(rootId, heading) {
  var listRoot = document.getElementById(rootId);
  var itemRoot = document.createElement("div");
  itemRoot.setAttribute("class", "accordion-group");
  listRoot.appendChild(itemRoot);

  var itemHeading = document.createElement("div");
  itemHeading.setAttribute("class", "accordion-heading");
  itemRoot.appendChild(itemHeading);

  var itemCollection = document.createElement("a");
  itemCollection.setAttribute("class", "accordion-toggle");
  itemCollection.setAttribute("data-toggle", "collapse");
  itemCollection.setAttribute("data-parent", "#"+rootId);
  itemCollection.setAttribute("href", "#collapse-"+rootId);
  itemCollection.appendChild(document.createTextNode(heading));
  itemHeading.appendChild(itemCollection);

  var subItemsRoot = document.createElement("div");
  subItemsRoot.setAttribute("class", "accordion-body collapse in");
  subItemsRoot.setAttribute("id", "collapse-"+rootId);
  itemRoot.appendChild(subItemsRoot);
  var subItemsList = document.createElement("div");
  subItemsList.setAttribute("class", "accordion-inner");
  subItemsRoot.appendChild(subItemsList);

  var tableRoot = document.createElement("table");
  tableRoot.setAttribute("id", 'table-' + rootId);
  subItemsList.appendChild(tableRoot);

  var tbody = document.createElement("tbody");
  tableRoot.appendChild(tbody);
};

/**
 * Create a list of documents that could be added as a layer
 *
 * @param rootId
 * @param heading
 * @param layersRootId
 * @param data
 */
uiModule.gis.createDataList = function(rootId, heading, layersRootId, data, callback) {
  var listRoot = $(document.getElementById(rootId));

  var itemRoot = $(document.createElement('div'));
  itemRoot.attr('class', 'accordion-group');
  listRoot.append(itemRoot);

  var itemHeading = $(document.createElement('div'));
  itemHeading.attr('class', 'accordion-heading');
  itemRoot.append(itemHeading);

  var itemCollection = $(document.createElement('a'));
  itemCollection.attr('class', 'accordion-toggle');
  itemCollection.attr('data-toggle', 'collapse');
  itemCollection.attr('data-parent', '#'+rootId);
  itemCollection.attr('href', '#collapse-'+rootId);
  itemCollection.append(document.createTextNode(heading));
  itemHeading.append(itemCollection);

  var subItemsRoot = $(document.createElement('div'));
  subItemsRoot.attr('class', 'accordion-body collapse in');
  subItemsRoot.attr('id', 'collapse-'+rootId);
  itemRoot.append(subItemsRoot);

  var subItemsList = $(document.createElement('div'));
  subItemsList.attr('class', 'accordion-inner');
  subItemsRoot.append(subItemsList);

  var tableRoot = $(document.createElement('table'));
  tableRoot.attr('class', 'table-hover');
  subItemsList.append(tableRoot);

  $.each(data, function(i, item) {
    var row = $(document.createElement('tr'));
    row.attr('class', 'success');
    tableRoot.append(row);

    var col = $(document.createElement('td'));
    var he = $(document.createElement('h4'));
    he.html(item.basename);
    col.append(he);
    row.append(col);

    // Add drop-down so that users can select a variable
    col = $(document.createElement('td'));
    var select = $(document.createElement('select'));
    select.attr('class', 'combobox');
    col.append(select);
    for (var k = 0; k < item.variables.length; ++k) {
      var varname = item.variables[k].name;
      var option = $(document.createElement('option'));
      option.attr('value', varname);
      option.html(varname);
      select.append(option);
    }
    row.append(col);

    // Add 'add' button
    col = $(document.createElement('td'));
    var button = $(document.createElement('button'));
    button.attr('type', 'button');
    button.attr('class', 'btn btn-primary');
    button.attr('id', 'btn-add-' + item.name);
    button.attr('_id', item._id);
    button.attr('name', item.name);
    button.attr('basename', item.basename);
    button.attr('data-toggle', 'button');
    button.attr('data-loading-text', 'Loading...');
    button.html('Add');
    col.append(button);
    row.append(col);

    if (callback != undefined) {
      $(button).on("click", callback);
    }
  });

  $('.combobox').width(Math.max.apply(Math,
                                       $('.combobox').map(function(){
                                         return $(this).outerWidth();}).get()));
  $('.combobox').select2();
};

/**
 * Add a document as a layer to the list
 *
 * @todo Actually load a layer
 *
 * @param layersRootId
 * @param elem
 */
uiModule.gis.addLayer = function(object, layersRootId, elem, selectfunc, togglefunc,
  removefunc, callback) {

  var rootId = "#" + layersRootId;
  var _id = $(elem).attr("_id");
  if (_id !== null) {
    var tbody = $(rootId).find('tbody');
    var basename = $(elem).attr("name");
    $(elem).button('loading');

    var layerId = basename;

    var tr = $(document.createElement('tr'));
    tr.attr('id', layerId);
    $(tbody).append(tr);

    // Name of the layer
    var td = $(document.createElement('td'));
    td.append($(document.createElement('h4')).html(basename));
    tr.append(td);

    // Select button
    td = $(document.createElement('td'));
    td.attr('class', 'td-btn-layer');
    var button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-select-layer btn btn-primary disabled');
    button.attr('disabled', 'disabled');
    button.html('Select');
    button.click(layerId, function() {
      selectfunc(this, layerId);
    });
    td.append(button);

    // Toggle button
    button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-toggle-layer btn btn-warning disabled');
    button.attr('disabled', 'disabled');
    button.html('Toggle');
    button.click(layerId, function() {
      togglefunc(this, layerId);
    });
    td.append(button);

    // Remove button
    button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-remove-layer btn btn-danger disabled');
    button.attr('disabled', 'disabled');
    button.html('Remove');
    button.click(layerId, function() {
      removefunc(this, layerId);
    });
    td.append(button);
    tr.append(td);

    $('.btn-layer').width(Math.max.apply(Math,
                                            $('.btn-layer').map(function(){
                                              return $(this).outerWidth();}).get()));
    }
    // @todo Just calling fadeIn does not work. It has to be set invisible
    // and then only it works. We need to check if this is expected.
    $('#'+layerId).fadeOut(0);
    $('#'+layerId).fadeIn('slow', callback);
};

/**
 *
 */
uiModule.gis.layerAdded = function(elem) {
  $(elem).removeClass("btn-primary");
  $(elem).addClass("btn-success");
  $(elem).addClass("disabled");
  $(elem).attr('data-loading-text', 'Added');
  $(elem).attr('disabled', 'disabled');
  $(elem).html('Added');
}

/**
 * Remove a layer from the list
 *
 * @param elem
 * @returns {Boolean}
 */
uiModule.gis.removeLayer = function(elem, layerId) {
  var buttonId = $('#btn-add-'+layerId);
  var button = $(buttonId);

  if (button !== null || button !== undefined) {
    button.removeClass('disabled');
    button.removeAttr('disabled');
    button.removeClass('btn-success');
    button.removeClass('active');
    button.button('reset');
    button.addClass('btn-primary');

    $('#' + layerId).fadeOut(function() {
      $('#' + layerId).remove();
    });

    return true;
  }

  return false;
};

uiModule.gis.toggleLayer = function(elem, layerId) {
  // Do nothing
};

/**
 * Update UI to when a layer is selected
 */
uiModule.gis.selectLayer = function(target, layerId) {
  $('btn-select-layer').siblings().removeClass('active');

  if (target !== null || target !== undefined) {
    $(target).addClass('active');
  }

  return true;
};

uiModule.gis.generateOptions = function(rootId, map) {
  var options = map.options();

  var parent = $('#'+rootId);

  for (var key in options) {
    if (key === "source" || key === "center") {
      continue;
    }

    if (options.hasOwnProperty(key)) {

      var row = $(document.createElement('tr'));
      row.attr('class', 'row-fluid');
      parent.append(row);
      var col = $(document.createElement('td'));
      row.append(col);

      var heading = $(document.createElement('h4'));
      heading.html(key);
      col.append(heading);

      switch(key) {
        case "zoom":
          // Create a slider here
          var sliderDiv = $(document.createElement('div'));
          sliderDiv.slider({
            range: "min",
            min: 0.0,
            max: 17.0,
            step: 1,
            value: options[key],
            slide: function( event, ui ) {
              map.setZoom( ui.value );
              map.redraw();
            }
          });
          $(sliderDiv).on('mousedown', function(e) {
            e.stopPropagation();
            return false;
          });
          col.attr('class', 'span10');
          $(col).append(sliderDiv);
          break;
        case "center":
          // @todo We need to update center dynamically which
          // will require quite a bit of work.
          // Text box
          // var latInput = $(document.createElement('input'));
          // latInput.attr('type', 'number');
          // latInput.attr('min', -180.0);
          // latInput.attr('max', +180.0);
          // latInput.val(map.options().center.lat());
          // latInput.click(function() {
          //   map.redraw();
          // });
          // $(latInput).on('mousedown', function(e) {
          //   e.stopPropagation();
          //   return false;
          // });
          // col.append(latInput);

          // var lngInput = $(document.createElement('input'));
          // lngInput.attr('type', 'number');
          // lngInput.attr('min', -90.0);
          // lngInput.attr('max', +90.0);
          // lngInput.val(map.options().center.lng());
          // lngInput.click(function() {
          //   map.redraw();
          // });
          // $(lngInput).on('mousedown', function(e) {
          //   e.stopPropagation();
          //   return false;
          // });
          // col.append(lngInput);
          break;
        case "country_boundries":
          // Boolean
          var input = $(document.createElement('input'));
          input.attr('type', 'checkbox');
          input.attr('checked', map.options().country_boundries);
          input.click(function() {
            map.toggleCountryBoundries();
            map.redraw();
          });
          col.append(input);

          break;
        case "us_states":
          // Boolean
          break;
        case "source":
          // Dropdown
          break;
      }
    }
  }
};<commit_msg>Move creation of controls from application to library<commit_after>
uiModule.gis = function() {
  if (!(this instanceof uiModule.gis)) {
    return new uiModule.gis();
  }

  return this;
};

/**
 * Create a placeholder to display current layers
 *
 * @param rootId
 * @param heading
 */
uiModule.gis.createList = function(rootId, heading) {
  var listRoot = document.getElementById(rootId);
  var itemRoot = document.createElement("div");
  itemRoot.setAttribute("class", "accordion-group");
  listRoot.appendChild(itemRoot);

  var itemHeading = document.createElement("div");
  itemHeading.setAttribute("class", "accordion-heading");
  itemRoot.appendChild(itemHeading);

  var itemCollection = document.createElement("a");
  itemCollection.setAttribute("class", "accordion-toggle");
  itemCollection.setAttribute("data-toggle", "collapse");
  itemCollection.setAttribute("data-parent", "#"+rootId);
  itemCollection.setAttribute("href", "#collapse-"+rootId);
  itemCollection.appendChild(document.createTextNode(heading));
  itemHeading.appendChild(itemCollection);

  var subItemsRoot = document.createElement("div");
  subItemsRoot.setAttribute("class", "accordion-body collapse in");
  subItemsRoot.setAttribute("id", "collapse-"+rootId);
  itemRoot.appendChild(subItemsRoot);
  var subItemsList = document.createElement("div");
  subItemsList.setAttribute("class", "accordion-inner");
  subItemsRoot.appendChild(subItemsList);

  var tableRoot = document.createElement("table");
  tableRoot.setAttribute("id", 'table-' + rootId);
  subItemsList.appendChild(tableRoot);

  var tbody = document.createElement("tbody");
  tableRoot.appendChild(tbody);

  return tableRoot;
};

/**
 * Create a list of documents that could be added as a layer
 *
 * @param rootId
 * @param heading
 * @param layersRootId
 * @param data
 */
uiModule.gis.createDataList = function(rootId, heading, layersRootId, data, callback) {
  var listRoot = $(document.getElementById(rootId));

  var itemRoot = $(document.createElement('div'));
  itemRoot.attr('class', 'accordion-group');
  listRoot.append(itemRoot);

  var itemHeading = $(document.createElement('div'));
  itemHeading.attr('class', 'accordion-heading');
  itemRoot.append(itemHeading);

  var itemCollection = $(document.createElement('a'));
  itemCollection.attr('class', 'accordion-toggle');
  itemCollection.attr('data-toggle', 'collapse');
  itemCollection.attr('data-parent', '#'+rootId);
  itemCollection.attr('href', '#collapse-'+rootId);
  itemCollection.append(document.createTextNode(heading));
  itemHeading.append(itemCollection);

  var subItemsRoot = $(document.createElement('div'));
  subItemsRoot.attr('class', 'accordion-body collapse in');
  subItemsRoot.attr('id', 'collapse-'+rootId);
  itemRoot.append(subItemsRoot);

  var subItemsList = $(document.createElement('div'));
  subItemsList.attr('class', 'accordion-inner');
  subItemsRoot.append(subItemsList);

  var tableRoot = $(document.createElement('table'));
  tableRoot.attr('class', 'table-hover');
  subItemsList.append(tableRoot);

  $.each(data, function(i, item) {
    var row = $(document.createElement('tr'));
    row.attr('class', 'success');
    tableRoot.append(row);

    var col = $(document.createElement('td'));
    var he = $(document.createElement('h4'));
    he.html(item.basename);
    col.append(he);
    row.append(col);

    // Add drop-down so that users can select a variable
    col = $(document.createElement('td'));
    var select = $(document.createElement('select'));
    select.attr('class', 'combobox');
    col.append(select);
    for (var k = 0; k < item.variables.length; ++k) {
      var varname = item.variables[k].name;
      var option = $(document.createElement('option'));
      option.attr('value', varname);
      option.html(varname);
      select.append(option);
    }
    row.append(col);

    // Add 'add' button
    col = $(document.createElement('td'));
    var button = $(document.createElement('button'));
    button.attr('type', 'button');
    button.attr('class', 'btn btn-primary');
    button.attr('id', 'btn-add-' + item.name);
    button.attr('_id', item._id);
    button.attr('name', item.name);
    button.attr('basename', item.basename);
    button.attr('data-toggle', 'button');
    button.attr('data-loading-text', 'Loading...');
    button.html('Add');
    col.append(button);
    row.append(col);

    if (callback != undefined) {
      $(button).on("click", callback);
    }
  });

  $('.combobox').width(Math.max.apply(Math,
                                       $('.combobox').map(function(){
                                         return $(this).outerWidth();}).get()));
  $('.combobox').select2();
};

/**
 * Add a document as a layer to the list
 *
 * @todo Actually load a layer
 *
 * @param layersRootId
 * @param elem
 */
uiModule.gis.addLayer = function(object, layersRootId, elem, selectfunc, togglefunc,
  removefunc, callback) {

  var rootId = "#" + layersRootId;
  var _id = $(elem).attr("_id");
  if (_id !== null) {
    var tbody = $(rootId).find('tbody');
    var basename = $(elem).attr("name");
    $(elem).button('loading');

    var layerId = basename;

    var tr = $(document.createElement('tr'));
    tr.attr('id', layerId);
    $(tbody).append(tr);

    // Name of the layer
    var td = $(document.createElement('td'));
    td.append($(document.createElement('h4')).html(basename));
    tr.append(td);

    // Select button
    td = $(document.createElement('td'));
    td.attr('class', 'td-btn-layer');
    var button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-select-layer btn btn-primary disabled');
    button.attr('disabled', 'disabled');
    button.html('Select');
    button.click(layerId, function() {
      selectfunc(this, layerId);
    });
    td.append(button);

    // Toggle button
    button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-toggle-layer btn btn-warning disabled');
    button.attr('disabled', 'disabled');
    button.html('Toggle');
    button.click(layerId, function() {
      togglefunc(this, layerId);
    });
    td.append(button);

    // Remove button
    button = $(document.createElement('button'));
    button.attr('class', 'btn-layer btn-remove-layer btn btn-danger disabled');
    button.attr('disabled', 'disabled');
    button.html('Remove');
    button.click(layerId, function() {
      removefunc(this, layerId);
    });
    td.append(button);
    tr.append(td);

    $('.btn-layer').width(Math.max.apply(Math,
                                            $('.btn-layer').map(function(){
                                              return $(this).outerWidth();}).get()));
    }
    // @todo Just calling fadeIn does not work. It has to be set invisible
    // and then only it works. We need to check if this is expected.
    $('#'+layerId).fadeOut(0);
    $('#'+layerId).fadeIn('slow', callback);
};

/**
 *
 */
uiModule.gis.layerAdded = function(elem) {
  $(elem).removeClass("btn-primary");
  $(elem).addClass("btn-success");
  $(elem).addClass("disabled");
  $(elem).attr('data-loading-text', 'Added');
  $(elem).attr('disabled', 'disabled');
  $(elem).html('Added');
}

/**
 * Remove a layer from the list
 *
 * @param elem
 * @returns {Boolean}
 */
uiModule.gis.removeLayer = function(elem, layerId) {
  var buttonId = $('#btn-add-'+layerId);
  var button = $(buttonId);

  if (button !== null || button !== undefined) {
    button.removeClass('disabled');
    button.removeAttr('disabled');
    button.removeClass('btn-success');
    button.removeClass('active');
    button.button('reset');
    button.addClass('btn-primary');

    $('#' + layerId).fadeOut(function() {
      $('#' + layerId).remove();
    });

    return true;
  }

  return false;
};

uiModule.gis.toggleLayer = function(elem, layerId) {
  // Do nothing
};

/**
 * Update UI to when a layer is selected
 */
uiModule.gis.selectLayer = function(target, layerId) {
  $('btn-select-layer').siblings().removeClass('active');

  if (target !== null || target !== undefined) {
    $(target).addClass('active');
  }

  return true;
};

uiModule.gis.generateOptions = function(table, map) {
  var options = map.options();

  var parent = $(table);

  for (var key in options) {
    if (key === "source" || key === "center") {
      continue;
    }

    if (options.hasOwnProperty(key)) {

      var row = $(document.createElement('tr'));
      row.attr('class', 'row-fluid');
      parent.append(row);
      var col = $(document.createElement('td'));
      row.append(col);

      var heading = $(document.createElement('h4'));
      heading.html(key);
      col.append(heading);

      switch(key) {
        case "zoom":
          // Create a slider here
          var sliderDiv = $(document.createElement('div'));
          sliderDiv.slider({
            range: "min",
            min: 0.0,
            max: 17.0,
            step: 1,
            value: options[key],
            slide: function( event, ui ) {
              map.setZoom( ui.value );
              map.redraw();
            }
          });
          $(sliderDiv).on('mousedown', function(e) {
            e.stopPropagation();
            return false;
          });
          col.attr('class', 'span10');
          $(col).append(sliderDiv);
          break;
        case "center":
          // @todo We need to update center dynamically which
          // will require quite a bit of work.
          // Text box
          // var latInput = $(document.createElement('input'));
          // latInput.attr('type', 'number');
          // latInput.attr('min', -180.0);
          // latInput.attr('max', +180.0);
          // latInput.val(map.options().center.lat());
          // latInput.click(function() {
          //   map.redraw();
          // });
          // $(latInput).on('mousedown', function(e) {
          //   e.stopPropagation();
          //   return false;
          // });
          // col.append(latInput);

          // var lngInput = $(document.createElement('input'));
          // lngInput.attr('type', 'number');
          // lngInput.attr('min', -90.0);
          // lngInput.attr('max', +90.0);
          // lngInput.val(map.options().center.lng());
          // lngInput.click(function() {
          //   map.redraw();
          // });
          // $(lngInput).on('mousedown', function(e) {
          //   e.stopPropagation();
          //   return false;
          // });
          // col.append(lngInput);
          break;
        case "country_boundries":
          // Boolean
          var input = $(document.createElement('input'));
          input.attr('type', 'checkbox');
          input.attr('checked', map.options().country_boundries);
          input.click(function() {
            map.toggleCountryBoundries();
            map.redraw();
          });
          col.append(input);

          break;
        case "us_states":
          // Boolean
          break;
        case "source":
          // Dropdown
          break;
      }
    }
  }
};

uiModule.gis.createControls = function(table, map) {
  var tbody = $($(table).find('tbody'));
  var row = $(document.createElement('tr'));
  tbody.append(row);

  var col = $(document.createElement('td'));
  row.append(col);
  col.append('<h4>opacity</h4>');

  // Create slider to control opacity of a layer
  var opacityDiv = $(document.createElement('div'));
  opacityDiv.addClass('ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all');
  col.append(opacityDiv);

  opacityDiv.slider({
    range: "min",
    min: 0.0,
    max: 1.0,
    step: 0.01,
    value: 0.5,
  });

  // Listen for slider slidechange event
  opacityDiv.slider().bind('slide', function(event, ui) {
    if (map.activeLayer() !== null) {
      map.activeLayer().setOpacity(ui.value);
    }
    map.redraw();
  });

  opacityDiv.on('mousedown', function(e) {
    e.stopPropagation();
    return false;
  });
}<|endoftext|>