<commit_before>/** @jsx h */
import { h, Component } from 'preact';

import audio from '../../audio';
import viewer from '../../viewer';
import Room from '../../room';
import layout from '../../room/layout';
import feature from '../../utils/feature';
import { waitRoomColor, getRoomColor } from '../../theme/colors';
import recording from '../../recording';

import RecordOrbs from '../RecordOrbs';

const state = {};

export default class RoomComponent extends Component {
  constructor() {
    super();
    this.performOrbLeftRoom = this.performOrbLeftRoom.bind(this);
    this.performOrbEnteredRoom = this.performOrbEnteredRoom.bind(this);
    this.receiveOrb = this.receiveOrb.bind(this);
    this.tick = this.tick.bind(this);
  }

  getChildContext() {
    return this.state;
  }

  componentDidMount() {
    this.mounted = true;
    this.asyncMount(this.props);
    const { roomId } = this.props;
    this.roomColor = getRoomColor(roomId);
  }

  componentWillUnmount() {
    this.mounted = false;
    viewer.camera.position.copy(state.originalCameraPosition);
    viewer.camera.zoom = state.originalZoom;
    viewer.camera.updateProjectionMatrix();
    audio.reset();
    audio.fadeOut();
    if (this.state.room) {
      this.state.room.destroy();
    }
    viewer.camera.position.y = 0;
    viewer.camera.updateProjectionMatrix();
    viewer.events.off('tick', this.tick);
  }

  async asyncMount({ roomId, id, record }) {
    Room.reset();
    state.originalCameraPosition = viewer.camera.position.clone();
    state.originalZoom = viewer.camera.zoom;
    if (!record) {
      viewer.switchCamera('orthographic');
      viewer.camera.position.y = 2;
      viewer.camera.position.z = 1.3;
      viewer.camera.updateProjectionMatrix();
      Room.rotate180();
    }

    await audio.load({
      src: `/public/sound/room-${layout.loopIndex(roomId)}.${feature.isChrome ? 'ogg' : 'mp3'}`,
      loops: 2,
      loopOffset: 0.5,
    });
    if (!this.mounted) return;
    const room = new Room({
      id,
      index: roomId - 1,
      single: true,
      recording: record ? recording : null,
    });
    if (id) {
      audio.play();
      room.load();
    }
    this.setState({ room });
    viewer.events.on('tick', this.tick);
  }

  performOrbLeftRoom() {
    if (!this.state.room) return;
    this.state.room.changeColor(waitRoomColor);

    const { onOrbLeftRoom } = this.props;
    if (onOrbLeftRoom) {
      onOrbLeftRoom();
    }
  }

  performOrbEnteredRoom() {
    const { room } = this.state;
    if (!room) return;
    if (room && this.roomColor) {
      room.changeColor(this.roomColor);
    }

    const { onOrbEnteredRoom } = this.props;
    if (onOrbEnteredRoom) {
      onOrbEnteredRoom();
    }
  }

  receiveOrb(orb) {
    this.setState({ orb });
  }

  tick() {
    const layers = this.props.layers
      ? Math.min(Math.floor(audio.totalProgress) + 1, this.props.layers)
      : null;
    this.state.room.gotoTime(audio.time, layers);
  }

  render() {
    return (

        {this.props.orbs &&
          <RecordOrbs
            onEnteredRoom={this.performOrbEnteredRoom}
            onLeftRoom={this.performOrbLeftRoom}
            onCreatedOrb={this.receiveOrb}
            reversed={this.props.reverseOrbs}
          />
        }
        {this.props.children}

    );
  }
}
<commit_msg>check for undefined<commit_after>/** @jsx h */
import { h, Component } from 'preact';

import audio from '../../audio';
import viewer from '../../viewer';
import Room from '../../room';
import layout from '../../room/layout';
import feature from '../../utils/feature';
import { waitRoomColor, getRoomColor } from '../../theme/colors';
import recording from '../../recording';

import RecordOrbs from '../RecordOrbs';

const state = {};

export default class RoomComponent extends Component {
  constructor() {
    super();
    this.performOrbLeftRoom = this.performOrbLeftRoom.bind(this);
    this.performOrbEnteredRoom = this.performOrbEnteredRoom.bind(this);
    this.receiveOrb = this.receiveOrb.bind(this);
    this.tick = this.tick.bind(this);
  }

  getChildContext() {
    return this.state;
  }

  componentDidMount() {
    this.mounted = true;
    this.asyncMount(this.props);
    const { roomId } = this.props;
    this.roomColor = getRoomColor(roomId);
  }

  componentWillUnmount() {
    this.mounted = false;
    viewer.camera.position.copy(state.originalCameraPosition);
    viewer.camera.zoom = state.originalZoom;
    viewer.camera.updateProjectionMatrix();
    audio.reset();
    audio.fadeOut();
    if (this.state.room) {
      this.state.room.destroy();
    }
    viewer.camera.position.y = 0;
    viewer.camera.updateProjectionMatrix();
    viewer.events.off('tick', this.tick);
  }

  async asyncMount({ roomId, id, record }) {
    Room.reset();
    state.originalCameraPosition = viewer.camera.position.clone();
    state.originalZoom = viewer.camera.zoom;
    if (!record) {
      viewer.switchCamera('orthographic');
      viewer.camera.position.y = 2;
      viewer.camera.position.z = 1.3;
      viewer.camera.updateProjectionMatrix();
      Room.rotate180();
    }

    await audio.load({
      src: `/public/sound/room-${layout.loopIndex(roomId)}.${feature.isChrome ? 'ogg' : 'mp3'}`,
      loops: 2,
      loopOffset: 0.5,
    });
    if (!this.mounted) return;
    const room = new Room({
      id,
      index: roomId - 1,
      single: true,
      recording: record ? recording : null,
    });
    if (id) {
      audio.play();
      room.load();
    }
    this.setState({ room });
    viewer.events.on('tick', this.tick);
  }

  performOrbLeftRoom() {
    if (!this.state.room) return;
    this.state.room.changeColor(waitRoomColor);

    const { onOrbLeftRoom } = this.props;
    if (onOrbLeftRoom) {
      onOrbLeftRoom();
    }
  }

  performOrbEnteredRoom() {
    const { room } = this.state;
    if (!room) return;
    if (room && this.roomColor) {
      room.changeColor(this.roomColor);
    }

    const { onOrbEnteredRoom } = this.props;
    if (onOrbEnteredRoom) {
      onOrbEnteredRoom();
    }
  }

  receiveOrb(orb) {
    this.setState({ orb });
  }

  tick() {
    const layers = this.props.layers !== undefined
      ? Math.min(Math.floor(audio.totalProgress) + 1, this.props.layers)
      : null;
    this.state.room.gotoTime(audio.time, layers);
  }

  render() {
    return (

        {this.props.orbs &&
          <RecordOrbs
            onEnteredRoom={this.performOrbEnteredRoom}
            onLeftRoom={this.performOrbLeftRoom}
            onCreatedOrb={this.receiveOrb}
            reversed={this.props.reverseOrbs}
          />
        }
        {this.props.children}

    );
  }
}
<|endoftext|>


<commit_before>/*
 * Displays a single conversation/dialog. Also the input
 */

import React from 'react'
import PropTypes from 'prop-types'
import Immutable from 'immutable'
import styled from 'styled-components'

const Main = styled.div`
  margin: 0.3em;
  display: flex;
  flex-direction: column;
`

const MessageList = styled.div`
  flex: 1 1 100%;
`

const Message = styled.div`
  & > span {
    padding-right: 0.3em;
    font-size: 120%;
  }
`

const AvatarName = styled.span`
  :after {
    content: ":";
  }
`

const ChatTextSend = styled.div`
  margin: .4em;
  display: flex;
  flex-direction: row;
`

const SendButton = styled.button`
  flex: 1 0 auto;
`

const TextBox = styled.input`
  flex: 4 0 auto;
  margin-right: 0.5em;
`

// Adds to all Numbers a leading zero if it has only one digit
function leadingZero (num) {
  return String(num).padStart(2, '0')
}

export default class ChatDialog extends React.Component {
  constructor () {
    super()
    this.state = {
      text: ''
    }
  }

  componentDidMount () {
    const isIM = this.props.isIM
    const data = this.props.data
    if (isIM && !data.get('didLoadHistory') && !data.get('isLoadingHistory')) {
      this.props.loadHistory(data.get('chatUUID'))
    }
  }

  render () {
    const msgData = this.props.isIM ? this.props.data.get('messages') : this.props.data
    const messages = msgData.map(msg => {
      const time = new Date(msg.get('time'))
      const fromId = this.props.isIM ? msg.get('fromId') : msg.get('sourceID')
      const name = this.props.names.get(fromId) || ''
      return (
        <Message key={time.getTime()}>

            {leadingZero(time.getHours())}
            :
            {leadingZero(time.getMinutes())}
            :
            {leadingZero(time.getSeconds())}

          <AvatarName>{name.toString()}</AvatarName>
          {msg.get('message')}
        </Message>
      )
    })

    const placeholderText = 'Send ' +
      (this.props.isIM ? 'Instant Message' : 'to local chat')

    return
      <MessageList>
        {messages}
      </MessageList>
      <ChatTextSend>
        <TextBox
          type='text'
          name='chatInput'
          placeholder={placeholderText}
          value={this.state.text}
          onChange={this._onChange.bind(this)}
          onKeyDown={this._onKeyDown.bind(this)} />
        <SendButton onClick={this._onClick.bind(this)}>
          send
        </SendButton>
      </ChatTextSend>

  }

  _onChange (event, value) {
    this.setState({
      text: event.target.value
    })
  }

  _onKeyDown (event) {
    if (event.keyCode === 13) {
      event.preventDefault()
      const text = this.state.text.trim()
      if (text) {
        this.props.sendTo(text)
      }
      this.setState({
        text: ''
      })
    }
  }

  _onClick (event) {
    event.preventDefault()
    const text = this.state.text.trim()
    if (text) {
      this.props.sendTo(text)
    }
    this.setState({
      text: ''
    })
  }
}

ChatDialog.displayName = 'ChatDialog'
// https://facebook.github.io/react/docs/typechecking-with-proptypes.html
ChatDialog.propTypes = {
  data: PropTypes.oneOfType([
    PropTypes.instanceOf(Immutable.List),
    PropTypes.instanceOf(Immutable.Map)
  ]).isRequired,
  names: PropTypes.instanceOf(Immutable.Map).isRequired,
  sendTo: PropTypes.func.isRequired,
  isIM: PropTypes.bool
}
ChatDialog.defaultProps = {
  isIM: false,
  data: []
}
<commit_msg>fix(chatDialog): make chatDialog scrollable<commit_after>/*
 * Displays a single conversation/dialog. Also the input
 */

