<commit_before>var rp = require('request-promise'),
    HttpsProxyAgent = require('https-proxy-agent'),
    Promise = require('bluebird'),
    sh = require('shelljs');

const BASE_URL = "https://api.github.com/repos/";
const AUTH_URL = "https://github.com/login/oauth/authorize";
const OWNER = "Nordstrom/";
const REPO = "build-bot/";
const BASIC_AUTH = "Basic amFzb25vbG1zdGVhZDMzOkJAc2ViYWxsMzM=";
const MERGE_MESSAGE = "Merging master into branch: ";
const MASTER_MERGE_MESSAGE = "Merging into master from: ";

var Github = {
    push : function(branch, message){
        if (!branch){
            return Promise.reject("No branch name on push");
        }
        var code = sh.exec('git add .');
        if (code == 1){
            return Promise.reject("Error on git add");
        }
        code = sh.exec('git commit -m "auto commit from bot: ' + message + '"');
        if (code == 1){
            return Promise.reject("Error on git commit");
        }
        code = sh.exec('git push origin ' + branch);
        if (code == 1){
            return Promise.reject("Error on git push");
        }
        return Promise.resolve();
    },
    preCheck : function(branch) {
        if (!branch){
            return Promise.reject("Invalid request -- need branch name")
        }

        return merge(branch, "master", MERGE_MESSAGE + branch)
            .then(function(){
                console.log("Success...");
            })
            .catch(function(err){
                if (err.message.message.indexOf("409")){
                    return Promise.reject("Conflict merging master into " + branch);
                } else {
                    return Promise.reject(err.message);
                }
            })
    },

    mergeToMaster : function(branch){
        if (!branch){
            return Promise.reject("Invalid request -- need branch name")
        }

        return merge("master", branch, MASTER_MERGE_MESSAGE + branch)
            .then(function(){
                console.log("Success...");
            })
            .catch(function(err){
                if (err.message.message.indexOf("409")){
                    return Promise.reject("Conflict merging " + branch + "into master");
                } else {
                    return Promise.reject(err.message);
                }
            })
    }
};

module.exports = Github;

function merge(base, head, message){
    if (!base || !head || !message){
        return Promise.reject("Invalid request, cant merge")
    }

    var params = {
        uri : BASE_URL + OWNER + REPO + "merges",
        method : "POST",
        json : true,
        headers : {
            "Accept": "application/json",
            "Content-Type": "application/json",
            "User-Agent" : "Hackathon-Local-Dev",
            "Authorization" : BASIC_AUTH
        },
        body : {
            "base": base,
            "head": head,
            "commit_message": message
        }
    };

    params = checkProxy(params);

    return rp(params);
}

function checkProxy(params){
    if (!!process.env.LOCAL){
        params.agent = new HttpsProxyAgent("http://webproxysea.nordstrom.net:8181");
    }
    return params;
}

//** TEST CODE ****/
Github.push("testing push from shelljs");
<commit_msg>auto commit from bot: testing push from shelljs<commit_after>var rp = require('request-promise'),
    HttpsProxyAgent = require('https-proxy-agent'),
    Promise = require('bluebird'),
    sh = require('shelljs');

const BASE_URL = "https://api.github.com/repos/";
const AUTH_URL = "https://github.com/login/oauth/authorize";
const OWNER = "Nordstrom/";
const REPO = "build-bot/";
const BASIC_AUTH = "Basic amFzb25vbG1zdGVhZDMzOkJAc2ViYWxsMzM=";
const MERGE_MESSAGE = "Merging master into branch: ";
const MASTER_MERGE_MESSAGE = "Merging into master from: ";

var Github = {
    push : function(branch, message){
        if (!branch){
            return Promise.reject("No branch name on push");
        }
        var code = sh.exec('git add .');
        if (code == 1){
            return Promise.reject("Error on git add");
        }
        code = sh.exec('git commit -m "auto commit from bot: ' + message + '"');
        if (code == 1){
            return Promise.reject("Error on git commit");
        }
        code = sh.exec('git push origin ' + branch);
        if (code == 1){
            return Promise.reject("Error on git push");
        }
        return Promise.resolve();
    },
    preCheck : function(branch) {
        if (!branch){
            return Promise.reject("Invalid request -- need branch name")
        }

        return merge(branch, "master", MERGE_MESSAGE + branch)
            .then(function(){
                console.log("Success...");
            })
            .catch(function(err){
                if (err.message.message.indexOf("409")){
                    return Promise.reject("Conflict merging master into " + branch);
                } else {
                    return Promise.reject(err.message);
                }
            })
    },

    mergeToMaster : function(branch){
        if (!branch){
            return Promise.reject("Invalid request -- need branch name")
        }

        return merge("master", branch, MASTER_MERGE_MESSAGE + branch)
            .then(function(){
                console.log("Success...");
            })
            .catch(function(err){
                if (err.message.message.indexOf("409")){
                    return Promise.reject("Conflict merging " + branch + "into master");
                } else {
                    return Promise.reject(err.message);
                }
            })
    }
};

module.exports = Github;

function merge(base, head, message){
    if (!base || !head || !message){
        return Promise.reject("Invalid request, cant merge")
    }

    var params = {
        uri : BASE_URL + OWNER + REPO + "merges",
        method : "POST",
        json : true,
        headers : {
            "Accept": "application/json",
            "Content-Type": "application/json",
            "User-Agent" : "Hackathon-Local-Dev",
            "Authorization" : BASIC_AUTH
        },
        body : {
            "base": base,
            "head": head,
            "commit_message": message
        }
    };

    params = checkProxy(params);

    return rp(params);
}

function checkProxy(params){
    if (!!process.env.LOCAL){
        params.agent = new HttpsProxyAgent("http://webproxysea.nordstrom.net:8181");
    }
    return params;
}

//** TEST CODE ****/
Github.push("test-bot-branch", "testing push from shelljs");
<|endoftext|>


<commit_before>'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

class FullScreenTextArea extends Component {
  static defaultProps = {
    position: 'fixed',
  }

  classes() {
    return {
      'default': {
        wrap: {
          position: this.props.position,
          top: '0',
          right: '0',
          bottom: '0',
          left: '0',
          zIndex: '10',
          background: '#fff',
          display: 'flex',
          flexDirection: 'column',
          background: '#eee',
        },
        text: {
          flex: '1',
          position: 'relative',
        },
        textarea: {
          Absolute: '10px 10px 10px 10px',
          padding: '3%',
          border: 'none',
          outline: 'none',
          width: '87%',
          color: '#333',
        },
        actions: {
          marginTop: '-10px',
          height: '40px',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
        },
      },
      'actions-false': {
        actions: {
          display: 'none',
        },
      },
    }
  }

  handleClick = () => {
    this.props.onCancel && this.props.onCancel()
  }

  handleKeyDown = (e) => {
    if (e.keyCode === 27) { // escape key
      this.handleClick()
    }
  }

  render() {
    return (

          <textarea is="textarea" placeholder="Write a Message" onKeyDown={ this.handleKeyDown } />

          Cancel
          Encrypt

    )
  }
}

export default ReactCSS(FullScreenTextArea)
<commit_msg>Add Dark Styling to FullScreenCompose<commit_after>'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

import colors from '../../styles/variables/colors'

class FullScreenTextArea extends Component {
  static defaultProps = {
    position: 'fixed',
  }

  classes() {
    return {
      'default': {
        wrap: {
          position: this.props.position,
          top: '0',
          right: '0',
          bottom: '0',
          left: '0',
          zIndex: '10',
          display: 'flex',
          flexDirection: 'column',
          background: colors.bgDark,
        },
        text: {
          flex: '1',
          position: 'relative',
        },
        textarea: {
          Absolute: '10px 10px 10px 10px',
          border: 'none',
          outline: 'none',
          width: '94%',
          boxSizing: 'border-box',
          padding: '10px 3%',
          color: '#333',
          borderRadius: '2px',
          fontSize: '14px',
          fontFamily: 'Andale Mono',
        },
        actions: {
          marginTop: '-10px',
          height: '40px',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          padding: '0 10px',
        },
        link: {
          textDecoration: 'none',
        },
        cancel: {
          color: '#999',
        },
        confirm: {
          color: colors.primary,
        },
      },
      'actions-false': {
        actions: {
          display: 'none',
        },
      },
    }
  }

  handleClick = () => {
    this.props.onCancel && this.props.onCancel()
  }

  handleKeyDown = (e) => {
    if (e.keyCode === 27) { // escape key
      this.handleClick()
    }
  }

  render() {
    return (

          <textarea is="textarea" placeholder="Write a Message" onKeyDown={ this.handleKeyDown } />

          Cancel
          Encrypt

    )
  }
}

export default ReactCSS(FullScreenTextArea)
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import PencilIcon from '../../icons/StrokePencil'
import CancelIcon from '../../icons/GlyphSmallCancel'
import Button from '../../components/button/Button'

class RenamePrompt extends React.Component {
  static propTypes = {
    onCancel: PropTypes.func.isRequired,
    onSubmit: PropTypes.func.isRequired,
    filename: PropTypes.string.isRequired,
    folder: PropTypes.bool
  }

  static defaultProps = {
    className: '',
    folder: false
  }

  constructor (props) {
    super(props)
    this.state = { filename: props.filename }

    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleCancel = this.handleCancel.bind(this)
  }

  handleChange (event) {
    this.setState({ filename: event.target.value })
  }

  handleSubmit (event) {
    this.props.onSubmit(this.state.filename)
    event.preventDefault()
  }

  handleCancel = (event) => {
    this.props.onCancel()
    event.preventDefault()
  }

