<commit_before>'use strict';

angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, sendFlowService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {

  var root = {};

  root.showMenu = function(data) {
    $rootScope.$broadcast('incomingDataMenu.showMenu', data);
  };

  root.redir = function(data, serviceId, serviceData) {
    var originalAddress = null;
    var noPrefixInAddress = 0;

    if (data.toLowerCase().indexOf('bitcoin') < 0) {
      noPrefixInAddress = 1;
    }

    if (typeof(data) == 'string' && !(/^bitcoin(cash)?:\?r=[\w+]/).exec(data) && (data.toLowerCase().indexOf('bitcoincash:') >= 0 || data[0] == 'q' || data[0] == 'p' || data[0] == 'C' || data[0] == 'H')) {
      try {
        noPrefixInAddress = 0;

        if (data[0] == 'p' || data[0] == 'q') {
          data = 'bitcoincash:' + data;
        }
        var paramString = '';
        if (data.indexOf('?') >= 0) {
          paramString = data.substring(data.indexOf('?'));
          data = data.substring(0, data.indexOf('?'));
        }

        if (data.indexOf('BITCOINCASH:') >= 0) {
          data = data.toLowerCase();
        }
        originalAddress = data.replace('bitcoincash:', '');
        var legacyAddress = bitcoinCashJsService.readAddress(data).legacy;
        data = 'bitcoincash:' + legacyAddress + paramString;
      } catch (ex) {}
    }

    $log.debug('Processing incoming data: ' + data);

    function sanitizeUri(data) {
      // Fixes when a region uses comma to separate decimals
      var regex = /[\?\&]amount=(\d+([\,\.]\d+)?)/i;
      var match = regex.exec(data);
      if (!match || match.length === 0) {
        return data;
      }
      var value = match[0].replace(',', '.');
      var newUri = data.replace(regex, value);

      // mobile devices, uris like copay://glidera
      newUri.replace('://', ':');

      return newUri;
    }

    function getParameterByName(name, url) {
      if (!url) return;
      name = name.replace(/[\[\]]/g, "\\$&");
      var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, " "));
    }

    function checkPrivateKey(privateKey) {
      try {
        new bitcore.PrivateKey(privateKey, 'livenet');
      } catch (err) {
        return false;
      }
      return true;
    }

    function goSend(addr, amount, message, coin, serviceId, serviceData) {
      $state.go('tabs.send', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.send' ? false : true
      });
      // Timeout is required to enable the "Back" button
      $timeout(function() {
        var params = sendFlowService.getState();

        if (amount) {
          params.amount = amount;
        }

        if (addr) {
          params.toAddress = addr;
          params.displayAddress = originalAddress ? originalAddress : addr;
        }

        if (coin) {
          params.coin = coin;
        }

        if (noPrefixInAddress) {
          params.noPrefixInAddress = noPrefixInAddress;
        }

        if (serviceId) {
          params.thirdParty = [];
          params.thirdParty.id = serviceId;
          params.thirdParty.data = serviceData;
          sendFlowService.pushState(params);
          $state.transitionTo('tabs.send.amount');
        } else {
          sendFlowService.pushState(params);
          $state.transitionTo('tabs.send.origin');
        }
      }, 100);
    }
    // data extensions for Payment Protocol with non-backwards-compatible request
    if ((/^bitcoin(cash)?:\?r=[\w+]/).exec(data)) {
      var coin = data.indexOf('bitcoincash') >= 0 ? 'bch' : 'btc';
      data = decodeURIComponent(data.replace(/bitcoin(cash)?:\?r=/, ''));
      if (coin == 'bch') {
        payproService.getPayProDetailsViaHttp(data, function onGetPayProDetailsViaHttp(err, details) {
          if (err) {
            var message = err.toString();
            if (typeof err.data === 'string') {
              // i.e. 'This invoice is no longer accepting payments'
              message = gettextCatalog.getString(err.data);
            }
            popupService.showAlert(gettextCatalog.getString('Error'), message)
          } else {
            handlePayPro(details, coin);
          }
        });
      } else {
        payproService.getPayProDetails(data, coin, function onGetPayProDetails(err, details) {
          if (err) {
            popupService.showAlert(gettextCatalog.getString('Error'), err);
          } else {
            handlePayPro(details, coin);
          }
        });
      }
      return true;
    }

    data = sanitizeUri(data);

    // Bitcoin  URL
    if (bitcore.URI.isValid(data)) {
        var coin = 'btc';
        var parsed = new bitcore.URI(data);

        var addr = parsed.address ? parsed.address.toString() : '';
        var message = parsed.message;

        var amount = parsed.amount ? parsed.amount : '';

        if (parsed.r) {
          payproService.getPayProDetails(parsed.r, coin, function(err, details) {
            if (err) {
              if (addr && amount) goSend(addr, amount, message, coin, serviceId, serviceData);
              else popupService.showAlert(gettextCatalog.getString('Error'), err);
            } else handlePayPro(details, coin);
          });
        } else {
          goSend(addr, amount, message, coin, serviceId, serviceData);
        }
        return true;
    // Cash URI
    } else if (bitcoreCash.URI.isValid(data)) {
        var coin = 'bch';
        var parsed = new bitcoreCash.URI(data);

        var addr = parsed.address ? parsed.address.toString() : '';
        var message = parsed.message;

        var amount = parsed.amount ? parsed.amount : '';

        // paypro not yet supported on cash
        if (parsed.r) {
          payproService.getPayProDetails(parsed.r, coin, function(err, details) {
            if (err) {
              if (addr && amount)
                goSend(addr, amount, message, coin, serviceId, serviceData);
              else
                popupService.showAlert(gettextCatalog.getString('Error'), err);
            }
            handlePayPro(details, coin);
          });
        } else {
          goSend(addr, amount, message, coin, serviceId, serviceData);
        }
        return true;

    // Cash URI with bitcoin (btc) address version number?
    } else if (bitcore.URI.isValid(data.replace(/^bitcoincash:/,'bitcoin:'))) {
        $log.debug('Handling bitcoincash URI with legacy address');
        var coin = 'bch';
        var parsed = new bitcore.URI(data.replace(/^bitcoincash:/,'bitcoin:'));

        var oldAddr = parsed.address ? parsed.address.toString() : '';
        if (!oldAddr) return false;

        var addr = '';

        var a = bitcore.Address(oldAddr).toObject();
        addr = bitcoreCash.Address.fromObject(a).toString();

        // Translate address
        $log.debug('address transalated to:' + addr);
        popupService.showConfirm(
          gettextCatalog.getString('Bitcoin cash Payment'),
          gettextCatalog.getString('Payment address was translated to new Bitcoin Cash address format: ' + addr),
          gettextCatalog.getString('OK'),
          gettextCatalog.getString('Cancel'),
          function(ret) {
            if (!ret) return false;

            var message = parsed.message;
            var amount = parsed.amount ? parsed.amount : '';

            // paypro not yet supported on cash
            if (parsed.r) {
              payproService.getPayProDetails(parsed.r, coin, function(err, details) {
                if (err) {
                  if (addr && amount)
                    goSend(addr, amount, message, coin, serviceId, serviceData);
                  else
                    popupService.showAlert(gettextCatalog.getString('Error'), err);
                }
                handlePayPro(details, coin);
              });
            } else {
              goSend(addr, amount, message, coin, serviceId, serviceData);
            }
          }
        );
      return true;
      // Plain URL
    } else if (/^https?:\/\//.test(data)) {
      payproService.getPayProDetails(data, coin, function(err, details) {
        if (err) {
          if ($state.includes('tabs.scan')) {
            root.showMenu({
              data: data,
              type: 'url'
            });
          }
          return;
        }
        handlePayPro(details);
        return true;
      });
      // Plain Address
    } else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'bitcoinAddress'
        });
      } else {
        goToAmountPage(data);
      }
    } else if (bitcoreCash.Address.isValid(data, 'livenet')) {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'bitcoinAddress',
          coin: 'bch',
        });
      } else {
        goToAmountPage(data, 'bch');
      }
    } else if (data && data.indexOf(appConfigService.name + '://glidera') === 0) {
      var code = getParameterByName('code', data);
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $ionicHistory.nextViewOptions({
          disableAnimate: true
        });
        $state.transitionTo('tabs.buyandsell.glidera', {
          code: code
        });
      });
      return true;

    } else if (data && data.indexOf(appConfigService.name + '://coinbase') === 0) {
      var code = getParameterByName('code', data);
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $ionicHistory.nextViewOptions({
          disableAnimate: true
        });
        $state.transitionTo('tabs.buyandsell.coinbase', {
          code: code
        });
      });
      return true;

      // BitPayCard Authentication
    } else if (data && data.indexOf(appConfigService.name + '://') === 0) {

      // Disable BitPay Card
      if (!appConfigService._enabledExtensions.debitcard) return false;

      var secret = getParameterByName('secret', data);
      var email = getParameterByName('email', data);
      var otp = getParameterByName('otp', data);
      var reason = getParameterByName('r', data);

      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        switch (reason) {
          default:
            case '0':
            /* For BitPay card binding */
            $state.transitionTo('tabs.bitpayCardIntro', {
              secret: secret,
              email: email,
              otp: otp
            });
          break;
        }
      });
      return true;

      // Join
    } else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $state.transitionTo('tabs.add.join', {
          url: data
        });
      });
      return true;

      // Old join
    } else if (data && data.match(/^[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $state.transitionTo('tabs.add.join', {
          url: data
        });
      });
      return true;
    } else if (data && (data.substring(0, 2) == '6P' || checkPrivateKey(data))) {
      root.showMenu({
        data: data,
        type: 'privateKey'
      });
    } else if (data && ((data.substring(0, 2) == '1|') || (data.substring(0, 2) == '2|') || (data.substring(0, 2) == '3|'))) {
      $state.go('tabs.home').then(function() {
        $state.transitionTo('tabs.add.import', {
          code: data
        });
      });
      return true;

    } else {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'text'
        });
      }
    }
    return false;
  };

  function goToAmountPage(toAddress, coin) {
    $state.go('tabs.send', {}, {
      'reload': true,
      'notify': $state.current.name == 'tabs.send' ? false : true
    });
    $timeout(function() {
      var stateParams = {
        toAddress: toAddress,
        coin: coin,
        noPrefix: 1
      };
      sendFlowService.pushState(stateParams);
      $state.transitionTo('tabs.send.origin');
    }, 100);
  }

  function handlePayPro(payProData, coin) {

    console.log(payProData);

    var toAddr = payProData.toAddress;
    var amount = payProData.amount;
    var paymentUrl = payProData.url;
    var expires = payProData.expires;
    var time = payProData.time;

    if (coin === 'bch') {
      var displayAddr = payProData.outputs[0].address;
      toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy;
      amount = payProData.outputs[0].amount;
      paymentUrl = payProData.paymentUrl;
      expires = Math.floor(new Date(expires).getTime() / 1000)
      time = Math.ceil(new Date(time).getTime() / 1000)
    }

    var name = payProData.domain;

    if (payProData.memo.indexOf('eGifter') > -1) {
      name = 'eGifter'
    } else if (paymentUrl.indexOf('https://bitpay.com') > -1) {
      name = 'BitPay';
    }

    var thirdPartyData = {
      id: 'bip70',
      amount: amount,
      caTrusted: true,
      name: name,
      domain: payProData.domain,
      expires: expires,
      memo: payProData.memo,
      network: 'livenet',
      requiredFeeRate: payProData.requiredFeeRate,
      selfSigned: 0,
      time: time,
      displayAddress: displayAddr,
      toAddress: toAddr,
      url: paymentUrl,
      verified: true
    };

    var stateParams = {
      amount: thirdPartyData.amount,
      toAddress: thirdPartyData.toAddress,
      coin: coin,
      thirdParty: JSON.stringify(thirdPartyData)
    };

    // fee
    if (thirdPartyData.requiredFeeRate) {
      stateParams.requiredFeeRate = thirdPartyData.requiredFeeRate * 1024;
    }

    scannerService.pausePreview();
    $state.go('tabs.send', {}, {
      'reload': true,
      'notify': $state.current.name == 'tabs.send' ? false : true
    }).then(function() {
      $timeout(function() {
        sendFlowService.pushState(stateParams); // Need to do more here
        $state.transitionTo('tabs.send.origin');
      });
    });
  }

  return root;
});
<commit_msg>thirdParty fix<commit_after>'use strict';

angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, sendFlowService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {

  var root = {};

  root.showMenu = function(data) {
    $rootScope.$broadcast('incomingDataMenu.showMenu', data);
  };

  root.redir = function(data, serviceId, serviceData) {
    var originalAddress = null;
    var noPrefixInAddress = 0;

    if (data.toLowerCase().indexOf('bitcoin') < 0) {
      noPrefixInAddress = 1;
    }

    if (typeof(data) == 'string' && !(/^bitcoin(cash)?:\?r=[\w+]/).exec(data) && (data.toLowerCase().indexOf('bitcoincash:') >= 0 || data[0] == 'q' || data[0] == 'p' || data[0] == 'C' || data[0] == 'H')) {
      try {
        noPrefixInAddress = 0;

        if (data[0] == 'p' || data[0] == 'q') {
          data = 'bitcoincash:' + data;
        }
        var paramString = '';
        if (data.indexOf('?') >= 0) {
          paramString = data.substring(data.indexOf('?'));
          data = data.substring(0, data.indexOf('?'));
        }

        if (data.indexOf('BITCOINCASH:') >= 0) {
          data = data.toLowerCase();
        }
        originalAddress = data.replace('bitcoincash:', '');
        var legacyAddress = bitcoinCashJsService.readAddress(data).legacy;
        data = 'bitcoincash:' + legacyAddress + paramString;
      } catch (ex) {}
    }

    $log.debug('Processing incoming data: ' + data);

    function sanitizeUri(data) {
      // Fixes when a region uses comma to separate decimals
      var regex = /[\?\&]amount=(\d+([\,\.]\d+)?)/i;
      var match = regex.exec(data);
      if (!match || match.length === 0) {
        return data;
      }
      var value = match[0].replace(',', '.');
      var newUri = data.replace(regex, value);

      // mobile devices, uris like copay://glidera
      newUri.replace('://', ':');

      return newUri;
    }

    function getParameterByName(name, url) {
      if (!url) return;
      name = name.replace(/[\[\]]/g, "\\$&");
      var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, " "));
    }

    function checkPrivateKey(privateKey) {
      try {
        new bitcore.PrivateKey(privateKey, 'livenet');
      } catch (err) {
        return false;
      }
      return true;
    }

    function goSend(addr, amount, message, coin, serviceId, serviceData) {
      $state.go('tabs.send', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.send' ? false : true
      });
      // Timeout is required to enable the "Back" button
      $timeout(function() {
        var params = sendFlowService.getState();

        if (amount) {
          params.amount = amount;
        }

        if (addr) {
          params.toAddress = addr;
          params.displayAddress = originalAddress ? originalAddress : addr;
        }

        if (coin) {
          params.coin = coin;
        }

        if (noPrefixInAddress) {
          params.noPrefixInAddress = noPrefixInAddress;
        }

        if (serviceId) {
          params.thirdParty = [];
          params.thirdParty.id = serviceId;
          params.thirdParty.data = serviceData;
          sendFlowService.pushState(params);
          $state.transitionTo('tabs.send.amount');
        } else {
          sendFlowService.pushState(params);
          $state.transitionTo('tabs.send.origin');
        }
      }, 100);
    }
    // data extensions for Payment Protocol with non-backwards-compatible request
    if ((/^bitcoin(cash)?:\?r=[\w+]/).exec(data)) {
      var coin = data.indexOf('bitcoincash') >= 0 ? 'bch' : 'btc';
      data = decodeURIComponent(data.replace(/bitcoin(cash)?:\?r=/, ''));
      if (coin == 'bch') {
        payproService.getPayProDetailsViaHttp(data, function onGetPayProDetailsViaHttp(err, details) {
          if (err) {
            var message = err.toString();
            if (typeof err.data === 'string') {
              // i.e. 'This invoice is no longer accepting payments'
              message = gettextCatalog.getString(err.data);
            }
            popupService.showAlert(gettextCatalog.getString('Error'), message)
          } else {
            handlePayPro(details, coin);
          }
        });
      } else {
        payproService.getPayProDetails(data, coin, function onGetPayProDetails(err, details) {
          if (err) {
            popupService.showAlert(gettextCatalog.getString('Error'), err);
          } else {
            handlePayPro(details, coin);
          }
        });
      }
      return true;
    }

    data = sanitizeUri(data);

    // Bitcoin  URL
    if (bitcore.URI.isValid(data)) {
        var coin = 'btc';
        var parsed = new bitcore.URI(data);

        var addr = parsed.address ? parsed.address.toString() : '';
        var message = parsed.message;

        var amount = parsed.amount ? parsed.amount : '';

        if (parsed.r) {
          payproService.getPayProDetails(parsed.r, coin, function(err, details) {
            if (err) {
              if (addr && amount) goSend(addr, amount, message, coin, serviceId, serviceData);
              else popupService.showAlert(gettextCatalog.getString('Error'), err);
            } else handlePayPro(details, coin);
          });
        } else {
          goSend(addr, amount, message, coin, serviceId, serviceData);
        }
        return true;
    // Cash URI
    } else if (bitcoreCash.URI.isValid(data)) {
        var coin = 'bch';
        var parsed = new bitcoreCash.URI(data);

        var addr = parsed.address ? parsed.address.toString() : '';
        var message = parsed.message;

        var amount = parsed.amount ? parsed.amount : '';

        // paypro not yet supported on cash
        if (parsed.r) {
          payproService.getPayProDetails(parsed.r, coin, function(err, details) {
            if (err) {
              if (addr && amount)
                goSend(addr, amount, message, coin, serviceId, serviceData);
              else
                popupService.showAlert(gettextCatalog.getString('Error'), err);
            }
            handlePayPro(details, coin);
          });
        } else {
          goSend(addr, amount, message, coin, serviceId, serviceData);
        }
        return true;

    // Cash URI with bitcoin (btc) address version number?
    } else if (bitcore.URI.isValid(data.replace(/^bitcoincash:/,'bitcoin:'))) {
        $log.debug('Handling bitcoincash URI with legacy address');
        var coin = 'bch';
        var parsed = new bitcore.URI(data.replace(/^bitcoincash:/,'bitcoin:'));

        var oldAddr = parsed.address ? parsed.address.toString() : '';
        if (!oldAddr) return false;

        var addr = '';

        var a = bitcore.Address(oldAddr).toObject();
        addr = bitcoreCash.Address.fromObject(a).toString();

        // Translate address
        $log.debug('address transalated to:' + addr);
        popupService.showConfirm(
          gettextCatalog.getString('Bitcoin cash Payment'),
          gettextCatalog.getString('Payment address was translated to new Bitcoin Cash address format: ' + addr),
          gettextCatalog.getString('OK'),
          gettextCatalog.getString('Cancel'),
          function(ret) {
            if (!ret) return false;

            var message = parsed.message;
            var amount = parsed.amount ? parsed.amount : '';

            // paypro not yet supported on cash
            if (parsed.r) {
              payproService.getPayProDetails(parsed.r, coin, function(err, details) {
                if (err) {
                  if (addr && amount)
                    goSend(addr, amount, message, coin, serviceId, serviceData);
                  else
                    popupService.showAlert(gettextCatalog.getString('Error'), err);
                }
                handlePayPro(details, coin);
              });
            } else {
              goSend(addr, amount, message, coin, serviceId, serviceData);
            }
          }
        );
      return true;
      // Plain URL
    } else if (/^https?:\/\//.test(data)) {
      payproService.getPayProDetails(data, coin, function(err, details) {
        if (err) {
          if ($state.includes('tabs.scan')) {
            root.showMenu({
              data: data,
              type: 'url'
            });
          }
          return;
        }
        handlePayPro(details);
        return true;
      });
      // Plain Address
    } else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'bitcoinAddress'
        });
      } else {
        goToAmountPage(data);
      }
    } else if (bitcoreCash.Address.isValid(data, 'livenet')) {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'bitcoinAddress',
          coin: 'bch',
        });
      } else {
        goToAmountPage(data, 'bch');
      }
    } else if (data && data.indexOf(appConfigService.name + '://glidera') === 0) {
      var code = getParameterByName('code', data);
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $ionicHistory.nextViewOptions({
          disableAnimate: true
        });
        $state.transitionTo('tabs.buyandsell.glidera', {
          code: code
        });
      });
      return true;

    } else if (data && data.indexOf(appConfigService.name + '://coinbase') === 0) {
      var code = getParameterByName('code', data);
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $ionicHistory.nextViewOptions({
          disableAnimate: true
        });
        $state.transitionTo('tabs.buyandsell.coinbase', {
          code: code
        });
      });
      return true;

      // BitPayCard Authentication
    } else if (data && data.indexOf(appConfigService.name + '://') === 0) {

      // Disable BitPay Card
      if (!appConfigService._enabledExtensions.debitcard) return false;

      var secret = getParameterByName('secret', data);
      var email = getParameterByName('email', data);
      var otp = getParameterByName('otp', data);
      var reason = getParameterByName('r', data);

      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        switch (reason) {
          default:
            case '0':
            /* For BitPay card binding */
            $state.transitionTo('tabs.bitpayCardIntro', {
              secret: secret,
              email: email,
              otp: otp
            });
          break;
        }
      });
      return true;

      // Join
    } else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $state.transitionTo('tabs.add.join', {
          url: data
        });
      });
      return true;

      // Old join
    } else if (data && data.match(/^[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
      $state.go('tabs.home', {}, {
        'reload': true,
        'notify': $state.current.name == 'tabs.home' ? false : true
      }).then(function() {
        $state.transitionTo('tabs.add.join', {
          url: data
        });
      });
      return true;
    } else if (data && (data.substring(0, 2) == '6P' || checkPrivateKey(data))) {
      root.showMenu({
        data: data,
        type: 'privateKey'
      });
    } else if (data && ((data.substring(0, 2) == '1|') || (data.substring(0, 2) == '2|') || (data.substring(0, 2) == '3|'))) {
      $state.go('tabs.home').then(function() {
        $state.transitionTo('tabs.add.import', {
          code: data
        });
      });
      return true;

    } else {
      if ($state.includes('tabs.scan')) {
        root.showMenu({
          data: data,
          type: 'text'
        });
      }
    }
    return false;
  };

  function goToAmountPage(toAddress, coin) {
    $state.go('tabs.send', {}, {
      'reload': true,
      'notify': $state.current.name == 'tabs.send' ? false : true
    });
    $timeout(function() {
      var stateParams = {
        toAddress: toAddress,
        coin: coin,
        noPrefix: 1
      };
      sendFlowService.pushState(stateParams);
      $state.transitionTo('tabs.send.origin');
    }, 100);
  }

  function handlePayPro(payProData, coin) {

    console.log(payProData);

    var toAddr = payProData.toAddress;
    var amount = payProData.amount;
    var paymentUrl = payProData.url;
    var expires = payProData.expires;
    var time = payProData.time;

    if (coin === 'bch') {
      var displayAddr = payProData.outputs[0].address;
      toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy;
      amount = payProData.outputs[0].amount;
      paymentUrl = payProData.paymentUrl;
      expires = Math.floor(new Date(expires).getTime() / 1000)
      time = Math.ceil(new Date(time).getTime() / 1000)
    }

    var name = payProData.domain;

    if (payProData.memo.indexOf('eGifter') > -1) {
      name = 'eGifter'
    } else if (paymentUrl.indexOf('https://bitpay.com') > -1) {
      name = 'BitPay';
    }

    var thirdPartyData = {
      id: 'bip70',
      amount: amount,
      caTrusted: true,
      name: name,
      domain: payProData.domain,
      expires: expires,
      memo: payProData.memo,
      network: 'livenet',
      requiredFeeRate: payProData.requiredFeeRate,
      selfSigned: 0,
      time: time,
      displayAddress: displayAddr,
      toAddress: toAddr,
      url: paymentUrl,
      verified: true
    };

    var stateParams = {
      amount: thirdPartyData.amount,
      toAddress: thirdPartyData.toAddress,
      coin: coin,
      thirdParty: thirdPartyData
    };

    // fee
    if (thirdPartyData.requiredFeeRate) {
      stateParams.requiredFeeRate = thirdPartyData.requiredFeeRate * 1024;
    }

    sendFlowService.pushState(thirdPartyData);

    scannerService.pausePreview();
    $state.go('tabs.send', {}, {
      'reload': true,
      'notify': $state.current.name == 'tabs.send' ? false : true
    }).then(function() {
      $timeout(function() {
        sendFlowService.pushState(stateParams); // Need to do more here
        $state.transitionTo('tabs.send.origin');
      });
    });
  }

  return root;
});
<|endoftext|>


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