import React from 'react'
import PropTypes from 'prop-types'
import Immutable from 'immutable'
import styled from 'styled-components'

const Main = styled.div`
  margin: 0.3em;
  display: flex;
  flex-direction: column;
`

const MessageList = styled.div`
  flex: 1 1 100%;
  overflow-y: scroll;
  max-height: calc(100vh - 8em);
`

const Message = styled.div`
  & > span {
    padding-right: 0.3em;
    font-size: 120%;
  }
`

const AvatarName = styled.span`
  :after {
    content: ":";
  }
`

const ChatTextSend = styled.div`
  margin: .4em;
  display: flex;
  flex-direction: row;
`

const SendButton = styled.button`
  flex: 1 0 auto;
`

const TextBox = styled.input`
  flex: 4 0 auto;
  margin-right: 0.5em;
`

// Adds to all Numbers a leading zero if it has only one digit
function leadingZero (num) {
  return String(num).padStart(2, '0')
}

export default class ChatDialog extends React.Component {
  constructor () {
    super()
    this.state = {
      text: ''
    }
  }

  componentDidMount () {
    const isIM = this.props.isIM
    const data = this.props.data
    if (isIM && !data.get('didLoadHistory') && !data.get('isLoadingHistory')) {
      this.props.loadHistory(data.get('chatUUID'))
    }
  }

  render () {
    const msgData = this.props.isIM ? this.props.data.get('messages') : this.props.data
    const messages = msgData.map(msg => {
      const time = new Date(msg.get('time'))
      const fromId = this.props.isIM ? msg.get('fromId') : msg.get('sourceID')
      const name = this.props.names.get(fromId) || ''
      return (
        <Message key={time.getTime()}>

            {leadingZero(time.getHours())}
            :
            {leadingZero(time.getMinutes())}
            :
            {leadingZero(time.getSeconds())}

          <AvatarName>{name.toString()}</AvatarName>
          {msg.get('message')}
        </Message>
      )
    })

    const placeholderText = 'Send ' +
      (this.props.isIM ? 'Instant Message' : 'to local chat')

    return
      <MessageList>
        {messages}
      </MessageList>
      <ChatTextSend>
        <TextBox
          type='text'
          name='chatInput'
          placeholder={placeholderText}
          value={this.state.text}
          onChange={this._onChange.bind(this)}
          onKeyDown={this._onKeyDown.bind(this)} />
        <SendButton onClick={this._onClick.bind(this)}>
          send
        </SendButton>
      </ChatTextSend>

  }

  _onChange (event, value) {
    this.setState({
      text: event.target.value
    })
  }

  _onKeyDown (event) {
    if (event.keyCode === 13) {
      event.preventDefault()
      const text = this.state.text.trim()
      if (text) {
        this.props.sendTo(text)
      }
      this.setState({
        text: ''
      })
    }
  }

  _onClick (event) {
    event.preventDefault()
    const text = this.state.text.trim()
    if (text) {
      this.props.sendTo(text)
    }
    this.setState({
      text: ''
    })
  }
}

ChatDialog.displayName = 'ChatDialog'
// https://facebook.github.io/react/docs/typechecking-with-proptypes.html
ChatDialog.propTypes = {
  data: PropTypes.oneOfType([
    PropTypes.instanceOf(Immutable.List),
    PropTypes.instanceOf(Immutable.Map)
  ]).isRequired,
  names: PropTypes.instanceOf(Immutable.Map).isRequired,
  sendTo: PropTypes.func.isRequired,
  isIM: PropTypes.bool
}
ChatDialog.defaultProps = {
  isIM: false,
  data: []
}
<|endoftext|>


<commit_before>const utilities = require('../utilities');
const rp = require('request-promise');
const localHost = 'http://localhost:3000/';
const webServer = 'http://159.65.75.193/';
const rootServer = '/';
const server = webServer;
/*This is supposed to be the workhorse to keep ptravels-map clean*/

