<commit_before>/**
 * Simple knockout model and view model for rendering the revision table on the
 * file detail page.
 */
;(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['knockout', 'jquery', 'osfutils'], factory);
    } else {
        global.VersionTable  = factory(ko, jQuery);
    }
}(this, function(ko, $) {
    'use strict';
    ko.punches.enableAll();
    ko.punches.attributeInterpolationMarkup.enable();

    function confirmedDeleteFile(api_url) {

    }

    function Version(data) {
        this.version_number = data.version_number;
        this.modified_date = new $.osf.FormattableDate(data.modified_date);
        this.downloads = data.downloads;
        this.download_url = data.download_url;
        this.committer_name = data.committer_name;
        this.committer_url = data.committer_url;
        this.view = data.view;
    }
    function VersionViewModel(url, global) {
        var self = this;
        self.versions = ko.observable([]);

        self.file_name = ko.observable(null);
        self.files_url = ko.observable(null);
        self.node_title = ko.observable(null);
        self.latest_version_url = ko.observable(null);
        self.api_url = ko.observable(null);
        self.files_page_url = ko.observable(null);

        // Date when this project was registered, or null if not a registration
        // TODO: should I populate this? (@mambocab)
        self.not_registered = ko.observable(null);

        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json'
        }).done(function(response) {
            self.versions(ko.utils.arrayMap(response.versions, function(rev) {
                return new Version(rev);
            }));
            self.node_title(response.node_title);
            self.file_name(response.file_name);
            self.node_title(response.node_title);
            self.latest_version_url(response.latest_version_url);
            self.api_url(response.api_url);
            self.files_page_url(response.files_page_url);
            self.not_registered(response.not_registered);
        }).fail(
            $.osf.handleJSONError
        );

        self.deleteFile = function(){
            bootbox.confirm("Are you sure you want to delete this file? It will not be recoverable.",
                function(result) {
                    if (result) {
                        $('#deleting-alert').addClass('in');
                        var result = $.ajax({
                            type: 'DELETE',
                            url: self.api_url()
                        });
                        result.done(function() {
                            window.location = self.files_page_url();
                        });
                        result.fail(function( jqXHR, textStatus ) {
                            $('#deleting-alert').removeClass('in');
                            bootbox.alert( "Could not delete: " + textStatus );
                        });
                    }
                });
        };
    }
    // Public API
    function VersionTable(selector, url) {
        this.viewModel = new VersionViewModel(url);
        $.osf.applyBindings(this.viewModel, selector);
    }

    return VersionTable;
}));
<commit_msg>Remove some unused changes.<commit_after>/**
 * Simple knockout model and view model for rendering the revision table on the
 * file detail page.
 */
;(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['knockout', 'jquery', 'osfutils'], factory);
    } else {
        global.VersionTable  = factory(ko, jQuery);
    }
}(this, function(ko, $) {
    'use strict';
    ko.punches.enableAll();
    ko.punches.attributeInterpolationMarkup.enable();

    function Version(data) {
        this.version_number = data.version_number;
        this.modified_date = new $.osf.FormattableDate(data.modified_date);
        this.downloads = data.downloads;
        this.download_url = data.download_url;
        this.committer_name = data.committer_name;
        this.committer_url = data.committer_url;
        this.view = data.view;
    }
    function VersionViewModel(url) {
        var self = this;
        self.versions = ko.observable([]);

        self.file_name = ko.observable(null);
        self.files_url = ko.observable(null);
        self.node_title = ko.observable(null);
        self.latest_version_url = ko.observable(null);
        self.api_url = ko.observable(null);
        self.files_page_url = ko.observable(null);

        // Date when this project was registered, or null if not a registration
        // TODO: should I populate this? (@mambocab)
        self.not_registered = ko.observable(null);

        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json'
        }).done(function(response) {
            self.versions(ko.utils.arrayMap(response.versions, function(rev) {
                return new Version(rev);
            }));
            self.node_title(response.node_title);
            self.file_name(response.file_name);
            self.node_title(response.node_title);
            self.latest_version_url(response.latest_version_url);
            self.api_url(response.api_url);
            self.files_page_url(response.files_page_url);
            self.not_registered(response.not_registered);
        }).fail(
            $.osf.handleJSONError
        );

        self.deleteFile = function(){
            bootbox.confirm("Are you sure you want to delete this file? It will not be recoverable.",
                function(result) {
                    if (result) {
                        $('#deleting-alert').addClass('in');
                        var result = $.ajax({
                            type: 'DELETE',
                            url: self.api_url()
                        });
                        result.done(function() {
                            window.location = self.files_page_url();
                        });
                        result.fail(function( jqXHR, textStatus ) {
                            $('#deleting-alert').removeClass('in');
                            bootbox.alert( "Could not delete: " + textStatus );
                        });
                    }
                });
        };
    }
    // Public API
    function VersionTable(selector, url) {
        this.viewModel = new VersionViewModel(url);
        $.osf.applyBindings(this.viewModel, selector);
    }

    return VersionTable;
}));
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {filter, groupBy, sortBy as _sortBy} from 'lodash';
import {isPast, parse, format} from 'date-fns';

import Heading from '../Heading';
import Divider from '../Divider';
import ConferenceItem from '../ConferenceItem';
import styles from './ConferenceList.css';

export default class ConferenceList extends Component {
  renderConferences = (conferences) => {
    const {showCFP} = this.props;
    return (

        {getConfsMonthsSorted(conferences).map((monthKey) => {
          const month = monthKey.split('-')[1];
          return (
            <Months
              key={monthKey}
              month={month}
              showCFP={showCFP}
              conferences={conferences[monthKey]}
            />
          );
        })}

    );
  };

  render() {
    const {conferences, showCFP, sortBy} = this.props;
    let filteredConferences = conferences;
    if (showCFP) {
      filteredConferences = filter(conferences, (conf) => {
        return conf.cfpEndDate && !isPast(parse(conf.cfpEndDate));
      });
    }
    const confs = groupAndSortConferences(filteredConferences, sortBy);

    if (confs.length === 0) {
      return (
{"Oh shoot! We don't have any conferences yet."}
);
    }

    const confsTable = Object.keys(confs).map((year) => {
      return [
        <Divider key="hr" />,
        <Year key={year} year={year} />,
        this.renderConferences(confs[year]),
      ];
    });

    return (
{confsTable}
);
  }
}

function groupAndSortConferences(conferences, sortBy = 'startDate') {
  // Group conferences by year
  const confs = groupBy(conferences, (conf) =>
    format(conf[sortBy], 'YYYY')
  );

  // Group conferences by month within the year
  Object.keys(confs).map((year) => {
    confs[year] = groupBy(confs[year], (conf) =>
      format(conf[sortBy], 'YYYY-MM')
    );
    Object.keys(confs[year]).map((month) => {
      confs[year][month] = _sortBy(confs[year][month], (conference) =>
        conference[sortBy]
      );
    });
  });

  return confs;
}

function getMonthName(month) {
  return format(parse(`2017/${month}/01`), 'MMMM');
}

function Months({month, conferences, showCFP}) {
  return [
    <Heading key={month} element="h2" level={3}>
      {getMonthName(month)}
    </Heading>,
    conferences.map((conf) => {
      return (
        <ConferenceItem
          {...conf}
          key={`${conf.url} ${conf.date}`}
          showCFP={showCFP}
        />
      );
    }),
  ];
}

function Year({year}) {
  return (
    <Heading key={year} element="h2" level={2}>
      {year}
    </Heading>
  );
}

function getConfsMonthsSorted(conferences) {
  return _sortBy(Object.keys(conferences), (conference) => {
    return parseInt(conference.replace('-', ''), 10);
  });
}
<commit_msg>Fixed empty view<commit_after>import React, {Component} from 'react';
import {filter, groupBy, sortBy as _sortBy} from 'lodash';
import {isPast, parse, format} from 'date-fns';

import Heading from '../Heading';
import Divider from '../Divider';
import ConferenceItem from '../ConferenceItem';
import styles from './ConferenceList.css';

export default class ConferenceList extends Component {
  renderConferences = (conferences) => {
    const {showCFP} = this.props;
    return (

        {getConfsMonthsSorted(conferences).map((monthKey) => {
          const month = monthKey.split('-')[1];
          return (
            <Months
              key={monthKey}
              month={month}
              showCFP={showCFP}
              conferences={conferences[monthKey]}
            />
          );
        })}

    );
  };

  render() {
    const {conferences, showCFP, sortBy} = this.props;
    let filteredConferences = conferences;
    if (showCFP) {
      filteredConferences = filter(conferences, (conf) => {
        return conf.cfpEndDate && !isPast(parse(conf.cfpEndDate));
      });
    }
    const confs = groupAndSortConferences(filteredConferences, sortBy);

    if (Object.keys(confs).length === 0) {
      return (
{"Oh shoot! We don't have any conferences yet."}
);
    }

    const confsTable = Object.keys(confs).map((year) => {
      return [
        <Divider key="hr" />,
        <Year key={year} year={year} />,
        this.renderConferences(confs[year]),
      ];
    });

    return (
{confsTable}
);
  }
}

function groupAndSortConferences(conferences, sortBy = 'startDate') {
  // Group conferences by year
  const confs = groupBy(conferences, (conf) =>
    format(conf[sortBy], 'YYYY')
  );

  // Group conferences by month within the year
  Object.keys(confs).map((year) => {
    confs[year] = groupBy(confs[year], (conf) =>
      format(conf[sortBy], 'YYYY-MM')
    );
    Object.keys(confs[year]).map((month) => {
      confs[year][month] = _sortBy(confs[year][month], (conference) =>
        conference[sortBy]
      );
    });
  });

  return confs;
}

function getMonthName(month) {
  return format(parse(`2017/${month}/01`), 'MMMM');
}

function Months({month, conferences, showCFP}) {
  return [
    <Heading key={month} element="h2" level={3}>
      {getMonthName(month)}
    </Heading>,
    conferences.map((conf) => {
      return (
        <ConferenceItem
          {...conf}
          key={`${conf.url} ${conf.date}`}
          showCFP={showCFP}
        />
      );
    }),
  ];
}

function Year({year}) {
  return (
    <Heading key={year} element="h2" level={2}>
      {year}
    </Heading>
  );
}

