<commit_before>import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { TAPi18n } from 'meteor/tap:i18n';
import { $ } from 'meteor/jquery';
import { Session } from 'meteor/session';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';

import { sendDelegationVotes } from '/imports/startup/both/modules/Contract';
import { displayModal } from '/imports/ui/modules/modal';
import { Vote } from '/imports/ui/modules/Vote';
import { contractReady, purgeBallot, candidateBallot, getRightToVote, getBallot, setBallot } from '/imports/ui/modules/ballot';
import { clearPopups } from '/imports/ui/modules/popup';
import { Contracts } from '/imports/api/contracts/Contracts';

import './liquid.html';
import '../action/action.js';

/**
* @summary converts a percentage value to pixels for current liquid bar
* @param {number} percentage percentage value to be converted
* @param {string} voteId where to store the vote
* @return {number} pixels
*/
function percentageToPixel(percentage, voteId) {
  return parseInt(((percentage * $(`#voteBar-${voteId}`).width()) / 100), 10);
}

/**
* @summary given absolute value returns relative pixel width
* @param {number} value nominal votes to pixel width
* @param {object} bar the item being rendered
* @param {string} voteId session var containing vote info
* @param {boolean} interactive return value from slider
*/
function getBarWidth(value, voteId, editable, interactive) {
  if (editable) {
    const wallet = Session.get(voteId);
    if (wallet !== undefined) {
      if (wallet.balance === 0) { return 0; }
      const percentage = parseFloat((value * 100) / wallet.balance, 10).toFixed(2);
      if (interactive) {
        return `${parseInt(wallet.sliderWidth, 10)}px`;
      }
      return `${percentageToPixel(percentage, voteId)}px`;
    }
  }
  // profile, only logged user
  const wallet = Meteor.user().profile.wallet;
  return `${percentageToPixel(parseFloat((value * 100) / wallet.balance, 10).toFixed(2), voteId)}px`;
}

/**
* @summary verifies vote settings are in onRendered
* @param {Vote} vote
*/
function voteFailure(vote) {
  return (vote.allocateQuantity <= vote.minVotes && vote.minVotes !== 0 && vote.voteType === 'DELEGATION') ||
    (vote.allocateQuantity < vote.minVotes && vote.voteType === 'VOTE') ||
    (vote.allocateQuantity === vote.inBallot) ||
    (vote.voteType === 'VOTE' && purgeBallot(getBallot(vote.targetId)).length === 0) ||
    (isNaN(vote.allocateQuantity));
}

/**
* @summary decides what to display in liquid bar as counterparty value
* @param {string} voteId vote controller for gui
* @param {boolean} editable if its an editable liquid vote
*/
function agreement(voteId, editable) {
  if (Session.get(voteId).voteType === 'BALANCE') {
    return getBarWidth(Session.get(voteId).placed, voteId, true);
  }
  return getBarWidth(parseFloat((Session.get(voteId).placed - Session.get(voteId).inBallot) + Session.get(voteId).delegated, 10), voteId, editable);
}

function getPercentage(value, voteId) {
  return parseFloat((value * 100) / Session.get(voteId).balance, 10);
}