  render () {
    let {onCancel, onSubmit, className, filename, folder, ...props} = this.props
    className = `${className} bg-white w-80 shadow-4 sans-serif relative`

    return (
      <form onSubmit={this.handleSubmit} className={className} style={{maxWidth: '30em'}} {...props}>
        <CancelIcon className='absolute pointer w2 h2 top-0 right-0 fill-gray' onClick={this.handleCancel} />

            <PencilIcon className='fill-gray w3' />

Rename {folder ? 'Folder' : 'File'}

            Choose a new name for this {folder ? 'folder' : 'file'}.

          <input
            onChange={this.handleChange}
            value={this.state.filename}
            required
            className='input-reset charcoal ba b--black-20 pa2 mb2 db w-75 center'
            type='text' />

          <Button className='ma2' type='button' bg='bg-gray' onClick={this.handleCancel}>Cancel</Button>
          <Button className='ma2' bg='bg-aqua'>Save</Button>

      </form>
    )
  }
}

export default RenamePrompt
<commit_msg>fix: input focus (#692)<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import PencilIcon from '../../icons/StrokePencil'
import CancelIcon from '../../icons/GlyphSmallCancel'
import Button from '../../components/button/Button'

class RenamePrompt extends React.Component {
  static propTypes = {
    onCancel: PropTypes.func.isRequired,
    onSubmit: PropTypes.func.isRequired,
    filename: PropTypes.string.isRequired,
    folder: PropTypes.bool
  }

  static defaultProps = {
    className: '',
    folder: false
  }

  constructor (props) {
    super(props)
    this.state = { filename: props.filename }

    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleCancel = this.handleCancel.bind(this)
  }

  handleChange (event) {
    this.setState({ filename: event.target.value })
  }

  handleSubmit (event) {
    this.props.onSubmit(this.state.filename)
    event.preventDefault()
  }

  handleCancel = (event) => {
    this.props.onCancel()
    event.preventDefault()
  }

  render () {
    let {onCancel, onSubmit, className, filename, folder, ...props} = this.props
    className = `${className} bg-white w-80 shadow-4 sans-serif relative`

    return (
      <form onSubmit={this.handleSubmit} className={className} style={{maxWidth: '30em'}} {...props}>
        <CancelIcon className='absolute pointer w2 h2 top-0 right-0 fill-gray' onClick={this.handleCancel} />

            <PencilIcon className='fill-gray w3' />

Rename {folder ? 'Folder' : 'File'}

            Choose a new name for this {folder ? 'folder' : 'file'}.

          <input
            onChange={this.handleChange}
            value={this.state.filename}
            required
            autoFocus
            className='input-reset charcoal ba b--black-20 pa2 mb2 db w-75 center focus-outline'
            type='text' />

          <Button className='ma2' type='button' bg='bg-gray' onClick={this.handleCancel}>Cancel</Button>
          <Button className='ma2' bg='bg-aqua'>Save</Button>

      </form>
    )
  }
}

export default RenamePrompt
<|endoftext|>


<commit_before>var gitlab= (function(){
    var per_page = 100;
    var eventPath = {
        "Issue"        : {page: "issues"        , api: "issues"},
        "MergeRequest" : {page: "merge_requests", api: "merge_request"},
        "Milestone"    : {page: "milestones"    , api: "milestones"}
    };

    // public methods
    function getProjects(projectCallback){
        var df = $.Deferred();
        getProjectsBase(projectCallback, df, 1);
        return df.promise();
    }

    function getProjectEvents(project_id){
        return $.ajax({
            url: config.getApiPath() + "projects/" + project_id + "/events",
            data: {
                per_page: per_page
            },
            type: "GET",
            dataType: "json",
            timeout: config.getPollingSecond() * 1000,
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        });
    }

    function getEventInternalUrl(args, internalUrlCallback){
        getEventInternalId(args, function(res){
            internalUrlCallback(config.getGitlabPath() + args.project_name + "/" + eventPath[args.target_type].page + "/" + res.target_id);
        });
    }

    function getEventInternalId(args, callback){
        util.checkArgs(args, ["project_name", "target_type", "target_id"]);

        $.ajax({
            url: config.getApiPath() + "projects/" + encodeURIComponent(args.project_name) + "/" + eventPath[args.target_type].api + "/" + args.target_id,
            type: "GET",
            dataType: "json",
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        }).then(function(res){
                var id = res.iid || res.id
                var url = config.getGitlabPath() + args.project_name + "/" + eventPath[args.target_type].page + "/" + id;
                callback({target_id: id, target_url: url});
            });
    }

    function events(){
        return [
            "Commit",   // target_type == null
            "Issue",
            "MergeRequest",
            "Milestone"
        ];
    }

    return {
        getProjects:         getProjects,
        getProjectEvents:    getProjectEvents,
        getEventInternalUrl: getEventInternalUrl,
        getEventInternalId:  getEventInternalId,
        events:              events
    };

    // private methods
    function getProjectsBase(projectCallback, df, page){
        $.ajax({
            url: config.getApiPath() + "projects",
            data: {
                page: page,
                per_page: per_page
            },
            type: "GET",
            dataType: "json",
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        }).fail(function(xhr, status, e){
                alert(status + " " + e);
                df.reject();
            }).done(function(projects){
                $.each(projects, function(index, project){
                    projectCallback(project);
                });

                if(projects.length < per_page){
                    // final page
                    df.resolve();
                } else{
                    // paging
                    getProjectsBase(projectCallback, df, page + 1);
                }
            });
    }

}());<commit_msg>[ci skip] Add comment<commit_after>var gitlab= (function(){
    var per_page = 100;
    var eventPath = {
        "Issue"        : {page: "issues"        , api: "issues"},
        "MergeRequest" : {page: "merge_requests", api: "merge_request"},
        "Milestone"    : {page: "milestones"    , api: "milestones"}
    };

    // public methods
    function getProjects(projectCallback){
        var df = $.Deferred();
        getProjectsBase(projectCallback, df, 1);
        return df.promise();
    }

    function getProjectEvents(project_id){
        // Get project events
        // GET /projects/:id/events
        // https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md#get-project-events
        return $.ajax({
            url: config.getApiPath() + "projects/" + project_id + "/events",
            data: {
                per_page: per_page
            },
            type: "GET",
            dataType: "json",
            timeout: config.getPollingSecond() * 1000,
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        });
    }

    function getEventInternalUrl(args, internalUrlCallback){
        getEventInternalId(args, function(res){
            internalUrlCallback(config.getGitlabPath() + args.project_name + "/" + eventPath[args.target_type].page + "/" + res.target_id);
        });
    }

    function getEventInternalId(args, callback){
        util.checkArgs(args, ["project_name", "target_type", "target_id"]);

        // Single issue
        // GET /projects/:id/issues/:issue_id
        // https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md#single-issue
        //   or
        // Get single MR
        // GET /projects/:id/merge_request/:merge_request_id
        // https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/merge_requests.md#get-single-mr
        //   or
        // Get single milestone
        // GET /projects/:id/milestones/:milestone_id
        // https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/milestones.md#get-single-milestone
        $.ajax({
            url: config.getApiPath() + "projects/" + encodeURIComponent(args.project_name) + "/" + eventPath[args.target_type].api + "/" + args.target_id,
            type: "GET",
            dataType: "json",
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        }).then(function(res){
                var id = res.iid || res.id
                var url = config.getGitlabPath() + args.project_name + "/" + eventPath[args.target_type].page + "/" + id;
                callback({target_id: id, target_url: url});
            });
    }

    function events(){
        return [
            "Commit",   // target_type == null
            "Issue",
            "MergeRequest",
            "Milestone"
        ];
    }

    return {
        getProjects:         getProjects,
        getProjectEvents:    getProjectEvents,
        getEventInternalUrl: getEventInternalUrl,
        getEventInternalId:  getEventInternalId,
        events:              events
    };

    // private methods
    function getProjectsBase(projectCallback, df, page){
        // List projects
        // GET /projects
        // https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md#list-projects
        $.ajax({
            url: config.getApiPath() + "projects",
            data: {
                page: page,
                per_page: per_page
            },
            type: "GET",
            dataType: "json",
            headers: {
                "PRIVATE-TOKEN" : config.getPrivateToken()
            }
        }).fail(function(xhr, status, e){
                alert(status + " " + e);
                df.reject();
            }).done(function(projects){
                $.each(projects, function(index, project){
                    projectCallback(project);
                });

                if(projects.length < per_page){
                    // final page
                    df.resolve();
                } else{
                    // paging
                    getProjectsBase(projectCallback, df, page + 1);
                }
            });
    }

}());<|endoftext|>


<commit_before>var e = module.exports = {};
var bu;
var http = require('http');

var bot;
e.init = (Tbot, blargutil) => {
    bot = Tbot;
    bu = blargutil;

    e.category = bu.CommandType.GENERAL;

};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = 'xkcd [number]';
e.info = 'Gets an xkcd comic. If a number is not specified, gets a random one.';
e.longinfo = `<p>Gives you an xkcd comic. If a number isn't specified, it gives you a random one.</p>`;

var xkcdMax = 0;

e.execute = (msg, words) => {
    getXkcd(msg.channel.id, words);
};

function getXkcd(channel, words) {
    if (xkcdMax === 0) {
        http.get('http://xkcd.com/info.0.json', function (res) {
            var body = '';
            res.on('data', function (chunk) {
                body += chunk;
            });
            res.on('end', function () {
                bu.logger.debug(body);
                var output = JSON.parse(body);
                xkcdMax = output.num;
                getXkcd(channel, words);

                //sendMessageToDiscord(channel, output.file, bot);
            });
        });
        return;
    }
    var choice;
    if (words.length === 1) {
        choice = bu.getRandomInt(1, xkcdMax);
    } else {
        choice = parseInt(words[1]);
        if (choice > xkcdMax || choice < 0) {
            bu.sendMessageToDiscord(channel, `Comic #${choice} does not exist!`);
        }
    }
    var url = '';
    if (choice === 0) {
        url = 'http://xkcd.com/info.0.json';
    } else {
        url = `http://xkcd.com/${choice}/info.0.json`;
    }
    http.get(url, function (res) {
        var body = '';
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
            var output = JSON.parse(body);
            var message = '';
            //  if (bot === BotEnum.DISCORD) {
            message = `__**${output.title}, ${output.year}**__
*Comic #${output.num}*
${output.alt}`;
            bu.sendFile(channel, message, output.img);
            xkcdMax = output.num;
            //getXkcd(channel, words, bot);
            //sendMessageToDiscord(channel, output.file, bot);
        });
    });
}<commit_msg>fixed xkcd<commit_after>var e = module.exports = {};
var bu;
var http = require('http');