function getConfsMonthsSorted(conferences) {
  return _sortBy(Object.keys(conferences), (conference) => {
    return parseInt(conference.replace('-', ''), 10);
  });
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { hashHistory } from 'react-router';
import { connect } from 'react-redux';
import { bindActionCreators, dispatch } from 'redux';
import {
    actionFetchOneRole,
    actionFetchComponents,
    actionFetchPermissions,
    actionUpdateRoles,
    actionDeleteRoles
} from '../../../actions/RolesAction';
import InfoModal from '../../InfoModal/InfoModal';
import ModalAlert from '../../ModalAlert/ModalAlert';
require('./AddRoles.css');

class AddRolesComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            role: this.props.location.query['role'],
            permissions: null,
            selectedComponent: null
        };
        this.dataSource = null;
        this.formData = [];
        this.componentList = null;
        this.permissionList = null;
        this.infoModal = null;
        this.modalAlert = null;
        this.buttonClicked = null;
        this.isDefaultChecked = this.isDefaultChecked.bind(this);
        this.savePrevious = this.savePrevious.bind(this);
        this.onTextChange = this.onTextChange.bind(this);
        this.onComponentSelect = this.onComponentSelect.bind(this);
        this.onPermissionSelect = this.onPermissionSelect.bind(this);
        this.goPreviousPage = this.goPreviousPage.bind(this);
        this.onClickOkay = this.onClickOkay.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
        this.handleDelete = this.handleDelete.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.formSubmit = this.formSubmit.bind(this);
    }

    componentWillMount() {
        if (this.state.role != null) {
            this.props.fetchOne(this.state.role);
        }
        this.props.fetchComponents();
        this.props.fetchPermissions();
    }

    componentDidMount() {
      document.title = "RegOpz Dashboard | Add Role";
    }

    render() {
        if (this.props.location.query['role']) {
            this.dataSource = this.props.form
        }
        this.componentList = this.props.components;
        this.permissionList = this.props.permissions;
        console.log("Add Roles:", this.state);

        return(

Role Management Add a new role

                      <form className="form-horizontal form-label-left" onSubmit={ this.handleSubmit }>

                            Role *

                              <input
                                name="role"
                                placeholder="Title"
                                value={ this.state.role }
                                type="text"
                                id="role-title"
                                className="form-control col-md-7 col-xs-12"
                                onChange={ this.onTextChange }
                              />

                                { this.renderComponents() }

                                { this.renderPermissions() }

                              <button type="button"
                              className="btn btn-primary"
                              onClick={this.handleCancel}>
                                Cancel
                              </button>
                              <button type="submit"
                              className="btn btn-success"
                              disabled={ !this.state.role }>
                                Submit
                              </button>
                              <button type="button"
                              className="btn btn-danger"
                              disabled={ !this.props.location.query['role'] }
                              onClick={this.handleDelete}>
                                Delete
                              </button>

                      </form>

                  <InfoModal
                  title={ this.state.role }
                  ref={ (infoModal) => { this.infoModal = infoModal }}
                  onClickOkay={ this.goPreviousPage }/>
                  <ModalAlert
                  showDiscard={ true }
                  ref={ (modalAlert) => { this.modalAlert = modalAlert }}
                  onClickOkay= { this.onClickOkay }/>

        );
    }

    renderComponents() {
        if (this.componentList != null) {
            return(

Asigning Permissions
                   for { this.state.selectedComponent? this.state.selectedComponent:"component" }

                  {
                      this.componentList.map((item, index) => {
                          return(

                                  <button type="button"
                                  name={ item.component }
                                  className="btn btn-primary component-btn"
                                  onClick={ this.onComponentSelect }>
                                      { item.component }
                                  </button>

                          );
                      })
                  }

          );
      } else {
          return (

No Component Available
                  for permissions

Ooops, No component available

          );
        }
    }

    renderPermissions() {
        if (this.permissionList != null && this.state.selectedComponent != null) {
          return(

{ this.state.selectedComponent }
                  Available permissions

                  {
                      this.permissionList.map((item, index) => {
                          return(

                                <input
                                  type="checkbox"
                                  id={ item.permission }
                                  name={ item.permission }
                                  value={ item.permission }
                                  onChange={ this.onPermissionSelect }
                                  checked={ this.isDefaultChecked(item.permission) }/>

                                  { item.permission }

                          );
                      })
                  }

          );
      } else {
          return (

No Component Selected
                  for permissions

Please selec a component to asign permissions

          );
        }
    }

    isDefaultChecked(permission) {
        console.log("Checking for:", permission);
        console.log("Selected Component:", this.state.selectedComponent);
        if (this.state.permissions != null) {
            let selectedPermission = this.state.permissions.filter(
                (item) => {
                    return item.permission == permission;
                }
            );
            return selectedPermission.length != 0 && selectedPermission[0].permission_id;
        }
        return false;
    }

    savePrevious() {
        if (this.state.selectedComponent != null && this.state.permissions != null) {
            let selectedComponent = this.state.selectedComponent;
            let permissions = this.state.permissions;
            let pushObj = {
                'component': selectedComponent,
                'permissions': permissions
            };
            if (this.dataSource == null) {
                this.dataSource = { 'components': [ pushObj ]};
            } else {
                let selectedPermissionsIndex = this.dataSource.components.findIndex(
                    (item) => {
                        return item.component == selectedComponent;
                    }
                );
                if (selectedPermissionsIndex == -1) {
                    this.dataSource.components.push(pushObj);
                } else {
                    this.dataSource.components[selectedPermissionsIndex].permissions = permissions;
                }
            }
        }
    }

    onTextChange(e) {
        this.setState({ [e.target.name]: e.target.value });
    }

    onComponentSelect(e) {
        this.savePrevious();
        let selectedComponent = e.target.name;
        let permissions = null;
        if (this.dataSource != null) {
            let selectedPermissions = this.dataSource.components.filter(
                (item) => {
                    return item.component == selectedComponent;
                }
            );
            permissions = selectedPermissions.length != 0 && selectedPermissions[0].permissions;
        }
        this.setState({ selectedComponent: selectedComponent, permissions: permissions });
    }

    onPermissionSelect(e) {
        let targetName = e.target.name;
        let permissionObj = {
            'permission': targetName,
            'permission_id': 1
        }
        console.log("Clicked:", targetName, "on component", this.state.selectedComponent);
        if (this.state.permissions == null) {
            this.setState({ permissions: [ permissionObj ] });
        } else {
            let permissions = this.state.permissions;
            let permissionIndex = permissions.findIndex(
                (item) => {
                    return item.permission == targetName;
                }
            );
            if (permissionIndex == -1) {
                permissions.push(permissionObj);
            } else {
                permissions[permissionIndex].permission_id = permissions[permissionIndex].permission_id ? null : 1;
            }
            this.setState({ permissions: permissions });
        }
    }

    goPreviousPage() {
        const encodedUrl = encodeURI('/dashboard/manage-roles');
        hashHistory.push(encodedUrl);
    }

    onClickOkay(e) {
        /*if (this.buttonClicked == 'Cancel') {
            this.goPreviousPage();
        } else */if (this.buttonClicked == 'Delete') {
            this.props.deleteRow(this.state.role);
            console.log(this.props.message);
            // this.infoModal.open(this.props.message);
        } else if (this.buttonClicked == 'Submit') {
            this.formSubmit();
            console.log(this.props.message);
            // this.infoModal.open(this.props.message);
        }
        this.goPreviousPage();
    }

    handleCancel(e) {
        this.buttonClicked = "Cancel";
        this.modalAlert.open("Are you sure to cancel all the changes?");
    }

    handleDelete(e) {
        this.buttonClicked = "Delete";
        this.modalAlert.open("Are you sure to delete this role?");
    }

    handleSubmit(e) {
        e.preventDefault();
        this.buttonClicked = "Submit";
        this.modalAlert.open("Are you sure to submit this role?");
    }

    formSubmit() {
        if (this.dataSource != null) {
            console.log("Submiting form data:", this.dataSource);
            this.props.submitForm(this.dataSource)
        } else {
            console.log("Nothing to commit, no data found!");
        }
    }
}

function mapStateToProps(state) {
    return {
        form: state.role_management.form,
        components: state.role_management.components,
        permissions: state.role_management.permissions,
        message: state.role_management.message
    };
}

const mapDispatchToProps = (dispatch) => {
  return {
    fetchOne: (role) => {
        dispatch(actionFetchOneRole(role));
    },
    fetchComponents: () => {
        dispatch(actionFetchComponents());
    },
    fetchPermissions: () => {
        dispatch(actionFetchPermissions());
    },
    deleteRow: (role) => {
        dispatch(actionDeleteRoles(role));
    },
    submitForm: (data) => {
        dispatch(actionUpdateRoles(data));
    }
  };
};

const VisibleAddRoles = connect(
    mapStateToProps,
    mapDispatchToProps
)(AddRolesComponent);

export default VisibleAddRoles;
<commit_msg>State: Changed state update style and data collecting before submit<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { hashHistory } from 'react-router';
import { connect } from 'react-redux';
import { bindActionCreators, dispatch } from 'redux';
import {
    actionFetchOneRole,
    actionFetchComponents,
    actionFetchPermissions,
    actionUpdateRoles,
    actionDeleteRoles
} from '../../../actions/RolesAction';
import InfoModal from '../../InfoModal/InfoModal';
import ModalAlert from '../../ModalAlert/ModalAlert';
require('./AddRoles.css');

class AddRolesComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            role: this.props.location.query['role'],
            permissions: null,
            selectedComponent: null
        };
        this.dataSource = null;
        this.formData = [];
        this.componentList = null;
        this.permissionList = null;
        this.infoModal = null;
        this.modalAlert = null;
        this.buttonClicked = null;
        this.isDefaultChecked = this.isDefaultChecked.bind(this);
        this.savePrevious = this.savePrevious.bind(this);
        this.onTextChange = this.onTextChange.bind(this);
        this.onComponentSelect = this.onComponentSelect.bind(this);
        this.onPermissionSelect = this.onPermissionSelect.bind(this);
        this.goPreviousPage = this.goPreviousPage.bind(this);
        this.onClickOkay = this.onClickOkay.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
        this.handleDelete = this.handleDelete.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.formSubmit = this.formSubmit.bind(this);
    }

    componentWillMount() {
        if (this.state.role != null) {
            this.props.fetchOne(this.state.role);
        }
        this.props.fetchComponents();
        this.props.fetchPermissions();
    }

    componentDidMount() {
      document.title = "RegOpz Dashboard | Add Role";
    }

    render() {
        if (this.props.location.query['role']) {
            this.dataSource = this.props.form
        }
        this.componentList = this.props.components;
        this.permissionList = this.props.permissions;
        console.log("Add Roles:", this.state);

        return(

Role Management Add a new role

                      <form className="form-horizontal form-label-left" onSubmit={ this.handleSubmit }>

                            Role *

                              <input
                                name="role"
                                placeholder="Title"
                                value={ this.state.role }
                                type="text"
                                id="role-title"
                                className="form-control col-md-7 col-xs-12"
                                onChange={ this.onTextChange }
                              />

                                { this.renderComponents() }

                                { this.renderPermissions() }

                              <button type="button"
                              className="btn btn-primary"
                              onClick={this.handleCancel}>
                                Cancel
                              </button>
                              <button type="submit"
                              className="btn btn-success"
                              disabled={ !this.state.role }>
                                Submit
                              </button>
                              <button type="button"
                              className="btn btn-danger"
                              disabled={ !this.props.location.query['role'] }
                              onClick={this.handleDelete}>
                                Delete
                              </button>

                      </form>

                  <InfoModal
                  title={ this.state.role }
                  ref={ (infoModal) => { this.infoModal = infoModal }}
                  onClickOkay={ this.goPreviousPage }/>
                  <ModalAlert
                  showDiscard={ true }
                  ref={ (modalAlert) => { this.modalAlert = modalAlert }}
                  onClickOkay= { this.onClickOkay }/>

        );
    }

    renderComponents() {
        if (this.componentList != null) {
            return(

Asigning Permissions
                   for { this.state.selectedComponent? this.state.selectedComponent:"component" }

                  {
                      this.componentList.map((item, index) => {
                          return(

                                  <button type="button"
                                  name={ item.component }
                                  className="btn btn-primary component-btn"
                                  onClick={ this.onComponentSelect }>
                                      { item.component }
                                  </button>

                          );
                      })
                  }

          );
      } else {
          return (

No Component Available
                  for permissions

Ooops, No component available

          );
        }
    }

    renderPermissions() {
        if (this.permissionList != null && this.state.selectedComponent != null) {
          return(

{ this.state.selectedComponent }
                  Available permissions

                  {
                      (() => {
                          let permissionIndex = this.permissionList.findIndex(
                              (item) => {
                                  return item.component == this.state.selectedComponent;
                              }
                          );
                          console.log("PermissionIndex inside permission list..",permissionIndex,this.permissionList[permissionIndex]);
                          let permission_list =[];
                          this.permissionList[permissionIndex].permissions.map((item, index) => {
                              //console.log("permission",item);
                              //console.log("check for state permissions", this.state.permissions);
                              permission_list.push(

                                    <input
                                      type="checkbox"
                                      id={ item.permission }
                                      name={ item.permission }
                                      value={ item.permission }
                                      onChange={ this.onPermissionSelect }
                                      checked={ this.isDefaultChecked(item.permission) }/>

                                      { item.permission }

                              );
                          })
                          return permission_list;
                      })(this)
                  }

          );
      } else {
          return (

No Component Selected
                  for permissions

Please select a component to assign permissions

          );
        }
    }

    isDefaultChecked(permission) {
        //console.log("Checking for:", permission);
        //console.log("Selected Component:", this.state.selectedComponent);
        //console.log("Value of permissions", this.state.permissions);
        if (this.state.permissions != null) {
            let selectedPermission = this.state.permissions.filter(
                (item) => {
                    return item.permission == permission;
                }
            );
            return selectedPermission.length != 0 && selectedPermission[0].permission_id;
        }
        return false;
    }

    savePrevious() {
        //console.log("savePrevious check for permissions at the begining",this.state.permissions);
        if (this.state.selectedComponent != null && this.state.permissions != null) {
            let selectedComponent = this.state.selectedComponent;
            let permissions = this.state.permissions;
            let pushObj = {
                'component': selectedComponent,
                'permissions': permissions
            };
            if (this.dataSource == null) {
                this.dataSource = { 'components': [ pushObj ]};
            } else {
                let selectedPermissionsIndex = this.dataSource.components.findIndex(
                    (item) => {
                        return item.component == selectedComponent;
                    }
                );
                if (selectedPermissionsIndex == -1) {
                    this.dataSource.components.push(pushObj);
                } else {
                    this.dataSource.components[selectedPermissionsIndex].permissions = permissions;
                }
            }
        }
        //console.log("savePrevious check for permissions at the end",this.state.permissions)
    }

    onTextChange(e) {
        this.setState({ [e.target.name]: e.target.value });
    }

    onComponentSelect(e) {
        this.savePrevious();
        let selectedComponent = e.target.name;
        let permissions = null;
        //console.log("onComponentSelect...",selectedComponent);
        if (this.dataSource != null) {
            let selectedPermissions = this.dataSource.components.filter(
                (item) => {
                    return item.component == selectedComponent;
                }
            );
            console.log(selectedComponent, "selectedPermissions...", selectedPermissions);
            if (selectedPermissions.length != 0) {
              permissions = selectedPermissions[0].permissions;
            }
        }
        this.setState({ selectedComponent: selectedComponent, permissions: permissions });
    }

    onPermissionSelect(e) {
        let targetName = e.target.name;
        let permissionObj = {
            'permission': targetName,
            'permission_id': 1
        }
        console.log("Clicked:", targetName, "on component", this.state.selectedComponent,this.state.permissions);
        if (this.state.permissions == null) {
            this.setState({ permissions: [ permissionObj ] });
        } else {
            let permissions = this.state.permissions;
            let permissionIndex = permissions.findIndex(
                (item) => {
                    return item.permission == targetName;
                }
            );
            if (permissionIndex == -1) {
                permissions.push(permissionObj);
            } else {
                permissions[permissionIndex].permission_id = permissions[permissionIndex].permission_id ? null : 1;
            }
            this.setState({ permissions: permissions });
        }
    }

    goPreviousPage() {
        const encodedUrl = encodeURI('/dashboard/manage-roles');
        hashHistory.push(encodedUrl);
    }

    onClickOkay(e) {
        /*if (this.buttonClicked == 'Cancel') {
            this.goPreviousPage();
        } else */if (this.buttonClicked == 'Delete') {
            this.props.deleteRow(this.state.role);
            console.log(this.props.message);
            // this.infoModal.open(this.props.message);
        } else if (this.buttonClicked == 'Submit') {
            this.formSubmit();
            console.log(this.props.message);
            // this.infoModal.open(this.props.message);
        }
        this.goPreviousPage();
    }

    handleCancel(e) {
        this.buttonClicked = "Cancel";
        this.modalAlert.open("Are you sure to cancel all the changes?");
    }

    handleDelete(e) {
        this.buttonClicked = "Delete";
        this.modalAlert.open("Are you sure to delete this role?");
    }

    handleSubmit(e) {
        e.preventDefault();
        this.buttonClicked = "Submit";
        this.modalAlert.open("Are you sure to submit this role?");
    }

    formSubmit() {
        if (this.dataSource != null) {
            if (this.state.selectedComponent != null) {
              this.savePrevious();
            }
            let formData = { ...this.dataSource, role: this.state.role} ;
            console.log("Submiting form data:", formData);
            this.props.submitForm(formData)
        } else {
            console.log("Nothing to commit, no data found!");
        }
    }
}

function mapStateToProps(state) {
    return {
        form: state.role_management.form,
        components: state.role_management.components,
        permissions: state.role_management.permissions,
        message: state.role_management.message
    };
}

const mapDispatchToProps = (dispatch) => {
  return {
    fetchOne: (role) => {
        dispatch(actionFetchOneRole(role));
    },
    fetchComponents: () => {
        dispatch(actionFetchComponents());
    },
    fetchPermissions: () => {
        dispatch(actionFetchPermissions());
    },
    deleteRow: (role) => {
        dispatch(actionDeleteRoles(role));
    },
    submitForm: (data) => {
        dispatch(actionUpdateRoles(data));
    }
  };
};

const VisibleAddRoles = connect(
    mapStateToProps,
    mapDispatchToProps
)(AddRolesComponent);

export default VisibleAddRoles;
<|endoftext|>


<commit_before>angular.module('elfSantaHolidayJs')
  .directive('countdown',function($rootScope, $window) {
    "use strict";

    return {
      restrict: 'E',
      scope: {},
      templateUrl: 'components/countdown/countdown.html',
      link: function(scope,element,attrs){
       	scope.countdownCount = 60;
        scope.countClass = '';

         var countTimer = setInterval(function(){
             if (scope.countdownCount === 0) {
               scope.countdownCount = 60;
               scope.countClass = '';
               $rootScope.$broadcast('timeExpired');
             }
             else {
               scope.countdownCount--;
               if (scope.countdownCount === 10)
               {
                  scope.countClass = 'red';
               }
               scope.$digest();
             }
          }, 250);

          scope.$destroy(function (){
            $window.clearInterval(countTimer);
          });
      }
    };
  });
<commit_msg>* fix scope off<commit_after>angular.module('elfSantaHolidayJs')
  .directive('countdown',function($rootScope, $window) {
    "use strict";

    return {
      restrict: 'E',
      scope: {},
      templateUrl: 'components/countdown/countdown.html',
      link: function(scope,element,attrs){
       	scope.countdownCount = 60;
        scope.countClass = '';

         var countTimer = setInterval(function(){
             if (scope.countdownCount === 0) {
               scope.countdownCount = 60;
               scope.countClass = '';
               $rootScope.$broadcast('timeExpired');
             }
             else {
               scope.countdownCount--;
               if (scope.countdownCount === 10)
               {
                  scope.countClass = 'red';
               }
               scope.$digest();
             }
          }, 250);
          /*
          scope.$destroy(function (){
            $window.clearInterval(countTimer);
          });
          */
      }
    };
  });
<|endoftext|>