export default class ClientApi {
    constructor(props) {
        this.getCoordsForSingleShow = this.getCoordsForSingleShow.bind(this);
    }
    getAllUserDataFromPhishnet = async(username) => {
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            return apiResponse;
        } catch (err) {
            console.log(err);
        };
    }

    getCoordsForSingleShow = async(username) => {
        /* Super messy, but finally works. */
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            // Get most recent show & turn it into an address string for geolookup:
            let showString = utilities.getMostRecentShowString(apiResponse);
            // Get showid
            let showid = utilities.getShowIdForLatest(apiResponse);

            const options2 = {
                uri: `${server}geodata/${showString}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Pass address string to geolookup:
            var geodata = await rp(options2)
            // Parse results and extract lat/lng into coords object
            var returnObj = utilities.getCoordsFromGeoData(geodata);
            returnObj.showid = showid;
            return returnObj;
        } catch (err) {
            console.log(err);
        };
    }

    getCoordsForAllShowsByUser = async(username) => {
        let returnArray = [];
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            // Loop through each show & turn it into an address string for geolookup:
            for (let individualShow of apiResponse) {
                let showidCoordsCombo = {
                    showid: [],
                    latLng: []
                };
                let showString = utilities.getShowString(individualShow);
                let showid = individualShow.showid
                showidCoordsCombo.showid.push(showid);

                const options2 = {
                    uri: `${server}geodata/${showString}`,
                    headers: {'User-Agent': 'Request-Promise'},
                    json: true
                };
                // Pass address string to geolookup:
                var geodata = await rp(options2);
                // We may get multiple address results, but for now just take the first.
                var latLongsArray = utilities.getCoordsArrayFromGeoData(geodata.results[0]);
                showidCoordsCombo.latLng.push(latLongsArray);
                returnArray.push(showidCoordsCombo)
            }
            return returnArray;
        } catch (err) {
            console.log(err);
        };
    }

    getSetlistInfoForSingleShow = async showid => {
        try {
            console.log("I'm client API, showId is : " + showid)
            const options = {
                uri: `${server}setlistinfo/${showid}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            let apiResponse = await rp(options);
            return apiResponse;
        } catch (err) {
            console.log(err);
        };
    }

    getInfoForSingleShowFromPhishin = async showdate => {
        try {
            const options = {
                uri: `${server}phishin/shows/${showdate}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            let apiResponse = await rp(options);
            console.log(apiResponse)
            if (apiResponse.success == false || apiResponse.data.venue == null) {
                apiResponse.success == false
                ? console.log(`showdate ${showdate} not found`)
                : apiResponse.data.venue == null ? console.log(`showdate ${showdate} venue is null`)
                : console.log(`ERROR! with if statement.`)
                return;
            }
            // Rearrange the object to be venue-lead
            let newObject = {
                venueid: apiResponse.data.venue.id,
                venue: apiResponse.data.venue,
                shows: [apiResponse.data],
            };
            delete newObject.shows[0].venue;
            return newObject;
        } catch (err) {
            console.log(err);
        };
    }
}<commit_msg>needed to update fetch uri for ssl<commit_after>const utilities = require('../utilities');
const rp = require('request-promise');
const localHost = 'https://localhost:3000/';
const webServer = 'https://159.65.75.193/';
const rootServer = '/';
const server = webServer;
/*This is supposed to be the workhorse to keep ptravels-map clean*/

export default class ClientApi {
    constructor(props) {
        this.getCoordsForSingleShow = this.getCoordsForSingleShow.bind(this);
    }
    getAllUserDataFromPhishnet = async(username) => {
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            return apiResponse;
        } catch (err) {
            console.log(err);
        };
    }

    getCoordsForSingleShow = async(username) => {
        /* Super messy, but finally works. */
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            // Get most recent show & turn it into an address string for geolookup:
            let showString = utilities.getMostRecentShowString(apiResponse);
            // Get showid
            let showid = utilities.getShowIdForLatest(apiResponse);

            const options2 = {
                uri: `${server}geodata/${showString}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Pass address string to geolookup:
            var geodata = await rp(options2)
            // Parse results and extract lat/lng into coords object
            var returnObj = utilities.getCoordsFromGeoData(geodata);
            returnObj.showid = showid;
            return returnObj;
        } catch (err) {
            console.log(err);
        };
    }

    getCoordsForAllShowsByUser = async(username) => {
        let returnArray = [];
        try {
            const options = {
                uri: `${server}usershows/${username}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            // Get all shows by user:
            let apiResponse = await rp(options);
            // Loop through each show & turn it into an address string for geolookup:
            for (let individualShow of apiResponse) {
                let showidCoordsCombo = {
                    showid: [],
                    latLng: []
                };
                let showString = utilities.getShowString(individualShow);
                let showid = individualShow.showid
                showidCoordsCombo.showid.push(showid);

                const options2 = {
                    uri: `${server}geodata/${showString}`,
                    headers: {'User-Agent': 'Request-Promise'},
                    json: true
                };
                // Pass address string to geolookup:
                var geodata = await rp(options2);
                // We may get multiple address results, but for now just take the first.
                var latLongsArray = utilities.getCoordsArrayFromGeoData(geodata.results[0]);
                showidCoordsCombo.latLng.push(latLongsArray);
                returnArray.push(showidCoordsCombo)
            }
            return returnArray;
        } catch (err) {
            console.log(err);
        };
    }

    getSetlistInfoForSingleShow = async showid => {
        try {
            console.log("I'm client API, showId is : " + showid)
            const options = {
                uri: `${server}setlistinfo/${showid}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            let apiResponse = await rp(options);
            return apiResponse;
        } catch (err) {
            console.log(err);
        };
    }

    getInfoForSingleShowFromPhishin = async showdate => {
        try {
            const options = {
                uri: `${server}phishin/shows/${showdate}`,
                headers: {'User-Agent': 'Request-Promise'},
                json: true
            };
            let apiResponse = await rp(options);
            console.log(apiResponse)
            if (apiResponse.success == false || apiResponse.data.venue == null) {
                apiResponse.success == false
                ? console.log(`showdate ${showdate} not found`)
                : apiResponse.data.venue == null ? console.log(`showdate ${showdate} venue is null`)
                : console.log(`ERROR! with if statement.`)
                return;
            }
            // Rearrange the object to be venue-lead
            let newObject = {
                venueid: apiResponse.data.venue.id,
                venue: apiResponse.data.venue,
                shows: [apiResponse.data],
            };
            delete newObject.shows[0].venue;
            return newObject;
        } catch (err) {
            console.log(err);
        };
    }
}<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router-dom';

import * as FetchAPI from '../fetch_data';

const parse = require('parse-diff');

/* DiffViewer loads a raw diff from Mozilla's hg-web and code coverage from
 * shiptit-uplift to show a diff with code coverage information for added
 * lines.
 */
export default class DiffViewerContainer extends Component {
  state = {
    appError: undefined,
    coverage: undefined,
    parsedDiff: []
  }

  componentDidMount() {
    const { changeset } = this.props;

    FetchAPI.getDiff(changeset).then(response =>
      response.text()
    ).then(text =>
      this.setState({ parsedDiff: parse(text) })
    ).catch(error =>
      this.setState({ appError: error })
    );

    FetchAPI.getChangesetCoverage(changeset).then(response =>
      response.text()
    ).then(text =>
      this.setState({ coverage: JSON.parse(text) })
    ).catch(error =>
      this.setState({ appError: error })
    );
  }

  render() {
    const { changeset } = this.props;
    const { appError, coverage, parsedDiff } = this.state;
    return (
      <DiffViewer
        appError={appError}
        changeset={changeset}
        coverage={coverage}
        parsedDiff={parsedDiff} />
    );
  }
}

const DiffViewer = ({ appError, changeset, coverage, parsedDiff }) => (

    <Link className="return-home" to="/">Return to main page</Link>
    <DiffViewerMeta appError={appError} changeset={changeset} />
    <CoverageMeta coverage={coverage} parsedDiff={parsedDiff} />

    {parsedDiff.map(
      (diffBlock, index) =>
        // We only push down the subset of code coverage data
        // applicable to a file
        (
          <DiffFile
            key={index}
            id={index}
            diffBlock={diffBlock}
            coverage={coverage} />
        )
    )}

);

const DiffViewerMeta = ({ appError, changeset }) => {
  const hgRev = `${FetchAPI.hgHost}/mozilla-central/rev/${changeset}`;
  const ccovUrl = `${FetchAPI.ccovBackend}/coverage/changeset/${changeset}`;

  return (

Link to Hg diff ({changeset})

Link to Code coverage backend

{appError}

  );
};

const NetCoverageContainer = ({ coverage, parsedDiff }) => {
  if (parsedDiff.length > 0) {
    const addedLines = parsedDiff.reduce((sum, file) => (
      sum + file.additions), 0);
    const coveredLines = (coverage.diffs.length !== 0) ?
      coverage.diffs.reduce((sum, file) => (
        ('changes' in file) ?
          sum + file.changes.reduce((acumm, lineCov) => (
              (lineCov.coverage === 'Y') ? acumm + 1 : acumm), 0) :
          sum), 0) : 0;

    let netGain = ((addedLines !== 0) ?
      (coveredLines / addedLines) * 100 : 0);
    netGain = netGain.toPrecision(3);

    return (<NetCoverage
      addedLines={addedLines}
      coveredLines={coveredLines}
      netGain={netGain} />);
  }
};

const NetCoverage = ({ addedLines, coveredLines, netGain }) => (

    {`New lines coverage change: ${netGain}% / `}
    {`Added lines: ${addedLines} / `}
    {`Covered lines: ${coveredLines}`}

);

const CoverageMeta = ({ coverage, parsedDiff }) => {
  let errorMessage;
  if (!coverage || coverage.error) {
    if (!coverage) {
      errorMessage = "We're waiting for coverage data from the backend.";
    } else if (coverage.error) {
      errorMessage = coverage.error;
    }
    return (

{errorMessage}

    );
  }

  if (coverage.diffs.length === 0) {
    errorMessage = 'This change does not have NEW LINES.';
  }

  const codecov = `https://codecov.io/gh/marco-c/gecko-dev/commit/${coverage.git_build_changeset}`;
  const gh = `https://github.com/mozilla/gecko-dev/commit/${coverage.git_build_changeset}`;

  return (

Link to Codecov

Link to GitHub

        {(parsedDiff.length > 0 && coverage) &&
          <NetCoverageContainer
            coverage={coverage}
            parsedDiff={parsedDiff} />}

{`Current coverage: ${coverage.overall_cur.substring(0, 4)}%`}

{`Build changeset: ${coverage.build_changeset}`}

{errorMessage}

  );
};

/* A DiffLine contains all diff changes for a specific file */
const DiffFile = ({ coverage, diffBlock }) => {
  // We try to see if the file modified shows up in the code
  // coverage data we have for this diff
  let coverageInfo;
  if (coverage) {
    coverageInfo = (coverage.diffs) ?
      coverage.diffs.find(info => info.name === diffBlock.from) : undefined;
  }

  return (

{diffBlock.from}

      {diffBlock.chunks.map((block, index) => (
        <DiffBlock
          key={index}
          block={block}
          coverageInfo={coverageInfo} />
      ))}

  );
};

/* A DiffBlock is *one* of the blocks changed for a specific file */
const DiffBlock = ({ block, coverageInfo }) => (

{block.content}

        {block.changes.map((change, index) => (
          <DiffLine
            key={index}
            id={index}
            change={change}
            coverageInfo={coverageInfo} />
         ))}

);

/* A DiffLine contains metadata about a line in a DiffBlock */
const DiffLine = ({ change, coverageInfo, id }) => {
  // Information about the line itself
  const c = change;
  // Added, deleted or unchanged line
  const changeType = change.type;
  // CSS tr and td classes
  let rowClass = 'nolinechange';
  const rowId = id;
  // Cell contents
  let [oldLineNumber, newLineNumber] = ['', ''];

  if (changeType === 'add') {
    // Added line - <blank> | <new line number>
    if (coverageInfo) {
      const { coverage } = coverageInfo.changes.find(lineCovInfo =>
        (lineCovInfo.new_line === c.ln));

      if (coverage === 'Y') {
        rowClass = 'hit';
      } else if (coverage === '?') {
        rowClass = 'nolinechange';
      } else {
        rowClass = 'miss'; // Let's start assuming a miss
      }
    }
    newLineNumber = c.ln;
  } else if (changeType === 'del') {
    // Removed line - <old line number> | <blank>
    oldLineNumber = c.ln;
  } else {
    // Unchanged line - <old line number> | <blank>
    oldLineNumber = c.ln1;
    if (oldLineNumber !== c.ln2) {
      newLineNumber = c.ln2;
    }
  }

  return (

      {oldLineNumber}
      {newLineNumber}

{c.content}

  );
};
<commit_msg>fix: Display app errors correctly<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router-dom';

import * as FetchAPI from '../fetch_data';

const parse = require('parse-diff');

/* DiffViewer loads a raw diff from Mozilla's hg-web and code coverage from
 * shiptit-uplift to show a diff with code coverage information for added
 * lines.
 */
export default class DiffViewerContainer extends Component {
  state = {
    appError: undefined,
    coverage: undefined,
    parsedDiff: []
  }

  componentDidMount() {
    const { changeset } = this.props;

    FetchAPI.getDiff(changeset).then(response =>
      response.text()
    ).then(text =>
      this.setState({ parsedDiff: parse(text) })
    ).catch((error) => {
      console.error(error);
      this.setState({
        appError: 'We did not manage to parse the diff correctly.'
      });
    });

    FetchAPI.getChangesetCoverage(changeset).then(response =>
      response.text()
    ).then(text =>
      this.setState({ coverage: JSON.parse(text) })
    ).catch((error) => {
      console.error(error);
      this.setState({
        appError: 'There was an error fetching the code coverage data.'
      });
    });
  }

  render() {
    const { changeset } = this.props;
    const { appError, coverage, parsedDiff } = this.state;
    return (
      <DiffViewer
        appError={appError}
        changeset={changeset}
        coverage={coverage}
        parsedDiff={parsedDiff} />
    );
  }
}

const DiffViewer = ({ appError, changeset, coverage, parsedDiff }) => (

    <Link className="return-home" to="/">Return to main page</Link>
    <DiffViewerMeta appError={appError} changeset={changeset} />
    <CoverageMeta coverage={coverage} parsedDiff={parsedDiff} />

    {parsedDiff.map(
      (diffBlock, index) =>
        // We only push down the subset of code coverage data
        // applicable to a file
        (
          <DiffFile
            key={index}
            id={index}
            diffBlock={diffBlock}
            coverage={coverage} />
        )
    )}

);

const DiffViewerMeta = ({ appError, changeset }) => {
  const hgRev = `${FetchAPI.hgHost}/mozilla-central/rev/${changeset}`;
  const ccovUrl = `${FetchAPI.ccovBackend}/coverage/changeset/${changeset}`;

  return (

Link to Hg diff ({changeset})

Link to Code coverage backend

{appError}

  );
};

const NetCoverageContainer = ({ coverage, parsedDiff }) => {
  if (parsedDiff.length > 0) {
    const addedLines = parsedDiff.reduce((sum, file) => (
      sum + file.additions), 0);
    const coveredLines = (coverage.diffs.length !== 0) ?
      coverage.diffs.reduce((sum, file) => (
        ('changes' in file) ?
          sum + file.changes.reduce((acumm, lineCov) => (
              (lineCov.coverage === 'Y') ? acumm + 1 : acumm), 0) :
          sum), 0) : 0;

    let netGain = ((addedLines !== 0) ?
      (coveredLines / addedLines) * 100 : 0);
    netGain = netGain.toPrecision(3);

    return (<NetCoverage
      addedLines={addedLines}
      coveredLines={coveredLines}
      netGain={netGain} />);
  }
};

const NetCoverage = ({ addedLines, coveredLines, netGain }) => (

    {`New lines coverage change: ${netGain}% / `}
    {`Added lines: ${addedLines} / `}
    {`Covered lines: ${coveredLines}`}

);

const CoverageMeta = ({ coverage, parsedDiff }) => {
  let errorMessage;
  if (!coverage || coverage.error) {
    if (!coverage) {
      errorMessage = "We're waiting for coverage data from the backend.";
    } else if (coverage.error) {
      errorMessage = coverage.error;
    }
    return (

{errorMessage}

    );
  }

  if (coverage.diffs.length === 0) {
    errorMessage = `There is no code coverage for this diff
                    or no new lines are being added to this diff.`;
  }

  const codecov = `https://codecov.io/gh/marco-c/gecko-dev/commit/${coverage.git_build_changeset}`;
  const gh = `https://github.com/mozilla/gecko-dev/commit/${coverage.git_build_changeset}`;

  return (

Link to Codecov

Link to GitHub

        {(parsedDiff.length > 0 && coverage) &&
          <NetCoverageContainer
            coverage={coverage}
            parsedDiff={parsedDiff} />}

{`Current coverage: ${coverage.overall_cur.substring(0, 4)}%`}

{`Build changeset: ${coverage.build_changeset}`}

{errorMessage}

  );
};

/* A DiffLine contains all diff changes for a specific file */
const DiffFile = ({ coverage, diffBlock }) => {
  // We try to see if the file modified shows up in the code
  // coverage data we have for this diff
  let coverageInfo;
  if (coverage) {
    coverageInfo = (coverage.diffs) ?
      coverage.diffs.find(info => info.name === diffBlock.from) : undefined;
  }

  return (

{diffBlock.from}

      {diffBlock.chunks.map((block, index) => (
        <DiffBlock
          key={index}
          block={block}
          coverageInfo={coverageInfo} />
      ))}

  );
};

/* A DiffBlock is *one* of the blocks changed for a specific file */
const DiffBlock = ({ block, coverageInfo }) => (

{block.content}

        {block.changes.map((change, index) => (
          <DiffLine
            key={index}
            id={index}
            change={change}
            coverageInfo={coverageInfo} />
         ))}

);

/* A DiffLine contains metadata about a line in a DiffBlock */
const DiffLine = ({ change, coverageInfo, id }) => {
  // Information about the line itself
  const c = change;
  // Added, deleted or unchanged line
  const changeType = change.type;
  // CSS tr and td classes
  let rowClass = 'nolinechange';
  const rowId = id;
  // Cell contents
  let [oldLineNumber, newLineNumber] = ['', ''];

  if (changeType === 'add') {
    // Added line - <blank> | <new line number>
    if (coverageInfo) {
      const { coverage } = coverageInfo.changes.find(lineCovInfo =>
        (lineCovInfo.new_line === c.ln));

      if (coverage === 'Y') {
        rowClass = 'hit';
      } else if (coverage === '?') {
        rowClass = 'nolinechange';
      } else {
        rowClass = 'miss'; // Let's start assuming a miss
      }
    }
    newLineNumber = c.ln;
  } else if (changeType === 'del') {
    // Removed line - <old line number> | <blank>
    oldLineNumber = c.ln;
  } else {
    // Unchanged line - <old line number> | <blank>
    oldLineNumber = c.ln1;
    if (oldLineNumber !== c.ln2) {
      newLineNumber = c.ln2;
    }
  }

  return (

      {oldLineNumber}
      {newLineNumber}

{c.content}

  );
};
<|endoftext|>


<commit_before>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var Lib = require('../../lib');
var constants = require('./constants');

// look for either subplot or xaxis and yaxis attributes
exports.getSubplot = function getSubplot(trace) {
    return trace.subplot || (trace.xaxis + trace.yaxis) || trace.geo;
};

// convenience functions for mapping all relevant axes
exports.flat = function flat(subplots, v) {
    var out = new Array(subplots.length);
    for(var i = 0; i < subplots.length; i++) {
        out[i] = v;
    }
    return out;
};

exports.p2c = function p2c(axArray, v) {
    var out = new Array(axArray.length);
    for(var i = 0; i < axArray.length; i++) {
        out[i] = axArray[i].p2c(v);
    }
    return out;
};

exports.getDistanceFunction = function getDistanceFunction(mode, dx, dy, dxy) {
    if(mode === 'closest') return dxy || quadrature(dx, dy);
    return mode === 'x' ? dx : dy;
};

exports.getClosest = function getClosest(cd, distfn, pointData) {
    // do we already have a point number? (array mode only)
    if(pointData.index !== false) {
        if(pointData.index >= 0 && pointData.index < cd.length) {
            pointData.distance = 0;
        }
        else pointData.index = false;
    }
    else {
        // apply the distance function to each data point
        // this is the longest loop... if this bogs down, we may need
        // to create pre-sorted data (by x or y), not sure how to
        // do this for 'closest'
        for(var i = 0; i < cd.length; i++) {
            var newDistance = distfn(cd[i]);
            if(newDistance <= pointData.distance) {
                pointData.index = i;
                pointData.distance = newDistance;
            }
        }
    }
    return pointData;
};

// for bar charts and others with finite-size objects: you must be inside
// it to see its hover info, so distance is infinite outside.
// But make distance inside be at least 1/4 MAXDIST, and a little bigger
// for bigger bars, to prioritize scatter and smaller bars over big bars
//
// note that for closest mode, two inbox's will get added in quadrature
// args are (signed) difference from the two opposite edges
// count one edge as in, so that over continuous ranges you never get a gap
exports.inbox = function inbox(v0, v1) {
    if(v0 * v1 < 0 || v0 === 0) {
        return constants.MAXDIST * (0.6 - 0.3 / Math.max(3, Math.abs(v0 - v1)));
    }
    return Infinity;
};

function quadrature(dx, dy) {
    return function(di) {
        var x = dx(di),
            y = dy(di);
        return Math.sqrt(x * x + y * y);
    };
}

/** Appends values inside array attributes corresponding to given point number
 *
 * @param {object} pointData : point data object (gets mutated here)
 * @param {object} trace : full trace object
 * @param {number} pointNumber : point number
 */
exports.appendArrayPointValue = function(pointData, trace, pointNumber) {
    var arrayAttrs = trace._arrayAttrs;

    for(var i = 0; i < arrayAttrs.length; i++) {
        var astr = arrayAttrs[i];
        var key;

        if(astr === 'ids') key = 'id';
        else if(astr === 'locations') key = 'location';
        else key = astr;

        if(pointData[key] === undefined) {
            var val = Lib.nestedProperty(trace, astr).get();
            pointData[key] = Array.isArray(pointNumber) ?
                val[pointNumber[0]][pointNumber[1]] :
                val[pointNumber];
        }
    }
};
<commit_msg>Fix hover error in appendArrayPointValue<commit_after>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var Lib = require('../../lib');
var constants = require('./constants');

// look for either subplot or xaxis and yaxis attributes
exports.getSubplot = function getSubplot(trace) {
    return trace.subplot || (trace.xaxis + trace.yaxis) || trace.geo;
};

// convenience functions for mapping all relevant axes
exports.flat = function flat(subplots, v) {
    var out = new Array(subplots.length);
    for(var i = 0; i < subplots.length; i++) {
        out[i] = v;
    }
    return out;
};

exports.p2c = function p2c(axArray, v) {
    var out = new Array(axArray.length);
    for(var i = 0; i < axArray.length; i++) {
        out[i] = axArray[i].p2c(v);
    }
    return out;
};

exports.getDistanceFunction = function getDistanceFunction(mode, dx, dy, dxy) {
    if(mode === 'closest') return dxy || quadrature(dx, dy);
    return mode === 'x' ? dx : dy;
};

exports.getClosest = function getClosest(cd, distfn, pointData) {
    // do we already have a point number? (array mode only)
    if(pointData.index !== false) {
        if(pointData.index >= 0 && pointData.index < cd.length) {
            pointData.distance = 0;
        }
        else pointData.index = false;
    }
    else {
        // apply the distance function to each data point
        // this is the longest loop... if this bogs down, we may need
        // to create pre-sorted data (by x or y), not sure how to
        // do this for 'closest'
        for(var i = 0; i < cd.length; i++) {
            var newDistance = distfn(cd[i]);
            if(newDistance <= pointData.distance) {
                pointData.index = i;
                pointData.distance = newDistance;
            }
        }
    }
    return pointData;
};

// for bar charts and others with finite-size objects: you must be inside
// it to see its hover info, so distance is infinite outside.
// But make distance inside be at least 1/4 MAXDIST, and a little bigger
// for bigger bars, to prioritize scatter and smaller bars over big bars
//
// note that for closest mode, two inbox's will get added in quadrature
// args are (signed) difference from the two opposite edges
// count one edge as in, so that over continuous ranges you never get a gap
exports.inbox = function inbox(v0, v1) {
    if(v0 * v1 < 0 || v0 === 0) {
        return constants.MAXDIST * (0.6 - 0.3 / Math.max(3, Math.abs(v0 - v1)));
    }
    return Infinity;
};

function quadrature(dx, dy) {
    return function(di) {
        var x = dx(di),
            y = dy(di);
        return Math.sqrt(x * x + y * y);
    };
}

/** Appends values inside array attributes corresponding to given point number
 *
 * @param {object} pointData : point data object (gets mutated here)
 * @param {object} trace : full trace object
 * @param {number} pointNumber : point number
 */
exports.appendArrayPointValue = function(pointData, trace, pointNumber) {
    var arrayAttrs = trace._arrayAttrs;

    if(!arrayAttrs) {
        return;
    }

    for(var i = 0; i < arrayAttrs.length; i++) {
        var astr = arrayAttrs[i];
        var key;

        if(astr === 'ids') key = 'id';
        else if(astr === 'locations') key = 'location';
        else key = astr;

        if(pointData[key] === undefined) {
            var val = Lib.nestedProperty(trace, astr).get();
            pointData[key] = Array.isArray(pointNumber) ?
                val[pointNumber[0]][pointNumber[1]] :
                val[pointNumber];
        }
    }
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import styled, { injectGlobal } from 'styled-components';
import * as Mousetrap from 'mousetrap';
import { withRouter } from 'react-router-dom';

import { baseAppColor } from 'constants/colors';
import { isElectron } from 'utils/electron';

import SuperSearch from 'components/layout/SuperSearch';
import KeyBindings from 'components/layout/KeyBindings';

// eslint-disable-next-line no-unused-expressions
injectGlobal`
  ::-webkit-scrollbar {
    width: 5px;
    margin: 0 20px 0 0;
  }

  ::-webkit-scrollbar-track {
    background: #fff;
  }

  ::-webkit-scrollbar-thumb {
    background: ${baseAppColor};
  }

  *:hover {
    transition: all .3s ease-in-out;
  }
`;

const AppWrapper = styled.div`
  display: flex;
  background: #fff;
  flex-direction: column;
  justify-content: flex-start;
  height: 100vh;
  color: ${baseAppColor};
`;

export class App  extends React.Component {
  state = {
    showSuperSearch: false,
    showKeyBindings: false
  };

  componentDidMount() {
    Mousetrap.bind(['shift shift', 'ctrl+f'], this.toggleSuperSesrch);
    Mousetrap.bind(['?'], this.toggleKeyBindings);
    Mousetrap.bind(['esc'], this.toggleAllOff);

    // Disallow to drop files
    document.addEventListener('dragover', (event) => event.preventDefault());
    document.addEventListener('dragenter', (event) => event.preventDefault());
    document.addEventListener('dragleave', (event) => event.preventDefault());
    document.addEventListener('drop', (event) => event.preventDefault());

    if (isElectron) {
      const { ipcRenderer } = require('electron');

      // Route if 'routeTo' event sent from main
      ipcRenderer.on('routeTo', (event, routeTo) => {
        this.props.history.push(routeTo);
      });
    }
  }

  componentWillUnmount() {
    Mousetrap.unbind(['shift shift', 'ctrl+f'], this.toggleSuperSesrch);
    Mousetrap.unbind(['?'], this.toggleKeyBindings);
    Mousetrap.unbind(['esc'], this.toggleAllOff);
  }

  toggleSuperSesrch = () => {
    this.setState((prevState) => ({
      showSuperSearch: !prevState.showSuperSearch
    }));
  };

  toggleKeyBindings = () => {
    this.setState((prevState) => ({
      showKeyBindings: !prevState.showKeyBindings
    }));
  };

  toggleAllOff = () => {
    this.setState({
      showKeyBindings: false,
      showSuperSearch: false
    });
  };

  render() {
    return (
      <AppWrapper>
        { this.props.children }
        { this.state.showSuperSearch && (
          <SuperSearch toggleSuperSesrch={ () => this.toggleSuperSesrch() }/>
        ) }
        { this.state.showKeyBindings && (<KeyBindings/>) }
      </AppWrapper>
    );
  }
}

App.propTypes = {
  children: PropTypes.node,
  history: PropTypes.object
};

export default withRouter(App);
<commit_msg>FIX (scrollbars): horizontal scrollbar size<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import styled, { injectGlobal } from 'styled-components';
import * as Mousetrap from 'mousetrap';
import { withRouter } from 'react-router-dom';

import { baseAppColor } from 'constants/colors';
import { isElectron } from 'utils/electron';

import SuperSearch from 'components/layout/SuperSearch';
import KeyBindings from 'components/layout/KeyBindings';

// eslint-disable-next-line no-unused-expressions
injectGlobal`
  ::-webkit-scrollbar {
    width: 5px;
    height: 5px;
  }

  ::-webkit-scrollbar-track {
    background: #fff;
  }

  ::-webkit-scrollbar-thumb {
    background: ${baseAppColor};
  }

  *:hover {
    transition: all .3s ease-in-out;
  }
`;

const AppWrapper = styled.div`
  display: flex;
  background: #fff;
  flex-direction: column;
  justify-content: flex-start;
  height: 100vh;
  color: ${baseAppColor};
`;

export class App  extends React.Component {
  state = {
    showSuperSearch: false,
    showKeyBindings: false
  };

  componentDidMount() {
    Mousetrap.bind(['shift shift', 'ctrl+f'], this.toggleSuperSesrch);
    Mousetrap.bind(['?'], this.toggleKeyBindings);
    Mousetrap.bind(['esc'], this.toggleAllOff);

    // Disallow to drop files
    document.addEventListener('dragover', (event) => event.preventDefault());
    document.addEventListener('dragenter', (event) => event.preventDefault());
    document.addEventListener('dragleave', (event) => event.preventDefault());
    document.addEventListener('drop', (event) => event.preventDefault());

    if (isElectron) {
      const { ipcRenderer } = require('electron');

      // Route if 'routeTo' event sent from main
      ipcRenderer.on('routeTo', (event, routeTo) => {
        this.props.history.push(routeTo);
      });
    }
  }

  componentWillUnmount() {
    Mousetrap.unbind(['shift shift', 'ctrl+f'], this.toggleSuperSesrch);
    Mousetrap.unbind(['?'], this.toggleKeyBindings);
    Mousetrap.unbind(['esc'], this.toggleAllOff);
  }

  toggleSuperSesrch = () => {
    this.setState((prevState) => ({
      showSuperSearch: !prevState.showSuperSearch
    }));
  };

  toggleKeyBindings = () => {
    this.setState((prevState) => ({
      showKeyBindings: !prevState.showKeyBindings
    }));
  };

  toggleAllOff = () => {
    this.setState({
      showKeyBindings: false,
      showSuperSearch: false
    });
  };

  render() {
    return (
      <AppWrapper>
        { this.props.children }
        { this.state.showSuperSearch && (
          <SuperSearch toggleSuperSesrch={ () => this.toggleSuperSesrch() }/>
        ) }
        { this.state.showKeyBindings && (<KeyBindings/>) }
      </AppWrapper>
    );
  }
}

App.propTypes = {
  children: PropTypes.node,
  history: PropTypes.object
};

export default withRouter(App);
<|endoftext|>


<commit_before>import { h, Component } from 'preact';

export default class SearchBar extends Component {

  onInputChange(query) {
    this.props.updateState({query});
  }

  onSortChange(order) {
    this.props.updateState({order});
  }

  render({query, order}) {
    return (

          <input
            className="search-bar"
            placeholder="Search..."
            value={query}
            onChange={event => this.onInputChange(event.target.value)}
          />

        <form className="search-order-container">

            <input id="stars" type="radio" name="order" value="stars" checked={order == 'stars'} onChange={event => this.onSortChange(event.target.id)} />

            <input id="forks" type="radio" name="order" value="forks" checked={order == 'forks'} onChange={event => this.onSortChange(event.target.id)} />

            <input id="updated" type="radio" name="order" value="updated" checked={order == 'updated'} onChange={event => this.onSortChange(event.target.id)} />

        </form>

    );
  }
};
<commit_msg>Added a function to render the search Options (#11)<commit_after>import { h, Component } from 'preact';

export default class SearchBar extends Component {

  onInputChange(query) {
    this.props.updateState({query});
  }

  onSortChange(order) {
    this.props.updateState({order});
  }

  renderSearchContainer(order, searchItems) {
    return searchItems.map(orderid =>

      <input id={orderid} type="radio" name="order" value={orderid} checked={order == orderid} onChange={event => this.onSortChange(event.target.id)} />
      <label className={`order-${orderid}`} htmlFor={orderid}>

);
  }

  render({query, order}) {
    return (

          <input
            className="search-bar"
            placeholder="Search..."
            value={query}
            onChange={event => this.onInputChange(event.target.value)}
          />

        <form className="search-order-container">
          {this.renderSearchContainer(order, ['stars', 'forks', 'updated'])}
        </form>

    );
  }
};
<|endoftext|>


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

class SearchBar extends Component {
  constructor(props) {
    super(props);

    this.state = { term: '' };

    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  };

  render() {
    const topicsStyle = {
      color: '#DF0101',
    };

    return (

          Topics ♫
          <input
            placeholder="Find super HQ music!"
            value={this.state.term}
            onChange={event => this.onInputChange(event.target.value)} onKeyPress={this.handleKeyPress}
            className="input" />
          <button
            onClick={event => this.handleClick(this.state.term)}
            className="button" >♫
          </button>

    );
  }

  onInputChange(term) { // Use on or handle
    this.setState({term});
    this.props.onSearchTermChange(term);
  }

  handleClick(term) {
    console.log(term);
    this.setState({term});
    this.props.onButtonPress(term);
  }

  handleKeyPress = (target) => {
    if (target.key == 'Enter') {
      console.log("Enter key has been pressed");
      this.handleClick(this.state.term);
    }
  }
}

export default SearchBar;
<commit_msg>jQuery selection, edited scss, added footer<commit_after>import React, { Component } from 'react';

class SearchBar extends Component {
  constructor(props) {
    super(props);

    this.state = { term: '' };

    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  };

  render() {
    const topicsStyle = {
      color: '#DF0101',
    };

    return (

          Topics ♫
          <input
            placeholder="Find super HQ music!"
            value={this.state.term}
            onChange={event => this.onInputChange(event.target.value)} onKeyPress={this.handleKeyPress}
            className="input" />
          <button
            onClick={event => this.handleClick(this.state.term)}
            className="button" >♫
          </button>

    );
  }

  onInputChange(term) { // Use on or handle
    this.setState({term});
    this.props.onSearchTermChange(term);
  }

  handleClick(term) {
    console.log(term);
    this.setState({term});
    this.props.onButtonPress(term);
  }

  handleKeyPress = (target) => {
    if (target.key == 'Enter') {
      console.log("Enter key has been pressed");
      this.handleClick(this.state.term);
    }
  }
}

export default SearchBar;
<|endoftext|>


<commit_before>'use strict';

import React, {
  AsyncStorage,
  Component,
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Modal from 'react-native-simple-modal';

import GridView from './grid-view';
import Profile from "../scenes/profile";
import SearchBar from './search-bar';

let database = new Firebase("poopapp1.firebaseio.com");

const windowSize = Dimensions.get('window');

class SmallPost extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false,
    };
  }

  render() {
    return (
      <View>
        <View style = {styles.item}>
          <TouchableOpacity
            style = {styles.photo}
            onPress = {() => this.picture()}>
            <Image
              style = {{flex: 1}}
              resizeMode = "cover"
              source = {{uri: this.state.photo}}>

              <View style = {styles.buttonContainer}>
              <TouchableOpacity
                style = {styles.button}
                onPress = {() => this.favorite()}>
                <Icon
                  name = "star"
                  size = {16}
                  color = {this.getFavoriteColor()}
                />
              </TouchableOpacity>

              <TouchableOpacity
                style = {styles.button}
                onPress = {() => this.messages()}>
                <Icon
                  name = "feedback"
                  size = {16}
                  color = "green"
                />
              </TouchableOpacity>
              </View>

            </Image>
          </TouchableOpacity>
          <View style = {styles.buttonView}>

          </View>
        </View>
        <Modal
           offset = {this.state.offset}
           open = {this.state.open}
           modalDidOpen = {() => console.log('modal did open')}
           modalDidClose = {() => this.setState({open: false})}
           style = {{alignItems: 'center', borderRadius: 20, margin: 0}}>
           <View>
              <View style = {{flexDirection: 'row', justifyContent: 'space-between'}}>
                <TouchableOpacity onPress = {() => {this.props.navigator.push({component: Profile, state: this.state.userID});}}>
                  <View style = {{flexDirection: 'row'}}>
                    <Image
                      resizeMode = "cover"
                      style = {{borderRadius: 90, width: 20, height: 20, marginRight: 4}}
                      source = {{uri: this.state.userPhoto}}
                    />
                    <Text>{this.state.user}</Text>
                  </View>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => this.setState({open: false})}>
                  <Icon name = "close"
                  size = {25}
                  borderWidth = {7}
                  color = "black"
                  />
                </TouchableOpacity>
              </View>
              <Image
                resizeMode = "cover"
                style = {{width: windowSize.width-10, height: windowSize.width-10}}
                source = {{uri: this.state.image}}
              />
              <View style = {styles.buttonViewModal}>
                <TouchableOpacity
                  style = {styles.button}
                  onPress = {() => {alert("Database access");}}>
                  <Icon
                    name = "star"
                    size = {28}
                    color = {(this.state.isFavorite) ? ("orange") : ("gray")}
                  />
                </TouchableOpacity>
                <TouchableOpacity
                  style = {styles.button}
                  onPress = {() => {alert("Go to messages page.");}}>
                  <Icon
                    name = "feedback"
                    size = {28}
                    color = "green"
                  />
                </TouchableOpacity>
              </View>
              <Text style={{marginTop: 5}}><Text style={{fontWeight: 'bold'}}>Description: </Text>{this.state.description}</Text>
           </View>
        </Modal>
      </View>
    );
  }

  componentDidMount() {
    var postSnapshot = this.props.id;
    var self = this;

    database.once("value", function(snapshot){
      var userid = postSnapshot.val().userID;
      var userSnapshot = snapshot.child("users/" + userid);
      var proPic = userSnapshot.val().profilePic;

      self.setState({
        postID: postSnapshot.key().toString(),
        userID: userid,
        user: postSnapshot.val().user,
        userPhoto: proPic,
        photo: postSnapshot.val().photoID,
        rating: postSnapshot.val().rating,
        description: postSnapshot.val().description,
        isFavorite: false,
      });
    });
  }

  picture() {
    // TODO
    alert("Pressed picture.");
    this.setState({open: true, image: this.state.photo});
  }

  favorite() {
    this.state.isFavorite = !this.state.isFavorite;
    // TODO: update database

    // this is probably bad because it rerenders the entire scene. only really needs to update the Icon's color prop
    this.forceUpdate();
  }

  messages() {
    alert("Go to messages page.");
  }

  getFavoriteColor() {
    if(this.state.isFavorite) {
      return "orange";
    } else {
      return "gray";
    }
  }
}