var bot;
e.init = (Tbot, blargutil) => {
    bot = Tbot;
    bu = blargutil;

    e.category = bu.CommandType.GENERAL;

};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = 'xkcd [number]';
e.info = 'Gets an xkcd comic. If a number is not specified, gets a random one.';
e.longinfo = `<p>Gives you an xkcd comic. If a number isn't specified, it gives you a random one.</p>`;

var xkcdMax = 0;

e.execute = (msg, words) => {
    getXkcd(msg.channel.id, words);
};

function getXkcd(channel, words) {
    if (xkcdMax === 0) {
        http.get('http://xkcd.com/info.0.json', function (res) {
            var body = '';
            res.on('data', function (chunk) {
                body += chunk;
            });
            res.on('end', function () {
                bu.logger.debug(body);
                var output = JSON.parse(body);
                xkcdMax = output.num;
                getXkcd(channel, words);

                //sendMessageToDiscord(channel, output.file, bot);
            });
        });
        return;
    }
    var choice;
    if (words.length === 1) {
        choice = bu.getRandomInt(1, xkcdMax);
    } else {
        choice = parseInt(words[1]);
        if (choice > xkcdMax || choice < 0) {
            bu.sendMessageToDiscord(channel, `Comic #${choice} does not exist!`);
        }
    }
    var url = '';
    if (choice === 0) {
        url = 'http://xkcd.com/info.0.json';
    } else {
        url = `http://xkcd.com/${choice}/info.0.json`;
    }
    http.get(url, function (res) {
        var body = '';
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
            var output = JSON.parse(body);
            var message = '';
            //  if (bot === BotEnum.DISCORD) {
            message = `__**${output.title}, ${output.year}**__
*Comic #${output.num}*
${output.alt}`;
            bu.sendFile(channel, message, output.img);
            //xkcdMax = output.num;
            //getXkcd(channel, words, bot);
            //sendMessageToDiscord(channel, output.file, bot);
        });
    });
}<|endoftext|>