<commit_before>angular
  .module('sidenavDemo1', ['ngMaterial'])
  .controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $mdUtil, $log) {
    $scope.toggleLeft = buildToggler('left');
    $scope.toggleRight = buildToggler('right');

    /**
     * Supplies a function that will continue to operate until the
     * time is up.
     */
    function debounce(func, wait) {
      var timer;

      return function debounced() {
        var context = scope,
            args = Array.prototype.slice.call(arguments);
        $timeout.cancel(timer);
        timer = $timeout(function() {
          timer = undefined;
          func.apply(context, args);
        }, wait || 10);
      };
    }

    /**
     * Build handler to open/close a SideNav; when animation finishes
     * report completion in console
     */
    function buildToggler(navID) {
      return debounce(function() {
        $mdSidenav(navID).
            toggle().
            then(function () {
              $log.debug("toggle " + navID + " is done");
            });
      }, 200);
    }
  })
  .controller('LeftCtrl', function ($scope, $timeout, $mdSidenav, $log) {
    $scope.close = function () {
      $mdSidenav('left').close()
        .then(function () {
          $log.debug("close LEFT is done");
        });

    };
  })
  .controller('RightCtrl', function ($scope, $timeout, $mdSidenav, $log) {
    $scope.close = function () {
      $mdSidenav('right').close()
        .then(function () {
          $log.debug("close RIGHT is done");
        });
    };
  });
<commit_msg>Re-added the scope context (which is required).<commit_after>angular
  .module('sidenavDemo1', ['ngMaterial'])
  .controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $mdUtil, $log) {
    $scope.toggleLeft = buildToggler('left');
    $scope.toggleRight = buildToggler('right');

    /**
     * Supplies a function that will continue to operate until the
     * time is up.
     */
    function debounce(func, wait, context) {
      var timer;

      return function debounced() {
        var context = scope,
            args = Array.prototype.slice.call(arguments);
        $timeout.cancel(timer);
        timer = $timeout(function() {
          timer = undefined;
          func.apply(context, args);
        }, wait || 10);
      };
    }

    /**
     * Build handler to open/close a SideNav; when animation finishes
     * report completion in console
     */
    function buildToggler(navID) {
      return debounce(function() {
        $mdSidenav(navID).
            toggle().
            then(function () {
              $log.debug("toggle " + navID + " is done");
            });
      }, 200);
    }
  })
  .controller('LeftCtrl', function ($scope, $timeout, $mdSidenav, $log) {
    $scope.close = function () {
      $mdSidenav('left').close()
        .then(function () {
          $log.debug("close LEFT is done");
        });

    };
  })
  .controller('RightCtrl', function ($scope, $timeout, $mdSidenav, $log) {
    $scope.close = function () {
      $mdSidenav('right').close()
        .then(function () {
          $log.debug("close RIGHT is done");
        });
    };
  });
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
} from 'react-native'

import PropTypes from 'prop-types'
import { LineChart } from 'react-native-svg-charts'
import * as shape from 'd3-shape'

import TextPingFang from '../../../components/TextPingFang'

import {
  getResponsiveWidth,
  getResponsiveHeight
} from '../../../common/styles'

export default class ModeCharts extends Component {
  static propTypes = {
    modeData: PropTypes.arrayOf(PropTypes.number).isRequired,
    timeRange: PropTypes.arrayOf(PropTypes.string).isRequired
  }

  render() {

    const contentInset = { top: 20, bottom: 20 }

    return (
      <View style={styles.container}>
        <View style={styles.top_container}>
          <View style={styles.yaxis}>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>积极</TextPingFang>
            </View>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>中级</TextPingFang>
            </View>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>消极</TextPingFang>
            </View>
          </View>

          <LineChart
            style={styles.line_chart}
            data={this.props.modeData}
            svg={{ stroke: '#2DC3A6', strokeWidth: 1.5 }}
            curve={ shape.curveNatural }
            contentInset={{ top: 15, bottom: 15 }}
            animate={true}
            gridMin={0}
            gridMax={100}
          >
          </LineChart>
        </View>

        <View style={styles.xaxis}>
          {
            this.props.timeRange.map((time, index) => {
              return (
                <TextPingFang key={index} style={styles.text_axis_item}>{time}</TextPingFang>
              )
            })
          }
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: getResponsiveWidth(48)
  },
  top_container: {
    flexDirection: 'row',
    // backgroundColor: 'red'
  },
  yaxis: {
    width: '100%',
    height: getResponsiveHeight(168),
    position: 'absolute',
  },
  y_item: {
    height: getResponsiveHeight(56),
    justifyContent: 'flex-end',
    borderBottomWidth: getResponsiveWidth(1),
    borderBottomColor: 'rgba(45,195,166,.15)',
  },
  text_axis_item: {
    color: '#000',
    fontSize: 12,
  },
  line_chart: {
    flex: 1,
    height: getResponsiveHeight(168),
    marginLeft: getResponsiveWidth(32),
  },
  xaxis: {
    height: getResponsiveHeight(24),
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    marginLeft: getResponsiveWidth(32)
  }
})
<commit_msg>fix: 修复情绪曲线显示问题<commit_after>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
} from 'react-native'

import PropTypes from 'prop-types'
import { LineChart } from 'react-native-svg-charts'
import * as shape from 'd3-shape'

import TextPingFang from '../../../components/TextPingFang'

import {
  getResponsiveWidth,
  getResponsiveHeight
} from '../../../common/styles'

export default class ModeCharts extends Component {
  static propTypes = {
    modeData: PropTypes.arrayOf(PropTypes.number).isRequired,
    timeRange: PropTypes.arrayOf(PropTypes.string).isRequired
  }

  render() {

    const contentInset = { top: 20, bottom: 20 }

    return (
      <View style={styles.container}>
        <View style={styles.top_container}>
          <View style={styles.yaxis}>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>积极</TextPingFang>
            </View>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>中级</TextPingFang>
            </View>
            <View style={styles.y_item}>
              <TextPingFang style={styles.text_axis_item}>消极</TextPingFang>
            </View>
          </View>

          <LineChart
            style={styles.line_chart}
            data={this.props.modeData}
            svg={{ stroke: '#2DC3A6', strokeWidth: 1.5 }}
            curve={ shape.curveNatural }
            contentInset={{ top: 20, bottom: 20 }}
            animate={true}
            gridMin={0}
            gridMax={100}
          >
          </LineChart>
        </View>

        <View style={styles.xaxis}>
          {
            this.props.timeRange.map((time, index) => {
              return (
                <TextPingFang key={index} style={styles.text_axis_item}>{time}</TextPingFang>
              )
            })
          }
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: getResponsiveWidth(48)
  },
  top_container: {
    flexDirection: 'row',
    // backgroundColor: 'red'
  },
  yaxis: {
    width: '100%',
    height: getResponsiveHeight(168),
    position: 'absolute',
  },
  y_item: {
    height: getResponsiveHeight(56),
    justifyContent: 'flex-end',
    borderBottomWidth: getResponsiveWidth(1),
    borderBottomColor: 'rgba(45,195,166,.15)',
  },
  text_axis_item: {
    color: '#000',
    fontSize: 12,
  },
  line_chart: {
    flex: 1,
    height: getResponsiveHeight(168),
    marginLeft: getResponsiveWidth(32),
  },
  xaxis: {
    height: getResponsiveHeight(24),
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    marginLeft: getResponsiveWidth(32)
  }
})
<|endoftext|>