const styles = StyleSheet.create({
  item: {
    margin: 2,
  },
  photo: {
    width: windowSize.width / 3 - 6,
    height: windowSize.width / 3 - 6,
  },
  buttonView: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center'
  },
  buttonViewModal: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-start'
  },
  buttonContainer: {
    flexDirection: 'row',
    padding: 4,
    alignItems: 'center',
    justifyContent: 'center',
    color: 'black',
    opacity: 80
  },
  button: {
    marginLeft: 8,
    marginRight: 8,
    marginTop: 4,
    marginBottom: 4,
  }
});

module.exports = SmallPost;
<commit_msg>Fixed modal<commit_after>'use strict';

import React, {
  AsyncStorage,
  Component,
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  Modal
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/MaterialIcons';

import GridView from './grid-view';
import Profile from "../scenes/profile";
import SearchBar from './search-bar';

let database = new Firebase("poopapp1.firebaseio.com");

const windowSize = Dimensions.get('window');

class SmallPost extends Component {
  constructor(props) {
    super(props);
    this.state = {
      modalVisible: false,
    };
  }

  render() {
    return (
      <View>
        <View style = {styles.item}>
          <TouchableOpacity
            style = {styles.photo}
            onPress = {() => this.picture()}>
            <Image
              style = {{flex: 1}}
              resizeMode = "cover"
              source = {{uri: this.state.photo}}>
              <View style = {styles.buttonContainer}>
              <TouchableOpacity
                style = {styles.button}
                onPress = {() => this.favorite()}>
                <Icon
                  name = "star"
                  size = {16}
                  color = {this.getFavoriteColor()}
                />
              </TouchableOpacity>

              <TouchableOpacity
                style = {styles.button}
                onPress = {() => this.messages()}>
                <Icon
                  name = "feedback"
                  size = {16}
                  color = "green"
                />
              </TouchableOpacity>
              </View>
            </Image>
          </TouchableOpacity>
        </View>
        <Modal
          visible={this.state.modalVisible}
          onRequestClose={() => {this._setModalVisible(false)}}
          >
          <View style={styles.container}>
            <View style={styles.innerContainer}>
              <View style={styles.modalUserBar}>
                <TouchableOpacity onPress={() => {this._setModalVisible(false); this.props.navigator.push({component: Profile, state: this.state.userID});}}>
                  <View style={styles.modalUser}>
                    <Image
                      resizeMode = "cover"
                      style = {{borderRadius: 90, width: 20, height: 20, marginRight: 4}}
                      source = {{uri: this.state.userPhoto}}
                    />
                    <Text>{this.state.user}</Text>
                  </View>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => {this._setModalVisible(false);}}>
                  <Icon name = "close"
                  size = {25}
                  borderWidth = {7}
                  color = "black"
                  />
                </TouchableOpacity>
              </View>
              <Image
                resizeMode = "cover"
                style = {styles.modalPhoto}
                source = {{uri: this.state.photo}}
              />
              <View style = {styles.buttonViewModal}>
                <TouchableOpacity
                  style = {styles.button}
                  onPress = {() => {alert("Database access");}}>
                  <Icon
                    name = "star"
                    size = {28}
                    color = {(this.state.isFavorite) ? ("orange") : ("gray")}
                  />
                </TouchableOpacity>
                <TouchableOpacity
                  style = {styles.button}
                  onPress = {() => {alert("Go to messages page.");}}>
                  <Icon
                    name = "feedback"
                    size = {28}
                    color = "green"
                  />
                </TouchableOpacity>
              </View>
              <Text style={styles.description}><Text style={{fontWeight: 'bold'}}>Description: </Text>{this.state.description}</Text>
            </View>
          </View>
        </Modal>
      </View>
    );
  }

  componentDidMount() {
    var postSnapshot = this.props.id;
    var self = this;

    database.once("value", function(snapshot){
      var userid = postSnapshot.val().userID;
      var userSnapshot = snapshot.child("users/" + userid);
      var proPic = userSnapshot.val().profilePic;

      self.setState({
        postID: postSnapshot.key().toString(),
        userID: userid,
        user: postSnapshot.val().user,
        userPhoto: proPic,
        photo: postSnapshot.val().photoID,
        rating: postSnapshot.val().rating,
        description: postSnapshot.val().description,
        isFavorite: false,
      });
    });
  }

  picture() {
    this._setModalVisible(true);
  }

  favorite() {
    this.state.isFavorite = !this.state.isFavorite;
    // TODO: update database

    // this is probably bad because it rerenders the entire scene. only really needs to update the Icon's color prop
    this.forceUpdate();
  }

  messages() {
    alert("Go to messages page.");
  }

  getFavoriteColor() {
    if(this.state.isFavorite) {
      return "orange";
    } else {
      return "gray";
    }
  }

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }
}