import { EventsList, EventFilters, Loading } from '../';
import { eventsAPI } from '../../api';
import styles from './Events.sass';

const odataFilterTypes = ['searchText', 'startDate'];
const nonOdataFiltertypes = ['location', 'range'];

function hasMoreEventsToLoad(currentPage, totalPages) {
  return currentPage + 1 < totalPages;
}

function buildFilterValues(filters, filterTypes) {
  // This looks weird but "pick" builds an object of the appropriate filters, then pickBy removes the falsey properties
  /*
    e.g.
    odataFilterTypes +
    {
      searchText: '',
      location: '90210',
      range: 1000,
      startDate: [[moment object]]
    }
  // returns { startDate: [[moment object]] }
  */
  return _.pickBy(_.pick(filters, filterTypes));
}

class Events extends Component {
  constructor(props) {
    super(props);
    this.state = {
      filters: {
        searchText: '',
        location: null,
        range: null,
        startDate: moment()
      },
      hasFilter: false,
      isFetchingEvents: true,
      isFetchingMoreEvents: false,
      events: [],
      hasMoreEvents: true,  // to show/hide "Load More Events" button
      currentPage: 0
    };

    this._getEvents = _.debounce(this.getEvents, 400);
  }

  componentDidMount() {
    this.getEvents();
  }

  getEvents() {
    this.setState({ isFetchingEvents: true });

    const { filters } = this.state;

    // Filter values
    const odataValues = buildFilterValues(filters, odataFilterTypes);
    const nonOdataValues = buildFilterValues(filters, nonOdataFiltertypes);

    eventsAPI.getEvents(nonOdataValues, odataValues)
      .then(res => this.setState({
        events: res._embedded['osdi:events'],
        isFetchingEvents: false,
        hasMoreEvents: hasMoreEventsToLoad(res.page, res.total_pages)
      }))
      .catch(err => {
        console.error(err);
        this.setState({ isFetchingEvents: false });
      });
  }

  loadMoreEvents() {
    const { currentPage, events, filters } = this.state;
    const nextPage = currentPage + 1;

    // Filter values
    const odataValues = buildFilterValues(filters, odataFilterTypes);
    const nonOdataValues = buildFilterValues(filters, nonOdataFiltertypes);

    this.setState({ currentPage: nextPage, isFetchingMoreEvents: true });

    eventsAPI.getEvents({ page: nextPage, ...nonOdataValues }, odataValues)
      .then(res => this.setState({
        events: [...events, ...res._embedded['osdi:events']],
        isFetchingMoreEvents: false,
        hasMoreEvents: hasMoreEventsToLoad(res.page, res.total_pages)
      }))
      .catch(err => {
        this.setState({ isFetchingMoreEvents: false });
        console.error(err);
      });
  }

  updateFilters(updatedFilters) {
    this.setState({
      filters: {
        ...this.state.filters,
        ...updatedFilters
      }
    }, () => {
      // After state update, fetch events (via debounced function to prevent rapid service calls)
      this._getEvents();
    });
  }

  renderEventsList(events, hasMoreEvents, isFetchingMoreEvents, filters) {
    return (

        <EventsList events={events} filters={filters} />
        { hasMoreEvents &&

            { isFetchingMoreEvents ?
              <Loading /> :
              <button type="button" onClick={this.loadMoreEvents.bind(this)}>
                load more events
              </button>
            }

        }

    );
  }

  render() {
    const {
      filters,
      events,
      isFetchingEvents,
      isFetchingMoreEvents,
      hasMoreEvents
    } = this.state;

    return (

          <EventFilters
            filters={filters}
            updateFilters={this.updateFilters.bind(this)}
          />

        { isFetchingEvents ?

<Loading />
 :
          this.renderEventsList(events, hasMoreEvents, isFetchingMoreEvents, filters)
        }

    );
  }
}

Events.propTypes = {};

export default Events;
<commit_msg>remove obsolete hasFilter state prop in Events component<commit_after>import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';

import { EventsList, EventFilters, Loading } from '../';
import { eventsAPI } from '../../api';
import styles from './Events.sass';

const odataFilterTypes = ['searchText', 'startDate'];
const nonOdataFiltertypes = ['location', 'range'];

function hasMoreEventsToLoad(currentPage, totalPages) {
  return currentPage + 1 < totalPages;
}