<commit_before>/*
 * Copyright 2014 XWiki SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
define([
    '/common/common-util.js',
    '/customize/application_config.js',
    '/bower_components/chainpad/chainpad.dist.js'
], function (Util, AppConfig) {
    var ChainPad = window.ChainPad;
    var module = { exports: {} };

    var badStateTimeout = typeof(AppConfig.badStateTimeout) === 'number' ?
        AppConfig.badStateTimeout : 30000;

    var verbose = function (x) { console.log(x); };
    verbose = function () {}; // comment out to enable verbose logging

    module.exports.start = function (config) {
        var onConnectionChange = config.onConnectionChange || function () { };
        var onRemote = config.onRemote || function () { };
        var onInit = config.onInit || function () { };
        var onLocal = config.onLocal || function () { };
        var setMyID = config.setMyID || function () { };
        var onReady = config.onReady || function () { };
        var userName = config.userName;
        var initialState = config.initialState;
        var transformFunction = config.transformFunction;
        var validateContent = config.validateContent;
        var avgSyncMilliseconds = config.avgSyncMilliseconds;
        var logLevel = typeof(config.logLevel) !== 'undefined'? config.logLevel : 1;
        var readOnly = config.readOnly || false;
        var sframeChan = config.sframeChan;
        var metadataMgr = config.metadataMgr;
        config = undefined;

        var chainpad;
        var myID;
        var isReady = false;
        var evConnected = Util.mkEvent(true);
        var evInfiniteSpinner = Util.mkEvent(true);

        window.setInterval(function () {
            if (!chainpad || !myID) { return; }
            var l;
            try {
                l = chainpad.getLag();
            } catch (e) {
                throw new Error("ChainPad.getLag() does not exist, please `bower update`");
            }
            if (l.lag < badStateTimeout) { return; }
            chainpad.abort();
            evInfiniteSpinner.fire();
        }, 2000);

        sframeChan.on('EV_RT_DISCONNECT', function () {
            isReady = false;
            if (chainpad) { chainpad.abort(); }
            onConnectionChange({ state: false });
        });
        sframeChan.on('EV_RT_CONNECT', function (content) {
            //content.members.forEach(userList.onJoin);
            myID = content.myID;
            isReady = false;
            if (chainpad) {
                // it's a reconnect
                if (chainpad) { chainpad.start(); }
                onConnectionChange({ state: true, myId: myID });
                return;
            }
            chainpad = ChainPad.create({
                userName: userName,
                initialState: initialState,
                transformFunction: transformFunction,
                validateContent: validateContent,
                avgSyncMilliseconds: avgSyncMilliseconds,
                logLevel: logLevel
            });
            chainpad.onMessage(function(message, cb) {
                sframeChan.query('Q_RT_MESSAGE', message, cb);
            });
            chainpad.onPatch(function () {
                onRemote({ realtime: chainpad });
            });
            onInit({
                myID: myID,
                realtime: chainpad,
                readOnly: readOnly
            });
            evConnected.fire();
        });
        sframeChan.on('Q_RT_MESSAGE', function (content, cb) {
            if (isReady) {
                onLocal(); // should be onBeforeMessage
            }
            chainpad.message(content);
            cb('OK');
        });
        sframeChan.on('EV_RT_READY', function () {
            if (isReady) { return; }
            isReady = true;
            chainpad.start();
            setMyID({ myID: myID });
            onReady({ realtime: chainpad });
        });

        var whenRealtimeSyncs = function (cb) {
            evConnected.reg(function () {
                if (chainpad.getAuthDoc() === chainpad.getUserDoc()) {
                    return void cb();
                } else {
                    chainpad.onSettle(cb);
                }
            });
        };

        return Object.freeze({
            getMyID: function () { return myID; },
            metadataMgr: metadataMgr,
            whenRealtimeSyncs: whenRealtimeSyncs,
            onInfiniteSpinner: evInfiniteSpinner.reg
        });
    };
    return Object.freeze(module.exports);
});<commit_msg>Refactor sframe-cpnf-inner to export chainpad<commit_after>/*
 * Copyright 2014 XWiki SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
define([
    '/common/common-util.js',
    '/customize/application_config.js',
    '/bower_components/chainpad/chainpad.dist.js'
], function (Util, AppConfig) {
    var ChainPad = window.ChainPad;
    var module = { exports: {} };

    var badStateTimeout = typeof(AppConfig.badStateTimeout) === 'number' ?
        AppConfig.badStateTimeout : 30000;

    var verbose = function (x) { console.log(x); };
    verbose = function () {}; // comment out to enable verbose logging

    module.exports.start = function (config) {
        var onConnectionChange = config.onConnectionChange || function () { };
        var onRemote = config.onRemote || function () { };
        var onInit = config.onInit || function () { };
        var onLocal = config.onLocal || function () { };
        var setMyID = config.setMyID || function () { };
        var onReady = config.onReady || function () { };
        var userName = config.userName;
        var initialState = config.initialState;
        var transformFunction = config.transformFunction;
        var validateContent = config.validateContent;
        var avgSyncMilliseconds = config.avgSyncMilliseconds;
        var logLevel = typeof(config.logLevel) !== 'undefined'? config.logLevel : 1;
        var readOnly = config.readOnly || false;
        var sframeChan = config.sframeChan;
        var metadataMgr = config.metadataMgr;
        config = undefined;

        var chainpad = ChainPad.create({
            userName: userName,
            initialState: initialState,
            transformFunction: transformFunction,
            validateContent: validateContent,
            avgSyncMilliseconds: avgSyncMilliseconds,
            logLevel: logLevel
        });
        chainpad.onMessage(function(message, cb) {
            sframeChan.query('Q_RT_MESSAGE', message, cb);
        });
        chainpad.onPatch(function () {
            onRemote({ realtime: chainpad });
        });

        var myID;
        var isReady = false;
        var evConnected = Util.mkEvent(true);
        var evInfiniteSpinner = Util.mkEvent(true);

        window.setInterval(function () {
            if (!chainpad || !myID) { return; }
            var l;
            try {
                l = chainpad.getLag();
            } catch (e) {
                throw new Error("ChainPad.getLag() does not exist, please `bower update`");
            }
            if (l.lag < badStateTimeout) { return; }
            chainpad.abort();
            evInfiniteSpinner.fire();
        }, 2000);

        sframeChan.on('EV_RT_DISCONNECT', function () {
            isReady = false;
            chainpad.abort();
            onConnectionChange({ state: false });
        });
        sframeChan.on('EV_RT_CONNECT', function (content) {
            //content.members.forEach(userList.onJoin);
            isReady = false;
            if (myID) {
                // it's a reconnect
                myID = content.myID;
                chainpad.start();
                onConnectionChange({ state: true, myId: myID });
                return;
            }
            myID = content.myID;
            onInit({
                myID: myID,
                realtime: chainpad,
                readOnly: readOnly
            });
            evConnected.fire();
        });
        sframeChan.on('Q_RT_MESSAGE', function (content, cb) {
            if (isReady) {
                onLocal(); // should be onBeforeMessage
            }
            chainpad.message(content);
            cb('OK');
        });
        sframeChan.on('EV_RT_READY', function () {
            if (isReady) { return; }
            isReady = true;
            chainpad.start();
            setMyID({ myID: myID });
            onReady({ realtime: chainpad });
        });

        var whenRealtimeSyncs = function (cb) {
            evConnected.reg(function () {
                if (chainpad.getAuthDoc() === chainpad.getUserDoc()) {
                    return void cb();
                } else {
                    chainpad.onSettle(cb);
                }
            });
        };

        return Object.freeze({
            getMyID: function () { return myID; },
            metadataMgr: metadataMgr,
            whenRealtimeSyncs: whenRealtimeSyncs,
            onInfiniteSpinner: evInfiniteSpinner.reg,
            chainpad: chainpad,
        });
    };
    return Object.freeze(module.exports);
});<|endoftext|>


<commit_before>/**
 * Minds::mobile
 * Newsfeed controller
 *
 * @author Mark Harding
 */