const styles = StyleSheet.create({
  item: {
    margin: 2,
  },
  photo: {
    width: windowSize.width / 3 - 6,
    height: windowSize.width / 3 - 6,
  },
  buttonView: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center'
  },
  buttonViewModal: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-start'
  },
  buttonContainer: {
    flexDirection: 'row',
    padding: 4,
    alignItems: 'center',
    justifyContent: 'center',
    color: 'black',
    opacity: 80
  },
  button: {
    marginLeft: 8,
    marginRight: 8,
    marginTop: 4,
    marginBottom: 4,
  },
  container: {
    justifyContent: 'center',
    flex: 1,
    alignItems: 'center',
  },
  innerContainer: {
    borderRadius: 20,
    margin: 5,
    backgroundColor: "white",
  },
  modalUserBar: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    padding: 2,
    marginRight:2,
    marginLeft: 4,
    marginTop: 4,
  },
  modalUser: {
    flexDirection: 'row',
  },
  modalPhoto: {
    width: windowSize.width-20,
    height: windowSize.width-20,
    marginLeft: 5,
    marginRight: 5,
  },
  description: {
    padding: 5,
    marginLeft: 2,
  }
});

module.exports = SmallPost;
<|endoftext|>


<commit_before>$.Redactor.prototype.WoltLabKeyup = function() {
	"use strict";

	return {
		init: function () {
			this.WoltLabEvent.register('keyup', (function (data) {
				if (data.event.originalEvent.which === this.keyCode.ENTER) {
					this.WoltLabKeyup._keyupEnter();
				}
			}).bind(this));
		},

		_keyupEnter: function () {
			var editor = this.$editor[0];

			var selection = window.getSelection();
			var node = selection.anchorNode;
			var parent = null;
			while (node.parentNode) {
				if (node.parentNode === editor) {
					parent = node;
					break;
				}

				node = node.parentNode;
			}

			if (parent !== null && parent.nodeName === 'P') {
				this.WoltLabKeyup._rebuildEmptyParagraph(parent, false);

				parent = parent.previousElementSibling;
				if (parent !== null && parent.nodeName === 'P') {
					this.WoltLabKeyup._rebuildEmptyParagraph(parent, true);
				}
			}
		},

		/**
		 * Rebuilds an empty paragraph, that is a paragraph that only contains
		 * a zero-width whitespace, optionally nested inside inline elements. No
		 * node in the entire tree may contain more than one element child node.
		 *
		 * @param       {Element}       p
		 * @param       {boolean}       isPreviousElement
		 * @protected
		 */
		_rebuildEmptyParagraph: function (p, isPreviousElement) {
			if (p.textContent.replace(/\u200B/g, '').trim().length > 0) {
				return;
			}

			var node = p;
			while (node.nodeType === Node.ELEMENT_NODE) {
				// element contains no nodes
				if (node.childNodes.length === 0) break;

				// more than two elements are present
				if (node.children.length > 1) return;

				if (node.children.length === 1) {
					node = node.children[0];
				}
				else {
					node = node.childNodes[0];
				}
			}

			if (node.nodeType === Node.TEXT_NODE) {
				var br = elCreate('br');
				node.parentNode.appendChild(br);

				if (isPreviousElement) elRemove(node);
			}
		}
	}
};
<commit_msg>Work-around for the caret position in nested lists in Firefox<commit_after>$.Redactor.prototype.WoltLabKeyup = function() {
	"use strict";

	return {
		init: function () {
			this.WoltLabEvent.register('keyup', (function (data) {
				if (data.event.originalEvent.which === this.keyCode.ENTER) {
					this.WoltLabKeyup._keyupEnter();
				}
			}).bind(this));
		},

		_keyupEnter: function () {
			var editor = this.$editor[0];

			var selection = window.getSelection();
			var parent = null;

			if (this.detect.isFirefox()) {
				var anchorNode = selection.anchorNode;
				if (anchorNode.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
					parent = anchorNode.parentNode;
					if (parent.childNodes[0] === anchorNode) {
						anchorNode = anchorNode.parentNode;
					}
				}

				if (anchorNode.nodeName === 'LI') {
					// check if this is a nested list
					var list = anchorNode.parentNode;
					parent = list.parentNode;

					// Firefox does not handle nested lists well, yielding untargetable list items
					// see https://bugzilla.mozilla.org/show_bug.cgi?id=1428073
					if (parent.nodeName === 'LI' && list.previousSibling === null) {
						parent.insertBefore(this.marker.get(), list);
						parent.insertBefore(elCreate('br'), list);

						this.selection.restore();

						return;
					}
				}
			}

			var node = selection.anchorNode;
			while (node.parentNode) {
				if (node.parentNode === editor) {
					parent = node;
					break;
				}

				node = node.parentNode;
			}

			if (parent !== null && parent.nodeName === 'P') {
				this.WoltLabKeyup._rebuildEmptyParagraph(parent, false);

				parent = parent.previousElementSibling;
				if (parent !== null && parent.nodeName === 'P') {
					this.WoltLabKeyup._rebuildEmptyParagraph(parent, true);
				}
			}
		},

		/**
		 * Rebuilds an empty paragraph, that is a paragraph that only contains
		 * a zero-width whitespace, optionally nested inside inline elements. No
		 * node in the entire tree may contain more than one element child node.
		 *
		 * @param       {Element}       p
		 * @param       {boolean}       isPreviousElement
		 * @protected
		 */
		_rebuildEmptyParagraph: function (p, isPreviousElement) {
			if (p.textContent.replace(/\u200B/g, '').trim().length > 0) {
				return;
			}

			var node = p;
			while (node.nodeType === Node.ELEMENT_NODE) {
				// element contains no nodes
				if (node.childNodes.length === 0) break;

				// more than two elements are present
				if (node.children.length > 1) return;

				if (node.children.length === 1) {
					node = node.children[0];
				}
				else {
					node = node.childNodes[0];
				}
			}

			if (node.nodeType === Node.TEXT_NODE) {
				var br = elCreate('br');
				node.parentNode.appendChild(br);

				if (isPreviousElement) elRemove(node);
			}
		}
	}
};
<|endoftext|>