<commit_before>// jshint esversion: 6
(function() {
  'use strict';

  const Generator = require('yeoman-generator');
  const chalk = require('chalk');
  const yosay = require('yosay');
  const path = require('path');
  const fs = require('fs');
  const _ = require('lodash');

  var copyTemplate = (fs, template, path, options) => {
    fs.copyTpl(template, path, options);
  };

  var chooseDBImage = (dbType) =>{
    switch (dbType) {
      case 'postgres':
        return {image: 'postgres:9.6.2-alpine', port: '5432:5432'};
      default:
      return '';
    }
  };

  module.exports = class extends Generator {

    constructor(args, opts) {
      super(args, opts);
      this.option('skip-install');

      this.options.appname = path.basename(process.cwd());
      this.props = {};
    }

    initializing() {
      this.log(yosay(
        'Welcome to the awesome ' + chalk.red('generator-rest-es6') + ' generator!'
      ));
    }

    prompting() {
      this.questions = [];
      this.questions = this.questions.concat({
        type: 'input',
        name: 'appname',
        message: 'Your project name',
        default: this.options.appname // Default to current folder name
      }, {
        type: 'list',
        name: 'database',
        message: 'Select a database to use:',
        choices: [
          'none',
          'MongoDB',
          'Postgres',
          'Mysql',
          'Sqlite',
          'Mssql'
        ]
      });
      return this.prompt(this.questions).then((answers) => {
        this.props = answers;
      });
    }

    configuring() {
      this.destinationRoot('./' + this.props.appname);
    }

    writing() {
      copyTemplate(this.fs, this.templatePath('.jshint'), this.destinationPath('.jshint'));
      copyTemplate(this.fs, this.templatePath('.gitignore'), this.destinationPath('.gitignore'));
      copyTemplate(this.fs, this.templatePath('.editorconfig'), this.destinationPath('.editorconfig'));
      copyTemplate(this.fs, this.templatePath('.babelrc'), this.destinationPath('.babelrc'));
      copyTemplate(this.fs, this.templatePath('.env'), this.destinationPath('.env'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase()
      });
      copyTemplate(this.fs, this.templatePath('_Dockerfile'), this.destinationPath('Dockerfile'));

      let dockerDBImage = chooseDBImage(this.props.database.toLowerCase());
      copyTemplate(this.fs, this.templatePath('_docker-compose.yml'), this.destinationPath('docker-compose.yml'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase(),
        dbImage: dockerDBImage.image,
        dbPorts: dockerDBImage.port
      });

      copyTemplate(this.fs, this.templatePath('_package.json'), this.destinationPath('package.json'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('config/_config.json'), this.destinationPath('config/config.json'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase()
      });
      copyTemplate(this.fs, this.templatePath('config/_db-config.js'), this.destinationPath('config/db-config.js'), {
        dbName: this.props.appname,
        dbType: this.props.database.toLowerCase()
      });

      copyTemplate(this.fs, this.templatePath('bin/_www'), this.destinationPath('bin/www'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('_app.js'), this.destinationPath('app.js'), {
        appName: this.props.appname
      });

      copyTemplate(this.fs, this.templatePath('models/_index.js'), this.destinationPath('server/models/index.js'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('components/_index.js'), this.destinationPath('server/components/index.js'), {});

      copyTemplate(this.fs, this.templatePath('test/**/*'), this.destinationPath('test/'));

    }

    end() {
      this.npmInstall(['express', 'debug', 'body-parser', 'cors', 'compression', 'morgan',
        'cookie-parser', 'pg', 'pg-hstore', 'http-status', 'sequelize', 'sequelize-cli', 'sequelize-fixtures'
      ], {
        'save': true
      });
      this.npmInstall(['mocha', 'chai', 'nodemon', 'supertest', 'testdouble', 'babel-cli',
        'babel', 'babel-preset-es2015', 'babel-preset-es2017'
      ], {
        'saveDev': true
      });
    }
  };
})();
<commit_msg>iamges docker<commit_after>// jshint esversion: 6
(function() {
  'use strict';

  const Generator = require('yeoman-generator');
  const chalk = require('chalk');
  const yosay = require('yosay');
  const path = require('path');
  const fs = require('fs');
  const _ = require('lodash');

  var copyTemplate = (fs, template, path, options) => {
    fs.copyTpl(template, path, options);
  };

  var chooseDBImage = (dbType) => {
    switch (dbType) {
      case 'postgres':
        return {
          image: 'postgres',
          port: '5432:5432'
        };
      case 'mysql':
        return {
          image: "mysql",
          port: "3306:3306"
        };
      case 'sqlite':
        return {
          image: "dockerpinata/sqlite",
          port: "12345:12345"
        };
      case 'mssql':
        return {
          image: "microsoft/mssql-server-linux",
          port: "1433:1433"
        };
      case 'mongodb':
        return {
          image: "mongo",
          port: "27017:27017"
        };
      default:
        return '';
    }
  };

  module.exports = class extends Generator {

    constructor(args, opts) {
      super(args, opts);
      this.option('skip-install');

      this.options.appname = path.basename(process.cwd());
      this.props = {};
    }

    initializing() {
      this.log(yosay(
        'Welcome to the awesome ' + chalk.red('generator-rest-es6') + ' generator!'
      ));
    }

    prompting() {
      this.questions = [];
      this.questions = this.questions.concat({
        type: 'input',
        name: 'appname',
        message: 'Your project name',
        default: this.options.appname // Default to current folder name
      }, {
        type: 'list',
        name: 'database',
        message: 'Select a database to use:',
        choices: [
          'none',
          'MongoDB',
          'Postgres',
          'Mysql',
          'Sqlite',
          'Mssql'
        ]
      });
      return this.prompt(this.questions).then((answers) => {
        this.props = answers;
      });
    }

    configuring() {
      this.destinationRoot('./' + this.props.appname);
    }

    writing() {
      copyTemplate(this.fs, this.templatePath('.jshint'), this.destinationPath('.jshint'));
      copyTemplate(this.fs, this.templatePath('.gitignore'), this.destinationPath('.gitignore'));
      copyTemplate(this.fs, this.templatePath('.editorconfig'), this.destinationPath('.editorconfig'));
      copyTemplate(this.fs, this.templatePath('.babelrc'), this.destinationPath('.babelrc'));
      copyTemplate(this.fs, this.templatePath('.env'), this.destinationPath('.env'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase()
      });
      copyTemplate(this.fs, this.templatePath('_Dockerfile'), this.destinationPath('Dockerfile'));

      let dockerDBImage = chooseDBImage(this.props.database.toLowerCase());
      copyTemplate(this.fs, this.templatePath('_docker-compose.yml'), this.destinationPath('docker-compose.yml'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase(),
        dbImage: dockerDBImage.image,
        dbPorts: dockerDBImage.port
      });

      copyTemplate(this.fs, this.templatePath('_package.json'), this.destinationPath('package.json'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('config/_config.json'), this.destinationPath('config/config.json'), {
        appName: this.props.appname.toLowerCase(),
        dbType: this.props.database.toLowerCase()
      });
      copyTemplate(this.fs, this.templatePath('config/_db-config.js'), this.destinationPath('config/db-config.js'), {
        dbName: this.props.appname,
        dbType: this.props.database.toLowerCase()
      });

      copyTemplate(this.fs, this.templatePath('bin/_www'), this.destinationPath('bin/www'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('_app.js'), this.destinationPath('app.js'), {
        appName: this.props.appname
      });

      copyTemplate(this.fs, this.templatePath('models/_index.js'), this.destinationPath('server/models/index.js'), {
        appName: this.props.appname
      });
      copyTemplate(this.fs, this.templatePath('components/_index.js'), this.destinationPath('server/components/index.js'), {});

      copyTemplate(this.fs, this.templatePath('test/**/*'), this.destinationPath('test/'));

    }

    end() {
      this.npmInstall(['express', 'debug', 'body-parser', 'cors', 'compression', 'morgan',
        'cookie-parser', 'pg', 'pg-hstore', 'http-status', 'sequelize', 'sequelize-cli', 'sequelize-fixtures'
      ], {
        'save': true
      });
      this.npmInstall(['mocha', 'chai', 'nodemon', 'supertest', 'testdouble', 'babel-cli',
        'babel', 'babel-preset-es2015', 'babel-preset-es2017'
      ], {
        'saveDev': true
      });
    }
  };
})();
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.INTERFACE({
  package: 'foam.nanos.auth',
  name: 'AgentAuthService',

  documentation: `
    The agent auth service is responsible for allowing users to act as
    others if permitted and places the requesting user as an agent of the system within the context.
    A junction between users are created to determine if a user is permitted to act as another user.
    Along with the target & source Id on the junction object (UserUserJunction), a group is
    appended and is used to determine the list of permissions for the current user agent
    access to the system. When acting as another user, the user requesting to act is an "agent"
    within the context. The user being acted as becomes the "user" within the context, and
    the group associated to the junction object is associated to the "user" within the context.
  `,

  methods: [
    {
      name: 'actAs',
      javaReturns: 'foam.nanos.auth.User',
      swiftReturns: 'foam_nanos_auth_User',
      javaThrows: [ 'foam.nanos.auth.AuthorizationException' ],
      swiftThrows: true,
      args: [
        {
          name: 'x',
          javaType: 'foam.core.X',
          swiftType: 'Context'
        },
        {
          name: 'superUser',
          javaType: 'foam.nanos.auth.User'
        }
      ]
    },
    {
      name: 'getCurrentAgent',
      javaReturns: 'foam.nanos.auth.User',
      swiftReturns: 'foam_nanos_auth_User?',
      javaThrows: [ 'foam.nanos.auth.AuthorizationException' ],
      swiftThrows: true,
      args: [
        {
          name: 'x',
          javaType: 'foam.core.X',
          swiftType: 'Context'
        }
      ]
    }
  ]
});
<commit_msg>javaThrows on agentAuthService extended to both authorization & authentication<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.INTERFACE({
  package: 'foam.nanos.auth',
  name: 'AgentAuthService',

  documentation: `
    The agent auth service is responsible for allowing users to act as
    others if permitted and places the requesting user as an agent of the system within the context.
    A junction between users are created to determine if a user is permitted to act as another user.
    Along with the target & source Id on the junction object (UserUserJunction), a group is
    appended and is used to determine the list of permissions for the current user agent
    access to the system. When acting as another user, the user requesting to act is an "agent"
    within the context. The user being acted as becomes the "user" within the context, and
    the group associated to the junction object is associated to the "user" within the context.
  `,

  methods: [
    {
      name: 'actAs',
      javaReturns: 'foam.nanos.auth.User',
      swiftReturns: 'foam_nanos_auth_User',
      javaThrows: [
        'foam.nanos.auth.AuthorizationException',
        'foam.nanos.auth.AuthenticationException'
      ],
      swiftThrows: true,
      args: [
        {
          name: 'x',
          javaType: 'foam.core.X',
          swiftType: 'Context'
        },
        {
          name: 'superUser',
          javaType: 'foam.nanos.auth.User'
        }
      ]
    },
    {
      name: 'getCurrentAgent',
      javaReturns: 'foam.nanos.auth.User',
      swiftReturns: 'foam_nanos_auth_User?',
      javaThrows: [
        'foam.nanos.auth.AuthorizationException',
        'foam.nanos.auth.AuthenticationException'
      ],
      swiftThrows: true,
      args: [
        {
          name: 'x',
          javaType: 'foam.core.X',
          swiftType: 'Context'
        }
      ]
    }
  ]
});
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { Container, Row, Col, Card, CardBody, Button, Label } from "reactstrap";
import gql from "graphql-tag";
import { graphql, withApollo } from "react-apollo";
import Measure from "react-measure";
import Slider from "react-rangeslider";
import "react-rangeslider/lib/index.css";
import Tour from "reactour";
import DecodingCanvas from "./decodingCanvas";

import "./style.css";

const DECODING_SUB = gql`
  subscription LRDecoding($simulatorId: ID!) {
    longRangeCommunicationsUpdate(simulatorId: $simulatorId, crew: true) {
      id
      simulatorId
      name
      messages {
        id
        a
        f
        ra
        rf
        sender
        message
        decodedMessage
        datestamp
      }
    }
  }
`;

const trainingSteps = [
  {
    selector: ".nothing",
    content:
      "When you receive messages from someone outside of your ship, you must first decode them before you can read them."
  },
  {
    selector: ".incoming-messages",
    content:
      "This is the list of messages you have received. Click on one to read it or decode it."
  },
  {
    selector: ".decode-sliders",
    content:
      "Use these two knobs to adjust the amplitude and frequency of the waves you are sending. Amplitude is the height of the wave and frequency is how close together the waves are, or how quickly you send out the waves. To decode the message, you have to line up the yellow wave and the red wave by adjusting the frequency and amplitude."
  },
  {
    selector: ".decode-button ",
    content:
      "Once your yellow intercepting waves line up with the red waves you are receiving, press this button to decode the message."
  },
  {
    selector: ".message-field",
    content:
      "The decoded message will appear here. If the message isn’t coming through in a language you understand, continue to refine your intercepting wavelength until the message comes through clearly."
  }
];

class Decoding extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedMessage: null,
      a: 20,
      f: 10,
      ra: 30,
      rf: 20,
      message:
        "This is my really long testing testing 123 test message. It represents a message" +
        " which might be given to the captain and crew during their flight and would be g" +
        "reat cause for celebration when it is recieved. ",
      decodedMessage: "",
      decodeProgress: null
    };
    this.decodeSubscription = null;
    this.decodeTimeout = null;
  }
  componentWillReceiveProps(nextProps) {
    if (!this.decodeSubscription && !nextProps.data.loading) {
      this.decodeSubscription = nextProps.data.subscribeToMore({
        document: DECODING_SUB,
        variables: { simulatorId: this.props.simulator.id },
        updateQuery: (previousResult, { subscriptionData }) => {
          return Object.assign({}, previousResult, {
            longRangeCommunications:
              subscriptionData.data.longRangeCommunicationsUpdate
          });
        }
      });
    }
  }
  componentWillUnmount() {
    this.decodeSubscription && this.decodeSubscription();
    clearTimeout(this.decodeTimeout);
  }
  decode = () => {
    let {
      selectedMessage,
      decodeProgress,
      decodedMessage,
      message,
      a,
      f,
      ra,
      rf
    } = this.state;
    if (!decodeProgress) {
      decodeProgress = 0;
      decodedMessage = "";
    }

    if (decodeProgress < message.length) {
      decodeProgress += 1;
      // Deterministic function to figure out the char code. Char codes go from 32 to
      // 126 Get the adjuster
      decodedMessage = decodedMessage.split();
      const adjuster =
        (Math.round(Math.sin(decodeProgress * a + f) * ra + rf) +
          message.length) %
          94 +
        32;
      if (a === ra && f === rf) {
        decodedMessage[decodeProgress] = message[decodeProgress - 1];
      } else {
        decodedMessage[decodeProgress] = String.fromCharCode(adjuster);
      }
      this.setState({
        decodedMessage: decodedMessage.join(""),
        decodeProgress
      });
      clearTimeout(this.decodeTimeout);
      this.decodeTimeout = setTimeout(this.decode, 50);
    } else {
      // Update the server
      const mutation = gql`
        mutation UpdateDecodedMessage(
          $id: ID!
          $messageId: ID!
          $decodedMessage: String
          $a: Int
          $f: Int
        ) {
          updateLongRangeDecodedMessage(
            id: $id
            messageId: $messageId
            decodedMessage: $decodedMessage
            a: $a
            f: $f
          )
        }
      `;
      const variables = {
        id: this.props.data.longRangeCommunications[0].id,
        messageId: selectedMessage,
        decodedMessage: this.state.decodedMessage,
        a,
        f
      };
      this.props.client.mutate({
        mutation,
        variables
      });
      this.setState({ decodeProgress: null });
    }
  };
  _selectMessage(message) {
    this.setState({
      selectedMessage: message.id,
      a: message.a,
      f: message.f,
      decodedMessage:
        message.a === message.ra && message.f === message.rf
          ? message.message
          : ""
    });
  }
  _handleOnChange(which, e) {
    const obj = {};
    obj[which] = e;
    this.setState(obj);
  }
  _handleChangeComplete() {
    let { selectedMessage, a, f } = this.state;
    const mutation = gql`
      mutation UpdateDecodedMessage(
        $id: ID!
        $messageId: ID!
        $a: Int
        $f: Int
      ) {
        updateLongRangeDecodedMessage(
          id: $id
          messageId: $messageId
          a: $a
          f: $f
        )
      }
    `;
    const variables = {
      id: this.props.data.longRangeCommunications[0].id,
      messageId: selectedMessage,
      a,
      f
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  }
  render() {
    let alertClass = `alertColor${this.props.simulator.alertLevel || 5}`;
    if (this.props.data.loading || !this.props.data.longRangeCommunications)
      return null;
    const sys = this.props.data.longRangeCommunications[0];
    let selectedMessage = { a: 20, f: 20 };
    if (this.state.selectedMessage) {
      selectedMessage = sys.messages.find(
        m => m.id === this.state.selectedMessage
      );
    }
    return (
      <Container fluid className="lrComm">
        <Row>
          <Col sm={8}>
            <Card style={{ padding: 0 }}>
              <Measure
                bounds
                onResize={contentRect => {
                  this.setState({ dimensions: contentRect.bounds });
                }}
              >
                {({ measureRef }) => (

                    {this.state.dimensions &&
                      selectedMessage && (
                        <DecodingCanvas
                          dimensions={this.state.dimensions}
                          decodeProgress={this.state.decodeProgress}
                          ra={selectedMessage.ra}
                          rf={selectedMessage.rf}
                          message={selectedMessage.message}
                          a={this.state.a}
                          f={this.state.f}
                        />
                      )}

                )}
              </Measure>
            </Card>
            <Button
              className="decode-button"
              disabled={!this.state.selectedMessage}
              color="secondary"
              onClick={() => {
                this.setState(
                  {
                    decodedMessage: "",
                    message: selectedMessage.message,
                    ra: selectedMessage.ra,
                    rf: selectedMessage.rf
                  },
                  this.decode.bind(this)
                );
              }}
            >
              Decode
            </Button>
            <Row className="decode-sliders">
              <Col>
                Frequency
                <Slider
                  className={`frequency-slider ${alertClass}`}
                  value={this.state.f}
                  orientation="horizontal"
                  onChange={this._handleOnChange.bind(this, "f")}
                  onChangeComplete={this._handleChangeComplete.bind(this, "f")}
                  tooltip={false}
                  min={5}
                  step={5}
                  max={50}
                />
                Amplitude
                <Slider
                  className={`amplitude-slider ${alertClass}`}
                  value={this.state.a}
                  orientation="horizontal"
                  onChange={this._handleOnChange.bind(this, "a")}
                  onChangeComplete={this._handleChangeComplete.bind(this, "a")}
                  tooltip={false}
                  min={5}
                  step={5}
                  max={100}
                />
              </Col>
            </Row>
            <Row>
              <Card className="message-field">
                <CardBody>

{this.state.decodedMessage}

                </CardBody>
              </Card>
            </Row>
          </Col>
          <Col sm={4} className="incoming-messages">

Incoming Messages

            <Card style={{ minHeight: "40px" }}>
              {sys.messages.map(m => (

                  {m.datestamp} - {m.sender}

              ))}
            </Card>
          </Col>
        </Row>
        <Tour
          steps={trainingSteps}
          isOpen={this.props.clientObj.training}
          onRequestClose={this.props.stopTraining}
        />
      </Container>
    );
  }
}

const DECODING_QUERY = gql`
  query LRDecoding($simulatorId: ID) {
    longRangeCommunications(simulatorId: $simulatorId, crew: true) {
      id
      simulatorId
      name
      messages {
        id
        a
        f
        ra
        rf
        sender
        message
        decodedMessage
        datestamp
      }
    }
  }
`;
export default graphql(DECODING_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: {
      simulatorId: ownProps.simulator.id
    }
  })
})(withApollo(Decoding));
<commit_msg>Closes #593<commit_after>import React, { Component } from "react";
import { Container, Row, Col, Card, CardBody, Button, Label } from "reactstrap";
import gql from "graphql-tag";
import { graphql, withApollo } from "react-apollo";
import Measure from "react-measure";
import Slider from "react-rangeslider";
import "react-rangeslider/lib/index.css";
import Tour from "reactour";
import DecodingCanvas from "./decodingCanvas";