define(function () {
    'use strict';

    function ctrl( $rootScope, $scope, $state, $stateParams, NewsfeedAPI, $filter, $ionicScrollDelegate, Cacher, Client, storage, $ionicPopover, $ionicLoading, $timeout, $ionicActionSheet, $ionicModal, $ionicPlatform) {

    	//if same tab click, refresh and go to top
    	$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
			if(toState.name == fromState.name){
				$ionicScrollDelegate.scrollTop();
				$scope.refresh();
			}
			if(toState.name == 'tab.newsfeed'){

			}
		});

    	$rootScope.$on('newsfeed:updated', function() {
    		$ionicScrollDelegate.scrollTop();
    	    $scope.refresh();
    	});

    	$rootScope.$on('newsfeed:boost', function($event, v2) {
    		$scope.boost({guid:v2, owner_guid: $rootScope.user_guid});
    	});

    	$scope.newsfeedItems =  [];
    	$scope.next  = "";

    	$scope.hasMoreData = true;

    	if(Cacher.get('newsfeed.cachebreaker')){
    		$scope.cachebreaker = Cacher.get('newsfeed.cachebreaker');
    	} else {
    		$scope.cachebreaker = 0;
    	}

    	/**
    	 * Load more posts
    	 */
    	$scope.loadMore = function(){
    		console.log('==== loading more ====');

    		if(!$scope.hasMoreData){
    			$scope.$broadcast('scroll.infiniteScrollComplete');
    			return;
    		}

    		NewsfeedAPI.all({ limit: 12, offset: $scope.next, cachebreaker: $scope.cachebreaker },
    			function(data){

	    			if(!data.activity){
	    				$scope.hasMoreData = false;
	    				$scope.$broadcast('scroll.infiniteScrollComplete');
	    				return false;
	    			} else {
	    				$scope.hasMoreData = true;
	    			};

	    			if($scope.newsfeedItems.length > 50){
	    				$ionicScrollDelegate.scrollTop();
	    				$scope.newsfeedItems = data.activity;
	    			} else {

	    				$scope.newsfeedItems = $scope.newsfeedItems.concat(data.activity);
	     			}
	    				//Cacher.put('newsfeed.items', $scope.newsfeedItems);
	    			//} else {
	    			//	Cacher.put('newsfeed.items', data.activity);
	    			//}

	    			$scope.next = data['load-next'];
	    			console.log("next is:: " + $scope.next);
	    			//Cacher.put('newsfeed.item', $scope.next);

	    			$scope.$broadcast('scroll.infiniteScrollComplete');

	    		},
	    		function(error){
	    			$scope.hasMoreData = false;
	    			$scope.$broadcast('scroll.infiniteScrollComplete');
	    		});

    	};

		$scope.refresh = function(){
			console.log("=== refreshing ===");
			$scope.hasMoreData = true;
			NewsfeedAPI.all({ limit: 12, offset: '', cache_break: Date.now() },
				function(data){

	    			$scope.newsfeedItems = data.activity;
	    			Cacher.put('newsfeed.items', $scope.newsfeedItems );

	    			$scope.next = data['load-next'];

	    			$scope.cachebreaker = Date.now();
	    			Cacher.put('newsfeed.cachebreaker', Date.now());

	    			$scope.$broadcast('scroll.refreshComplete');

	    		},
	    		function(error){
	    			$scope.$broadcast('scroll.refreshComplete');
	    		});

		};

		/**************************
		 **** Newsfeed actions ****
		 *************************/
		/**
		 * Thumb up an activity
		 */
		$scope.thumbsUp = function(guid){
			//increment count
			$rootScope.points = $rootScope.points + 1;

			if($scope.ChannelItems)
				$scope.newsfeedItems = $scope.ChannelItems;

			if($scope.activity)
				$scope.newsfeedItems[0] = $scope.activity;

			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == guid){
					if(!array[index].hasOwnProperty('thumbs:up:user_guids') || !array[index]['thumbs:up:user_guids'])
						array[index]['thumbs:up:user_guids'] = [];

					for(var key in array[index]['thumbs:up:user_guids']){
							if(array[index]['thumbs:up:user_guids'][key] === storage.get('user_guid')){
								delete array[index]['thumbs:up:user_guids'][key];
								array[index]['thumbs:up:count'] = array[index]['thumbs:up:count'] -1;
								//remove count
								$rootScope.points = $rootScope.points - 2;
								return true;
							}
					}

					array[index]['thumbs:up:user_guids'][1] = storage.get('user_guid');
					array[index]['thumbs:up:count'] = array[index]['thumbs:up:count'] +1;

				}
			});

			Client.put('api/v1/thumbs/'+guid+'/up', {},
				function(success){

				},
				function(error){
					alert('failed..');
				});

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Thumb down an activity
		 */
		$scope.thumbsDown = function(guid){
			//increment count
			$rootScope.points = $rootScope.points + 1;

			if($scope.ChannelItems)
				$scope.newsfeedItems = $scope.ChannelItems;

			if($scope.activity)
				$scope.newsfeedItems[0] = $scope.activity;

			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == guid){
					if(!array[index].hasOwnProperty('thumbs:down:user_guids') || !array[index]['thumbs:down:user_guids'])
						array[index]['thumbs:down:user_guids'] = [];

					for(var key in array[index]['thumbs:down:user_guids']){
						if(array[index]['thumbs:down:user_guids'][key] === storage.get('user_guid')){
							delete array[index]['thumbs:down:user_guids'][key];
							array[index]['thumbs:down:count'] = array[index]['thumbs:down:count'] -1;
							//remove count
							$rootScope.points = $rootScope.points - 2;
							return true;
						}
					}

					array[index]['thumbs:down:user_guids'][1] = storage.get('user_guid');
					array[index]['thumbs:down:count'] = array[index]['thumbs:down:count'] +1;

				}
			});

			Client.put('api/v1/thumbs/'+guid+'/down', {},
				function(success){

				},
				function(error){
					alert('failed..');
				});

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Load comments
		 */
		$scope.commentsData = {};
		$scope.loadComments = function(activity, $event){
			$scope.comments.show($event);
			$scope.commentsData = {};

			var guid;
			if(activity.entity_guid){
				guid = activity.entity_guid;
			} else {
				guid = activity.guid;
			}

			/**
			 * Now load the comments
			 */
			Client.get('api/v1/comments/'+guid, {
					cachebreaker: Date.now
				},
				function(success){
					console.log('success for ' + guid );
					console.log(success);
					$scope.commentsData = success.comments;
				}, function(error){
					console.log('error');
				});

		};
		$ionicPopover.fromTemplateUrl('templates/comments/list.html', {
		    scope: $scope,
		  }).then(function(popover) {
		    $scope.comments = popover;
		  });

		/**
		 * Remind an activity
		 */
		$scope.remind = function(activity, $event){

			Client.post('api/v1/newsfeed/remind/'+activity.guid, {},
					function(success){

					},
					function(error){
						alert('failed..');
					});

			/**
			 * @todo improve this way of updating!
			 */
			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == activity.guid){
					array[index].reminds = array[index].reminds + 1;
				}
			});
			if($scope.ChannelItems){
				$scope.ChannelItems.forEach(function(item, index, array){
					if(item.guid == activity.guid){
						array[index].reminds = array[index].reminds + 1;
					}
				});
			}

			if($scope.activity){
				$scope.activity.reminds = $scope.activity.reminds + 1;
			}

			//increment count
			$rootScope.points = $rootScope.points + 1;

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Init the composer popover
		 */
		$scope.composerData = {};
		$ionicPopover.fromTemplateUrl('templates/newsfeed/compose.html', {
		    scope: $scope,
		  }).then(function(popover) {
		    $scope.composer = popover;
		  });

		var posting;
		$scope.post = function(){
			if(posting)
				return false;

			console.log("posting");
			$ionicLoading.show({
		      template: 'Please wait a moment...'
		    });
		    var posting = true;

    		NewsfeedAPI.post({
    			message: $scope.composerData.message
	    	}, function(success){
	    		$scope.refresh();
	    		$scope.message = '';
	    		$scope.composer.hide();

	    		$ionicLoading.hide();
	    		posting = false;
	    	}, function(error){
	    		alert('there was an error and we couldn\'t save!');
	    		$ionicLoading.hide();
	    		posting = false;
	    	});

		};

		$scope.remove = function(guid){
			console.log('api/v1/newsfeed/'+guid);
			Client.delete('api/v1/newsfeed/'+guid, {
					cachebreaker: Date.now
				},
				function(success){
					console.log(success);
					$scope.newsfeedItems.forEach(function(item, index, array){
						if(item.guid == guid){
							console.log('removed');
							array.splice(index, 1);
						}
					});
					if($scope.ChannelItems){
						$scope.ChannelItems.forEach(function(item, index, array){
							if(item.guid == guid){
								console.log('removed');
								array.splice(index, 1);
							}
						});
					}
				}, function(error){
					console.log('error');
				});
		};

		$scope.loadNotifications = function(){
			$state.go('tab.more-notifications', {}, {reload:true});
		};

		var timeout;
		$scope.openUrl = function(url){
			$timeout.cancel(timeout);

			timeout = $timeout( function(){
				window.open(url, "_blank", "location=yes");
			}, 300);
		};

		$scope.boost = function(activity){
			$ionicModal.fromTemplateUrl('templates/newsfeed/boost.html', {
			    	 		    scope: $scope,
			    	 		    animation: 'slide-in-up'
			    	 		  }).then(function(modal) {
			    	 		    $scope.modal = modal;
			    	 		    $scope.guid = activity.guid;
			    	 		    $scope.owner_guid = activity.owner_guid;
			    	 		    $scope.modal.show();
			    	 		  });
		};

		$scope.openActions = function(activity){
			var guid = activity.guid;
			$ionicActionSheet.show({
			     buttons: [
			       //{ text: 'Share This' },
			       { text: 'Boost' },
			       { text: 'Share' },
			       { text: 'Download' },
			       { text: 'Report this' }
			     ],
			     destructiveText: 'Delete',
			     destructiveButtonClicked: function(){
			     	if(activity.p2p_boosted){
			     		$ionicLoading.show({
			    				template: 'Sorry, you can not delete a boosted post.'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);
			    		return false;
			     	}

			     	if(activity.owner_guid != $rootScope.user_guid){

			     		$ionicLoading.show({
			    				template: 'Sorry, you can not delete posts that are not yourss.'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);

			    		return false;

			     	}

			     	if(confirm("are you sure?"))
			    		 $scope.remove(guid);
			    	 return true;

			     },
			     cancelText: 'Cancel',
			     cancel: function() {
			          // add cancel code..
			        },
			     buttonClicked: function(index) {
			    	 switch(index){
			    	 	case 0:
			    	 		$scope.boost(activity);

			    	 		break;
			    	 	case 1:
			    	 		/*cordova.plugins.clipboard.copy($rootScope.node_url + 'newsfeed/' + guid);
			    	 		$ionicLoading.show({
			    				template: '
 Copied to clipboard
'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);
			    	 		break;*/
			    	 		window.plugins.socialsharing.share('via minds', null, null, $rootScope.node_url + 'newsfeed/' + guid);
			    	 	case 2:

			    	 		window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
			    	 			var ft = new FileTransfer();
			    	 			console.log(fs.root.toURL());
			    	 			fs.root.getDirectory('minds', { create: true, exclusive: false }, function(){}, function(){});
				    	 		ft.download(
				    	 			    activity.custom_data[0].src,
				    	 			    fs.root.toURL() + "minds/" + guid + '.jpg',
				    	 			    function(entry) {
				    	 			        console.log("download complete: " + entry.toURL());
				    	 			    },
				    	 			    function(error) {
				    	 			        console.log("download error source " + error.source);
				    	 			        console.log("download error target " + error.target);
				    	 			        console.log("upload error code" + error.code);
				    	 			    },
				    	 			    false
				    	 			);
			    	 			});
			    	 		break;
			    	 	case 3:
			    	 		window.location.href = "mailto:report@minds.com?subject=Report " + guid + "&body=This content violates the terms and conditions";
			    	 }
			       return true;
			     }
			   });

		};

    }

    ctrl.$inject = ['$rootScope', '$scope', '$state', '$stateParams', 'NewsfeedAPI', '$filter', '$ionicScrollDelegate', 'Cacher', 'Client', 'storage', '$ionicPopover', '$ionicLoading', '$timeout', '$ionicActionSheet', '$ionicModal', '$ionicPlatform'];
    return ctrl;

});<commit_msg>ensures that guid is passed, to prevent bad boost page<commit_after>/**
 * Minds::mobile
 * Newsfeed controller
 *
 * @author Mark Harding
 */