<commit_before>// ─────────────────────────────────────────────────────────────────────────────
// import
// ─────────────────────────────────────────────────────────────────────────────

import styled from 'styled-components';

import { Text } from '../primitives';

// ─────────────────────────────────────────────────────────────────────────────
// component
// ─────────────────────────────────────────────────────────────────────────────

export const Label = styled(Text)`
  animation: ${({ animation }) => animation};
`;
Label.defaultProps = {
  as:            'label',
  display:       'block',
  color:         'hsla(var(--hsl-text), 0.75)',
  fontSize:      '1.25rem',
  lineHeight:    '3rem',
  textTransform: 'uppercase',
};
<commit_msg>update label styles<commit_after>// ─────────────────────────────────────────────────────────────────────────────
// import
// ─────────────────────────────────────────────────────────────────────────────

import styled from 'styled-components';

import { Text } from '../primitives';

// ─────────────────────────────────────────────────────────────────────────────
// component
// ─────────────────────────────────────────────────────────────────────────────

export const Label = styled(Text)`
  animation: ${({ animation }) => animation};
`;

Label.defaultProps = {
  as:            'label',
  display:       'flex',
  alignItems:    'center',
  color:         'hsla(var(--hsl-text), 0.75)',
  fontSize:      '1.25rem',
  textTransform: 'uppercase',
};
<|endoftext|>