import "./style.css";

const DECODING_SUB = gql`
  subscription LRDecoding($simulatorId: ID!) {
    longRangeCommunicationsUpdate(simulatorId: $simulatorId, crew: true) {
      id
      simulatorId
      name
      messages {
        id
        a
        f
        ra
        rf
        sender
        message
        decodedMessage
        datestamp
      }
    }
  }
`;

const trainingSteps = [
  {
    selector: ".nothing",
    content:
      "When you receive messages from someone outside of your ship, you must first decode them before you can read them."
  },
  {
    selector: ".incoming-messages",
    content:
      "This is the list of messages you have received. Click on one to read it or decode it."
  },
  {
    selector: ".decode-sliders",
    content:
      "Use these two knobs to adjust the amplitude and frequency of the waves you are sending. Amplitude is the height of the wave and frequency is how close together the waves are, or how quickly you send out the waves. To decode the message, you have to line up the yellow wave and the red wave by adjusting the frequency and amplitude."
  },
  {
    selector: ".decode-button ",
    content:
      "Once your yellow intercepting waves line up with the red waves you are receiving, press this button to decode the message."
  },
  {
    selector: ".message-field",
    content:
      "The decoded message will appear here. If the message isn’t coming through in a language you understand, continue to refine your intercepting wavelength until the message comes through clearly."
  }
];

class Decoding extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedMessage: null,
      a: 20,
      f: 10,
      ra: 30,
      rf: 20,
      message:
        "This is my really long testing testing 123 test message. It represents a message" +
        " which might be given to the captain and crew during their flight and would be g" +
        "reat cause for celebration when it is recieved. ",
      decodedMessage: "",
      decodeProgress: null
    };
    this.decodeSubscription = null;
    this.decodeTimeout = null;
  }
  componentWillReceiveProps(nextProps) {
    if (!this.decodeSubscription && !nextProps.data.loading) {
      this.decodeSubscription = nextProps.data.subscribeToMore({
        document: DECODING_SUB,
        variables: { simulatorId: this.props.simulator.id },
        updateQuery: (previousResult, { subscriptionData }) => {
          return Object.assign({}, previousResult, {
            longRangeCommunications:
              subscriptionData.data.longRangeCommunicationsUpdate
          });
        }
      });
    }
  }
  componentWillUnmount() {
    this.decodeSubscription && this.decodeSubscription();
    clearTimeout(this.decodeTimeout);
  }
  decode = () => {
    let {
      selectedMessage,
      decodeProgress,
      decodedMessage,
      message,
      a,
      f,
      ra,
      rf
    } = this.state;
    if (!decodeProgress) {
      decodeProgress = 0;
      decodedMessage = "";
    }

    if (decodeProgress < message.length) {
      decodeProgress += 1;
      // Deterministic function to figure out the char code. Char codes go from 32 to
      // 126 Get the adjuster
      decodedMessage = decodedMessage.split();
      const adjuster =
        (Math.round(Math.sin(decodeProgress * a + f) * ra + rf) +
          message.length) %
          94 +
        32;
      if (a === ra && f === rf) {
        decodedMessage[decodeProgress] = message[decodeProgress - 1];
      } else {
        decodedMessage[decodeProgress] = String.fromCharCode(adjuster);
      }
      this.setState({
        decodedMessage: decodedMessage.join(""),
        decodeProgress
      });
      clearTimeout(this.decodeTimeout);
      this.decodeTimeout = setTimeout(this.decode, 50);
    } else {
      // Update the server
      const mutation = gql`
        mutation UpdateDecodedMessage(
          $id: ID!
          $messageId: ID!
          $decodedMessage: String
          $a: Int
          $f: Int
        ) {
          updateLongRangeDecodedMessage(
            id: $id
            messageId: $messageId
            decodedMessage: $decodedMessage
            a: $a
            f: $f
          )
        }
      `;
      const variables = {
        id: this.props.data.longRangeCommunications[0].id,
        messageId: selectedMessage,
        decodedMessage: this.state.decodedMessage,
        a,
        f
      };
      this.props.client.mutate({
        mutation,
        variables
      });
      this.setState({ decodeProgress: null });
    }
  };
  _selectMessage(message) {
    this.setState({
      selectedMessage: message.id,
      a: message.a,
      f: message.f,
      decodedMessage:
        message.a === message.ra && message.f === message.rf
          ? message.message
          : ""
    });
  }
  _handleOnChange(which, e) {
    const obj = {};
    obj[which] = e;
    this.setState(obj);
  }
  _handleChangeComplete() {
    let { selectedMessage, a, f } = this.state;
    if (!selectedMessage) return;
    const mutation = gql`
      mutation UpdateDecodedMessage(
        $id: ID!
        $messageId: ID!
        $a: Int
        $f: Int
      ) {
        updateLongRangeDecodedMessage(
          id: $id
          messageId: $messageId
          a: $a
          f: $f
        )
      }
    `;
    const variables = {
      id: this.props.data.longRangeCommunications[0].id,
      messageId: selectedMessage,
      a,
      f
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  }
  render() {
    let alertClass = `alertColor${this.props.simulator.alertLevel || 5}`;
    if (this.props.data.loading || !this.props.data.longRangeCommunications)
      return null;
    const sys = this.props.data.longRangeCommunications[0];
    let selectedMessage = { a: 20, f: 20 };
    if (this.state.selectedMessage) {
      selectedMessage = sys.messages.find(
        m => m.id === this.state.selectedMessage
      );
    }
    return (
      <Container fluid className="lrComm">
        <Row>
          <Col sm={8}>
            <Card style={{ padding: 0 }}>
              <Measure
                bounds
                onResize={contentRect => {
                  this.setState({ dimensions: contentRect.bounds });
                }}
              >
                {({ measureRef }) => (

                    {this.state.dimensions &&
                      selectedMessage && (
                        <DecodingCanvas
                          dimensions={this.state.dimensions}
                          decodeProgress={this.state.decodeProgress}
                          ra={selectedMessage.ra}
                          rf={selectedMessage.rf}
                          message={selectedMessage.message}
                          a={this.state.a}
                          f={this.state.f}
                        />
                      )}

                )}
              </Measure>
            </Card>
            <Button
              className="decode-button"
              disabled={!this.state.selectedMessage}
              color="secondary"
              onClick={() => {
                this.setState(
                  {
                    decodedMessage: "",
                    message: selectedMessage.message,
                    ra: selectedMessage.ra,
                    rf: selectedMessage.rf
                  },
                  this.decode.bind(this)
                );
              }}
            >
              Decode
            </Button>
            <Row className="decode-sliders">
              <Col>
                Frequency
                <Slider
                  className={`frequency-slider ${alertClass}`}
                  value={this.state.f}
                  orientation="horizontal"
                  onChange={this._handleOnChange.bind(this, "f")}
                  onChangeComplete={this._handleChangeComplete.bind(this, "f")}
                  tooltip={false}
                  min={5}
                  step={5}
                  max={50}
                />
                Amplitude
                <Slider
                  className={`amplitude-slider ${alertClass}`}
                  value={this.state.a}
                  orientation="horizontal"
                  onChange={this._handleOnChange.bind(this, "a")}
                  onChangeComplete={this._handleChangeComplete.bind(this, "a")}
                  tooltip={false}
                  min={5}
                  step={5}
                  max={100}
                />
              </Col>
            </Row>
            <Row>
              <Card className="message-field">
                <CardBody>

{this.state.decodedMessage}

                </CardBody>
              </Card>
            </Row>
          </Col>
          <Col sm={4} className="incoming-messages">

Incoming Messages

            <Card style={{ minHeight: "40px" }}>
              {sys.messages.map(m => (

                  {m.datestamp} - {m.sender}

              ))}
            </Card>
          </Col>
        </Row>
        <Tour
          steps={trainingSteps}
          isOpen={this.props.clientObj.training}
          onRequestClose={this.props.stopTraining}
        />
      </Container>
    );
  }
}