define(function () {
    'use strict';

    function ctrl( $rootScope, $scope, $state, $stateParams, NewsfeedAPI, $filter, $ionicScrollDelegate, Cacher, Client, storage, $ionicPopover, $ionicLoading, $timeout, $ionicActionSheet, $ionicModal, $ionicPlatform) {

    	//if same tab click, refresh and go to top
    	$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
			if(toState.name == fromState.name){
				$ionicScrollDelegate.scrollTop();
				$scope.refresh();
			}
			if(toState.name == 'tab.newsfeed'){

			}
		});

    	$rootScope.$on('newsfeed:updated', function() {
    		$ionicScrollDelegate.scrollTop();
    	    $scope.refresh();
    	});

    	$rootScope.$on('newsfeed:boost', function($event, v2) {
    		if(v2){
    			$scope.boost({guid:v2, owner_guid: $rootScope.user_guid});
    		}
    	});

    	$scope.newsfeedItems =  [];
    	$scope.next  = "";

    	$scope.hasMoreData = true;

    	if(Cacher.get('newsfeed.cachebreaker')){
    		$scope.cachebreaker = Cacher.get('newsfeed.cachebreaker');
    	} else {
    		$scope.cachebreaker = 0;
    	}

    	/**
    	 * Load more posts
    	 */
    	$scope.loadMore = function(){
    		console.log('==== loading more ====');

    		if(!$scope.hasMoreData){
    			$scope.$broadcast('scroll.infiniteScrollComplete');
    			return;
    		}

    		NewsfeedAPI.all({ limit: 12, offset: $scope.next, cachebreaker: $scope.cachebreaker },
    			function(data){

	    			if(!data.activity){
	    				$scope.hasMoreData = false;
	    				$scope.$broadcast('scroll.infiniteScrollComplete');
	    				return false;
	    			} else {
	    				$scope.hasMoreData = true;
	    			};

	    			if($scope.newsfeedItems.length > 50){
	    				$ionicScrollDelegate.scrollTop();
	    				$scope.newsfeedItems = data.activity;
	    			} else {

	    				$scope.newsfeedItems = $scope.newsfeedItems.concat(data.activity);
	     			}
	    				//Cacher.put('newsfeed.items', $scope.newsfeedItems);
	    			//} else {
	    			//	Cacher.put('newsfeed.items', data.activity);
	    			//}

	    			$scope.next = data['load-next'];
	    			console.log("next is:: " + $scope.next);
	    			//Cacher.put('newsfeed.item', $scope.next);

	    			$scope.$broadcast('scroll.infiniteScrollComplete');

	    		},
	    		function(error){
	    			$scope.hasMoreData = false;
	    			$scope.$broadcast('scroll.infiniteScrollComplete');
	    		});

    	};

		$scope.refresh = function(){
			console.log("=== refreshing ===");
			$scope.hasMoreData = true;
			NewsfeedAPI.all({ limit: 12, offset: '', cache_break: Date.now() },
				function(data){

	    			$scope.newsfeedItems = data.activity;
	    			Cacher.put('newsfeed.items', $scope.newsfeedItems );

	    			$scope.next = data['load-next'];

	    			$scope.cachebreaker = Date.now();
	    			Cacher.put('newsfeed.cachebreaker', Date.now());

	    			$scope.$broadcast('scroll.refreshComplete');

	    		},
	    		function(error){
	    			$scope.$broadcast('scroll.refreshComplete');
	    		});

		};

		/**************************
		 **** Newsfeed actions ****
		 *************************/
		/**
		 * Thumb up an activity
		 */
		$scope.thumbsUp = function(guid){
			//increment count
			$rootScope.points = $rootScope.points + 1;

			if($scope.ChannelItems)
				$scope.newsfeedItems = $scope.ChannelItems;

			if($scope.activity)
				$scope.newsfeedItems[0] = $scope.activity;

			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == guid){
					if(!array[index].hasOwnProperty('thumbs:up:user_guids') || !array[index]['thumbs:up:user_guids'])
						array[index]['thumbs:up:user_guids'] = [];

					for(var key in array[index]['thumbs:up:user_guids']){
							if(array[index]['thumbs:up:user_guids'][key] === storage.get('user_guid')){
								delete array[index]['thumbs:up:user_guids'][key];
								array[index]['thumbs:up:count'] = array[index]['thumbs:up:count'] -1;
								//remove count
								$rootScope.points = $rootScope.points - 2;
								return true;
							}
					}

					array[index]['thumbs:up:user_guids'][1] = storage.get('user_guid');
					array[index]['thumbs:up:count'] = array[index]['thumbs:up:count'] +1;

				}
			});

			Client.put('api/v1/thumbs/'+guid+'/up', {},
				function(success){

				},
				function(error){
					alert('failed..');
				});

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Thumb down an activity
		 */
		$scope.thumbsDown = function(guid){
			//increment count
			$rootScope.points = $rootScope.points + 1;

			if($scope.ChannelItems)
				$scope.newsfeedItems = $scope.ChannelItems;

			if($scope.activity)
				$scope.newsfeedItems[0] = $scope.activity;

			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == guid){
					if(!array[index].hasOwnProperty('thumbs:down:user_guids') || !array[index]['thumbs:down:user_guids'])
						array[index]['thumbs:down:user_guids'] = [];

					for(var key in array[index]['thumbs:down:user_guids']){
						if(array[index]['thumbs:down:user_guids'][key] === storage.get('user_guid')){
							delete array[index]['thumbs:down:user_guids'][key];
							array[index]['thumbs:down:count'] = array[index]['thumbs:down:count'] -1;
							//remove count
							$rootScope.points = $rootScope.points - 2;
							return true;
						}
					}

					array[index]['thumbs:down:user_guids'][1] = storage.get('user_guid');
					array[index]['thumbs:down:count'] = array[index]['thumbs:down:count'] +1;

				}
			});

			Client.put('api/v1/thumbs/'+guid+'/down', {},
				function(success){

				},
				function(error){
					alert('failed..');
				});

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Load comments
		 */
		$scope.commentsData = {};
		$scope.loadComments = function(activity, $event){
			$scope.comments.show($event);
			$scope.commentsData = {};

			var guid;
			if(activity.entity_guid){
				guid = activity.entity_guid;
			} else {
				guid = activity.guid;
			}

			/**
			 * Now load the comments
			 */
			Client.get('api/v1/comments/'+guid, {
					cachebreaker: Date.now
				},
				function(success){
					console.log('success for ' + guid );
					console.log(success);
					$scope.commentsData = success.comments;
				}, function(error){
					console.log('error');
				});

		};
		$ionicPopover.fromTemplateUrl('templates/comments/list.html', {
		    scope: $scope,
		  }).then(function(popover) {
		    $scope.comments = popover;
		  });

		/**
		 * Remind an activity
		 */
		$scope.remind = function(activity, $event){

			Client.post('api/v1/newsfeed/remind/'+activity.guid, {},
					function(success){

					},
					function(error){
						alert('failed..');
					});

			/**
			 * @todo improve this way of updating!
			 */
			$scope.newsfeedItems.forEach(function(item, index, array){
				if(item.guid == activity.guid){
					array[index].reminds = array[index].reminds + 1;
				}
			});
			if($scope.ChannelItems){
				$scope.ChannelItems.forEach(function(item, index, array){
					if(item.guid == activity.guid){
						array[index].reminds = array[index].reminds + 1;
					}
				});
			}

			if($scope.activity){
				$scope.activity.reminds = $scope.activity.reminds + 1;
			}

			//increment count
			$rootScope.points = $rootScope.points + 1;

			$ionicLoading.show({
				template: ''
				});
			$timeout(function(){
				$ionicLoading.hide();
				}, 1000);
		};

		/**
		 * Init the composer popover
		 */
		$scope.composerData = {};
		$ionicPopover.fromTemplateUrl('templates/newsfeed/compose.html', {
		    scope: $scope,
		  }).then(function(popover) {
		    $scope.composer = popover;
		  });

		var posting;
		$scope.post = function(){
			if(posting)
				return false;

			console.log("posting");
			$ionicLoading.show({
		      template: 'Please wait a moment...'
		    });
		    var posting = true;

    		NewsfeedAPI.post({
    			message: $scope.composerData.message
	    	}, function(success){
	    		$scope.refresh();
	    		$scope.message = '';
	    		$scope.composer.hide();

	    		$ionicLoading.hide();
	    		posting = false;
	    	}, function(error){
	    		alert('there was an error and we couldn\'t save!');
	    		$ionicLoading.hide();
	    		posting = false;
	    	});

		};

		$scope.remove = function(guid){
			console.log('api/v1/newsfeed/'+guid);
			Client.delete('api/v1/newsfeed/'+guid, {
					cachebreaker: Date.now
				},
				function(success){
					console.log(success);
					$scope.newsfeedItems.forEach(function(item, index, array){
						if(item.guid == guid){
							console.log('removed');
							array.splice(index, 1);
						}
					});
					if($scope.ChannelItems){
						$scope.ChannelItems.forEach(function(item, index, array){
							if(item.guid == guid){
								console.log('removed');
								array.splice(index, 1);
							}
						});
					}
				}, function(error){
					console.log('error');
				});
		};

		$scope.loadNotifications = function(){
			$state.go('tab.more-notifications', {}, {reload:true});
		};

		var timeout;
		$scope.openUrl = function(url){
			$timeout.cancel(timeout);

			timeout = $timeout( function(){
				window.open(url, "_blank", "location=yes");
			}, 300);
		};

		$scope.boost = function(activity){
			$ionicModal.fromTemplateUrl('templates/newsfeed/boost.html', {
			    	 		    scope: $scope,
			    	 		    animation: 'slide-in-up'
			    	 		  }).then(function(modal) {
			    	 		    $scope.modal = modal;
			    	 		    $scope.guid = activity.guid;
			    	 		    $scope.owner_guid = activity.owner_guid;
			    	 		    $scope.modal.show();
			    	 		  });
		};

		$scope.openActions = function(activity){
			var guid = activity.guid;
			$ionicActionSheet.show({
			     buttons: [
			       //{ text: 'Share This' },
			       { text: 'Boost' },
			       { text: 'Share' },
			       { text: 'Download' },
			       { text: 'Report this' }
			     ],
			     destructiveText: 'Delete',
			     destructiveButtonClicked: function(){
			     	if(activity.p2p_boosted){
			     		$ionicLoading.show({
			    				template: 'Sorry, you can not delete a boosted post.'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);
			    		return false;
			     	}

			     	if(activity.owner_guid != $rootScope.user_guid){

			     		$ionicLoading.show({
			    				template: 'Sorry, you can not delete posts that are not yourss.'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);

			    		return false;

			     	}

			     	if(confirm("are you sure?"))
			    		 $scope.remove(guid);
			    	 return true;

			     },
			     cancelText: 'Cancel',
			     cancel: function() {
			          // add cancel code..
			        },
			     buttonClicked: function(index) {
			    	 switch(index){
			    	 	case 0:
			    	 		$scope.boost(activity);

			    	 		break;
			    	 	case 1:
			    	 		/*cordova.plugins.clipboard.copy($rootScope.node_url + 'newsfeed/' + guid);
			    	 		$ionicLoading.show({
			    				template: '
 Copied to clipboard
'
			    				});
			    			$timeout(function(){
			    				$ionicLoading.hide();
			    				}, 1000);
			    	 		break;*/
			    	 		window.plugins.socialsharing.share('via minds', null, null, $rootScope.node_url + 'newsfeed/' + guid);
			    	 	case 2:

			    	 		window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs){
			    	 			var ft = new FileTransfer();
			    	 			console.log(fs.root.toURL());
			    	 			fs.root.getDirectory('minds', { create: true, exclusive: false }, function(){}, function(){});
				    	 		ft.download(
				    	 			    activity.custom_data[0].src,
				    	 			    fs.root.toURL() + "minds/" + guid + '.jpg',
				    	 			    function(entry) {
				    	 			        console.log("download complete: " + entry.toURL());
				    	 			    },
				    	 			    function(error) {
				    	 			        console.log("download error source " + error.source);
				    	 			        console.log("download error target " + error.target);
				    	 			        console.log("upload error code" + error.code);
				    	 			    },
				    	 			    false
				    	 			);
			    	 			});
			    	 		break;
			    	 	case 3:
			    	 		window.location.href = "mailto:report@minds.com?subject=Report " + guid + "&body=This content violates the terms and conditions";
			    	 }
			       return true;
			     }
			   });

		};

    }

    ctrl.$inject = ['$rootScope', '$scope', '$state', '$stateParams', 'NewsfeedAPI', '$filter', '$ionicScrollDelegate', 'Cacher', 'Client', 'storage', '$ionicPopover', '$ionicLoading', '$timeout', '$ionicActionSheet', '$ionicModal', '$ionicPlatform'];
    return ctrl;

});<|endoftext|>