<commit_before>import * as configuration from './lib/configuration.js'
import TemplateProperties from './components/Properties/TemplateProperties.js'
import EntityTree from './components/EntityTree/EntityTree.js'
import EntityTreeInputSearch from './components/EntityTree/EntityTreeInputSearch.js'
import Startup from './containers/Startup/Startup.js'
import ApiModal from './components/Modals/ApiModal.js'

export default () => {
  configuration.propertiesComponents.push({
    title: TemplateProperties.title,
    shouldDisplay: (entity) => entity.__entitySet === 'templates',
    component: TemplateProperties
  })

  configuration.editorComponents.templates = require('./components/Editor/TemplateEditor.js')
  configuration.editorComponents.templates.reformat = (reformatter, entity) => {
    const content = reformatter(entity.content, 'html')
    const helpers = reformatter(entity.helpers, 'js')

    return {
      content: content,
      helpers: helpers
    }
  }
  configuration.editorComponents.startup = Startup
  configuration.entitySets.templates = {
    name: 'templates',
    visibleName: 'template',
    nameAttribute: 'name',
    referenceAttributes: ['name', 'recipe', 'shortid'],
    entityTreePosition: 1000
  }

  configuration.sharedComponents.EntityTree = EntityTree

  configuration.apiSpecs = {
    template: {
      content: '...',
      helpers: '...',
      engine: '...',
      recipe: '...'
    },
    data: {
      aProperty: '...'
    },
    options: {}
  }

  // default filter by name strategy
  configuration.entityTreeFilterItemResolvers.push((entity, entitySets, filterInfo) => {
    const { name } = filterInfo

    if (name == null || name === '') {
      return true
    }

    const entityName = entitySets[entity.__entitySet].nameAttribute ? entity[entitySets[entity.__entitySet].nameAttribute] : entity.name

    return entityName.indexOf(name) !== -1
  })

  configuration.entityTreeToolbarComponents.push((props) => (
    <EntityTreeInputSearch {...props} />
  ))

  configuration.toolbarComponents.settings.push(() =>
 configuration.modalHandler.open(ApiModal, { apiSpecs: configuration.apiSpecs })}>
     API
)

  configuration.initializeListeners.push(() => {
    configuration.entityTreeIconResolvers.push((entity) => {
      if (entity.__entitySet !== 'templates') {
        return
      }

      if (entity.recipe === 'html') {
        return 'fa-html5'
      }

      if (entity.recipe.indexOf('xlsx') !== -1) {
        return 'fa-table'
      }

      if (entity.recipe.indexOf('pdf') !== -1) {
        return 'fa-file-pdf-o'
      }

      if (entity.recipe.indexOf('html') !== -1) {
        return 'fa-html5'
      }
    })
  })
}
<commit_msg>add “Startup page” item in settings menu<commit_after>import { connect } from 'react-redux'
import * as configuration from './lib/configuration.js'
import TemplateProperties from './components/Properties/TemplateProperties.js'
import EntityTree from './components/EntityTree/EntityTree.js'
import EntityTreeInputSearch from './components/EntityTree/EntityTreeInputSearch.js'
import Startup from './containers/Startup/Startup.js'
import ApiModal from './components/Modals/ApiModal.js'
import { openTab } from './redux/editor/actions'

export default () => {
  configuration.propertiesComponents.push({
    title: TemplateProperties.title,
    shouldDisplay: (entity) => entity.__entitySet === 'templates',
    component: TemplateProperties
  })

  configuration.editorComponents.templates = require('./components/Editor/TemplateEditor.js')
  configuration.editorComponents.templates.reformat = (reformatter, entity) => {
    const content = reformatter(entity.content, 'html')
    const helpers = reformatter(entity.helpers, 'js')

    return {
      content: content,
      helpers: helpers
    }
  }
  configuration.editorComponents.startup = Startup
  configuration.entitySets.templates = {
    name: 'templates',
    visibleName: 'template',
    nameAttribute: 'name',
    referenceAttributes: ['name', 'recipe', 'shortid'],
    entityTreePosition: 1000
  }

  configuration.sharedComponents.EntityTree = EntityTree

  configuration.apiSpecs = {
    template: {
      content: '...',
      helpers: '...',
      engine: '...',
      recipe: '...'
    },
    data: {
      aProperty: '...'
    },
    options: {}
  }

  // default filter by name strategy
  configuration.entityTreeFilterItemResolvers.push((entity, entitySets, filterInfo) => {
    const { name } = filterInfo

    if (name == null || name === '') {
      return true
    }

    const entityName = entitySets[entity.__entitySet].nameAttribute ? entity[entitySets[entity.__entitySet].nameAttribute] : entity.name

    return entityName.indexOf(name) !== -1
  })

  configuration.entityTreeToolbarComponents.push((props) => (
    <EntityTreeInputSearch {...props} />
  ))

  configuration.toolbarComponents.settings.push(connect(
    undefined,
    { openTab }
  )((props) => (

 props.openTab({ key: 'StartupPage', editorComponentKey: 'startup', title: 'Startup' })}>
       Startup page

  )))

  configuration.toolbarComponents.settings.push(() => (

 configuration.modalHandler.open(ApiModal, { apiSpecs: configuration.apiSpecs })}>
       API

  ))

  configuration.initializeListeners.push(() => {
    configuration.entityTreeIconResolvers.push((entity) => {
      if (entity.__entitySet !== 'templates') {
        return
      }

      if (entity.recipe === 'html') {
        return 'fa-html5'
      }

      if (entity.recipe.indexOf('xlsx') !== -1) {
        return 'fa-table'
      }

      if (entity.recipe.indexOf('pdf') !== -1) {
        return 'fa-file-pdf-o'
      }

      if (entity.recipe.indexOf('html') !== -1) {
        return 'fa-html5'
      }
    })
  })
}
<|endoftext|>


<commit_before>// var redisClient = require('redis-connection')();
// var redisClient = require('redis');
// var client = redisClient.createClient();
// var env = require('env2')('.env');

var client = require('./redis.js');
var mandrillEmail = require('./mandrill.js');

exports.register = function(server, options, next) {

  var societyDatabase = function(request,reply){

    var societyFormObject = request.payload;
    var timeNow = Date.now();
    var date = new Date(timeNow);
    console.log(societyFormObject);

    var societyFormObjectKeys = Object.keys(societyFormObject);

    // societyFormObjectKeys.forEach(function(elem, i){
    //   var tf = _(elem);
    //   var rx = new RegExp;
    //   if(elem == "societyName" || elem == "university" || elem == "phone"){
    //     rx = /[^a-z 0-9.,?]/gi;
    //   }
    //   societyFormObject[elem]
    //   tf.value = tf.value.replace(rx , "" );
    // })

    client.incr('id');
    var thisId = client.get('id', function(err,reply){
      addHashToDatabase(reply);
      addToSet('university', societyFormObject.university, reply);
      addToSet('region', societyFormObject.region, reply);
      addToSet('typeSociety', societyFormObject.typeSociety, reply);
      addToSet('memberSize', societyFormObject.memberSize, reply);
      addToSet('type', 'society', reply);

    });

    function addHashToDatabase(reply){
      client.hmset(reply, 'id', reply, 'timestamp', timeNow, 'date', date, 'societyName', societyFormObject.societyName, 'university', societyFormObject.university, 'region', societyFormObject.region, 'typeSociety', societyFormObject.typeSociety, 'memberSize', societyFormObject.memberSize, 'email', societyFormObject.email,'phone',societyFormObject.phone,'aboutus', societyFormObject.aboutus,'societyLogo', societyFormObject.societyLogo, function(err,reply){
        if (err){
          console.log(err);

        } else if (reply){
          mandrillEmail.acknowledgeSocietyEmail(societyFormObject.email, societyFormObject.societyName);
          //TO DO Sort out reply names do not conflict return reply.view('societyformsuccess');
        }
      });

    }

    function addToSet (key, value, hashID){
      var keyValue = key + ":" + value;
      client.sadd(keyValue, hashID);
    }

     return reply.view('societyformsuccess');

    };

  server.route([{
    method: 'POST',
    path: '/societyredis',
    config: {
      description: 'return the home page',
      handler: societyDatabase

    }
  }, {
    method: 'GET',
    path: '/society',
    config: {
      description: 'returns society page',
      handler: function(request, reply) {

          return reply.view('society');
      }
    }
  }]);

  return next();
};

exports.register.attributes = {
  name: 'Societyredis'
};
<commit_msg>regular expression added to societyform #157<commit_after>// var redisClient = require('redis-connection')();
// var redisClient = require('redis');
// var client = redisClient.createClient();
// var env = require('env2')('.env');