const DECODING_QUERY = gql`
  query LRDecoding($simulatorId: ID) {
    longRangeCommunications(simulatorId: $simulatorId, crew: true) {
      id
      simulatorId
      name
      messages {
        id
        a
        f
        ra
        rf
        sender
        message
        decodedMessage
        datestamp
      }
    }
  }
`;
export default graphql(DECODING_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: {
      simulatorId: ownProps.simulator.id
    }
  })
})(withApollo(Decoding));
<|endoftext|>


<commit_before>'use strict';

var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var rp = require('request-promise');
var path = require('path');

var abort = false;

module.exports = yeoman.Base.extend({
  prompting: function () {
    var done = this.async();
    var dirname = path.basename(this.env.cwd);
    this.log(yosay('Welcome to ' + chalk.red('rff-gulp') + ' generator!'));
    var prompts = [{
      type: 'confirm',
      name: 'ready',
      message: 'Would you like to create a new project in "' + dirname + '" directory?',
      default: true
    }];
    this.prompt(prompts, function (props) {
      abort = !props.ready;
      done();
    });
  },

  writing: function () {
    if (abort) {
      this.log('Process canceled.');
      return;
    }
    var self = this;
    var user = 'rakuten-frontend';
    var repo = 'rff-gulp';
    var jsonUrl = 'https://github.com/' + user + '/' + repo + '/raw/master/package.json';
    return rp(jsonUrl)
      .then(function (json) {
        return JSON.parse(json);
      })
      .then(function (pkg) {
        var remoteUrl = 'https://github.com/' + user + '/' + repo + '/releases/download/v' + pkg.version + '/' + repo + '-v' + pkg.version + '.zip';
        return new Promise(function (resolve, reject) {
          self.remote(remoteUrl, function (err, remote) {
            if (err) {
              reject(err);
              return;
            }
            resolve(remote);
          }, true);
        });
      })
      .then(function (remote) {
        remote.directory('.', '.');
      })
      .catch(function (err) {
        abort = true;
        self.log(chalk.red('Failed to fetch template!'));
        self.log(chalk.gray(err.toString()));
      });
  },

  install: function () {
    if (abort) {
      return;
    }
    this.installDependencies({bower: false});
  }
});
<commit_msg>Follow official document syntax<commit_after>'use strict';

var generators = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var rp = require('request-promise');
var path = require('path');

var abort = false;

module.exports = generators.Base.extend({
  prompting: function () {
    var done = this.async();
    var dirname = path.basename(this.env.cwd);
    this.log(yosay('Welcome to ' + chalk.red('rff-gulp') + ' generator!'));
    var prompts = [{
      type: 'confirm',
      name: 'ready',
      message: 'Would you like to create a new project in "' + dirname + '" directory?',
      default: true
    }];
    this.prompt(prompts, function (props) {
      abort = !props.ready;
      done();
    });
  },

  writing: function () {
    if (abort) {
      this.log('Process canceled.');
      return;
    }
    var self = this;
    var user = 'rakuten-frontend';
    var repo = 'rff-gulp';
    var jsonUrl = 'https://github.com/' + user + '/' + repo + '/raw/master/package.json';
    return rp(jsonUrl)
      .then(function (json) {
        return JSON.parse(json);
      })
      .then(function (pkg) {
        var remoteUrl = 'https://github.com/' + user + '/' + repo + '/releases/download/v' + pkg.version + '/' + repo + '-v' + pkg.version + '.zip';
        return new Promise(function (resolve, reject) {
          self.remote(remoteUrl, function (err, remote) {
            if (err) {
              reject(err);
              return;
            }
            resolve(remote);
          }, true);
        });
      })
      .then(function (remote) {
        remote.directory('.', '.');
      })
      .catch(function (err) {
        abort = true;
        self.log(chalk.red('Failed to fetch template!'));
        self.log(chalk.gray(err.toString()));
      });
  },

  install: function () {
    if (abort) {
      return;
    }
    this.installDependencies({bower: false});
  }
});
<|endoftext|>


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

define(function() {
	'use strict';

	function ctrl($rootScope, $scope, $state, OAuth, $ionicPopup, storage, push) {

		cordova.plugins.Keyboard.disableScroll(true);

		if(storage.get('access_token') && storage.get('loggedin'))
			$state.go('tab.newsfeed');

			console.log(storage.get('access_token'));
			console.log(storage.get('loggedin'));

		$scope.inprogress = false;
		$scope.login = function() {
			if($scope.inprogress)
				return false;
			$scope.inprogress = true;

			OAuth.login($scope.username, $scope.password, function(success){
				if(success){
					//$state.go('tab.newsfeed');
					push.register();
					$rootScope.user_guid = storage.get('user_guid');
					$state.go('tutorial');
				} else {

					var alertPopup = $ionicPopup.alert({
						title: 'Ooops..',
						template: 'We couldn\'t log you in. Please check your credentials and try again.'
					});

					//clear the password?
					alertPopup.then(function(res) {

					});

				}
				$scope.inprogress = false;
			}, function(error){
				$scope.inprogress = false;
			});

		};

	}

	ctrl.$inject = ['$rootScope', '$scope', '$state', 'OAuth', '$ionicPopup', 'storage', 'push'];
	return ctrl;

}); <commit_msg>get location details after signup<commit_after>/**
 * Minds::mobile
 * Login controller
 *
 * @author Mark Harding
 */