<commit_before>/**
 * Created by Gaplo917 on 11/1/2016.
 */
import * as Controllers from './index'
import swal from 'sweetalert2'
import { Bridge, Channel } from '../bridge/index'

export class ChatDetailController {
  static get STATE () { return 'tab.features-chat-detail' }

  static get NAME () { return 'ChatDetailController' }

  static get CONFIG () {
    return {
      url: '/features/chats/:id',
      cache: false,
      views: {
        main: {
          templateUrl: 'templates/features/chats/chats.details.html',
          controller: ChatDetailController.NAME,
          controllerAs: 'vm'
        }
      }
    }
  }

  constructor ($scope, apiService, $stateParams, $ionicScrollDelegate, ngToast, $ionicHistory, $state, $compile, $timeout) {
    this.scope = $scope
    this.apiService = apiService
    this.ionicScrollDelegate = $ionicScrollDelegate.$getByHandle('chat-detail-scroll')
    this.ngToast = ngToast
    this.ionicHistory = $ionicHistory
    this.state = $state
    this.compile = $compile
    this.messageInput = ''
    this.$timeout = $timeout

    this.recipientId = $stateParams.id
    this.messages = null

    $scope.$on('$ionicView.loaded', (e) => {
      this.loadMessages()
    })
  }

  loadMessages () {
    this.apiService
      .chatDetails(this.recipientId)
      .safeApply(this.scope, ({ username, messages, actionUrl, hiddenFormInputs }) => {
        swal.close()

        // must exist in the list
        this.recipient = {
          id: this.recipientId,
          username: username
        }

        this.messages = messages

        // scroll to bottom
        this.ionicScrollDelegate.scrollBottom(false)

        this.actionUrl = actionUrl
        this.hiddenFormInputs = hiddenFormInputs
      }).subscribe()
  }

  sendMessage () {
    const { $timeout, actionUrl, hiddenFormInputs, messageInput: message } = this
    if (message === '') {
      // empty input
      this.ngToast.danger(`<i class="ion-alert-circled"> 不能發送空白訊息！</i>`)
      return
    }
    const spinnerHtml = `

傳送到 HKEPC 伺服器中

            `

    swal({
      animation: false,
      html: spinnerHtml,
      allowOutsideClick: false,
      showCancelButton: false,
      showConfirmButton: false
    })

    swal.showLoading()

    // Post to the server
    this.apiService.dynamicRequest({
      method: 'POST',
      url: actionUrl,
      data: {
        message: message,
        ...hiddenFormInputs
      },
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    }).safeApply(this.scope, (resp) => {
      $timeout(() => this.doRefresh(), 500)
    }).subscribe()
  }

  doRefresh () {
    this.messageInput = ''
    this.loadMessages()
  }

  onBack () {
    if (this.ionicHistory.viewHistory().currentView.index !== 0) {
      this.ionicHistory.goBack()
    } else {
      this.ionicHistory.nextViewOptions({
        disableAnimate: true,
        disableBack: true
      })
      this.state.go(Controllers.ChatListController.STATE)
    }
  }

  requestComposeDialog () {
    if (Bridge.isAvailable()) {
      Bridge.callHandler(Channel.composeDialog, {
        title: `發送訊息`,
        positiveText: '發送',
        cancelText: '取消'
      }, (content) => {
        if (content === null) {
          // cancelled
          return
        }
        this.messageInput = content
        this.sendMessage()
      })
    }
  }

  loadLazyImage (uid, imageSrc) {
    const image = document.getElementById(uid)
    if (image.getAttribute('src') === imageSrc) {
      window.open(imageSrc, '_system', 'location=yes')
    } else {
      image.setAttribute('src', imageSrc)
    }
  }

  openImage (uid, imageSrc) {
    window.open(imageSrc, '_system', 'location=yes')
  }
}
<commit_msg>add placeholder field to native<commit_after>/**
 * Created by Gaplo917 on 11/1/2016.
 */
import * as Controllers from './index'
import swal from 'sweetalert2'
import { Bridge, Channel } from '../bridge/index'

export class ChatDetailController {
  static get STATE () { return 'tab.features-chat-detail' }

  static get NAME () { return 'ChatDetailController' }

  static get CONFIG () {
    return {
      url: '/features/chats/:id',
      cache: false,
      views: {
        main: {
          templateUrl: 'templates/features/chats/chats.details.html',
          controller: ChatDetailController.NAME,
          controllerAs: 'vm'
        }
      }
    }
  }

  constructor ($scope, apiService, $stateParams, $ionicScrollDelegate, ngToast, $ionicHistory, $state, $compile, $timeout) {
    this.scope = $scope
    this.apiService = apiService
    this.ionicScrollDelegate = $ionicScrollDelegate.$getByHandle('chat-detail-scroll')
    this.ngToast = ngToast
    this.ionicHistory = $ionicHistory
    this.state = $state
    this.compile = $compile
    this.messageInput = ''
    this.$timeout = $timeout

    this.recipientId = $stateParams.id
    this.messages = null

    $scope.$on('$ionicView.loaded', (e) => {
      this.loadMessages()
    })
  }

  loadMessages () {
    this.apiService
      .chatDetails(this.recipientId)
      .safeApply(this.scope, ({ username, messages, actionUrl, hiddenFormInputs }) => {
        swal.close()

        // must exist in the list
        this.recipient = {
          id: this.recipientId,
          username: username
        }

        this.messages = messages

        // scroll to bottom
        this.ionicScrollDelegate.scrollBottom(false)

        this.actionUrl = actionUrl
        this.hiddenFormInputs = hiddenFormInputs
      }).subscribe()
  }

  sendMessage () {
    const { $timeout, actionUrl, hiddenFormInputs, messageInput: message } = this
    if (message === '') {
      // empty input
      this.ngToast.danger(`<i class="ion-alert-circled"> 不能發送空白訊息！</i>`)
      return
    }
    const spinnerHtml = `

傳送到 HKEPC 伺服器中

            `

    swal({
      animation: false,
      html: spinnerHtml,
      allowOutsideClick: false,
      showCancelButton: false,
      showConfirmButton: false
    })

    swal.showLoading()

    // Post to the server
    this.apiService.dynamicRequest({
      method: 'POST',
      url: actionUrl,
      data: {
        message: message,
        ...hiddenFormInputs
      },
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    }).safeApply(this.scope, (resp) => {
      $timeout(() => this.doRefresh(), 500)
    }).subscribe()
  }

  doRefresh () {
    this.messageInput = ''
    this.loadMessages()
  }

  onBack () {
    if (this.ionicHistory.viewHistory().currentView.index !== 0) {
      this.ionicHistory.goBack()
    } else {
      this.ionicHistory.nextViewOptions({
        disableAnimate: true,
        disableBack: true
      })
      this.state.go(Controllers.ChatListController.STATE)
    }
  }

  requestComposeDialog () {
    if (Bridge.isAvailable()) {
      Bridge.callHandler(Channel.composeDialog, {
        title: `發送訊息`,
        positiveText: '發送',
        cancelText: '取消',
        placeholder: '訊息'
      }, (content) => {
        if (content === null) {
          // cancelled
          return
        }
        this.messageInput = content
        this.sendMessage()
      })
    }
  }

  loadLazyImage (uid, imageSrc) {
    const image = document.getElementById(uid)
    if (image.getAttribute('src') === imageSrc) {
      window.open(imageSrc, '_system', 'location=yes')
    } else {
      image.setAttribute('src', imageSrc)
    }
  }

  openImage (uid, imageSrc) {
    window.open(imageSrc, '_system', 'location=yes')
  }
}
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var DOMElement = require('./DOMElement');
var GameObjectFactory = require('../GameObjectFactory');

/**
 * Creates a new Image Game Object and adds it to the Scene.
 *
 * Note: This method will only be available if the Image Game Object has been built into Phaser.
 *
 * @method Phaser.GameObjects.GameObjectFactory#dom
 * @since 3.12.0
 *
 * @param {number} x - The horizontal position of this Game Object in the world.
 * @param {number} y - The vertical position of this Game Object in the world.
 * @param {string} element - The DOM element.
 *
 * @return {Phaser.GameObjects.DOMElement} The Game Object that was created.
 */
GameObjectFactory.register('dom', function (x, y, element)
{
    return this.displayList.add(new DOMElement(this.scene, x, y, element));
});

//  When registering a factory function 'this' refers to the GameObjectFactory context.
//
//  There are several properties available to use:
//
//  this.scene - a reference to the Scene that owns the GameObjectFactory
//  this.displayList - a reference to the Display List the Scene owns
//  this.updateList - a reference to the Update List the Scene owns
<commit_msg>More flexible Factory function including element, style and innerText setters<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2019 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var DOMElement = require('./DOMElement');
var GameObjectFactory = require('../GameObjectFactory');

/**
 * Creates a new DOM Element Game Object and adds it to the parent DOM Container.
 *
 * The game must have been configured with the `dom.createContainer` property set to `true` for this to work.
 *
 * Note: This method will only be available if the DOM Element Game Object has been built into Phaser.
 *
 * @method Phaser.GameObjects.GameObjectFactory#dom
 * @since 3.17.0
 *
 * @param {number} x - The horizontal position of this DOM Element in the world.
 * @param {number} y - The vertical position of this DOM Element in the world.
 * @param {(HTMLElement|string)} [element] - An existing DOM element, or a string. If a string starting with a # it will do a `getElementById` look-up on the string (minus the hash). Without a hash, it represents the type of element to create, i.e. 'div'.
 * @param {(string|any)} [style] - If a string, will be set directly as the elements `style` property value. If a plain object, will be iterated and the values transferred. In both cases the values replacing whatever CSS styles may have been previously set.
 * @param {string} [innerText] - If given, will be set directly as the elements `innerText` property value, replacing whatever was there before.
 *
 * @return {Phaser.GameObjects.DOMElement} The Game Object that was created.
 */
GameObjectFactory.register('dom', function (x, y, element, style, innerText)
{
    return this.displayList.add(new DOMElement(this.scene, x, y, element, style, innerText));
});
<|endoftext|>