function buildFilterValues(filters, filterTypes) {
  // This looks weird but "pick" builds an object of the appropriate filters, then pickBy removes the falsey properties
  /*
    e.g.
    odataFilterTypes +
    {
      searchText: '',
      location: '90210',
      range: 1000,
      startDate: [[moment object]]
    }
  // returns { startDate: [[moment object]] }
  */
  return _.pickBy(_.pick(filters, filterTypes));
}

class Events extends Component {
  constructor(props) {
    super(props);
    this.state = {
      filters: {
        searchText: '',
        location: null,
        range: null,
        startDate: moment()
      },
      isFetchingEvents: true,
      isFetchingMoreEvents: false,
      events: [],
      hasMoreEvents: true,  // to show/hide "Load More Events" button
      currentPage: 0
    };

    this._getEvents = _.debounce(this.getEvents, 400);
  }

  componentDidMount() {
    this.getEvents();
  }

  getEvents() {
    this.setState({ isFetchingEvents: true });

    const { filters } = this.state;

    // Filter values
    const odataValues = buildFilterValues(filters, odataFilterTypes);
    const nonOdataValues = buildFilterValues(filters, nonOdataFiltertypes);

    eventsAPI.getEvents(nonOdataValues, odataValues)
      .then(res => this.setState({
        events: res._embedded['osdi:events'],
        isFetchingEvents: false,
        hasMoreEvents: hasMoreEventsToLoad(res.page, res.total_pages)
      }))
      .catch(err => {
        console.error(err);
        this.setState({ isFetchingEvents: false });
      });
  }

  loadMoreEvents() {
    const { currentPage, events, filters } = this.state;
    const nextPage = currentPage + 1;

    // Filter values
    const odataValues = buildFilterValues(filters, odataFilterTypes);
    const nonOdataValues = buildFilterValues(filters, nonOdataFiltertypes);

    this.setState({ currentPage: nextPage, isFetchingMoreEvents: true });

    eventsAPI.getEvents({ page: nextPage, ...nonOdataValues }, odataValues)
      .then(res => this.setState({
        events: [...events, ...res._embedded['osdi:events']],
        isFetchingMoreEvents: false,
        hasMoreEvents: hasMoreEventsToLoad(res.page, res.total_pages)
      }))
      .catch(err => {
        this.setState({ isFetchingMoreEvents: false });
        console.error(err);
      });
  }

  updateFilters(updatedFilters) {
    this.setState({
      filters: {
        ...this.state.filters,
        ...updatedFilters
      }
    }, () => {
      // After state update, fetch events (via debounced function to prevent rapid service calls)
      this._getEvents();
    });
  }

  renderEventsList(events, hasMoreEvents, isFetchingMoreEvents, filters) {
    return (

        <EventsList events={events} filters={filters} />
        { hasMoreEvents &&

            { isFetchingMoreEvents ?
              <Loading /> :
              <button type="button" onClick={this.loadMoreEvents.bind(this)}>
                load more events
              </button>
            }

        }

    );
  }

  render() {
    const {
      filters,
      events,
      isFetchingEvents,
      isFetchingMoreEvents,
      hasMoreEvents
    } = this.state;

    return (

          <EventFilters
            filters={filters}
            updateFilters={this.updateFilters.bind(this)}
          />

        { isFetchingEvents ?

<Loading />
 :
          this.renderEventsList(events, hasMoreEvents, isFetchingMoreEvents, filters)
        }

    );
  }
}

Events.propTypes = {};

export default Events;
<|endoftext|>


<commit_before>'use strict';
(function(){
  var Front = function(){
    this.version = '0.0.1';
  };
  var Base = require('base').Base;
  Front.prototype = new Base();

  (function(p){
    p.init = function(){
      this.initAs();
      this.clazz = 'gmxd';
      this.role = 'front';
      this.reset_();
      this.seq = 0;
      var gmxd = this;
      this.ownActions = {
	reset: function(req, res){
	  gmxd.reset_();
	  res.end("reset server\n");
	},
	stop: function(req, res){
	  gmxd.stopWorker();
	  console.log('stopping server ...');
	  gmxd.server.close();
	  console.log('stoped server ...');
	  //req.connection.end();
	  //req.connection.destroy();
	  process.exit();
	},
	status: function(req, res){
	  var str = '';
	  str += "<reqs>\n";
	  for (var seq in this.reqs) {
	    str += "\t" + seq + ': ' + 1 + " \n";
	  }
	  str += "</reqs>\n";
	  res.end(str);
	}
      };
      return this;
    };
    p.stopWorker = function(){
      if (this.worker && this.worker.connected) {
	this.worker.disconnect();
      }
    };
    p.reset_ = function(){
      var gmxd = this;
      this.reloadSettings_();
      this.reqs = {};
      this.stopWorker();
      this.worker = require('child_process').fork('start_worker.js');
      this.worker.on('message', function(msg){
	if (msg && msg.gmx) {
	  var seq = msg.gmx.seq;
	  var res = msg.gmx.res;
	  var httpres = gmxd.retrieveResponse(seq);
	  if (res && httpres) {
	    httpres.write(res);
	    httpres.end();
	  }
	}
      });
    };
    p.storeRequest = function(req, res) {
      var seq = this.seq++;
      this.reqs[seq] = { seq: seq, req: req, res: res };
      return seq;
    };
    p.retrieveResponse = function(seq) {
      var obj = this.reqs[seq];
      if (! obj) return null;
      var res = obj.res;
      if (! res) return null;
      delete this.reqs[seq];
      return res;
    };
    p.start = function() {
      process.on('uncaughtException', function (err) {
	console.error(err);
	console.error(err.stack);
      });
      var http = require('http');
      this.server = http.createServer();
      var gmxd = this;
      this.server.on('request', function(req, res) {
	var url = decodeURI(req.url);
	console.warn({request_url:url});
	res.writeHead(200, {'content-type': 'text/plain'});
	var args = url.substr(1).split('/');
	if (gmxd.ownActions[args[0]]) {
	  return gmxd.ownActions[args[0]](req, res);
	}
	if (gmxd.worker.connected) {
	  var seq = gmxd.storeRequest(req, res);
	  gmxd.worker.send({ gmx: { seq: seq, args: args } });
	}
      });
      this.server.listen(this.port, function() {
	console.log('server running (version:' + gmxd.version + ', pid:' + this.pid + ')');
      });
      return this;
    };
  })(Front.prototype);

  exports.Front = Front;
})();
<commit_msg>Modiefied server starting message<commit_after>'use strict';
(function(){
  var Front = function(){
    this.version = '0.0.1';
  };
  var Base = require('base').Base;
  Front.prototype = new Base();

  (function(p){
    p.init = function(){
      this.initAs();
      this.clazz = 'gmxd';
      this.role = 'front';
      this.reset_();
      this.seq = 0;
      var gmxd = this;
      this.ownActions = {
	reset: function(req, res){
	  gmxd.reset_();
	  res.end("reset server\n");
	},
	stop: function(req, res){
	  gmxd.stopWorker();
	  console.log('stopping server ...');
	  gmxd.server.close();
	  console.log('stoped server ...');
	  //req.connection.end();
	  //req.connection.destroy();
	  process.exit();
	},
	status: function(req, res){
	  var str = '';
	  str += "<reqs>\n";
	  for (var seq in this.reqs) {
	    str += "\t" + seq + ': ' + 1 + " \n";
	  }
	  str += "</reqs>\n";
	  res.end(str);
	}
      };
      return this;
    };
    p.stopWorker = function(){
      if (this.worker && this.worker.connected) {
	this.worker.disconnect();
      }
    };
    p.reset_ = function(){
      var gmxd = this;
      this.reloadSettings_();
      this.reqs = {};
      this.stopWorker();
      this.worker = require('child_process').fork('start_worker.js');
      this.worker.on('message', function(msg){
	if (msg && msg.gmx) {
	  var seq = msg.gmx.seq;
	  var res = msg.gmx.res;
	  var httpres = gmxd.retrieveResponse(seq);
	  if (res && httpres) {
	    httpres.write(res);
	    httpres.end();
	  }
	}
      });
    };
    p.storeRequest = function(req, res) {
      var seq = this.seq++;
      this.reqs[seq] = { seq: seq, req: req, res: res };
      return seq;
    };
    p.retrieveResponse = function(seq) {
      var obj = this.reqs[seq];
      if (! obj) return null;
      var res = obj.res;
      if (! res) return null;
      delete this.reqs[seq];
      return res;
    };
    p.start = function() {
      process.on('uncaughtException', function (err) {
	console.error(err);
	console.error(err.stack);
      });
      var http = require('http');
      this.server = http.createServer();
      var gmxd = this;
      this.server.on('request', function(req, res) {
	var url = decodeURI(req.url);
	console.warn({request_url:url});
	res.writeHead(200, {'content-type': 'text/plain'});
	var args = url.substr(1).split('/');
	if (gmxd.ownActions[args[0]]) {
	  return gmxd.ownActions[args[0]](req, res);
	}
	if (gmxd.worker.connected) {
	  var seq = gmxd.storeRequest(req, res);
	  gmxd.worker.send({ gmx: { seq: seq, args: args } });
	}
      });
      this.server.listen(this.port, function() {
	console.log('server running (version:' + gmxd.version + ', pid:' + gmxd.pid + ')');
      });
      return this;
    };
  })(Front.prototype);

  exports.Front = Front;
})();
<|endoftext|>


<commit_before>/*global require, module, setInterval, setTimeout, clearInterval, console*/
var AppConstants = require('../constants/app-action-name'),
    AppEvent = require('../constants/app-event'),
    AppDispatcher = require('../dispatchers/app-dispatcher'),
    merge = require('react/lib/Object.assign'),
    EventEmitter = require('events').EventEmitter,
    settings = require('./settings-manager'),
    DataManager = require('./data-manager'),
    ServiceAccessor = require('./service-accessor'),
    HttpHelper = require('./http-helper'),
    prettify = require('prettify-error'),
    StoreError = require('../constants/store-errors'),
    $ = require("jquery"),
    dataManager = null;