define(function() {
	'use strict';

	function ctrl($rootScope, $scope, $state, OAuth, Client, $ionicPopup, storage, push, $ionicLoading) {

		cordova.plugins.Keyboard.disableScroll(true);

		if(storage.get('access_token') && storage.get('loggedin'))
			$state.go('tab.newsfeed');

			console.log(storage.get('access_token'));
			console.log(storage.get('loggedin'));

		$scope.inprogress = false;
		$scope.login = function() {
			if($scope.inprogress)
				return false;

			$ionicLoading.show({
				template: '<ion-spinner></ion-spinner>'
				});

			$scope.inprogress = true;

			OAuth.login($scope.username, $scope.password, function(success){
				$ionicLoading.hide();
				if(success){
					//$state.go('tab.newsfeed');
					push.register();
					$rootScope.user_guid = storage.get('user_guid');

					//get our city and other information
					Client.get('api/v1/channel/me', {}, function(success){
						storage.set('city', success.channel.city);
					//	storage.set('coordinates', success.channel.coordinates);
					}, function(fail){});

					$state.go('tutorial');
				} else {

					var alertPopup = $ionicPopup.alert({
						title: 'Ooops..',
						template: 'We couldn\'t log you in. Please check your credentials and try again.'
					});

					//clear the password?
					alertPopup.then(function(res) {

					});

				}
				$scope.inprogress = false;
			}, function(error){
				$ionicLoading.hide();
				$scope.inprogress = false;
			});

		};

	}

	ctrl.$inject = ['$rootScope', '$scope', '$state', 'OAuth', 'Client', '$ionicPopup', 'storage', 'push', '$ionicLoading'];
	return ctrl;

}); <|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch.ui',
  name: 'CapableView',
  extends: 'foam.u2.View',
  documentation: 'A view for displaying capable objects',

  imports: [
    'crunchController',
    'notify',
    'subject',
    'userCapabilityJunctionDAO'
  ],

  requires: [
    'foam.log.LogLevel',
    'foam.nanos.crunch.AgentCapabilityJunction',
    'foam.nanos.crunch.UserCapabilityJunction',
    'foam.u2.detail.AbstractSectionedDetailView',
    'foam.u2.detail.SectionView'
  ],

  css: `
    ^ .foam-u2-detail-SectionedDetailPropertyView .foam-u2-CheckBox-label {
      top: 0px;
      position: relative;
    }
  `,

  properties: [
    {
      name: 'capableObj',
      documentation: 'a capable object'
    },
    {
      class: 'FObjectArray',
      of: 'foam.u2.wizard.BaseWizardlet',
      name: 'wizardlets',
      documentation: 'wizardlets for capable payloads',
      postSet: function() {
        this.addListeners();
      }
    },
    {
      class: 'Array',
      name: 'wizardletSectionsList',
      documentation: `
        sections for wizardlets
        wizardletSectionsList[i] stores sections for wizardlets[i]
      `,
      factory: function() {
        return this.wizardlets.map(wizardlet =>
          this.AbstractSectionedDetailView.create({
            of: wizardlet.of
          }).sections);
      }
    },
    {
      class: 'Boolean',
      name: 'showTitle'
    }
  ],

  methods: [
    async function initE() {
      this.SUPER();

      const self = this;

      // set capable payloads to capabilities if the capbilities don't have payloads yet
      const hasNoPayloads = ! this.capableObj.capablePayloads ||
        Object.keys(this.capableObj.capablePayloads).length === 0;

      if ( hasNoPayloads ) {
          try {
            await this.capableObj.setRequirements(this.capableObj.capableRequirements);
          } catch (e) {
            this.notify(e.message, '', this.LogLevel.ERROR, true);
          }
      }

      // set wizardlets based on the capableObj
      this.wizardlets = this.capableObj ?
        await this.crunchController.getWizardletsFromCapable(this.capableObj) : [];

      this.start().addClass(this.myClass())
        .forEach(this.wizardletSectionsList, function(sections, index) {
          sections.map(section => (
            this.tag(self.SectionView, {
              section,
              data: self.wizardlets[index].data,
              showTitle: self.showTitle
            })
          ));
        }).end()
      .end();
    },

    // add listeners to payloads
    function addListeners() {
      for ( payload of this.capableObj.capablePayloads ) {
        payload.data.sub(this.clonePayloads);
      }
    }
  ],

  listeners: [
    {
      name: 'clonePayloads',
      documentation: `
        This listener reassgins capablePayloads array each time its elements get updated.
        The purpose of this is to listen to changes for payloads of a capable object
        that calls this view. (e.g., for bank accounts which are an capable object, we want to
        know if acceptance doc payloads are valid or not)
      `,
      code: function() {
        this.capableObj.capablePayloads = [...this.capableObj.capablePayloads];
      }
    }
  ]
});
<commit_msg>Fix null pointer exception in CapableView  (#4396)<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch.ui',
  name: 'CapableView',
  extends: 'foam.u2.View',
  documentation: 'A view for displaying capable objects',

  imports: [
    'crunchController',
    'notify',
    'subject',
    'userCapabilityJunctionDAO'
  ],

  requires: [
    'foam.log.LogLevel',
    'foam.nanos.crunch.AgentCapabilityJunction',
    'foam.nanos.crunch.UserCapabilityJunction',
    'foam.u2.detail.AbstractSectionedDetailView',
    'foam.u2.detail.SectionView'
  ],

  css: `
    ^ .foam-u2-detail-SectionedDetailPropertyView .foam-u2-CheckBox-label {
      top: 0px;
      position: relative;
    }
  `,

  properties: [
    {
      name: 'capableObj',
      documentation: 'a capable object'
    },
    {
      class: 'FObjectArray',
      of: 'foam.u2.wizard.BaseWizardlet',
      name: 'wizardlets',
      documentation: 'wizardlets for capable payloads',
      postSet: function() {
        this.listenOnPayloads();
      }
    },
    {
      class: 'Array',
      name: 'wizardletSectionsList',
      documentation: `
        sections for wizardlets
        wizardletSectionsList[i] stores sections for wizardlets[i]
      `,
      factory: function() {
        return this.wizardlets.map(wizardlet =>
          this.AbstractSectionedDetailView.create({
            of: wizardlet.of
          }).sections);
      }
    },
    {
      class: 'Boolean',
      name: 'showTitle'
    }
  ],

  methods: [
    async function initE() {
      this.SUPER();

      const self = this;

      // a flag for checking if the capable object has payloads
      const hasPayloads = this.capableObj.capablePayloads &&
        Object.keys(this.capableObj.capablePayloads).length > 0;

      // set capable payloads to capabilities if the capbilities don't have payloads yet
      if ( ! hasPayloads ) {
          try {
            await this.capableObj.setRequirements(this.capableObj.capableRequirements);
          } catch (e) {
            this.notify(e.message, '', this.LogLevel.ERROR, true);
          }
      }

      // set wizardlets based on the capableObj
      // note: payloads data are also set from getWizardletsFromCapable
      //       this is why we add listeners to payloads data after wizardlets are set
      this.wizardlets = this.capableObj ?
        await this.crunchController.getWizardletsFromCapable(this.capableObj) : [];

      this.start().addClass(this.myClass())
        .forEach(this.wizardletSectionsList, function(sections, index) {
          sections.map(section => (
            this.tag(self.SectionView, {
              section,
              data: self.wizardlets[index].data,
              showTitle: self.showTitle
            })
          ));
        }).end()
      .end();
    },

    // add listeners to payload data
    function listenOnPayloads() {
      for ( const payload of this.capableObj.capablePayloads ) {
        if ( payload.data ) payload.data.sub(this.clonePayloads);
      }
    }
  ],

  listeners: [
    {
      name: 'clonePayloads',
      documentation: `
        This listener reassgins capablePayloads array each time its elements get updated.
        The purpose of this is to listen to changes for payloads of a capable object
        that calls this view. (e.g., for bank accounts which are an capable object, we want to
        know if acceptance doc payloads are valid or not)
      `,
      code: function() {
        this.capableObj.capablePayloads = [...this.capableObj.capablePayloads];
      }
    }
  ]
});
<|endoftext|>


<commit_before>/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import {formatDate} from '../../../DateUtils';
import { _t } from '../../../languageHandler';
import filesize from "filesize";
import AccessibleButton from "./AccessibleButton";
import Modal from "../../../Modal";
import * as sdk from "../../../index";
import {Key} from "../../../Keyboard";
import FocusLock from "react-focus-lock";

export default class ImageView extends React.Component {
    static propTypes = {
        src: PropTypes.string.isRequired, // the source of the image being displayed
        name: PropTypes.string, // the main title ('name') for the image
        link: PropTypes.string, // the link (if any) applied to the name of the image
        width: PropTypes.number, // width of the image src in pixels
        height: PropTypes.number, // height of the image src in pixels
        fileSize: PropTypes.number, // size of the image src in bytes
        onFinished: PropTypes.func.isRequired, // callback when the lightbox is dismissed

        // the event (if any) that the Image is displaying. Used for event-specific stuff like
        // redactions, senders, timestamps etc.  Other descriptors are taken from the explicit
        // properties above, which let us use lightboxes to display images which aren't associated
        // with events.
        mxEvent: PropTypes.object,
    };

    constructor(props) {
        super(props);
        this.state = {
            rotation: 0,
            zoom: 100,
            translationX: 0,
            translationY: 0,
            moving: false,
        };
    }

    initX = 0;
    initY = 0;
    lastX = 0;
    lastY = 0;

    componentDidMount() {
        /* We have to use addEventListener() because the listener
         * needs to be passive in order to work with Chromium */
        this.focusLock.addEventListener('wheel', this.onWheel, { passive: false });
    }

    componentWillUnmount() {
        this.focusLock.removeEventListener('wheel', this.onWheel);
    }

    onKeyDown = (ev) => {
        if (ev.key === Key.ESCAPE) {
            ev.stopPropagation();
            ev.preventDefault();
            this.props.onFinished();
        }
    };

    onWheel = (ev) => {
        ev.stopPropagation();
        ev.preventDefault();
        const newZoom =this.state.zoom - ev.deltaY;

        if (newZoom <= 100) {
            this.setState({
                zoom: 100,
                translationX: 0,
                translationY: 0,
            });
            return;
        }
        this.setState({
            zoom: newZoom,
        });
    }