var client = require('./redis.js');
var mandrillEmail = require('./mandrill.js');

exports.register = function(server, options, next) {

  var societyDatabase = function(request,reply){

    var societyFormObject = request.payload;
    var timeNow = Date.now();
    var date = new Date(timeNow);

    var societyFormObjectKeys = Object.keys(societyFormObject);

    societyFormObjectKeys.forEach(function(elem, i){

      var regEx = new RegExp(/^[a-zA-Z0-9 .,?-]+$/);

      if((elem === "societyName" || elem === "university" || elem === "phone") &&
      regEx.exec(societyFormObject[elem.toString()]) === null
      ){
          console.log("elem", elem);
          // console.log("regEx.exec(societyFormObject[elem]", regEx.exec(societyFormObject[elem]));
          // console.log("before regEX", societyFormObject[elem]);
          societyFormObject[elem.toString()] = "";
      }
    });
    console.log("after regEx", societyFormObject);

    client.incr('id');
    var thisId = client.get('id', function(err,reply){
      addHashToDatabase(reply);
      addToSet('university', societyFormObject.university, reply);
      addToSet('region', societyFormObject.region, reply);
      addToSet('typeSociety', societyFormObject.typeSociety, reply);
      addToSet('memberSize', societyFormObject.memberSize, reply);
      addToSet('type', 'society', reply);

    });

    function addHashToDatabase(reply){
      client.hmset(reply, 'id', reply, 'timestamp', timeNow, 'date', date, 'societyName', societyFormObject.societyName, 'university', societyFormObject.university, 'region', societyFormObject.region, 'typeSociety', societyFormObject.typeSociety, 'memberSize', societyFormObject.memberSize, 'email', societyFormObject.email,'phone',societyFormObject.phone,'aboutus', societyFormObject.aboutus,'societyLogo', societyFormObject.societyLogo, function(err,reply){
        if (err){
          console.log(err);

        } else if (reply){
          mandrillEmail.acknowledgeSocietyEmail(societyFormObject.email, societyFormObject.societyName);
          //TO DO Sort out reply names do not conflict return reply.view('societyformsuccess');
        }
      });

    }

    function addToSet (key, value, hashID){
      var keyValue = key + ":" + value;
      client.sadd(keyValue, hashID);
    }

     return reply.view('societyformsuccess');

    };

  server.route([{
    method: 'POST',
    path: '/societyredis',
    config: {
      description: 'return the home page',
      handler: societyDatabase

    }
  }, {
    method: 'GET',
    path: '/society',
    config: {
      description: 'returns society page',
      handler: function(request, reply) {

          return reply.view('society');
      }
    }
  }]);

  return next();
};

exports.register.attributes = {
  name: 'Societyredis'
};
<|endoftext|>


<commit_before>
module.exports = function (command, args, options, done) {
  try {
    done(null, spawn(cmd.command, cmd.args, options))
  } catch (e) {
    done(127)
  }
}

/**
    try {
      proc = spawn(cmd.command, cmd.args, options)
    } catch (e) {
      return next(127, '', 'Command not found')
    }
    **/
<commit_msg>bugfix<commit_after>
module.exports = function (command, args, options, done) {
  try {
    done(null, spawn(command, args, options))
  } catch (e) {
    done(127)
  }
}

/**
    try {
      proc = spawn(cmd.command, cmd.args, options)
    } catch (e) {
      return next(127, '', 'Command not found')
    }
    **/
<|endoftext|>


<commit_before>/* jslint node: true, esnext: true */

"use strict";

const child_process = require('child_process');

module.exports = {
	"name": "kronos-system",
	"description": "Starts a child process",
	"config": {
		"command": {
			"description": "command to execute",
			"type": "string"
		}
	},
	"endpoints": {
		"action": {
			"direction": "in(active,passive)"
		},
		"stdin": {
			"direction": "in(active)",
			"mandatory": false
		},
		"stdout": {
			"direction": "out(active)",
			"mandatory": false
		},
		"stderr": {
			"direction": "out(active)",
			"mandatory": false
		}
	},
	initialize(manager, sr, stepDefinition, endpoints, properties) {
		properties._start = {
			value: function () {
				const step = this;

				const command = step.command;
				let stdinRequest;
				let child;

				endpoints.action.receive(function* () {
					while (step.isRunning) {
						const request = yield;

						child = child_process.spawn(command, {
							stdio: ['pipe', 'pipe', 'pipe']
						});

						if (endpoints.stdin) {
							endpoints.stdin.receive(function* () {
								stdinRequest = yield;
								stdinRequest.stream.pipe(child.stdin);
							});
						}

						if (endpoints.stdout) {
							endpoints.stdout.send({
								info: {},
								stream: child.stdout
							});
						}

						if (endpoints.stderr) {
							endpoints.stderr.send({
								info: {},
								stream: child.stderr
							});
						}
					}
				});

				return Promise.resolve(step);
			}
		};

		properties._stop = {
			value: function () {
				if (child) {
					if (stdinRequest) {
						stdinRequest.stream.unpipe(child.stdin);
						stdinRequest = undefined;
					}

					child.kill();
					child = undefined;
				}

				return Promise.resolve(this);
			}
		};

		return this;
	}
};
<commit_msg>fix: child process stdio eithe ignore or pipe dependent on existence of endpoints<commit_after>/* jslint node: true, esnext: true */

"use strict";

const child_process = require('child_process');

module.exports = {
	"name": "kronos-system",
	"description": "Starts a child process",
	"config": {
		"command": {
			"description": "command to execute",
			"type": "string"
		}
	},
	"endpoints": {
		"action": {
			"direction": "in(active,passive)"
		},
		"stdin": {
			"direction": "in(active)",
			"mandatory": false
		},
		"stdout": {
			"direction": "out(active)",
			"mandatory": false
		},
		"stderr": {
			"direction": "out(active)",
			"mandatory": false
		}
	},
	initialize(manager, sr, stepDefinition, endpoints, properties) {
		properties._start = {
			value: function () {
				const step = this;

				let command = step.command;
				let stdinRequest;
				let child;

				endpoints.action.receive(function* () {
					while (step.isRunning) {
						const request = yield;

						child = child_process.spawn(command, {
							stdio: [endpoints.stdin ? 'pipe' : 'ignore',
								endpoints.stdout ? 'pipe' : 'ignore',
								endpoints.stderr ? 'pipe' : 'ignore'
							]
						});

						if (endpoints.stdin) {
							endpoints.stdin.receive(function* () {
								stdinRequest = yield;
								stdinRequest.stream.pipe(child.stdin);
							});
						}

						if (endpoints.stdout) {
							endpoints.stdout.send({
								info: {
									command: command
								},
								stream: child.stdout
							});
						}

						if (endpoints.stderr) {
							endpoints.stderr.send({
								info: {
									command: command
								},
								stream: child.stderr
							});
						}
					}
				});

				return Promise.resolve(step);
			}
		};

		properties._stop = {
			value: function () {
				if (child) {
					if (stdinRequest) {
						stdinRequest.stream.unpipe(child.stdin);
						stdinRequest = undefined;
					}

					child.kill();
					child = undefined;
				}

				return Promise.resolve(this);
			}
		};

		return this;
	}
};
<|endoftext|>


<commit_before>var BaseStore = require('./index').Store,
    util = require('util');

function MemoryStore (options) {
  BaseStore.call(this, options);

  var modules = {};
  var last_seq = null;

  this.emit("ready");

  this.has = function (key, cb) {
    cb(null, !!modules[key] && !modules[key].deleted);
  };

  this.get = function (key, cb) {
    cb(null, modules[key] || null);
  };

  this.put = function (key, data, cb) {
    var insert = !modules[key] || modules[key].deleted;
    modules[key] = data;
    if (cb) cb(null, insert, data);
  };

  this.remove = function (key, cb) {
    var found = false;
    if (modules[key]) {
      modules[key].deleted = true;
      found = true;
    }
    if (cb) cb(null, found);
  };

  this.lastSeq = function (value, cb) {
    if (typeof value === 'function') {
      cb = value;
      value = null;
    }
    if (typeof value === 'number') {
      last_seq = value;
    }
    if (cb) cb(null, last_seq || 0);
  };

  function getMany (emit, done, deleted) {
    if (emit) {
      for (var id in modules) {
        if ((!deleted && !modules[id].deleted) || (deleted && modules[id].deleted)) {
          emit(null, id, modules[id]);
        }
      }
    }
    if (done) done();
  }

  this.getAll = function (emit, done) {
    getMany(emit, done, false);
  };

  this.getGraveyard = function (emit, done) {
    getMany(emit, done, true);
  };

  this.close = function (cb) {
    modules = {};
    last_seq = null;
    if (cb) cb();
  };

}

util.inherits(MemoryStore, BaseStore);

module.exports = MemoryStore;
<commit_msg>Use process.nextTick in Memory store<commit_after>var BaseStore = require('./index').Store,
    util = require('util');

function MemoryStore (options) {
  BaseStore.call(this, options);

  var modules = {};
  var last_seq = null;

  this.emit("ready");

  this.has = function (key, cb) {
    process.nextTick(function () { cb(null, !!modules[key] && !modules[key].deleted); });
  };

  this.get = function (key, cb) {
    process.nextTick(function () { cb(null, modules[key] || null); });
  };

  this.put = function (key, data, cb) {
    var insert = !modules[key] || modules[key].deleted;
    modules[key] = data;
    if (cb) process.nextTick(function () { cb(null, insert, data); });
  };

  this.remove = function (key, cb) {
    var found = false;
    if (modules[key]) {
      modules[key].deleted = true;
      found = true;
    }
    if (cb) process.nextTick(function () { cb(null, found); });
  };

  this.lastSeq = function (value, cb) {
    if (typeof value === 'function') {
      cb = value;
      value = null;
    }
    if (typeof value === 'number') {
      last_seq = value;
    }
    if (cb) process.nextTick(function () { cb(null, last_seq || 0); });
  };

  function getMany (emit, done, deleted) {
    if (emit) {
      var doEmit = function (id, module) {
        process.nextTick(function () { emit(null, id, modules[id]); });
      };
      for (var id in modules) {
        if ((!deleted && !modules[id].deleted) || (deleted && modules[id].deleted)) {
          doEmit(id, modules[id]);
        }
      }
    }
    if (done) process.nextTick(done);
  }

  this.getAll = function (emit, done) {
    getMany(emit, done, false);
  };

  this.getGraveyard = function (emit, done) {
    getMany(emit, done, true);
  };

  this.close = function (cb) {
    modules = {};
    last_seq = null;
    if (cb) process.nextTick(cb);
  };

}

util.inherits(MemoryStore, BaseStore);

module.exports = MemoryStore;
<|endoftext|>