/**
* @summary configures dragger for liquid bar handle
*/
const _setupDrag = () => {
  if (Template.instance().data.editable) {
    // drag event
    $(`#voteHandle-${Template.instance().data._id}`).draggable({
      axis: 'x',
      create() {
        const voteId = this.id.replace('voteHandle-', '');
        this.newVote = new Vote(Session.get(voteId), Session.get(voteId).targetId, voteId);
        Session.set(voteId, this.newVote);
      },
      start(event, ui) {
        const voteId = ui.helper.context.id.replace('voteHandle-', '');
        this.calibrateNewPos = 0;
        this.calibrateCurrentPos = 0;
        this.newVote = new Vote(Session.get(voteId), Session.get(voteId).targetId, voteId);
        Session.set(voteId, this.newVote);
        if (Session.get(voteId) !== undefined) {
          $(`#voteSlider-${voteId}`).velocity('stop');
        }
        if (getBallot(this.newVote.targetId).length === 0 && this.newVote.voteType === 'VOTE') {
          if (this.newVote.inBallot > 0) {
            candidateBallot(Meteor.userId(), this.newVote.targetId);
          }
        }
        Session.set('dragging', voteId);
      },
      drag(event, ui) {
        const voteId = ui.helper.context.id.replace('voteHandle-', '');
        this.newVote.sliderInput(ui.position.left);
        this.calibrateCurrentPos = ui.position.left;
        Session.set(voteId, this.newVote);
        /*
        NOTE: dynamic calibration of slider will be done in the future
        if (this.calibrateCurrentPos !== this.calibrateNewPos) {
          this.timer = Meteor.setTimeout(() => {
            if ((this.calibrateCurrentPos - this.calibrateNewPos) > 10 || (this.calibrateCurrentPos - this.calibrateNewPos) < -10) {
              this.calibrateNewPos = this.calibrateCurrentPos;
              Session.set('liquidDynamicCenter', this.calibrateNewPos);
              Meteor.clearTimeout(this.timer);
            }
          }, timers.LIQUID_CALIBRATION);
        } else {
          Meteor.clearTimeout(this.timer);
        }
        */
        ui.position.left = 0;
      },
      stop(event, ui) {
        // executes the vote
        const voteId = ui.helper.context.id.replace('voteHandle-', '');

        const cancel = () => {
          if (this.newVote.inBallot === 0 && this.newVote.voteType === 'VOTE') {
            setBallot(this.newVote.targetId, undefined);
          }
          Session.set('dragging', false);
          this.newVote.resetSlider();
          Session.set(voteId, this.newVote);
        };

        Meteor.clearTimeout(this.timer);

        if (voteFailure(this.newVote)) {
          cancel();
          if (this.newVote.voteType === 'VOTE' && (this.newVote.allocateQuantity !== this.newVote.inBallot || this.newVote.inBallot === 0)) {
            Session.set('noSelectedOption', this.newVote.voteId);
          }
        } else if (contractReady(this.newVote, Contracts.findOne({ _id: this.newVote.targetId })) || this.newVote.voteType === 'DELEGATION') {
          clearPopups();

          // democracy wins
          this.newVote.execute(cancel);
        }
      },
    });
  }
};