var getDataManager = function () {
    "use strict";
    if ((dataManager === null || settings.forceLoad) && settings.available) {
        settings.forceLoad = false;
        dataManager = new DataManager(new ServiceAccessor(settings.BaseURL, new HttpHelper(settings.APIKey)));
    }

    return dataManager;
};

module.exports = merge(EventEmitter.prototype, (function () {
    "use strict";
    var State = {
            fetchInProgress: false, // denotes weather issues are being fetched.
            filteredResult: [], // filtered search results.
            activeItems: [], // active tasks selected by the user.
            activities: [], // activities available to enter time against. Fetched from server.
            isLoading: true,
            settings: settings,
            error: null
        },
        handleError = function (error) {
            State.error = error;
            EventEmitter.prototype.emit(AppEvent.Change);
        },
        clearError = function () {
            State.error = null;
            EventEmitter.prototype.emit(AppEvent.Change);
        },
        getState = function () {
            return State;
        },
        fetchLatestBackground = function () {
            var intervalId = setInterval(function () {
                try {
                    var manager = getDataManager();
                    if (manager !== null) {
                        $.when(manager.fetchLatest()).fail(function (error) {
                            handleError(error);
                        });
                    } else {
                        clearInterval(intervalId);
                    }
                } catch (error) {
                    handleError(StoreError.InternalServerError);
                    console.error(prettify(error) || error);
                }
            }.bind(this), settings.backgroundFetchTimerInterval);
        },
        fetchLatest = function () {
            try {
                var manager = getDataManager();
                if (State.isLoading) {
                    handleError(StoreError.DataFetchInProgress);
                    return null;
                }

                if (manager !== null) {
                    State.isLoading = true;
                    EventEmitter.prototype.emit(AppEvent.Change);
                    $.when(manager.fetchData()).done(function () {
                        State.isLoading = false;
                        State.filteredResult = [];
                        EventEmitter.prototype.emit(AppEvent.Change);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                    });
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        fetchData = function () {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    clearError.call(this);
                    $.when(manager.fetchData()).done(function () {
                        State.isLoading = false;
                        State.filteredResult = [];
                        manager.activityCollection.map(function (item) {
                            State.activities.push({
                                id: item.id,
                                text: item.name
                            });
                        }.bind(this));

                        if (settings.fetchTaskCollection()) {
                            manager.createActiveTaskCollection(settings.activeTaskCollection);
                            State.activeItems = manager.activeTaskCollection;
                        }
                        fetchLatestBackground.call(this);
                        EventEmitter.prototype.emit(AppEvent.Change);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                        setTimeout(function () {
                            fetchData.call(this);
                        }, settings.retryInterval);
                    }.bind(this));
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        filterTaskCollection = function (query) {
            try {
                var manager = getDataManager();
                if (!State.isLoading && manager !== null) {
                    State.filteredResult = manager.filterTaskCollection(query);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        clearSearch = function () {
            try {
                State.filteredResult = [];
                EventEmitter.prototype.emit(AppEvent.Change);
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        createActiveTask = function (issueId) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.createActiveTask(issueId);
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    State.activeItems = manager.activeTaskCollection;
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskActivityId = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskActivityId(entry.id, entry.activityId);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskComments = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskComments(entry.id, entry.comments);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskHours = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskHours(entry.id, entry.hours);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        removeActiveTask = function (entryId) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.removeActiveTask(entryId);
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        postUpdatedActiveTaskCollection = function (spentOn) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    $.when(manager.postUpdatedActiveTaskCollection(spentOn)).done(function () {
                        EventEmitter.prototype.emit(AppEvent.Change);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                    });
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        clearActiveTaskCollection = function () {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.clearActiveTaskCollection();
                    State.activeItems = manager.activeTaskCollection;
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        setSettings = function (data) {
            try {
                $.when(settings.setSettings(data.url, data.apiKey)).done(function () {
                    EventEmitter.prototype.emit(AppEvent.Change);
                }).fail(function (error) {
                    handleError(error);
                });
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        resetState = function () {
            State = {
                fetchInProgress: false,
                filteredResult: [],
                activeItems: [],
                activities: [],
                isLoading: true,
                settings: settings,
                error: null
            };
        },
        clearSettings = function () {
            try {
                if (State.isLoading) {
                    handleError(StoreError.DataFetchInProgress);
                    return null;
                }

                settings.clearSettings();
                resetState.call(this);
                EventEmitter.prototype.emit(AppEvent.Change);
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        addChangeListener = function (callback) {
            EventEmitter.prototype.on(AppEvent.Change, callback);
        },
        removeChangeListeners = function (callback) {
            EventEmitter.prototype.removeListener(AppEvent.Change, callback);
        },
        dispatcherIndex = AppDispatcher.register(function (payload) {
            // Clear the current error as its shown to the user already.
            State.error = null;

            var action = payload.action;
            switch (action.actionType) {
            case AppConstants.FetchIssues:
                fetchData.call(this);
                break;
            case AppConstants.Search:
                filterTaskCollection.call(this, action.query);
                break;
            case AppConstants.ClearSearch:
                clearSearch.call();
                break;
            case AppConstants.AddIssue:
                createActiveTask.call(this, action.issueId);
                break;
            case AppConstants.UpdateTaskActivityId:
                updateActiveTaskActivityId.call(this, action.entry);
                break;
            case AppConstants.UpdateTaskComments:
                updateActiveTaskComments.call(this, action.entry);
                break;
            case AppConstants.UpdateTaskHours:
                updateActiveTaskHours.call(this, action.entry);
                break;
            case AppConstants.CreateTimeEntries:
                postUpdatedActiveTaskCollection.call(this, action.spentOn);
                break;
            case AppConstants.ClearTimeEntries:
                clearActiveTaskCollection.call(this);
                break;
            case AppConstants.SaveSettings:
                setSettings.call(this, action.settings);
                break;
            case AppConstants.RemoveTimeEntry:
                removeActiveTask.call(this, action.taskId);
                break;
            case AppConstants.RefreshIssues:
                fetchLatest.call(this);
                break;
            case AppConstants.Logout:
                clearSettings.call(this);
                break;
            }
        });

    return {
        getState: getState,
        addChangeListener: addChangeListener,
        removeChangeListeners: removeChangeListeners,
        dispatcherIndex: dispatcherIndex
    };
}()));<commit_msg>Clear errors when data fetch success.<commit_after>/*global require, module, setInterval, setTimeout, clearInterval, console*/
var AppConstants = require('../constants/app-action-name'),
    AppEvent = require('../constants/app-event'),
    AppDispatcher = require('../dispatchers/app-dispatcher'),
    merge = require('react/lib/Object.assign'),
    EventEmitter = require('events').EventEmitter,
    settings = require('./settings-manager'),
    DataManager = require('./data-manager'),
    ServiceAccessor = require('./service-accessor'),
    HttpHelper = require('./http-helper'),
    prettify = require('prettify-error'),
    StoreError = require('../constants/store-errors'),
    $ = require("jquery"),
    dataManager = null;

var getDataManager = function () {
    "use strict";
    if ((dataManager === null || settings.forceLoad) && settings.available) {
        settings.forceLoad = false;
        dataManager = new DataManager(new ServiceAccessor(settings.BaseURL, new HttpHelper(settings.APIKey)));
    }

    return dataManager;
};

module.exports = merge(EventEmitter.prototype, (function () {
    "use strict";
    var State = {
            fetchInProgress: false, // denotes weather issues are being fetched.
            filteredResult: [], // filtered search results.
            activeItems: [], // active tasks selected by the user.
            activities: [], // activities available to enter time against. Fetched from server.
            isLoading: true,
            settings: settings,
            error: null
        },
        handleError = function (error) {
            State.error = error;
            EventEmitter.prototype.emit(AppEvent.Change);
        },
        clearError = function () {
            State.error = null;
            EventEmitter.prototype.emit(AppEvent.Change);
        },
        getState = function () {
            return State;
        },
        fetchLatestBackground = function () {
            var intervalId = setInterval(function () {
                try {
                    var manager = getDataManager();
                    if (manager !== null) {
                        $.when(manager.fetchLatest()).fail(function (error) {
                            handleError(error);
                        });
                    } else {
                        clearInterval(intervalId);
                    }
                } catch (error) {
                    handleError(StoreError.InternalServerError);
                    console.error(prettify(error) || error);
                }
            }.bind(this), settings.backgroundFetchTimerInterval);
        },
        fetchLatest = function () {
            try {
                var manager = getDataManager();
                if (State.isLoading) {
                    handleError(StoreError.DataFetchInProgress);
                    return null;
                }

                if (manager !== null) {
                    State.isLoading = true;
                    EventEmitter.prototype.emit(AppEvent.Change);
                    $.when(manager.fetchData()).done(function () {
                        State.isLoading = false;
                        State.filteredResult = [];
                        EventEmitter.prototype.emit(AppEvent.Change);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                    });
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        fetchData = function () {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    clearError.call(this);
                    $.when(manager.fetchData()).done(function () {
                        State.isLoading = false;
                        State.filteredResult = [];
                        manager.activityCollection.map(function (item) {
                            State.activities.push({
                                id: item.id,
                                text: item.name
                            });
                        }.bind(this));

                        if (settings.fetchTaskCollection()) {
                            manager.createActiveTaskCollection(settings.activeTaskCollection);
                            State.activeItems = manager.activeTaskCollection;
                        }
                        fetchLatestBackground.call(this);
                        clearError.call(this);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                        setTimeout(function () {
                            fetchData.call(this);
                        }, settings.retryInterval);
                    }.bind(this));
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        filterTaskCollection = function (query) {
            try {
                var manager = getDataManager();
                if (!State.isLoading && manager !== null) {
                    State.filteredResult = manager.filterTaskCollection(query);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        clearSearch = function () {
            try {
                State.filteredResult = [];
                EventEmitter.prototype.emit(AppEvent.Change);
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        createActiveTask = function (issueId) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.createActiveTask(issueId);
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    State.activeItems = manager.activeTaskCollection;
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskActivityId = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskActivityId(entry.id, entry.activityId);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskComments = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskComments(entry.id, entry.comments);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        updateActiveTaskHours = function (entry) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.updateActiveTaskHours(entry.id, entry.hours);
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        removeActiveTask = function (entryId) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.removeActiveTask(entryId);
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        postUpdatedActiveTaskCollection = function (spentOn) {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    $.when(manager.postUpdatedActiveTaskCollection(spentOn)).done(function () {
                        EventEmitter.prototype.emit(AppEvent.Change);
                    }.bind(this)).fail(function (error) {
                        handleError(error);
                    });
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        clearActiveTaskCollection = function () {
            try {
                var manager = getDataManager();
                if (manager !== null) {
                    manager.clearActiveTaskCollection();
                    State.activeItems = manager.activeTaskCollection;
                    settings.setTaskCollection(manager.getActiveTaskCollection());
                    EventEmitter.prototype.emit(AppEvent.Change);
                }
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        setSettings = function (data) {
            try {
                $.when(settings.setSettings(data.url, data.apiKey)).done(function () {
                    EventEmitter.prototype.emit(AppEvent.Change);
                }).fail(function (error) {
                    handleError(error);
                });
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        resetState = function () {
            State = {
                fetchInProgress: false,
                filteredResult: [],
                activeItems: [],
                activities: [],
                isLoading: true,
                settings: settings,
                error: null
            };
        },
        clearSettings = function () {
            try {
                if (State.isLoading) {
                    handleError(StoreError.DataFetchInProgress);
                    return null;
                }

                settings.clearSettings();
                resetState.call(this);
                EventEmitter.prototype.emit(AppEvent.Change);
            } catch (error) {
                handleError(StoreError.InternalServerError);
                console.error(prettify(error) || error);
            }
        },
        addChangeListener = function (callback) {
            EventEmitter.prototype.on(AppEvent.Change, callback);
        },
        removeChangeListeners = function (callback) {
            EventEmitter.prototype.removeListener(AppEvent.Change, callback);
        },
        dispatcherIndex = AppDispatcher.register(function (payload) {
            // Clear the current error as its shown to the user already.
            State.error = null;

            var action = payload.action;
            switch (action.actionType) {
            case AppConstants.FetchIssues:
                fetchData.call(this);
                break;
            case AppConstants.Search:
                filterTaskCollection.call(this, action.query);
                break;
            case AppConstants.ClearSearch:
                clearSearch.call();
                break;
            case AppConstants.AddIssue:
                createActiveTask.call(this, action.issueId);
                break;
            case AppConstants.UpdateTaskActivityId:
                updateActiveTaskActivityId.call(this, action.entry);
                break;
            case AppConstants.UpdateTaskComments:
                updateActiveTaskComments.call(this, action.entry);
                break;
            case AppConstants.UpdateTaskHours:
                updateActiveTaskHours.call(this, action.entry);
                break;
            case AppConstants.CreateTimeEntries:
                postUpdatedActiveTaskCollection.call(this, action.spentOn);
                break;
            case AppConstants.ClearTimeEntries:
                clearActiveTaskCollection.call(this);
                break;
            case AppConstants.SaveSettings:
                setSettings.call(this, action.settings);
                break;
            case AppConstants.RemoveTimeEntry:
                removeActiveTask.call(this, action.taskId);
                break;
            case AppConstants.RefreshIssues:
                fetchLatest.call(this);
                break;
            case AppConstants.Logout:
                clearSettings.call(this);
                break;
            }
        });

    return {
        getState: getState,
        addChangeListener: addChangeListener,
        removeChangeListeners: removeChangeListeners,
        dispatcherIndex: dispatcherIndex
    };
}()));<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import Modal from 'react-bootstrap/lib/Modal';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import Button from 'react-bootstrap/lib/Button';
import Thumbnail from 'react-bootstrap/lib/Thumbnail';
import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';

import mapEventEmitter from 'fm3/emitters/mapEventEmitter';

import { galleryRequestImages, gallerySetImages } from 'fm3/actions/galleryActions';

class GalleryResult extends React.Component {
  static propTypes = {
    onImageRequest: PropTypes.func.isRequired,
    images:
      PropTypes.arrayOf(PropTypes.shape({
      })).isRequired,
    onClose: PropTypes.func.isRequired,
  }

  componentWillMount() {
    mapEventEmitter.on('mapClick', this.handleMapClick);
  }

  componentWillUnmount() {
    mapEventEmitter.removeListener('mapClick', this.handleMapClick);
  }

  handleMapClick = (lat, lon) => {
    this.props.onImageRequest(lat, lon);
  }

  render() {
    const { images, onClose } = this.props;
    return (
      <Modal show={images.length} onHide={onClose}>
        <Modal.Header closeButton>
          <Modal.Title>Obrázky</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {images.map(({ path, title, description }) => (

              <Thumbnail
                src={`http://www.freemap.sk/lib/image.php?width=558&height=558&filename=upload/gallery/${path}`}
                alt={title}
                href={`http://www.freemap.sk/upload/gallery/${path}`}
                target="freemap_gallery_image"
              >
                {title && title !== '-' &&
{title}
}
                {description && description !== '-' &&
{description}
}
              </Thumbnail>

          ))}
        </Modal.Body>
        <Modal.Footer>
          <Button onClick={onClose}><Glyphicon glyph="remove" /> Zavrieť</Button>
        </Modal.Footer>
      </Modal>
    );
  }
}

export default connect(
  state => ({
    images: state.gallery.images,
  }),
  dispatch => ({
    onImageRequest(lat, lon) {
      dispatch(galleryRequestImages(lat, lon));
    },
    onClose() {
      dispatch(gallerySetImages([]));
    },
  }),
)(GalleryResult);
<commit_msg>removed unused imports<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import Modal from 'react-bootstrap/lib/Modal';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import Button from 'react-bootstrap/lib/Button';
import Thumbnail from 'react-bootstrap/lib/Thumbnail';

import mapEventEmitter from 'fm3/emitters/mapEventEmitter';

import { galleryRequestImages, gallerySetImages } from 'fm3/actions/galleryActions';

class GalleryResult extends React.Component {
  static propTypes = {
    onImageRequest: PropTypes.func.isRequired,
    images:
      PropTypes.arrayOf(PropTypes.shape({
      })).isRequired,
    onClose: PropTypes.func.isRequired,
  }

  componentWillMount() {
    mapEventEmitter.on('mapClick', this.handleMapClick);
  }

  componentWillUnmount() {
    mapEventEmitter.removeListener('mapClick', this.handleMapClick);
  }

  handleMapClick = (lat, lon) => {
    this.props.onImageRequest(lat, lon);
  }

  render() {
    const { images, onClose } = this.props;
    return (
      <Modal show={images.length} onHide={onClose}>
        <Modal.Header closeButton>
          <Modal.Title>Obrázky</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {images.map(({ path, title, description }) => (

              <Thumbnail
                src={`http://www.freemap.sk/lib/image.php?width=558&height=558&filename=upload/gallery/${path}`}
                alt={title}
                href={`http://www.freemap.sk/upload/gallery/${path}`}
                target="freemap_gallery_image"
              >
                {title && title !== '-' &&
{title}
}
                {description && description !== '-' &&
{description}
}
              </Thumbnail>

          ))}
        </Modal.Body>
        <Modal.Footer>
          <Button onClick={onClose}><Glyphicon glyph="remove" /> Zavrieť</Button>
        </Modal.Footer>
      </Modal>
    );
  }
}

export default connect(
  state => ({
    images: state.gallery.images,
  }),
  dispatch => ({
    onImageRequest(lat, lon) {
      dispatch(galleryRequestImages(lat, lon));
    },
    onClose() {
      dispatch(gallerySetImages([]));
    },
  }),
)(GalleryResult);
<|endoftext|>


<commit_before>/**
 * Implements Http File Upload (XEP-0363)
 *
 * @namespace jsxc.xmpp.httpUpload
 * @see {@link http://xmpp.org/extensions/xep-0363.html}
 */
jsxc.xmpp.httpUpload = {
   conn: null,

   ready: false,

   CONST: {
      NS: {
         HTTPUPLOAD: 'urn:xmpp:http:upload'
      }
   }
};

/**
 * Set up http file upload.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {Object} o options
 */
jsxc.xmpp.httpUpload.init = function(o) {
   var self = jsxc.xmpp.httpUpload;
   self.conn = jsxc.xmpp.conn;

   var fileTransferOptions = jsxc.options.get('fileTransfer') || {};
   var options = o || jsxc.options.get('httpUpload');

   if (!fileTransferOptions.httpUpload.enable) {
      jsxc.debug('http upload disabled');

      jsxc.options.set('httpUpload', false);

      return;
   }

   if (options && options.server) {
      self.ready = true;

      return;
   }

   var caps = jsxc.xmpp.conn.caps;
   var domain = jsxc.xmpp.conn.domain;

   if (!caps || !domain || typeof caps._knownCapabilities[caps._jidVerIndex[domain]] === 'undefined') {
      jsxc.debug('Waiting for server capabilities');

      $(document).on('caps.strophe', function onCaps(ev, from) {

         if (from !== domain) {
            return;
         }

         self.init();

         $(document).off('caps.strophe', onCaps);
      });

      return;
   }

   if (caps.hasFeatureByJid(domain, self.CONST.NS.HTTPUPLOAD)) {
      self.discoverUploadService();
   } else {
      jsxc.debug(domain + ' does not support http upload');
   }
};

/**
 * Discover upload service for http upload.
 *
 * @memberOf jsxc.xmpp.httpUpload
 */
jsxc.xmpp.httpUpload.discoverUploadService = function() {
   var self = jsxc.xmpp.httpUpload;

   jsxc.debug('discover http upload service');

   self.queryItemForUploadService(self.conn.domain);

   self.conn.disco.items(self.conn.domain, null, function(items) {
      $(items).find('item').each(function() {
         var jid = $(this).attr('jid');

         self.queryItemForUploadService(jid);
      });
   });
};

/**
 * Query item for upload service.
 *
 * @param {String} jid
 * @param {Function} cb Callback on success
 * @memberOf jsxc.xmpp.httpUpload
 */
jsxc.xmpp.httpUpload.queryItemForUploadService = function(jid, cb) {
   var self = jsxc.xmpp.httpUpload;

   jsxc.debug('query ' + jid + ' for upload service');

   self.conn.disco.info(jid, null, function(info) {
      var httpUploadFeature = $(info).find('feature[var="' + self.CONST.NS.HTTPUPLOAD + '"]');
      var httpUploadMaxSize = $(info).find('field[var="max-file-size"]');

      if (httpUploadFeature.length > 0) {
         jsxc.debug('http upload service found on ' + jid);

         jsxc.options.set('httpUpload', {
            server: jid,
            name: $(info).find('identity').attr('name'),
            maxSize: parseInt(httpUploadMaxSize.text())
         });

         self.ready = true;

         if (typeof cb === 'function') {
            cb.call(info);
         }
      }
   });
};

/**
 * Upload file and send link to peer.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {File} file
 * @param  {Message} message Preview message
 */
jsxc.xmpp.httpUpload.sendFile = function(file, message) {
   jsxc.debug('Send file via http upload');

   var self = jsxc.xmpp.httpUpload;

   // even if the link is encrypted the file isn't
   message.encrypted = false;

   self.requestSlot(file, function(data) {
      if (!data) {
         // general error
         jsxc.warn('Unknown error occured. Please check the debug log.');
      } else if (data.error) {
         // specific error
         jsxc.warn('The xmpp server responded with an error of the type "' + data.error.type + '"');

         message.getDOM().remove();

         jsxc.gui.window.postMessage({
            bid: message.bid,
            direction: jsxc.Message.SYS,
            msg: data.error.text
         });

         message.delete();
      } else if (data.get && data.put) {
         // slot received, start upload
         self.uploadFile(data.put, file, message, function() {
            var a = $('<a>');
            a.attr('href', data.get);
            a.attr('data-name', message.attachment.name);
            a.attr('data-type', message.attachment.type);
            a.attr('data-size', message.attachment.size);

            if (message.attachment.thumbnail) {
               a.attr('data-thumbnail', message.attachment.thumbnail);
            }

            a.text(data.get);
            message.attachment.data = data.get;

            message.msg = $('<span>').append(a).html();
            message.type = jsxc.Message.HTML;
            jsxc.gui.window.postMessage(message);
         });
      }
   });
};

/**
 * Upload the given file to the given url.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {String} url upload url
 * @param  {File} file
 * @param  {Message} message preview message
 * @param  {Function} success_cb callback on successful transition
 */
jsxc.xmpp.httpUpload.uploadFile = function(url, file, message, success_cb) {
   $.ajax({
      url: url,
      type: 'PUT',
      contentType: 'application/octet-stream',
      data: file,
      processData: false,
      xhr: function() {
         var xhr = $.ajaxSettings.xhr();

         // track upload progress
         xhr.upload.onprogress = function(ev) {
            if (ev.lengthComputable) {
               jsxc.gui.window.updateProgress(message, ev.loaded, ev.total);
            }
         };
         return xhr;
      },
      success: function() {
         jsxc.debug('file successful uploaded');

         // In case that upload progress is not available, inform user
         jsxc.gui.window.updateProgress(message, 1, 1);

         if (success_cb) {
            success_cb();
         }
      },
      error: function() {
         jsxc.warn('error while uploading file to ' + url);

         message.error = 'Could not upload file';
         jsxc.gui.window.postMessage(message);
      }
   });
};

/**
 * Request upload slot.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {File} file
 * @param  {Function} cb Callback after finished request
 */
jsxc.xmpp.httpUpload.requestSlot = function(file, cb) {
   var self = jsxc.xmpp.httpUpload;
   var options = jsxc.options.get('httpUpload');

   if (!options || !options.server) {
      jsxc.warn('could not request upload slot, because I am not aware of a server or http upload is disabled');

      return;
   }

   var iq = $iq({
         to: options.server,
         type: 'get'
      }).c('request', {
         xmlns: self.CONST.NS.HTTPUPLOAD
      }).c('filename').t(file.name)
      .up()
      .c('size').t(file.size);

   self.conn.sendIQ(iq, function(stanza) {
      self.successfulRequestSlotCB(stanza, cb);
   }, function(stanza) {
      self.failedRequestSlotCB(stanza, cb);
   });
};

/**
 * Process successful response to slot request.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param {String} stanza
 * @param {Function} cb
 */
jsxc.xmpp.httpUpload.successfulRequestSlotCB = function(stanza, cb) {
   var self = jsxc.xmpp.httpUpload;
   var slot = $(stanza).find('slot[xmlns="' + self.CONST.NS.HTTPUPLOAD + '"]');

   if (slot.length > 0) {
      var put = slot.find('put').text();
      var get = slot.find('get').text();

      cb({
         put: put,
         get: get
      });
   } else {
      self.failedRequestSlotCB(stanza, cb);
   }
};

/**
 * Process failed response to slot request.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {String} stanza
 * @param  {Function} cb
 */
jsxc.xmpp.httpUpload.failedRequestSlotCB = function(stanza, cb) {
   if ($(stanza).find('error').length <= 0) {
      jsxc.warn('response does not contain a slot element');

      cb();

      return;
   }

   var error = {
      type: $(stanza).find('error').attr('type') || 'unknown',
      text: $(stanza).find('error text').text()
   };

   if ($(stanza).find('error not-acceptable')) {
      error.reason = 'not-acceptable';
   } else if ($(stanza).find('error resource-constraint')) {
      error.reason = 'resource-constraint';
   } else if ($(stanza).find('error not-allowed')) {
      error.reason = 'not-allowed';
   }

   cb({
      error: error
   });
};

$(document).on('stateChange.jsxc', function(ev, state) {
   if (state === jsxc.CONST.STATE.READY) {
      jsxc.xmpp.httpUpload.init();
   }
});
<commit_msg>stop searching for upload service (#450)<commit_after>/**
 * Implements Http File Upload (XEP-0363)
 *
 * @namespace jsxc.xmpp.httpUpload
 * @see {@link http://xmpp.org/extensions/xep-0363.html}
 */
jsxc.xmpp.httpUpload = {
   conn: null,

   ready: false,

   CONST: {
      NS: {
         HTTPUPLOAD: 'urn:xmpp:http:upload'
      }
   }
};

/**
 * Set up http file upload.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {Object} o options
 */
jsxc.xmpp.httpUpload.init = function(o) {
   var self = jsxc.xmpp.httpUpload;
   self.conn = jsxc.xmpp.conn;

   var fileTransferOptions = jsxc.options.get('fileTransfer') || {};
   var options = o || jsxc.options.get('httpUpload');

   if (!fileTransferOptions.httpUpload.enable) {
      jsxc.debug('http upload disabled');

      jsxc.options.set('httpUpload', false);

      return;
   }

   if (options && options.server) {
      self.ready = true;

      return;
   }

   var caps = jsxc.xmpp.conn.caps;
   var domain = jsxc.xmpp.conn.domain;

   if (!caps || !domain || typeof caps._knownCapabilities[caps._jidVerIndex[domain]] === 'undefined') {
      jsxc.debug('Waiting for server capabilities');

      $(document).on('caps.strophe', function onCaps(ev, from) {

         if (from !== domain) {
            return;
         }

         self.init();

         $(document).off('caps.strophe', onCaps);
      });

      return;
   }

   if (caps.hasFeatureByJid(domain, self.CONST.NS.HTTPUPLOAD)) {
      self.discoverUploadService();
   } else {
      jsxc.debug(domain + ' does not support http upload');
   }
};

/**
 * Discover upload service for http upload.
 *
 * @memberOf jsxc.xmpp.httpUpload
 */
jsxc.xmpp.httpUpload.discoverUploadService = function() {
   var self = jsxc.xmpp.httpUpload;

   jsxc.debug('discover http upload service');

   self.queryItemForUploadService(self.conn.domain);

   self.conn.disco.items(self.conn.domain, null, function(items) {
      $(items).find('item').each(function() {
         var jid = $(this).attr('jid');

         if (self.ready) {
            // abort, because we already found a service
            return false;
         }

         self.queryItemForUploadService(jid);
      });
   });
};

/**
 * Query item for upload service.
 *
 * @param {String} jid
 * @param {Function} cb Callback on success
 * @memberOf jsxc.xmpp.httpUpload
 */
jsxc.xmpp.httpUpload.queryItemForUploadService = function(jid, cb) {
   var self = jsxc.xmpp.httpUpload;

   jsxc.debug('query ' + jid + ' for upload service');

   self.conn.disco.info(jid, null, function(info) {
      var httpUploadFeature = $(info).find('feature[var="' + self.CONST.NS.HTTPUPLOAD + '"]');
      var httpUploadMaxSize = $(info).find('field[var="max-file-size"]');

      if (httpUploadFeature.length > 0) {
         jsxc.debug('http upload service found on ' + jid);

         jsxc.options.set('httpUpload', {
            server: jid,
            name: $(info).find('identity').attr('name'),
            maxSize: parseInt(httpUploadMaxSize.text())
         });

         self.ready = true;

         if (typeof cb === 'function') {
            cb.call(info);
         }
      }
   });
};

/**
 * Upload file and send link to peer.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {File} file
 * @param  {Message} message Preview message
 */
jsxc.xmpp.httpUpload.sendFile = function(file, message) {
   jsxc.debug('Send file via http upload');

   var self = jsxc.xmpp.httpUpload;

   // even if the link is encrypted the file isn't
   message.encrypted = false;

   self.requestSlot(file, function(data) {
      if (!data) {
         // general error
         jsxc.warn('Unknown error occured. Please check the debug log.');
      } else if (data.error) {
         // specific error
         jsxc.warn('The xmpp server responded with an error of the type "' + data.error.type + '"');

         message.getDOM().remove();

         jsxc.gui.window.postMessage({
            bid: message.bid,
            direction: jsxc.Message.SYS,
            msg: data.error.text
         });

         message.delete();
      } else if (data.get && data.put) {
         // slot received, start upload
         self.uploadFile(data.put, file, message, function() {
            var a = $('<a>');
            a.attr('href', data.get);
            a.attr('data-name', message.attachment.name);
            a.attr('data-type', message.attachment.type);
            a.attr('data-size', message.attachment.size);

            if (message.attachment.thumbnail) {
               a.attr('data-thumbnail', message.attachment.thumbnail);
            }

            a.text(data.get);
            message.attachment.data = data.get;

            message.msg = $('<span>').append(a).html();
            message.type = jsxc.Message.HTML;
            jsxc.gui.window.postMessage(message);
         });
      }
   });
};

/**
 * Upload the given file to the given url.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {String} url upload url
 * @param  {File} file
 * @param  {Message} message preview message
 * @param  {Function} success_cb callback on successful transition
 */
jsxc.xmpp.httpUpload.uploadFile = function(url, file, message, success_cb) {
   $.ajax({
      url: url,
      type: 'PUT',
      contentType: 'application/octet-stream',
      data: file,
      processData: false,
      xhr: function() {
         var xhr = $.ajaxSettings.xhr();

         // track upload progress
         xhr.upload.onprogress = function(ev) {
            if (ev.lengthComputable) {
               jsxc.gui.window.updateProgress(message, ev.loaded, ev.total);
            }
         };
         return xhr;
      },
      success: function() {
         jsxc.debug('file successful uploaded');

         // In case that upload progress is not available, inform user
         jsxc.gui.window.updateProgress(message, 1, 1);

         if (success_cb) {
            success_cb();
         }
      },
      error: function() {
         jsxc.warn('error while uploading file to ' + url);

         message.error = 'Could not upload file';
         jsxc.gui.window.postMessage(message);
      }
   });
};

/**
 * Request upload slot.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {File} file
 * @param  {Function} cb Callback after finished request
 */
jsxc.xmpp.httpUpload.requestSlot = function(file, cb) {
   var self = jsxc.xmpp.httpUpload;
   var options = jsxc.options.get('httpUpload');

   if (!options || !options.server) {
      jsxc.warn('could not request upload slot, because I am not aware of a server or http upload is disabled');

      return;
   }

   var iq = $iq({
         to: options.server,
         type: 'get'
      }).c('request', {
         xmlns: self.CONST.NS.HTTPUPLOAD
      }).c('filename').t(file.name)
      .up()
      .c('size').t(file.size);

   self.conn.sendIQ(iq, function(stanza) {
      self.successfulRequestSlotCB(stanza, cb);
   }, function(stanza) {
      self.failedRequestSlotCB(stanza, cb);
   });
};

/**
 * Process successful response to slot request.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param {String} stanza
 * @param {Function} cb
 */
jsxc.xmpp.httpUpload.successfulRequestSlotCB = function(stanza, cb) {
   var self = jsxc.xmpp.httpUpload;
   var slot = $(stanza).find('slot[xmlns="' + self.CONST.NS.HTTPUPLOAD + '"]');

   if (slot.length > 0) {
      var put = slot.find('put').text();
      var get = slot.find('get').text();

      cb({
         put: put,
         get: get
      });
   } else {
      self.failedRequestSlotCB(stanza, cb);
   }
};

/**
 * Process failed response to slot request.
 *
 * @memberOf jsxc.xmpp.httpUpload
 * @param  {String} stanza
 * @param  {Function} cb
 */
jsxc.xmpp.httpUpload.failedRequestSlotCB = function(stanza, cb) {
   if ($(stanza).find('error').length <= 0) {
      jsxc.warn('response does not contain a slot element');

      cb();

      return;
   }

   var error = {
      type: $(stanza).find('error').attr('type') || 'unknown',
      text: $(stanza).find('error text').text()
   };

   if ($(stanza).find('error not-acceptable')) {
      error.reason = 'not-acceptable';
   } else if ($(stanza).find('error resource-constraint')) {
      error.reason = 'resource-constraint';
   } else if ($(stanza).find('error not-allowed')) {
      error.reason = 'not-allowed';
   }

   cb({
      error: error
   });
};

$(document).on('stateChange.jsxc', function(ev, state) {
   if (state === jsxc.CONST.STATE.READY) {
      jsxc.xmpp.httpUpload.init();
   }
});
<|endoftext|>


<commit_before>const Discord = require('discord.js');
module.exports = member => {
  const modlog = guild.channels.find('name', 'pie-log');
    let guild = member.guild;
    //${member.user.username}
    const embed = new Discord.RichEmbed()
    .setTimestamp()
    .setColor(0xff0000)
    .setTitle("User Left")
    .setThumbnail(`${member.user.avatarURL}`)
    .setDescription(`\n`)
    .addField("Username:",`${member.user.username} (${member.user})`,true)
    .addField("Highest Role:",`${member.user.highestRole.position}`,false)
  .setFooter(`User: ${member.user.username}`,`${member.user.avatarURL}`);
guild.channels.get(modlog.id).send({embed}).catch(console.error);
  };
<commit_msg>Update guildMemberRemove.js<commit_after>const Discord = require('discord.js');
module.exports = member => {
  const modlog = member.guild.channels.find('name', 'pie-log');
    //${member.user.username}
    const embed = new Discord.RichEmbed()
    .setTimestamp()
    .setColor(0xff0000)
    .setTitle("User Left")
    .setThumbnail(`${member.user.avatarURL}`)
    .setDescription(`\n`)
    .addField("Username:",`${member.user.username} (${member.user})`,true)
    .addField("Highest Role:",`${member.user.highestRole.position}`,false)
  .setFooter(`User: ${member.user.username}`,`${member.user.avatarURL}`);
member.guild.channels.get(modlog.id).send({embed}).catch(console.error);
  };
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import normalizeCss from 'normalize.css';
import { Form, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { compose } from 'react-apollo';
import { Container, Col, Card } from 'reactstrap';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import Header from '../libs/Header';
import s from './Layout.scss';
import scrollToItem from '../libs/scroll';
import { ESTIMATE_FORM } from '../../constants';

class Layout extends React.Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    handleSubmit: PropTypes.func.isRequired,
  };
  getChildContext() {
    const { handleSubmit } = this.props;
    return { handleSubmit };
  }

  render() {
    return (

        <Container className={s.estimator}>
          <Card id="screen">
            <Col
              xs="12"
              md="12"
              lg="10"
              className={s.estimator__container}
            >
              <Form
                form={ESTIMATE_FORM}
              >
                {this.props.children}
              </Form>
            </Col>
          </Card>
        </Container>

    );
  }
}

Layout.childContextTypes = {
  handleSubmit: PropTypes.func,
};

Layout = reduxForm({
  form: ESTIMATE_FORM,
  enableReinitialize: false,
  onSubmitFail: scrollToItem,
})(Layout);

const initializeValues = () => {
  const initialValues = {
    moneyRate: '25',
    estimateOptions: {
      qa: 10,
      pm: 10,
      risks: 10,
      bugFixes: 10,
      completing: 100,
    },
  };

  return { initialValues };
};

export default compose(
  connect(initializeValues),
  withStyles(normalizeCss, s),
)(Layout);
<commit_msg>prevent submit on enter press<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import normalizeCss from 'normalize.css';
import { Form, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { compose } from 'react-apollo';
import { Container, Col, Card } from 'reactstrap';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import Header from '../libs/Header';
import s from './Layout.scss';
import scrollToItem from '../libs/scroll';
import { ESTIMATE_FORM } from '../../constants';

class Layout extends React.Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    handleSubmit: PropTypes.func.isRequired,
  };

  getChildContext() {
    const { handleSubmit } = this.props;
    return { handleSubmit };
  }

  handleOnKeyPress(event) {
    if (event.key === 'Enter') {
      event.preventDefault();
    }
  }

  render() {
    return (

        <Container className={s.estimator}>
          <Card id="screen">
            <Col
              xs="12"
              md="12"
              lg="10"
              className={s.estimator__container}
            >
              <Form
                form={ESTIMATE_FORM}
                onKeyPress={this.handleOnKeyPress}
              >
                {this.props.children}
              </Form>
            </Col>
          </Card>
        </Container>

    );
  }
}

Layout.childContextTypes = {
  handleSubmit: PropTypes.func,
};

Layout = reduxForm({
  form: ESTIMATE_FORM,
  enableReinitialize: false,
  onSubmitFail: scrollToItem,
})(Layout);

const initializeValues = () => {
  const initialValues = {
    moneyRate: '25',
    estimateOptions: {
      qa: 10,
      pm: 10,
      risks: 10,
      bugFixes: 10,
      completing: 100,
    },
  };

  return { initialValues };
};

export default compose(
  connect(initializeValues),
  withStyles(normalizeCss, s),
)(Layout);
<|endoftext|>