    onRedactClick = () => {
        const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
        Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, {
            onFinished: (proceed) => {
                if (!proceed) return;
                this.props.onFinished();
                MatrixClientPeg.get().redactEvent(
                    this.props.mxEvent.getRoomId(), this.props.mxEvent.getId(),
                ).catch(function(e) {
                    const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                    // display error message stating you couldn't delete this.
                    const code = e.errcode || e.statusCode;
                    Modal.createTrackedDialog('You cannot delete this image.', '', ErrorDialog, {
                        title: _t('Error'),
                        description: _t('You cannot delete this image. (%(code)s)', {code: code}),
                    });
                });
            },
        });
    };

    getName() {
        let name = this.props.name;
        if (name && this.props.link) {
            name = { name };
        }
        return name;
    }

    onRotateCounterClockwiseClick = () => {
        const cur = this.state.rotation;
        const rotationDegrees = (cur - 90) % 360;
        this.setState({ rotation: rotationDegrees });
    };

    onRotateClockwiseClick = () => {
        const cur = this.state.rotation;
        const rotationDegrees = (cur + 90) % 360;
        this.setState({ rotation: rotationDegrees });
    };

    onZoomInClick = () => {
        this.setState({
            zoom: this.state.zoom + 10,
        });
    };

    onZoomOutClick = () => {
        if (this.state.zoom <= 100) {
            this.setState({
                zoom: 100,
                translationX: 0,
                translationY: 0,
            });
            return;
        }
        this.setState({
            zoom: this.state.zoom - 10,
        });
    }

    onStartMoving = ev => {
        ev.stopPropagation();
        ev.preventDefault();

        if (this.state.zoom <= 100) return false;

        this.setState({moving: true});
        this.initX = ev.pageX - this.lastX;
        this.initY = ev.pageY - this.lastY;
    }

    onMoving = ev => {
        ev.stopPropagation();
        ev.preventDefault();

        if (!this.state.moving) return false;

        this.lastX = ev.pageX - this.initX;
        this.lastY = ev.pageY - this.initY;
        this.setState({
            translationX: this.lastX,
            translationY: this.lastY,
        });
    }

    onEndMoving = ev => {
        this.setState({moving: false});
    }

    render() {
        let mayRedact = false;
        const showEventMeta = !!this.props.mxEvent;

        let res;
        if (this.props.width && this.props.height) {
            res = this.props.width + "x" + this.props.height + "px";
        }

        let size;
        if (this.props.fileSize) {
            size = filesize(this.props.fileSize);
        }

        let sizeRes;
        if (size && res) {
            sizeRes = size + ", " + res;
        } else {
            sizeRes = size || res;
        }

        let metadata;
        if (showEventMeta) {
            // Figure out the sender, defaulting to mxid
            let sender = this.props.mxEvent.getSender();
            const cli = MatrixClientPeg.get();
            const room = cli.getRoom(this.props.mxEvent.getRoomId());
            if (room) {
                mayRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId);
                const member = room.getMember(sender);
                if (member) sender = member.name;
            }

            metadata = (

                { _t('Uploaded on %(date)s by %(user)s', {
                    date: formatDate(new Date(this.props.mxEvent.getTs())),
                    user: sender,
                }) }

);
        }

        let redactButton;
        if (mayRedact) {
            redactButton = (
                <AccessibleButton className="mx_ImageView_button" title={_t("Remove")} onClick={ this.onRedactClick }>

                </AccessibleButton>
            );
        }

        const rotationDegrees = this.state.rotation + "deg";
        const zoomPercentage = this.state.zoom/100;
        const translatePixelsX = this.state.translationX + "px";
        const translatePixelsY = this.state.translationY + "px";
        /* The order of the values is important!
         * First, we translate and only then we rotate, otherwise
         * we would apply the translation to an already rotated
         * image causing it translate in the wrong direction. */
        const style = {
            transform: `translateX(${translatePixelsX})
                        translateY(${translatePixelsY})
                        scale(${zoomPercentage})
                        rotate(${rotationDegrees})`,
        };

        return (
            <FocusLock
                returnFocus={true}
                lockProps={{
                    onKeyDown: this.onKeyDown,
                    role: "dialog",
                }}
                className="mx_ImageView"
                ref={ref => this.focusLock = ref}
            >

                            { this.getName() }

                        { metadata }
                        { sizeRes }

                        <AccessibleButton className="mx_ImageView_button" title={_t("Zoom in")} onClick={ this.onZoomInClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Zoom out")} onClick={ this.onZoomOutClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Rotate Left")} onClick={ this.onRotateCounterClockwiseClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Rotate Right")} onClick={ this.onRotateClockwiseClick }>

                        </AccessibleButton>

                        { redactButton }
                        <AccessibleButton className="mx_ImageView_button" title={_t("Close")} onClick={ this.props.onFinished }>

                        </AccessibleButton>

            </FocusLock>
        );
    }
}
<commit_msg>Reorder label items<commit_after>/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import {formatDate} from '../../../DateUtils';
import { _t } from '../../../languageHandler';
import filesize from "filesize";
import AccessibleButton from "./AccessibleButton";
import Modal from "../../../Modal";
import * as sdk from "../../../index";
import {Key} from "../../../Keyboard";
import FocusLock from "react-focus-lock";

export default class ImageView extends React.Component {
    static propTypes = {
        src: PropTypes.string.isRequired, // the source of the image being displayed
        name: PropTypes.string, // the main title ('name') for the image
        link: PropTypes.string, // the link (if any) applied to the name of the image
        width: PropTypes.number, // width of the image src in pixels
        height: PropTypes.number, // height of the image src in pixels
        fileSize: PropTypes.number, // size of the image src in bytes
        onFinished: PropTypes.func.isRequired, // callback when the lightbox is dismissed

        // the event (if any) that the Image is displaying. Used for event-specific stuff like
        // redactions, senders, timestamps etc.  Other descriptors are taken from the explicit
        // properties above, which let us use lightboxes to display images which aren't associated
        // with events.
        mxEvent: PropTypes.object,
    };

    constructor(props) {
        super(props);
        this.state = {
            rotation: 0,
            zoom: 100,
            translationX: 0,
            translationY: 0,
            moving: false,
        };
    }

    initX = 0;
    initY = 0;
    lastX = 0;
    lastY = 0;

    componentDidMount() {
        /* We have to use addEventListener() because the listener
         * needs to be passive in order to work with Chromium */
        this.focusLock.addEventListener('wheel', this.onWheel, { passive: false });
    }

    componentWillUnmount() {
        this.focusLock.removeEventListener('wheel', this.onWheel);
    }

    onKeyDown = (ev) => {
        if (ev.key === Key.ESCAPE) {
            ev.stopPropagation();
            ev.preventDefault();
            this.props.onFinished();
        }
    };

    onWheel = (ev) => {
        ev.stopPropagation();
        ev.preventDefault();
        const newZoom =this.state.zoom - ev.deltaY;

        if (newZoom <= 100) {
            this.setState({
                zoom: 100,
                translationX: 0,
                translationY: 0,
            });
            return;
        }
        this.setState({
            zoom: newZoom,
        });
    }

    onRedactClick = () => {
        const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
        Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, {
            onFinished: (proceed) => {
                if (!proceed) return;
                this.props.onFinished();
                MatrixClientPeg.get().redactEvent(
                    this.props.mxEvent.getRoomId(), this.props.mxEvent.getId(),
                ).catch(function(e) {
                    const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                    // display error message stating you couldn't delete this.
                    const code = e.errcode || e.statusCode;
                    Modal.createTrackedDialog('You cannot delete this image.', '', ErrorDialog, {
                        title: _t('Error'),
                        description: _t('You cannot delete this image. (%(code)s)', {code: code}),
                    });
                });
            },
        });
    };

    getName() {
        let name = this.props.name;
        if (name && this.props.link) {
            name = { name };
        }
        return name;
    }

    onRotateCounterClockwiseClick = () => {
        const cur = this.state.rotation;
        const rotationDegrees = (cur - 90) % 360;
        this.setState({ rotation: rotationDegrees });
    };

    onRotateClockwiseClick = () => {
        const cur = this.state.rotation;
        const rotationDegrees = (cur + 90) % 360;
        this.setState({ rotation: rotationDegrees });
    };

    onZoomInClick = () => {
        this.setState({
            zoom: this.state.zoom + 10,
        });
    };

    onZoomOutClick = () => {
        if (this.state.zoom <= 100) {
            this.setState({
                zoom: 100,
                translationX: 0,
                translationY: 0,
            });
            return;
        }
        this.setState({
            zoom: this.state.zoom - 10,
        });
    }

    onStartMoving = ev => {
        ev.stopPropagation();
        ev.preventDefault();

        if (this.state.zoom <= 100) return false;

        this.setState({moving: true});
        this.initX = ev.pageX - this.lastX;
        this.initY = ev.pageY - this.lastY;
    }

    onMoving = ev => {
        ev.stopPropagation();
        ev.preventDefault();

        if (!this.state.moving) return false;

        this.lastX = ev.pageX - this.initX;
        this.lastY = ev.pageY - this.initY;
        this.setState({
            translationX: this.lastX,
            translationY: this.lastY,
        });
    }

    onEndMoving = ev => {
        this.setState({moving: false});
    }

    render() {
        let mayRedact = false;
        const showEventMeta = !!this.props.mxEvent;

        let res;
        if (this.props.width && this.props.height) {
            res = this.props.width + "x" + this.props.height + "px";
        }

        let size;
        if (this.props.fileSize) {
            size = filesize(this.props.fileSize);
        }

        let sizeRes;
        if (size && res) {
            sizeRes = size + ", " + res;
        } else {
            sizeRes = size || res;
        }

        let metadata;
        if (showEventMeta) {
            // Figure out the sender, defaulting to mxid
            let sender = this.props.mxEvent.getSender();
            const cli = MatrixClientPeg.get();
            const room = cli.getRoom(this.props.mxEvent.getRoomId());
            if (room) {
                mayRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId);
                const member = room.getMember(sender);
                if (member) sender = member.name;
            }

            metadata = (

                { _t('Uploaded on %(date)s by %(user)s', {
                    date: formatDate(new Date(this.props.mxEvent.getTs())),
                    user: sender,
                }) }

);
        }

        let redactButton;
        if (mayRedact) {
            redactButton = (
                <AccessibleButton className="mx_ImageView_button" title={_t("Remove")} onClick={ this.onRedactClick }>

                </AccessibleButton>
            );
        }

        const rotationDegrees = this.state.rotation + "deg";
        const zoomPercentage = this.state.zoom/100;
        const translatePixelsX = this.state.translationX + "px";
        const translatePixelsY = this.state.translationY + "px";
        /* The order of the values is important!
         * First, we translate and only then we rotate, otherwise
         * we would apply the translation to an already rotated
         * image causing it translate in the wrong direction. */
        const style = {
            transform: `translateX(${translatePixelsX})
                        translateY(${translatePixelsY})
                        scale(${zoomPercentage})
                        rotate(${rotationDegrees})`,
        };

        return (
            <FocusLock
                returnFocus={true}
                lockProps={{
                    onKeyDown: this.onKeyDown,
                    role: "dialog",
                }}
                className="mx_ImageView"
                ref={ref => this.focusLock = ref}
            >

                            { this.getName() }

                        { sizeRes }
                        { metadata }

                        <AccessibleButton className="mx_ImageView_button" title={_t("Zoom in")} onClick={ this.onZoomInClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Zoom out")} onClick={ this.onZoomOutClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Rotate Left")} onClick={ this.onRotateCounterClockwiseClick }>

                        </AccessibleButton>
                        <AccessibleButton className="mx_ImageView_button" title={_t("Rotate Right")} onClick={ this.onRotateClockwiseClick }>

                        </AccessibleButton>

                        { redactButton }
                        <AccessibleButton className="mx_ImageView_button" title={_t("Close")} onClick={ this.props.onFinished }>

                        </AccessibleButton>

            </FocusLock>
        );
    }
}
<|endoftext|>