Template.liquid.onCreated(function () {
  let wallet = new Vote(Template.instance().data.wallet, Template.instance().data.targetId, Template.instance().data._id);
  Session.set(Template.instance().data._id, wallet);
  Template.instance().contract = new ReactiveVar(Template.currentData().contract);
  Template.instance().rightToVote = new ReactiveVar(getRightToVote(Template.instance().contract.get()));
  Template.instance().candidateBallot = new ReactiveVar(Template.currentData().candidateBallot);
  Template.instance().ready = new ReactiveVar(false);

  const instance = this;

  instance.autorun(function () {
    if (!Session.get('dragging')) {
      const subscription = instance.subscribe('transaction', { view: 'singleVote', contractId: instance.data.targetId, sessionId: Session.get(instance.data._id) });
      if (subscription.ready()) {
        wallet = new Vote(instance.data.wallet, instance.data.targetId, instance.data._id);
        if (wallet.voteType === 'DELEGATION') {
          instance.rightToVote.set(getRightToVote(wallet.delegationContract));
          instance.contract.set(wallet.delegationContract);
        }
        Session.set(instance.data._id, wallet);
        instance.ready.set(true);
      }
    }
  });

/*
  if (wallet.voteType === 'DELEGATION') {
    Template.instance().rightToVote.set(getRightToVote(wallet.delegationContract));
    Template.instance().contract.set(wallet.delegationContract);
  }
  Template.instance().ready.set(true);
*/<commit_msg>removed reactivity from singlevot pubsub<commit_after>import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { TAPi18n } from 'meteor/tap:i18n';
import { $ } from 'meteor/jquery';
import { Session } from 'meteor/session';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';

import { sendDelegationVotes } from '/imports/startup/both/modules/Contract';
import { displayModal } from '/imports/ui/modules/modal';
import { Vote } from '/imports/ui/modules/Vote';
import { contractReady, purgeBallot, candidateBallot, getRightToVote, getBallot, setBallot } from '/imports/ui/modules/ballot';
import { clearPopups } from '/imports/ui/modules/popup';
import { Contracts } from '/imports/api/contracts/Contracts';

import './liquid.html';
import '../action/action.js';

/**
* @summary converts a percentage value to pixels for current liquid bar
* @param {number} percentage percentage value to be converted
* @param {string} voteId where to store the vote
* @return {number} pixels
*/
function percentageToPixel(percentage, voteId) {
  return parseInt(((percentage * $(`#voteBar-${voteId}`).width()) / 100), 10);
}

/**
* @summary given absolute value returns relative pixel width
* @param {number} value nominal votes to pixel width
* @param {object} bar the item being rendered
* @param {string} voteId session var containing vote info
* @param {boolean} interactive return value from slider
*/
function getBarWidth(value, voteId, editable, interactive) {
  if (editable) {
    const wallet = Session.get(voteId);
    if (wallet !== undefined) {
      if (wallet.balance === 0) { return 0; }
      const percentage = parseFloat((value * 100) / wallet.balance, 10).toFixed(2);
      if (interactive) {
        return `${parseInt(wallet.sliderWidth, 10)}px`;
      }
      return `${percentageToPixel(percentage, voteId)}px`;
    }
  }
  // profile, only logged user
  const wallet = Meteor.user().profile.wallet;
  return `${percentageToPixel(parseFloat((value * 100) / wallet.balance, 10).toFixed(2), voteId)}px`;
}

/**
* @summary verifies vote settings are in onRendered
* @param {Vote} vote
*/
function voteFailure(vote) {
  return (vote.allocateQuantity <= vote.minVotes && vote.minVotes !== 0 && vote.voteType === 'DELEGATION') ||
    (vote.allocateQuantity < vote.minVotes && vote.voteType === 'VOTE') ||
    (vote.allocateQuantity === vote.inBallot) ||
    (vote.voteType === 'VOTE' && purgeBallot(getBallot(vote.targetId)).length === 0) ||
    (isNaN(vote.allocateQuantity));
}

/**
* @summary decides what to display in liquid bar as counterparty value
* @param {string} voteId vote controller for gui
* @param {boolean} editable if its an editable liquid vote
*/
function agreement(voteId, editable) {
  if (Session.get(voteId).voteType === 'BALANCE') {
    return getBarWidth(Session.get(voteId).placed, voteId, true);
  }
  return getBarWidth(parseFloat((Session.get(voteId).placed - Session.get(voteId).inBallot) + Session.get(voteId).delegated, 10), voteId, editable);
}

function getPercentage(value, voteId) {
  return parseFloat((value * 100) / Session.get(voteId).balance, 10);
}

/**
* @summary configures dragger for liquid bar handle
*/
const _setupDrag = () => {
  if (Template.instance().data.editable) {
    // drag event
    $(`#voteHandle-${Template.instance().data._id}`).draggable({
      axis: 'x',
      create() {
        const voteId = this.id.replace('voteHandle-', '');
        this.newVote = new Vote(Session.get(voteId), Session.get(voteId).targetId, voteId);
        Session.set(voteId, this.newVote);
      },
      start(event, ui) {
        const voteId = ui.helper.context.id.replace('voteHandle-', '');
        this.calibrateNewPos = 0;
        this.calibrateCurrentPos = 0;
        this.newVote = new Vote(Session.get(voteId), Session.get(voteId).targetId, voteId);
        Session.set(voteId, this.newVote);
        if (Session.get(voteId) !== undefined) {
          $(`#voteSlider-${voteId}`).velocity('stop');
        }
        if (getBallot(this.newVote.targetId).length === 0 && this.newVote.voteType === 'VOTE') {
          if (this.newVote.inBallot > 0) {
            candidateBallot(Meteor.userId(), this.newVote.targetId);
          }
        }
        Session.set('dragging', voteId);
      },
      drag(event, ui) {
        const voteId = ui.helper.context.id.replace('voteHandle-', '');
        this.newVote.sliderInput(ui.position.left);
        this.calibrateCurrentPos = ui.position.left;
        Session.set(voteId, this.newVote);
        /*
        NOTE: dynamic calibration of slider will be done in the future
        if (this.calibrateCurrentPos !== this.calibrateNewPos) {
          this.timer = Meteor.setTimeout(() => {
            if ((this.calibrateCurrentPos - this.calibrateNewPos) > 10 || (this.calibrateCurrentPos - this.calibrateNewPos) < -10) {
              this.calibrateNewPos = this.calibrateCurrentPos;
              Session.set('liquidDynamicCenter', this.calibrateNewPos);
              Meteor.clearTimeout(this.timer);
            }
          }, timers.LIQUID_CALIBRATION);
        } else {
          Meteor.clearTimeout(this.timer);
        }
        */
        ui.position.left = 0;
      },
      stop(event, ui) {
        // executes the vote
        const voteId = ui.helper.context.id.replace('voteHandle-', '');

        const cancel = () => {
          if (this.newVote.inBallot === 0 && this.newVote.voteType === 'VOTE') {
            setBallot(this.newVote.targetId, undefined);
          }
          Session.set('dragging', false);
          this.newVote.resetSlider();
          Session.set(voteId, this.newVote);
        };

        Meteor.clearTimeout(this.timer);

        if (voteFailure(this.newVote)) {
          cancel();
          if (this.newVote.voteType === 'VOTE' && (this.newVote.allocateQuantity !== this.newVote.inBallot || this.newVote.inBallot === 0)) {
            Session.set('noSelectedOption', this.newVote.voteId);
          }
        } else if (contractReady(this.newVote, Contracts.findOne({ _id: this.newVote.targetId })) || this.newVote.voteType === 'DELEGATION') {
          clearPopups();

          // democracy wins
          this.newVote.execute(cancel);
        }
      },
    });
  }
};

Template.liquid.onCreated(function () {
  let wallet = new Vote(Template.instance().data.wallet, Template.instance().data.targetId, Template.instance().data._id);
  Session.set(Template.instance().data._id, wallet);
  Template.instance().contract = new ReactiveVar(Template.currentData().contract);
  Template.instance().rightToVote = new ReactiveVar(getRightToVote(Template.instance().contract.get()));
  Template.instance().candidateBallot = new ReactiveVar(Template.currentData().candidateBallot);
  Template.instance().ready = new ReactiveVar(false);

  const instance = this;

  instance.autorun(function () {

      const subscription = instance.subscribe('transaction', { view: 'singleVote', contractId: instance.data.targetId, sessionId: wallet });
      if (subscription.ready()) {
        wallet = new Vote(instance.data.wallet, instance.data.targetId, instance.data._id);
        if (wallet.voteType === 'DELEGATION') {
          instance.rightToVote.set(getRightToVote(wallet.delegationContract));
          instance.contract.set(wallet.delegationContract);
        }
        Session.set(instance.data._id, wallet);
        instance.ready.set(true);
      }

  });

/*
  if (wallet.voteType === 'DELEGATION') {
    Template.instance().rightToVote.set(getRightToVote(wallet.delegationContract));
    Template.instance().contract.set(wallet.delegationContract);
  }
  Template.instance().ready.set(true);
*/
{'fraction_non_alphanumeric': 0.14980909855691452, 'fraction_numerical': 0.005824111822947, 'mean_word_length': 3.29635807617459, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1214688', 'n_tokens_mistral': 4957, 'n_tokens_neox': 4782, 'n_words': 940}