<commit_before>App.searchController = Ember.ArrayController.create({

    isSearching: false,

    currentPage: 0,

    total_results: 0,

    current_query: '',

    query: '',

  contract: function() {
    this.set('isExpanded', false);
  },

    setCurrentQuery: function(query) {
        this.current_query=query;
    },

    getCurrentQuery: function() {
        return this.current_query;
    },

    parseSolrResponse: function(response) {
        var results = {};
        this.total_results = response.response.numFound;
        $.each(response.response.docs, function(i, doc) {
            var result = {};
            var id = doc.id;
            result["uri"] = doc.cw_uri[0];
            result["label"] = doc.prefLabel[0];
            result["biotrans"] = doc.db_biotran[0];
            result["description"] = doc.db_description[0];
            results[id] = result;
        });
        return results;
    },

    resetPageCount: function(query) {
        this.total_results = 0;
        this.currentPage = 0;
        //this.search(query);
        this.set('query', query);
        this.conceptWikiSearch(query);
        App.Router.router.transitionTo('search');
    },

    search: function(query) {
        var me = this;
        var q = query;
        //only search if there are more results than currently shown
        if (me.total_results > me.currentPage * 10 || me.currentPage == 0) {
        this.set('isSearching', true);
        this.set('content', []);

        var solr_search = $.ajax({
            dataType: "jsonp",
            // will not be localhost on deployment, actual url required
            url: "http://localhost:8080/solr/select?json.wrf=?",
            cache: true,
            data: {
                q: "prefLabel:" + q + " OR db_biotran:" + q + " OR db_description:" + q,
                wt: "json",
                rows: 10,
                start: me.currentPage * 10
            }
        });

        solr_search.success(function (data) {
            me.currentPage++;
            var search_results = me.parseSolrResponse(data);
            $.each(search_results, function(i, search_result){
            var compound_query = $.ajax({
                dataType: "jsonp",
                url: compound_info_search_url,
                cache: true,
                data: {
                    _format: "json",
                    uri: search_result["uri"]
                }
            });
                            compound_query.success(function (data) {
                    var drugbankData, cs_uri, smiles;
                    var cw_uri = data.result.primaryTopic["_about"];
                    var id = cw_uri.split("/").pop();
                    $.each(data.result.primaryTopic.exactMatch, function (i, exactMatch) {
                        if (exactMatch["_about"]) {
                            if (exactMatch["_about"].indexOf("http://www4.wiwiss.fu-berlin.de/drugbank") !== -1) {
                                drugbankData = exactMatch;
                            } else if(exactMatch["_about"].indexOf("http://linkedlifedata.com/resource/drugbank") !== -1) {
                                drugbankData = exactMatch;
                            } else if (exactMatch["_about"].indexOf("http://www.chemspider.com") !== -1) {
                                cs_uri = exactMatch["_about"];
                                smiles = exactMatch.smiles;
                            } else if (exactMatch["_about"].indexOf("http://rdf.chemspider.com") !== -1) {
                                cs_uri = exactMatch["_about"];
                                smiles = exactMatch.smiles;
                            }
                        }
                    });
                    this_compound = App.Compound.createRecord({
                        id: id,
                        cw_uri: cw_uri,
                        description: drugbankData ? drugbankData.description : null,
                        biotransformation_item: drugbankData ? drugbankData.biotransformation : null,
                        toxicity: drugbankData ? drugbankData.toxicity : null,
                        protein_binding: drugbankData ? drugbankData.proteinBinding : null,
                        compound_pref_label: data.result.primaryTopic.prefLabel,
                        exactMatch: data.result.primaryTopic.prefLabel.toLowerCase() === q.toLowerCase() ? true : false,
                        cs_uri: cs_uri,
                        compound_smiles: smiles
                    });
                    if (data.result.primaryTopic.prefLabel.toLowerCase() === q.toLowerCase()) {
                        App.compoundsController.addExactMatch(this_compound);
                    } else {
                        App.compoundsController.addCompound(this_compound);
                    }
                });
            });
            me.set('isSearching', false);
            pageScrolling = false;
            enable_scroll();
        });
        } else {
            // always enable the scroll before returning
            pageScrolling = false;
            enable_scroll();
        }
    },

    conceptWikiSearch: function(query) {
        var me = this;
        var q = query;

        this.set('isSearching', true);
        this.set('content', []);
        var searcher = new Openphacts.ConceptWikiSearch(ldaBaseUrl);
        var callback=function(success, status, response){
            if(success) {
                var results = searcher.parseResponse(response);
                $.each(results, function(index, compoundURI) {
                    var compoundSearcher = new Openphacts.CompoundSearch(ldaBaseUrl);
                    var compoundCallback=function(success, status, response){
                        var compound = compoundSearcher.parseCompoundResponse(response);
                        this_compound = App.Compound.createRecord({
                            id: compound.id,
                            cwURI: compound.cwUri,
                            description: compound.description,
                            biotransformationItem: compound.biotransformationItem,
                            toxicity: compound.toxicity,
                            proteinBinding: compound.proteinBinding,
                            prefLabel: compound.prefLabel,
                            exactMatch: compound.prefLabel.toLowerCase() === q.toLowerCase() ? true : false,
                            csUri: compound.csUri,
                            smiles: compound.smiles,
                            chemblURI: compound.chemblURI,
                            fullMWT: compound.fullMWT,
                            hba: compound.hba,
                            hbd: compound.hbd,
                            inchi: compound.inchi,
                            logp: compound.logp,
                            molform: compound. molform,
                            mwFreebase: compound.mwFreebase,
                            psa: compound.psa,
                            ro5Violations: compound.ro5Violations,
                            rtb: compound.rtb
                        });
                        if (this_compound.get('prefLabel').toLowerCase() === q.toLowerCase()) {
                            App.compoundsController.addExactMatch(this_compound);
                        } else {
                           App.compoundsController.addCompound(this_compound);
                        }
                    };
                    compoundSearcher.fetchCompound(appID, appKey, compoundURI, compoundCallback);
                });
            } else {
                // an error in the response, ignore for now
            }
            me.set('isSearching', false);
            pageScrolling = false;
            enable_scroll();
        };
        searcher.byTag(appID, appKey, 'Aspirin', '20', '4', '07a84994-e464-4bbf-812a-a4b96fa3d197', callback);
   }
});
<commit_msg>add exact match parameter to the compound hash which comes back from ops.js and use it to create the compound record<commit_after>App.searchController = Ember.ArrayController.create({

    isSearching: false,

    currentPage: 0,

    total_results: 0,

    current_query: '',

    query: '',

  contract: function() {
    this.set('isExpanded', false);
  },

    setCurrentQuery: function(query) {
        this.current_query=query;
    },

    getCurrentQuery: function() {
        return this.current_query;
    },

    parseSolrResponse: function(response) {
        var results = {};
        this.total_results = response.response.numFound;
        $.each(response.response.docs, function(i, doc) {
            var result = {};
            var id = doc.id;
            result["uri"] = doc.cw_uri[0];
            result["label"] = doc.prefLabel[0];
            result["biotrans"] = doc.db_biotran[0];
            result["description"] = doc.db_description[0];
            results[id] = result;
        });
        return results;
    },

    resetPageCount: function(query) {
        this.total_results = 0;
        this.currentPage = 0;
        //this.search(query);
        this.set('query', query);
        this.conceptWikiSearch(query);
        App.Router.router.transitionTo('search');
    },

    search: function(query) {
        var me = this;
        var q = query;
        //only search if there are more results than currently shown
        if (me.total_results > me.currentPage * 10 || me.currentPage == 0) {
        this.set('isSearching', true);
        this.set('content', []);

        var solr_search = $.ajax({
            dataType: "jsonp",
            // will not be localhost on deployment, actual url required
            url: "http://localhost:8080/solr/select?json.wrf=?",
            cache: true,
            data: {
                q: "prefLabel:" + q + " OR db_biotran:" + q + " OR db_description:" + q,
                wt: "json",
                rows: 10,
                start: me.currentPage * 10
            }
        });

        solr_search.success(function (data) {
            me.currentPage++;
            var search_results = me.parseSolrResponse(data);
            $.each(search_results, function(i, search_result){
            var compound_query = $.ajax({
                dataType: "jsonp",
                url: compound_info_search_url,
                cache: true,
                data: {
                    _format: "json",
                    uri: search_result["uri"]
                }
            });
                            compound_query.success(function (data) {
                    var drugbankData, cs_uri, smiles;
                    var cw_uri = data.result.primaryTopic["_about"];
                    var id = cw_uri.split("/").pop();
                    $.each(data.result.primaryTopic.exactMatch, function (i, exactMatch) {
                        if (exactMatch["_about"]) {
                            if (exactMatch["_about"].indexOf("http://www4.wiwiss.fu-berlin.de/drugbank") !== -1) {
                                drugbankData = exactMatch;
                            } else if(exactMatch["_about"].indexOf("http://linkedlifedata.com/resource/drugbank") !== -1) {
                                drugbankData = exactMatch;
                            } else if (exactMatch["_about"].indexOf("http://www.chemspider.com") !== -1) {
                                cs_uri = exactMatch["_about"];
                                smiles = exactMatch.smiles;
                            } else if (exactMatch["_about"].indexOf("http://rdf.chemspider.com") !== -1) {
                                cs_uri = exactMatch["_about"];
                                smiles = exactMatch.smiles;
                            }
                        }
                    });
                    this_compound = App.Compound.createRecord({
                        id: id,
                        cw_uri: cw_uri,
                        description: drugbankData ? drugbankData.description : null,
                        biotransformation_item: drugbankData ? drugbankData.biotransformation : null,
                        toxicity: drugbankData ? drugbankData.toxicity : null,
                        protein_binding: drugbankData ? drugbankData.proteinBinding : null,
                        compound_pref_label: data.result.primaryTopic.prefLabel,
                        exactMatch: data.result.primaryTopic.prefLabel.toLowerCase() === q.toLowerCase() ? true : false,
                        cs_uri: cs_uri,
                        compound_smiles: smiles
                    });
                    if (data.result.primaryTopic.prefLabel.toLowerCase() === q.toLowerCase()) {
                        App.compoundsController.addExactMatch(this_compound);
                    } else {
                        App.compoundsController.addCompound(this_compound);
                    }
                });
            });
            me.set('isSearching', false);
            pageScrolling = false;
            enable_scroll();
        });
        } else {
            // always enable the scroll before returning
            pageScrolling = false;
            enable_scroll();
        }
    },

    conceptWikiSearch: function(query) {
        var me = this;
        var q = query;

        this.set('isSearching', true);
        this.set('content', []);
        var searcher = new Openphacts.ConceptWikiSearch(ldaBaseUrl);
        var callback=function(success, status, response){
            if(success) {
                var results = searcher.parseResponse(response);
                $.each(results, function(index, compoundURI) {
                    var compoundSearcher = new Openphacts.CompoundSearch(ldaBaseUrl);
                    var compoundCallback=function(success, status, response){
                        var compound = compoundSearcher.parseCompoundResponse(response);
                        compound.prefLabel.toLowerCase() === q.toLowerCase() ? compound['exactMatch'] = true : compound['exactMatch'] = false;
                        this_compound = App.Compound.createRecord(compound);
                        if (this_compound.get('prefLabel').toLowerCase() === q.toLowerCase()) {
                            App.compoundsController.addExactMatch(this_compound);
                        } else {
                           App.compoundsController.addCompound(this_compound);
                        }
                    };
                    compoundSearcher.fetchCompound(appID, appKey, compoundURI, compoundCallback);
                });
            } else {
                // an error in the response, ignore for now
            }
            me.set('isSearching', false);
            pageScrolling = false;
            enable_scroll();
        };
        searcher.byTag(appID, appKey, 'Aspirin', '20', '4', '07a84994-e464-4bbf-812a-a4b96fa3d197', callback);
   }
});
<|endoftext|>


<commit_before>'use strict';

var editor = (function() {
  var active = {
    ev: {},
    id: 0
  };
  var $cal = $('#calendar');
  var saving = false;
  var success = false;
  var popoverOptions = {
    container: 'body',
    html: true,
    placement: 'auto right',
    content: $('.new-event').html()
  };

  // Hide currently open popover
  var close = function() {
    $('.input-date.d2').datetimepicker('destroy');
    $('.input-date.d1').datetimepicker('destroy');
    $('.input-time.t2').datetimepicker('destroy');
    $('.input-time.t1').datetimepicker('destroy');
    $('.popover').remove();
    active.id = 0;
  };

  var calById = function(id) {
    for (var i = 0, len = calendars.length; i < len; i++) {
      if (calendars[i].id === id)
        return calendars[i];
    }
    return null;
  };

  // Fixes impossible date ranges
  var logic = function() {
    var x = $('.popover');
    if (!x) return;
    var start = moment(x.find('.d1').val() + 'T' + x.find('.t1').val());
    var end = moment(x.find('.d2').val() + 'T' + x.find('.t2').val());
    if (start.isAfter(end)) {
      start = start.add(1, 'hour');
      $('.input-date.d2').val(start.format('YYYY-MM-DD'));
      $('.input-time.t2').val(start.format('HH:mm'));
    }
  };

  // Initialize popover
  var init = function() {

  };

  // Delete event by id
  var remove = function() {
    if (!active.id) return;
    api.deleteEvent(active.id).success(function(data) {
      close();
      console.log()
      $cal.fullCalendar('removeEvents', active.ev.id);
    }).error(function(data) {
      close();
    });
  };

  // Sync with backend
  var sync = function(data, revert) {
    data.id = data.id || active.ev.id;
    data.title = data.title || active.ev.title;
    data.calendar = data.calendar_id || active.ev.calendar_id; // TODO: fix API and remove this line
    data.calendar_id = data.calendar_id || active.ev.calendar_id;

    api.postEvent(data).success(function(data) {
      $cal.fullCalendar('refetchEvents');
    }).error(function(error) {
      console.log(error)
    });
  };

  // Move or resize event
  var drop = function(ev, delta, revert) {
    console.log(ev)
    active.ev = ev;
    var data = {
      start: ev.start.format('YYYY-MM-DD HH:mm'),
      allDay: !ev.start.hasTime()
    };
    if (ev.end) {
      data.end = ev.end.format('YYYY-MM-DD HH:mm');
    } else {
      data.end = ev.start.add(1, 'day').format('YYYY-MM-DD HH:mm');
    }

    sync(data, revert);
  };

  // Update existing event
  var update = function(data) {
    sync(data);

    // Update existing event
    active.ev.title = data.title;
    active.ev.description = data.description;
    active.ev.location = data.location;
    active.ev.start = Date.parse(data.start);
    active.ev.end = Date.parse(data.end);
    active.ev.calendar_id = data.calendar_id;
    active.ev.allDay = data.allDay;

    // Render
    $cal.fullCalendar('updateEvent', active.ev);
  };

  // Create new event
  var create = function(e) {
    e.preventDefault();
    var x = $('.popover');

    // Retrieve form values
    var formdata = {
      title: x.find('.input-title').val(),
      description: x.find('.input-descr').val(),
      location: x.find('.input-location').val(),
      start: x.find('.d1').val() + ' ' + x.find('.t1').val() || '00:00',
      end: x.find('.d2').val() + ' ' + x.find('.t2').val() || '00:00',
      allDay: x.find('.input-allday').val(),
      calendar_id: x.find('.input-cals').val(),
    };

    // Validate input?

    // Update
    if (active.ev._id) {
      close();
      update(formdata);
      return;
    }

    // Open calendar that event was added to

    // Apply to backend
    api.postEvent(formdata).success(function(data) {
      close();
      $cal.fullCalendar('refetchEvents');
    }).error(function(error) {
      console.log(error)
    });
  };

  // Default options
  var d1Options = {
    format: 'Y-m-d',
    timepicker: false,
    onChangeDateTime: logic,
    onShow: logic
  };
  var d2Options = $.extend({}, d1Options);
  var t1Options = {
    format: 'H:i',
    datepicker: false,
    onChangeDateTime: logic,
    onShow: logic,
    step: 30
  };
  var t2Options = $.extend({}, t1Options);

  var fixPopup = function(editable) {
    var $popover = $('.popover');
    $popover.on('click', function(e) {
      e.stopPropagation();
    });
    if ($popover.css('left').replace('px', '') < 0) {
      $popover.css('left', '30px');
    }

    if (editable) {

      // Launch datetimepicker
      $('.input-date.d2').datetimepicker(d2Options);
      $('.input-date.d1').datetimepicker(d1Options);
      $('.input-time.t2').datetimepicker(t2Options);
      $('.input-time.t1').datetimepicker(t1Options);

      // Listen to allDay toggle
      $('.input-allday').on('change', toggleAllDay);
    }
  };

  // Toggle allDay to reflect parameter active
  var toggleAllDay = function(e, allDay) {
    if (e) {
      allDay = $(this).prop('checked');
    } else {
      $('.input-allday').prop('checked', allDay);
    }
    $('.input-time').prop('disabled', allDay);
  };

  // Add event from scratch
  var add = function(jsEvent) {

    jsEvent.stopPropagation();

    // Close current popover
    close();

    if (!user.logged_in) return;

    d1Options.value = moment().format('YYYY-MM-DD');
    t1Options.value = '08:00';
    d2Options.value = moment().format('YYYY-MM-DD');
    t2Options.value = '09:00';

    // Launch popover
    var $target = $(jsEvent.target);
    $target.popover(popoverOptions);
    $target.popover('show');

    fixPopup(true);
    toggleAllDay(null, true);

    $('.popover .btn-danger').addClass('invisible');
  };

  // Show popover to create event
  var select = function(start, end, jsEvent, view) {

    // Close current popover
    close();

    if (!user.logged_in) return;

    // Create new event or edit existing event
    d1Options.value = start.format('YYYY-MM-DD');

    // If time is set, use it
    if (start.hasTime()) {
      t1Options.value = start.format('HH:mm');
      d2Options.value = end.format('YYYY-MM-DD');
      t2Options.value = end.format('HH:mm');
    }

    // If one day selected
    else if (end.diff(start, 'days') === 1) {
      t1Options.value = '08:00';
      d2Options.value = start.format('YYYY-MM-DD');
      t2Options.value = '09:00';
    }

    // If multiple days
    else {
      t1Options.value = '00:00';
      d2Options.value = end.subtract(1, 'day').format('YYYY-MM-DD');
      t2Options.value = '23:59';
      var allDay = true;
    }

    // Launch popover
    var $target = $(jsEvent.target);
    $target.popover(popoverOptions);
    $target.popover('show');

    fixPopup(true);
    toggleAllDay(null, allDay);

    $('.popover .btn-danger').addClass('invisible');
  };

  var open = function(ev, jsEvent, view) {

    // Close current popover
    close();

    var $target = $(jsEvent.target);

    if (ev.editable) {

      d1Options.value = ev.start.format('YYYY-MM-DD');
      t1Options.value = ev.start.format('HH:mm');
      if (ev.end) {
        d2Options.value = ev.end.format('YYYY-MM-DD');
        t2Options.value = ev.end.format('HH:mm');
      } else {
        d2Options.value = ev.start.format('YYYY-MM-DD');
        t2Options.value = ev.start.format('HH:mm');
      }
      active.ev = ev;
      active.id = ev.id || 0;

      // Launch popover
      $target.popover(popoverOptions);
      $target.popover('show');
      $('.popover .btn-success').text('Opslaan');
      toggleAllDay(null, active.ev.allDay);
      $('.input-allday').on('change', toggleAllDay);

      // Launch datetimepicker
      $('.input-date.d2').datetimepicker(d2Options);
      $('.input-date.d1').datetimepicker(d1Options);
      $('.input-time.t2').datetimepicker(t2Options);
      $('.input-time.t1').datetimepicker(t1Options);

      // Set input fields
      $('.input-title').val(ev.title);
      $('.input-descr').val(ev.description);
      $('.input-location').val(ev.location);
      $('.input-cals option[value="' + ev.calendar_id + '"]').prop('selected', true);
      fixPopup(true);
    } else {

      // Set input fields
      $('.read-title').text(ev.title);
      $('.read-descr').text(ev.description);
      $('.read-location').text(ev.location);
      $('.read-cal').text('Kalender ' + calendars[ev.calendar_id].name);

      var a = ev.start.format('MMM');
      var b = ev.start.format('DD');
      var c = ev.end ? ev.end.format('MMM') : ev.start.format('MMM');
      var d = ev.end ? ev.end.format('DD') : ev.start.format('DD');

      // Create readable date
      var readableDate = b;
      if (ev.allDay || ev.start.format('HHmm') === '0000') {
        if (a === c && b == d - 1) {
          readableDate += ev.end.format(' MMMM');
        } else if (a === c) {
          readableDate += ev.end.format(' - DD MMMM');
        } else {
          readableDate += ev.start.format(' MMMM') + ev.end.format(' - DD MMMM');
        }
      } else {
        readableDate += ev.start.format(' MMMM HH:mm');
        if (a === c && b === d) {
          readableDate += ev.end.format(' - HH:mm');
        } else {
          readableDate += ev.end.format(' - DD MMMM HH:mm');
        }
      }
      $('.read-dt').text(readableDate);
      $target.popover({
        container: 'body',
        html: true,
        placement: 'auto right',
        content: $('.read-event-template').html()
      });
      $target.popover('show');
      fixPopup();
    }
  };

  window.addEventListener('submit', create);

  return {
    active: active,
    add: add,
    close: close,
    drop: drop,
    init: init,
    logic: logic,
    open: open,
    remove: remove,
    select: select
  };
})();
<commit_msg>Fix #49<commit_after>'use strict';

var editor = (function() {
  var active = {
    ev: {},
    id: 0
  };
  var $cal = $('#calendar');
  var saving = false;
  var success = false;
  var popoverOptions = {
    container: 'body',
    html: true,
    placement: 'auto right',
    content: $('.new-event').html()
  };

  // Hide currently open popover
  var close = function() {
    $('.input-date.d2').datetimepicker('destroy');
    $('.input-date.d1').datetimepicker('destroy');
    $('.input-time.t2').datetimepicker('destroy');
    $('.input-time.t1').datetimepicker('destroy');
    $('.popover').remove();
    active.id = 0;
  };

  var calById = function(id) {
    for (var i = 0, len = calendars.length; i < len; i++) {
      if (calendars[i].id === id)
        return calendars[i];
    }
    return null;
  };

  // Fixes impossible date ranges
  var logic = function() {
    var x = $('.popover');
    if (!x) return;
    var start = moment(x.find('.d1').val() + 'T' + x.find('.t1').val());
    var end = moment(x.find('.d2').val() + 'T' + x.find('.t2').val());
    if (start.isAfter(end)) {
      start = start.add(1, 'hour');
      $('.input-date.d2').val(start.format('YYYY-MM-DD'));
      $('.input-time.t2').val(start.format('HH:mm'));
    }
  };

  // Initialize popover
  var init = function() {

  };

  // Delete event by id
  var remove = function() {
    if (!active.id) return;
    api.deleteEvent(active.id).success(function(data) {
      close();
      console.log()
      $cal.fullCalendar('removeEvents', active.ev.id);
    }).error(function(data) {
      close();
    });
  };

  // Sync with backend
  var sync = function(data, revert) {
    data.id = data.id || active.ev.id;
    data.title = data.title || active.ev.title;
    data.calendar = data.calendar_id || active.ev.calendar_id; // TODO: fix API and remove this line
    data.calendar_id = data.calendar_id || active.ev.calendar_id;

    api.postEvent(data).success(function(data) {
      $cal.fullCalendar('refetchEvents');
    }).error(function(error) {
      console.log(error)
    });
  };

  // Move or resize event
  var drop = function(ev, delta, revert) {
    console.log(ev)
    active.ev = ev;
    var data = {
      start: ev.start.format('YYYY-MM-DD HH:mm'),
      allDay: !ev.start.hasTime()
    };
    if (ev.end) {
      data.end = ev.end.format('YYYY-MM-DD HH:mm');
    } else {
      data.end = ev.start.add(1, 'day').format('YYYY-MM-DD HH:mm');
    }

    sync(data, revert);
  };

  // Update existing event
  var update = function(data) {
    sync(data);

    // Update existing event
    active.ev.title = data.title;
    active.ev.description = data.description;
    active.ev.location = data.location;
    active.ev.start = Date.parse(data.start);
    active.ev.end = Date.parse(data.end);
    active.ev.calendar_id = data.calendar_id;
    active.ev.allDay = data.allDay;

    // Render
    $cal.fullCalendar('updateEvent', active.ev);
  };

  // Create new event
  var create = function(e) {
    e.preventDefault();
    var x = $('.popover');

    // Retrieve form values
    var formdata = {
      title: x.find('.input-title').val(),
      description: x.find('.input-descr').val(),
      location: x.find('.input-location').val(),
      start: x.find('.d1').val() + ' ' + x.find('.t1').val() || '00:00',
      end: x.find('.d2').val() + ' ' + x.find('.t2').val() || '00:00',
      allDay: x.find('.input-allday').val(),
      calendar_id: x.find('.input-cals').val(),
    };

    // Validate input?

    // Update
    if (active.ev._id) {
      close();
      update(formdata);
      return;
    }

    // Open calendar that event was added to

    // Apply to backend
    api.postEvent(formdata).success(function(data) {
      close();
      $cal.fullCalendar('refetchEvents');
    }).error(function(error) {
      console.log(error)
    });
  };

  // Default options
  var d1Options = {
    format: 'Y-m-d',
    timepicker: false,
    onChangeDateTime: logic,
    onShow: logic
  };
  var d2Options = $.extend({}, d1Options);
  var t1Options = {
    format: 'H:i',
    datepicker: false,
    onChangeDateTime: logic,
    onShow: logic,
    step: 30
  };
  var t2Options = $.extend({}, t1Options);

  var fixPopup = function(editable) {
    var $popover = $('.popover');
    $popover.on('click', function(e) {
      e.stopPropagation();
    });
    if ($popover.css('left').replace('px', '') < 0) {
      $popover.css('left', '30px');
    }

    if (editable) {

      // Launch datetimepicker
      $('.input-date.d2').datetimepicker(d2Options);
      $('.input-date.d1').datetimepicker(d1Options);
      $('.input-time.t2').datetimepicker(t2Options);
      $('.input-time.t1').datetimepicker(t1Options);

      // Listen to allDay toggle
      $('.input-allday').on('change', toggleAllDay);
    }
  };

  // Toggle allDay to reflect parameter active
  var toggleAllDay = function(e, allDay) {
    if (e) {
      allDay = $(this).prop('checked');
    } else {
      $('.input-allday').prop('checked', allDay);
    }
    $('.input-time').prop('disabled', allDay);
  };

  // Add event from scratch
  var add = function(jsEvent) {

    jsEvent.stopPropagation();

    // Close current popover
    close();

    if (!user.logged_in) return;

    d1Options.value = moment().format('YYYY-MM-DD');
    t1Options.value = '08:00';
    d2Options.value = moment().format('YYYY-MM-DD');
    t2Options.value = '09:00';

    // Launch popover
    var $target = $(jsEvent.target);
    $target.popover(popoverOptions);
    $target.popover('show');

    fixPopup(true);
    toggleAllDay(null, true);

    $('.popover .btn-danger').addClass('invisible');
  };

  // Show popover to create event
  var select = function(start, end, jsEvent, view) {

    // Close current popover
    close();

    if (!user.logged_in) return;

    // Create new event or edit existing event
    d1Options.value = start.format('YYYY-MM-DD');
    t1Options.value = '08:00';
    t2Options.value = '09:00';

    // If time is set, use it
    var allDay = true;
    if (start.hasTime()) {
      t1Options.value = start.format('HH:mm');
      d2Options.value = end.format('YYYY-MM-DD');
      t2Options.value = end.format('HH:mm');
      allDay = false;
    }

    // If one day selected
    else if (end.diff(start, 'days') === 1) {
      d2Options.value = start.format('YYYY-MM-DD');
    }

    // If multiple days
    else {
      d2Options.value = end.subtract(1, 'day').format('YYYY-MM-DD');
    }

    // Launch popover
    var $target = $(jsEvent.target);
    $target.popover(popoverOptions);
    $target.popover('show');

    fixPopup(true);
    toggleAllDay(null, allDay);

    $('.popover .btn-danger').addClass('invisible');
  };

  var open = function(ev, jsEvent, view) {

    // Close current popover
    close();

    var $target = $(jsEvent.target);

    if (ev.editable) {

      d1Options.value = ev.start.format('YYYY-MM-DD');
      t1Options.value = ev.start.format('HH:mm');
      if (ev.end) {
        d2Options.value = ev.end.format('YYYY-MM-DD');
        t2Options.value = ev.end.format('HH:mm');
      } else {
        d2Options.value = ev.start.format('YYYY-MM-DD');
        t2Options.value = ev.start.format('HH:mm');
      }
      active.ev = ev;
      active.id = ev.id || 0;

      // Launch popover
      $target.popover(popoverOptions);
      $target.popover('show');
      $('.popover .btn-success').text('Opslaan');
      toggleAllDay(null, active.ev.allDay);
      $('.input-allday').on('change', toggleAllDay);

      // Launch datetimepicker
      $('.input-date.d2').datetimepicker(d2Options);
      $('.input-date.d1').datetimepicker(d1Options);
      $('.input-time.t2').datetimepicker(t2Options);
      $('.input-time.t1').datetimepicker(t1Options);

      // Set input fields
      $('.input-title').val(ev.title);
      $('.input-descr').val(ev.description);
      $('.input-location').val(ev.location);
      $('.input-cals option[value="' + ev.calendar_id + '"]').prop('selected', true);
      fixPopup(true);
    } else {

      // Set input fields
      $('.read-title').text(ev.title);
      $('.read-descr').text(ev.description);
      $('.read-location').text(ev.location);
      $('.read-cal').text('Kalender ' + calendars[ev.calendar_id].name);

      var a = ev.start.format('MMM');
      var b = ev.start.format('DD');
      var c = ev.end ? ev.end.format('MMM') : ev.start.format('MMM');
      var d = ev.end ? ev.end.format('DD') : ev.start.format('DD');

      // Create readable date
      var readableDate = b;
      if (ev.allDay || ev.start.format('HHmm') === '0000') {
        if (a === c && b == d - 1) {
          readableDate += ev.end.format(' MMMM');
        } else if (a === c) {
          readableDate += ev.end.format(' - DD MMMM');
        } else {
          readableDate += ev.start.format(' MMMM') + ev.end.format(' - DD MMMM');
        }
      } else {
        readableDate += ev.start.format(' MMMM HH:mm');
        if (a === c && b === d) {
          readableDate += ev.end.format(' - HH:mm');
        } else {
          readableDate += ev.end.format(' - DD MMMM HH:mm');
        }
      }
      $('.read-dt').text(readableDate);
      $target.popover({
        container: 'body',
        html: true,
        placement: 'auto right',
        content: $('.read-event-template').html()
      });
      $target.popover('show');
      fixPopup();
    }
  };

  window.addEventListener('submit', create);

  return {
    active: active,
    add: add,
    close: close,
    drop: drop,
    init: init,
    logic: logic,
    open: open,
    remove: remove,
    select: select
  };
})();
<|endoftext|>


<commit_before>Class.makeClass(Drawable, function BodyPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

BodyPart.prototype.clone = function(owner) {
	return new this.constructor(this.x, this.y, owner, this.flip);
}

BodyPart.prototype.setOwner = function(owner) {
	this.owner = owner;

	this.r = owner.r;
	this.g = owner.g;
	this.b = owner.b;
	this.a = owner.a;
}

BodyPart.prototype.parentDrawPath = BodyPart.prototype.drawPath;
BodyPart.prototype.drawPath = function() {
	this.a = this.owner.a;
	this.parentDrawPath();
}

/* BODY PART: SlimeBody */

Class.makeClass(BodyPart, function SlimeBody(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

SlimeBody.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top();
	var bottom = this.owner.y + (this.owner.size * this.y);
	var hMid = this.owner.x + (this.owner.size * this.x);

	var left = hMid - halfWidth;
	var right = hMid + halfWidth;

	var wobble = this.owner.wobble;
	var smallWobble = wobble/2;
	var stretch = this.owner.stretch;

	ctx.moveTo(left, bottom);

	if (this.type == 'platform') {
		var shallowWidth = halfWidth / 2;
		var vMid = bottom - (this.owner.size * this.owner.height/2);

		ctx.quadraticCurveTo(left + shallowWidth, vMid, left, top);
		ctx.lineTo(right, top);
		ctx.quadraticCurveTo(right - shallowWidth, vMid, right, bottom);
		ctx.lineTo(left, bottom);
	} else {
		if (this.owner.stiffness) {
			ctx.lineTo(hMid + wobble, top - stretch);
			ctx.lineTo(hMid + halfWidth, bottom);
		} else {
			ctx.bezierCurveTo(hMid + wobble - halfWidth, top - stretch, hMid + wobble + halfWidth, top - stretch, hMid + halfWidth, bottom);
		}
		ctx.bezierCurveTo(hMid + smallWobble + halfWidth, this.owner.y, hMid + smallWobble - halfWidth, this.owner.y, hMid - halfWidth, bottom);
	}
}

/* BODY PART: Leg */

Class.makeClass(BodyPart, function LegPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

LegPart.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top() + this.y;
	var bottom = this.owner.y;
	var vAnchor = bottom + this.owner.size * (this.owner.body.y + this.y);
	var hAnchor = this.owner.x + (this.owner.size * this.x);

	var dir = this.flip ? -1 : 1;

	var span = this.owner.x - dir * (-30 + this.y * this.owner.size * 1);
	var offset = 5 - (this.y/5);

	var wobble = this.owner.wobble;
	var stretch = this.owner.stretch;

	var footHeight = 4 * this.owner.fastAmp * this.owner.animSpeed();
	var footDist = -1 * this.owner.fastAmp * this.owner.animSpeed();

	ctx.moveTo(hAnchor, vAnchor);
	ctx.quadraticCurveTo(span + wobble, top - stretch, span + (footDist), bottom + (dir * footHeight));
	ctx.quadraticCurveTo(span + wobble - (dir * offset), top - stretch + offset, hAnchor + (dir * offset), vAnchor + offset);
}

/* BODY PART: Wing */

Class.makeClass(BodyPart, function WingPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

WingPart.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top();
	var bottom = this.owner.y;
	var vAnchor = bottom + this.owner.size * (this.owner.body.y + this.y);
	var hAnchor = this.owner.x + (this.owner.size * this.x);

	var vMid = top + (this.owner.height/2 * this.owner.size);

	top += 10;

	var dir = this.flip ? -1 : 1;

	var span = this.owner.x - dir * (-40 * this.owner.size);
	var offset = 5 - (this.y/5);

	var wobble = this.owner.wobble;
	var stretch = this.owner.stretch;

	var footHeight = 4 * this.owner.fastAmp * this.owner.animSpeed();
	var footDist = -1 * this.owner.fastAmp * this.owner.animSpeed();

	var flap = Math.abs(15 * (this.owner.rawAmp) * this.owner.animSpeed());

	ctx.moveTo(hAnchor, vAnchor);
	ctx.quadraticCurveTo(span + wobble, bottom, span, top - offset + flap);
	ctx.lineTo(span + (dir * offset * 2), top + flap);
	ctx.quadraticCurveTo(span + wobble, bottom, hAnchor, vAnchor);
}
<commit_msg>Add some life to the platform render<commit_after>Class.makeClass(Drawable, function BodyPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

BodyPart.prototype.clone = function(owner) {
	return new this.constructor(this.x, this.y, owner, this.flip);
}

BodyPart.prototype.setOwner = function(owner) {
	this.owner = owner;

	this.r = owner.r;
	this.g = owner.g;
	this.b = owner.b;
	this.a = owner.a;
}

BodyPart.prototype.parentDrawPath = BodyPart.prototype.drawPath;
BodyPart.prototype.drawPath = function() {
	this.a = this.owner.a;
	this.parentDrawPath();
}

/* BODY PART: SlimeBody */

Class.makeClass(BodyPart, function SlimeBody(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

SlimeBody.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top();
	var bottom = this.owner.y + (this.owner.size * this.y);
	var hMid = this.owner.x + (this.owner.size * this.x);

	var left = hMid - halfWidth;
	var right = hMid + halfWidth;

	var wobble = this.owner.wobble;
	var smallWobble = wobble/2;
	var stretch = this.owner.stretch;

	ctx.moveTo(left, bottom);

	if (this.type == 'platform') {
		var shallowWidth = halfWidth / 2;
		var vMid = bottom - (this.owner.size * this.owner.height/2);

		ctx.quadraticCurveTo(left + shallowWidth + smallWobble, vMid, left, top);
		ctx.lineTo(right, top);
		ctx.quadraticCurveTo(right - shallowWidth - smallWobble, vMid, right, bottom);
		ctx.lineTo(left, bottom);
	} else {
		if (this.owner.stiffness) {
			ctx.lineTo(hMid + wobble, top - stretch);
			ctx.lineTo(hMid + halfWidth, bottom);
		} else {
			ctx.bezierCurveTo(hMid + wobble - halfWidth, top - stretch, hMid + wobble + halfWidth, top - stretch, hMid + halfWidth, bottom);
		}
		ctx.bezierCurveTo(hMid + smallWobble + halfWidth, this.owner.y, hMid + smallWobble - halfWidth, this.owner.y, hMid - halfWidth, bottom);
	}
}

/* BODY PART: Leg */

Class.makeClass(BodyPart, function LegPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

LegPart.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top() + this.y;
	var bottom = this.owner.y;
	var vAnchor = bottom + this.owner.size * (this.owner.body.y + this.y);
	var hAnchor = this.owner.x + (this.owner.size * this.x);

	var dir = this.flip ? -1 : 1;

	var span = this.owner.x - dir * (-30 + this.y * this.owner.size * 1);
	var offset = 5 - (this.y/5);

	var wobble = this.owner.wobble;
	var stretch = this.owner.stretch;

	var footHeight = 4 * this.owner.fastAmp * this.owner.animSpeed();
	var footDist = -1 * this.owner.fastAmp * this.owner.animSpeed();

	ctx.moveTo(hAnchor, vAnchor);
	ctx.quadraticCurveTo(span + wobble, top - stretch, span + (footDist), bottom + (dir * footHeight));
	ctx.quadraticCurveTo(span + wobble - (dir * offset), top - stretch + offset, hAnchor + (dir * offset), vAnchor + offset);
}

/* BODY PART: Wing (unused) */

Class.makeClass(BodyPart, function WingPart(x, y, owner, flip) {
	this.init();

	this.x = x;
	this.y = y;
	this.flip = flip;

	this.setOwner(owner);
});

WingPart.prototype.definePath = function() {
	var halfWidth = this.owner.size * this.owner.width/2;
	var top = this.owner.top();
	var bottom = this.owner.y;
	var vAnchor = bottom + this.owner.size * (this.owner.body.y + this.y);
	var hAnchor = this.owner.x + (this.owner.size * this.x);

	var vMid = top + (this.owner.height/2 * this.owner.size);

	top += 10;

	var dir = this.flip ? -1 : 1;

	var span = this.owner.x - dir * (-40 * this.owner.size);
	var offset = 5 - (this.y/5);

	var wobble = this.owner.wobble;
	var stretch = this.owner.stretch;

	var footHeight = 4 * this.owner.fastAmp * this.owner.animSpeed();
	var footDist = -1 * this.owner.fastAmp * this.owner.animSpeed();

	var flap = Math.abs(15 * (this.owner.rawAmp) * this.owner.animSpeed());

	ctx.moveTo(hAnchor, vAnchor);
	ctx.quadraticCurveTo(span + wobble, bottom, span, top - offset + flap);
	ctx.lineTo(span + (dir * offset * 2), top + flap);
	ctx.quadraticCurveTo(span + wobble, bottom, hAnchor, vAnchor);
}
<|endoftext|>


<commit_before>define([ "jquery", "lib/utils/viewport_helper" ], function($, isInViewport) {
  "use strict";

  var HeroParallax,
      _pageYOffset,
      started = false,
      speed = 15,
      els;

  HeroParallax = function( args ) {
    this.$els = args.els || $(".js-bg-parallax");
    $(window).bind("scroll", $.proxy(this._onScroll, this));
  };

  HeroParallax.prototype._updateBg = function( i, el ) {
    var $el = $(el);
    if (isInViewport(el)) {
      var percent = 30 + ((($el.offset().top - _pageYOffset) * speed) / $el.height());
      $el.css("backgroundPosition", "center " + percent + "%");
    }
  };

  HeroParallax.prototype._update = function() {
    window.lp.supports.requestAnimationFrame($.proxy(this._update, this));
    $.each(this.$els, $.proxy(this._updateBg, this));
  };

  HeroParallax.prototype._startrAF = function() {
    if (!started){
      window.lp.supports.requestAnimationFrame($.proxy(this._update, this));
      started = true;
    }
  };

  HeroParallax.prototype._onScroll = function() {
    _pageYOffset = window.pageYOffset;
    this._startrAF();
  };

  if ( window.lp.supports.requestAnimationFrame ){
    els = $(".js-bg-parallax");
    if (els.length) {
      new HeroParallax({
        els: els
      });
    }
  }

  return HeroParallax;

});
<commit_msg>Fix @csutter's sloppy code style<commit_after>define([ "jquery", "lib/utils/viewport_helper" ], function($, isInViewport) {
  "use strict";

  var HeroParallax,
      _pageYOffset,
      started = false,
      speed = 15,
      els;

  HeroParallax = function( args ) {
    this.$els = args.els || $(".js-bg-parallax");
    $(window).bind("scroll", $.proxy(this._onScroll, this));
  };

  HeroParallax.prototype._updateBg = function( i, el ) {
    var $el = $(el);
    if (isInViewport(el)) {
      var percent = 30 + ((($el.offset().top - _pageYOffset) * speed) / $el.height());
      $el.css("backgroundPosition", "center " + percent + "%");
    }
  };

  HeroParallax.prototype._update = function() {
    window.lp.supports.requestAnimationFrame($.proxy(this._update, this));
    $.each(this.$els, $.proxy(this._updateBg, this));
  };

  HeroParallax.prototype._startrAF = function() {
    if (!started){
      window.lp.supports.requestAnimationFrame($.proxy(this._update, this));
      started = true;
    }
  };

  HeroParallax.prototype._onScroll = function() {
    _pageYOffset = window.pageYOffset;
    this._startrAF();
  };

  if ( window.lp.supports.requestAnimationFrame ){
    els = $(".js-bg-parallax");
    if (els.length) {
      new HeroParallax({
        els: els
      });
    }
  }

  return HeroParallax;

});
<|endoftext|>


<commit_before>import tracking from "./utils/tracking.js";

const header = {
  init() {
    this.trackLoginButtonClick();
    this.initProfileDropdownMenu();
    this.initClearSearchInput();
  },

  trackLoginButtonClick() {
    const loginButtonEl = document.querySelector(".js-header-login-button");

    if (!loginButtonEl) return;

    loginButtonEl.addEventListener("click", event => {
      event.preventDefault();
      tracking.sendWithCallback("header", "login_button_click", "", () => {
        location.href = event.target.href;
      });
    });
  },

  initProfileDropdownMenu() {
    const containerEl = document.querySelector(
      ".js-profile-dropdown-button-container"
    );

    if (!containerEl) return;

    containerEl.addEventListener("click", e => {
      const button = e.target.closest(".js-profile-dropdown-button-trigger");
      if (button) {
        const isOpen = containerEl.getAttribute("state") === "open";
        const itemsContainerEl = containerEl.querySelector(
          ".js-profile-dropdown-button-items"
        );
        if (isOpen) {
          // close items
          itemsContainerEl.style.display = "none";
          containerEl.setAttribute("state", "closed");
        } else {
          // open items
          itemsContainerEl.style.display = "flex";
          containerEl.setAttribute("state", "open");
        }
      }
    });
  },

  initClearSearchInput() {
    const searchInputEl = document.querySelector(".js-query-search-input");
    const clearSearchButtonEl = document.querySelector(".js-search-query-clear-button");
    const searchFormEl = document.querySelector(".js-query-search-form");
    this.hideOrShowSearchCloseButton(searchInputEl.value, clearSearchButtonEl);

    searchInputEl.addEventListener("input", e => {
      this.hideOrShowSearchCloseButton(e.target.value, clearSearchButtonEl);
    });

    clearSearchButtonEl.addEventListener("click", e => {
      searchInputEl.value = "";
      this.hideOrShowSearchCloseButton(searchInputEl.value, clearSearchButtonEl);
      history.pushState({}, "", '/search');
      location.href = '/search';
    });
  },

  hideOrShowSearchCloseButton(query, clearSearchButtonEl) {
    if (query.length > 0) {
      clearSearchButtonEl.classList.remove("hidden");
    } else {
      clearSearchButtonEl.classList.add("hidden");
    }
  }
};

export default header;
<commit_msg>Track search submit<commit_after>import tracking from "./utils/tracking.js";

const header = {
  init() {
    this.trackLoginButtonClick();
    this.initProfileDropdownMenu();
    this.initClearSearchInput();
  },

  trackLoginButtonClick() {
    const loginButtonEl = document.querySelector(".js-header-login-button");

    if (!loginButtonEl) return;

    loginButtonEl.addEventListener("click", event => {
      event.preventDefault();
      tracking.sendWithCallback("header", "login_button_click", "", () => {
        location.href = event.target.href;
      });
    });
  },

  initProfileDropdownMenu() {
    const containerEl = document.querySelector(
      ".js-profile-dropdown-button-container"
    );

    if (!containerEl) return;

    containerEl.addEventListener("click", e => {
      const button = e.target.closest(".js-profile-dropdown-button-trigger");
      if (button) {
        const isOpen = containerEl.getAttribute("state") === "open";
        const itemsContainerEl = containerEl.querySelector(
          ".js-profile-dropdown-button-items"
        );
        if (isOpen) {
          // close items
          itemsContainerEl.style.display = "none";
          containerEl.setAttribute("state", "closed");
        } else {
          // open items
          itemsContainerEl.style.display = "flex";
          containerEl.setAttribute("state", "open");
        }
      }
    });
  },

  initClearSearchInput() {
    const searchInputEl = document.querySelector(".js-query-search-input");
    const clearSearchButtonEl = document.querySelector(".js-search-query-clear-button");
    const searchFormEl = document.querySelector(".js-query-search-form");
    this.hideOrShowSearchCloseButton(searchInputEl.value, clearSearchButtonEl);

    searchFormEl.addEventListener("submit", e => {
      tracking.sendWithCallback("header", "search_submit", searchInputEl.value, () => {
        location.href = `/search?query=${searchInputEl.value}`;
      });
      e.preventDefault();
    });

    searchInputEl.addEventListener("input", e => {
      this.hideOrShowSearchCloseButton(e.target.value, clearSearchButtonEl);
    });

    clearSearchButtonEl.addEventListener("click", e => {
      searchInputEl.value = "";
      this.hideOrShowSearchCloseButton(searchInputEl.value, clearSearchButtonEl);
      history.pushState({}, "", '/search');
      location.href = '/search';
    });
  },

  hideOrShowSearchCloseButton(query, clearSearchButtonEl) {
    if (query.length > 0) {
      clearSearchButtonEl.classList.remove("hidden");
    } else {
      clearSearchButtonEl.classList.add("hidden");
    }
  }
};

export default header;
<|endoftext|>


<commit_before>/**
 * Copyright © Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
define([
    'jquery',
    'Amazon_PayV2/js/action/checkout-session-config-load',
    'Amazon_PayV2/js/model/storage',
    'mage/url',
    'Amazon_PayV2/js/amazon-checkout',
    'Magento_Customer/js/customer-data'
], function ($, checkoutSessionConfigLoad, amazonStorage, url, amazonCheckout, customerData) {
    'use strict';

    var cart = customerData.get('cart'),
        customer = customerData.get('customer'),
        canCheckoutWithAmazon = false;

    // to use Amazon Pay: customer needs to be logged in, or guest checkout allowed, or Amazon Sign-in enabled
    if (customer().firstname || amazonStorage.isGuestCheckoutEnabled || amazonStorage.isLwaEnabled) {
        canCheckoutWithAmazon = true;
    }

    if (amazonStorage.isEnabled && canCheckoutWithAmazon) {
        $.widget('amazon.AmazonButton', {
            options: {
                payOnly: null,
                placement: 'Cart',
                hideIfUnavailable: ''
            },

            _loadButtonConfig: function (callback) {
                checkoutSessionConfigLoad(function (checkoutSessionConfig) {
                    if (!$.isEmptyObject(checkoutSessionConfig)) {
                        callback({
                            merchantId: checkoutSessionConfig['merchant_id'],
                            createCheckoutSession: {
                                url: url.build('amazon_payv2/checkout/createSession'),
                                method: 'PUT'
                            },
                            ledgerCurrency: checkoutSessionConfig['currency'],
                            buttonColor: checkoutSessionConfig['button_color'],
                            checkoutLanguage: checkoutSessionConfig['language'],
                            productType: this._isPayOnly(checkoutSessionConfig['pay_only']) ? 'PayOnly' : 'PayAndShip',
                            placement: this.options.placement,
                            sandbox: checkoutSessionConfig['sandbox'],
                        });

                        this.options.placement !== "Checkout" && $(this.options.hideIfUnavailable).show();
                    } else {
                        $(this.options.hideIfUnavailable).hide();
                    }
                }.bind(this));
            },

            /**
             * @param {boolean} isCheckoutSessionPayOnly
             * @returns {boolean}
             * @private
             */
            _isPayOnly: function (isCheckoutSessionPayOnly) {
                var result = isCheckoutSessionPayOnly;
                if (result && this.options.payOnly !== null) {
                    result = this.options.payOnly;
                }
                return result;
            },

            /**
             * Create button
             */
            _create: function () {
                this._draw();

                if (this.options.placement == 'Product') {
                    this._redraw();
                }
            },

            /**
            * Draw button
            **/
            _draw: function () {
                var $buttonContainer = this.element;
                amazonCheckout.withAmazonCheckout(function (amazon, args) {
                    var $buttonRoot = $('

');
                    $buttonRoot.html('');
                    $buttonContainer.empty().append($buttonRoot);
                    this._loadButtonConfig(function (buttonConfig) {
                        amazon.Pay.renderButton('#' + $buttonRoot.empty().uniqueId().attr('id'), buttonConfig);
                        $('.amazon-button-container-v2 .field-tooltip').fadeIn();
                    });
                }, this);
            },

            /**
            * Redraw button if needed
            **/
            _redraw: function () {
                var self = this;
                var cartData = customerData.get('cart');
                cartData.subscribe(function (updatedCart) {
                    if (!$(self.options.hideIfUnavailable).first().is(':visible')) {
                        self._draw();
                    }
                });

            },

            click: function () {
                this.element.children().first().trigger('click');
            }
        });

        return $.amazon.AmazonButton;
    }
});
<commit_msg>ASD-490 - code style change for clarity<commit_after>/**
 * Copyright © Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
define([
    'jquery',
    'Amazon_PayV2/js/action/checkout-session-config-load',
    'Amazon_PayV2/js/model/storage',
    'mage/url',
    'Amazon_PayV2/js/amazon-checkout',
    'Magento_Customer/js/customer-data'
], function ($, checkoutSessionConfigLoad, amazonStorage, url, amazonCheckout, customerData) {
    'use strict';

    var cart = customerData.get('cart'),
        customer = customerData.get('customer'),
        canCheckoutWithAmazon = false;

    // to use Amazon Pay: customer needs to be logged in, or guest checkout allowed, or Amazon Sign-in enabled
    if (customer().firstname || amazonStorage.isGuestCheckoutEnabled || amazonStorage.isLwaEnabled) {
        canCheckoutWithAmazon = true;
    }

    if (amazonStorage.isEnabled && canCheckoutWithAmazon) {
        $.widget('amazon.AmazonButton', {
            options: {
                payOnly: null,
                placement: 'Cart',
                hideIfUnavailable: ''
            },

            _loadButtonConfig: function (callback) {
                checkoutSessionConfigLoad(function (checkoutSessionConfig) {
                    if (!$.isEmptyObject(checkoutSessionConfig)) {
                        callback({
                            merchantId: checkoutSessionConfig['merchant_id'],
                            createCheckoutSession: {
                                url: url.build('amazon_payv2/checkout/createSession'),
                                method: 'PUT'
                            },
                            ledgerCurrency: checkoutSessionConfig['currency'],
                            buttonColor: checkoutSessionConfig['button_color'],
                            checkoutLanguage: checkoutSessionConfig['language'],
                            productType: this._isPayOnly(checkoutSessionConfig['pay_only']) ? 'PayOnly' : 'PayAndShip',
                            placement: this.options.placement,
                            sandbox: checkoutSessionConfig['sandbox'],
                        });

                        if (this.options.placement !== "Checkout") {
                            $(this.options.hideIfUnavailable).show();
                        }
                    } else {
                        $(this.options.hideIfUnavailable).hide();
                    }
                }.bind(this));
            },

            /**
             * @param {boolean} isCheckoutSessionPayOnly
             * @returns {boolean}
             * @private
             */
            _isPayOnly: function (isCheckoutSessionPayOnly) {
                var result = isCheckoutSessionPayOnly;
                if (result && this.options.payOnly !== null) {
                    result = this.options.payOnly;
                }
                return result;
            },

            /**
             * Create button
             */
            _create: function () {
                this._draw();

                if (this.options.placement == 'Product') {
                    this._redraw();
                }
            },

            /**
            * Draw button
            **/
            _draw: function () {
                var $buttonContainer = this.element;
                amazonCheckout.withAmazonCheckout(function (amazon, args) {
                    var $buttonRoot = $('

');
                    $buttonRoot.html('');
                    $buttonContainer.empty().append($buttonRoot);
                    this._loadButtonConfig(function (buttonConfig) {
                        amazon.Pay.renderButton('#' + $buttonRoot.empty().uniqueId().attr('id'), buttonConfig);
                        $('.amazon-button-container-v2 .field-tooltip').fadeIn();
                    });
                }, this);
            },

            /**
            * Redraw button if needed
            **/
            _redraw: function () {
                var self = this;
                var cartData = customerData.get('cart');
                cartData.subscribe(function (updatedCart) {
                    if (!$(self.options.hideIfUnavailable).first().is(':visible')) {
                        self._draw();
                    }
                });

            },

            click: function () {
                this.element.children().first().trigger('click');
            }
        });

        return $.amazon.AmazonButton;
    }
});
<|endoftext|>


<commit_before>function Pager(size) {
  this.page      = 0;
  this.length    = 0;
  this.page_size = (size === undefined) ? 0 : size;
}

Pager.prototype.movePage = function(dir) {
  // Pages left/right relative to current page
  //  @dir: direction to move (+ to move up, - to move down)
  //        if dir is undefined, will move to page 0
  if(dir === undefined) { this.page = 0; return; }
  this.page += dir;

  if(this.page <= 0) this.page = 0;
  if(this.page >= this.total()) this.page = this.total();
}

// Accessors
Pager.prototype.total = function() {
  // Return total number of pages possible
  try {
    // round down to multiple of page_size
    var actual_length = this.length - 1; // correct 1-off errors
    var mult = actual_length - (actual_length % this.page_size);
    // Divide by page size, then add 1
    return Math.floor(mult / this.page_size);

  } catch(err) {
    console.log(err); // Most likely divide by zero error
    return 0;
  }
}

Pager.prototype.first = function() {
  // Get number of item at start of current page
  return this.page * this.page_size;
}

Pager.prototype.last = function() {
  // Get number of item at end of current page
  if(this.length <= 0) return 0;

  // Return last item on page regardless if exists
  var last = (this.page * this.page_size) + this.page_size;

  // Add in check if last item reached before end of page
  return (last <= this.length) ? last - 1 : this.length - 1;
}
<commit_msg>Renamed movePage() to move()<commit_after>function Pager(size) {
  this.page      = 0;
  this.length    = 0;
  this.page_size = (size === undefined) ? 0 : size;
}

Pager.prototype.move = function(dir) {
  // Pages left/right relative to current page
  //  @dir: direction to move (+ to move up, - to move down)
  //        if dir is undefined, will move to page 0
  if(dir === undefined) { this.page = 0; return; }
  this.page += dir;

  if(this.page <= 0) this.page = 0;
  if(this.page >= this.total()) this.page = this.total();
}

// Accessors
Pager.prototype.total = function() {
  // Return total number of pages possible
  try {
    // round down to multiple of page_size
    var actual_length = this.length - 1; // correct 1-off errors
    var mult = actual_length - (actual_length % this.page_size);
    // Divide by page size, then add 1
    return Math.floor(mult / this.page_size);

  } catch(err) {
    console.log(err); // Most likely divide by zero error
    return 0;
  }
}

Pager.prototype.first = function() {
  // Get number of item at start of current page
  return this.page * this.page_size;
}

Pager.prototype.last = function() {
  // Get number of item at end of current page
  if(this.length <= 0) return 0;

  // Return last item on page regardless if exists
  var last = (this.page * this.page_size) + this.page_size;

  // Add in check if last item reached before end of page
  return (last <= this.length) ? last - 1 : this.length - 1;
}
<|endoftext|>


<commit_before>/*========================================================================

   This file is part of the GOsa project -  http://gosa-project.org

   Copyright:
      (C) 2010-2017 GONICUS GmbH, Germany, http://www.gonicus.de

   License:
      LGPL-2.1: http://www.gnu.org/licenses/lgpl-2.1.html

   See the LICENSE file in the project's top-level directory for details.

======================================================================== */

/**
 * Dialog for editing dashboard widgets
 */
qx.Class.define("gosa.ui.dialogs.EditDashboardWidget", {
  extend: gosa.ui.dialogs.Dialog,

  construct: function(widget) {
    this.base(arguments, this.tr("Edit dashboard widget"));

    // form
    var form = new qx.ui.form.Form();

    // add the form items
    form.add(new qx.ui.form.TextField(widget.getBackgroundColor()), this.tr("Background color"), null, "backgroundColor");

    var properties = [];
    var selectionValues = {};

    var options = gosa.data.DashboardController.getWidgetOptions(widget);
    if (options.settings) {
      Object.getOwnPropertyNames(options.settings.properties).forEach(function(propertyName) {
        var typeSettings = options.settings.properties[propertyName];
        var type, title = propertyName;
        properties.push(propertyName);
        if (qx.lang.Type.isObject(typeSettings)) {
          type = typeSettings.type;
          if (typeSettings.title) {
            title = typeSettings.title;
            if (title.translate) {
              // trigger the translation
              title = title.translate();
            }
          }
        } else {
          type = typeSettings;
        }
        var formItem;
        switch (type) {
          case "Json":
            formItem = new qx.ui.form.TextArea(qx.lang.Json.stringify(widget.get(propertyName)));
            break;
          case "String":
            formItem = new qx.ui.form.TextArea(widget.get(propertyName));
            break;
          case "Number":
            formItem = new qx.ui.form.Spinner(widget.get(propertyName));
            break;
          case "selection":
            var selectBox = new qx.ui.form.SelectBox();
            if (!options.settings.mandatory || options.settings.mandatory.indexOf(propertyName) === -1) {
              selectBox.add(new qx.ui.form.ListItem("-"));
            }
            var currentValue = widget.get(propertyName);

            if (typeSettings.provider === "RPC" && typeSettings.method) {
              // retrieve data from rpc
              gosa.io.Rpc.getInstance().cA(typeSettings.method).then(function(result) {
                for (var key in result) {
                  if (result.hasOwnProperty(key)) {
                    var item = new qx.ui.form.ListItem(result[key][typeSettings.value]);
                    var keyValue = typeSettings.key === "KEY" ? key : result[key][typeSettings.key];
                    item.setUserData("key", keyValue);
                    if (typeSettings.icon) {
                      item.setIcon(result[key][typeSettings.icon])
                    }
                    selectBox.add(item);
                    if (keyValue === currentValue) {
                      selectBox.setSelection([item]);
                    }
                  }
                }
              }, this);
            }
            selectBox.addListener("changeSelection", function() {
              if (selectBox.getSelection().length) {
                var selectedValue = selectBox.getSelection()[0].getUserData("key");
                if (selectedValue) {
                  selectionValues[propertyName] = selectedValue;
                }
              }
            }, this);
            formItem = selectBox;
            break;
        }
        if (options.settings.mandatory && options.settings.mandatory.indexOf(propertyName) >= 0) {
          formItem.setRequired(true);
        }
        form.add(formItem, title, null, propertyName);
      }, this);
    }

    // buttons
    var saveButton = gosa.ui.base.Buttons.getOkButton();
    saveButton.setAppearance("button-primary");
    this.addButton(saveButton);
    var cancelButton = gosa.ui.base.Buttons.getCancelButton();
    this.addButton(cancelButton);

    // create the view
    this.addElement(new gosa.ui.form.renderer.Single(form));

    var controller = new qx.data.controller.Form(null, form);
    var model = controller.createModel();

    // serialization and reset /////////
    saveButton.addListener("execute", function() {
      if (form.validate()) {
        widget.setBackgroundColor(model.getBackgroundColor()||null);
        properties.forEach(function(prop) {
          var value = selectionValues[prop] || model.get(prop);
          widget.set(prop, value);
        });
        this.fireEvent("modified");
        this.close();
      }
    }, this);
    cancelButton.addListener("execute", function() {
      form.reset();
      this.close();
    }, this);

  },

  /*
  *****************************************************************************
     EVENTS
  *****************************************************************************
  */
  events : {
    "modified": "qx.event.type.Event"
  }

});
<commit_msg>rese background color property when no value given (to prevent it from beeing stored in the backend)<commit_after>/*========================================================================

   This file is part of the GOsa project -  http://gosa-project.org

   Copyright:
      (C) 2010-2017 GONICUS GmbH, Germany, http://www.gonicus.de

   License:
      LGPL-2.1: http://www.gnu.org/licenses/lgpl-2.1.html

   See the LICENSE file in the project's top-level directory for details.

======================================================================== */

/**
 * Dialog for editing dashboard widgets
 */
qx.Class.define("gosa.ui.dialogs.EditDashboardWidget", {
  extend: gosa.ui.dialogs.Dialog,

  construct: function(widget) {
    this.base(arguments, this.tr("Edit dashboard widget"));

    // form
    var form = new qx.ui.form.Form();

    // add the form items
    form.add(new qx.ui.form.TextField(widget.getBackgroundColor()), this.tr("Background color"), null, "backgroundColor");

    var properties = [];
    var selectionValues = {};

    var options = gosa.data.DashboardController.getWidgetOptions(widget);
    if (options.settings) {
      Object.getOwnPropertyNames(options.settings.properties).forEach(function(propertyName) {
        var typeSettings = options.settings.properties[propertyName];
        var type, title = propertyName;
        properties.push(propertyName);
        if (qx.lang.Type.isObject(typeSettings)) {
          type = typeSettings.type;
          if (typeSettings.title) {
            title = typeSettings.title;
            if (title.translate) {
              // trigger the translation
              title = title.translate();
            }
          }
        } else {
          type = typeSettings;
        }
        var formItem;
        switch (type) {
          case "Json":
            formItem = new qx.ui.form.TextArea(qx.lang.Json.stringify(widget.get(propertyName)));
            break;
          case "String":
            formItem = new qx.ui.form.TextArea(widget.get(propertyName));
            break;
          case "Number":
            formItem = new qx.ui.form.Spinner(widget.get(propertyName));
            break;
          case "selection":
            var selectBox = new qx.ui.form.SelectBox();
            if (!options.settings.mandatory || options.settings.mandatory.indexOf(propertyName) === -1) {
              selectBox.add(new qx.ui.form.ListItem("-"));
            }
            var currentValue = widget.get(propertyName);

            if (typeSettings.provider === "RPC" && typeSettings.method) {
              // retrieve data from rpc
              gosa.io.Rpc.getInstance().cA(typeSettings.method).then(function(result) {
                for (var key in result) {
                  if (result.hasOwnProperty(key)) {
                    var item = new qx.ui.form.ListItem(result[key][typeSettings.value]);
                    var keyValue = typeSettings.key === "KEY" ? key : result[key][typeSettings.key];
                    item.setUserData("key", keyValue);
                    if (typeSettings.icon) {
                      item.setIcon(result[key][typeSettings.icon])
                    }
                    selectBox.add(item);
                    if (keyValue === currentValue) {
                      selectBox.setSelection([item]);
                    }
                  }
                }
              }, this);
            }
            selectBox.addListener("changeSelection", function() {
              if (selectBox.getSelection().length) {
                var selectedValue = selectBox.getSelection()[0].getUserData("key");
                if (selectedValue) {
                  selectionValues[propertyName] = selectedValue;
                }
              }
            }, this);
            formItem = selectBox;
            break;
        }
        if (options.settings.mandatory && options.settings.mandatory.indexOf(propertyName) >= 0) {
          formItem.setRequired(true);
        }
        form.add(formItem, title, null, propertyName);
      }, this);
    }

    // buttons
    var saveButton = gosa.ui.base.Buttons.getOkButton();
    saveButton.setAppearance("button-primary");
    this.addButton(saveButton);
    var cancelButton = gosa.ui.base.Buttons.getCancelButton();
    this.addButton(cancelButton);

    // create the view
    this.addElement(new gosa.ui.form.renderer.Single(form));

    var controller = new qx.data.controller.Form(null, form);
    var model = controller.createModel();

    // serialization and reset /////////
    saveButton.addListener("execute", function() {
      if (form.validate()) {
        if (model.getBackgroundColor()) {
          widget.setBackgroundColor(model.getBackgroundColor());
        } else {
          widget.resetBackgroundColor();
        }
        properties.forEach(function(prop) {
          var value = selectionValues[prop] || model.get(prop);
          widget.set(prop, value);
        });
        this.fireEvent("modified");
        this.close();
      }
    }, this);
    cancelButton.addListener("execute", function() {
      form.reset();
      this.close();
    }, this);

  },

  /*
  *****************************************************************************
     EVENTS
  *****************************************************************************
  */
  events : {
    "modified": "qx.event.type.Event"
  }

});
<|endoftext|>


<commit_before>class UserInterface {
  constructor(p_xSizeAndPos){
    this.sizeAndPosition = p_xSizeAndPos;
    this.dialog = UserInterface.DIALOG_NONE;
    this.screen = undefined;
    this.keyHandler = undefined;
    this.activeButton = undefined;
    this.scrollSpeed = UserInterface.SCROLL_SPEED_START;

    this.marginX = 15;
    this.initDefaultDialog();
    this.initKeyboardInput();
    this.initButtons();
    this.initTouchTracking();
  }

  get x(){ return this.sizeAndPosition.x; }
  get y(){ return this.sizeAndPosition.y; }
  get width(){ return this.sizeAndPosition.width; }
  get height(){ return this.sizeAndPosition.height; }

  static get SCREEN_INTRO() { return 0; }
  static get SCREEN_INPUT() { return 1; }

  static get ACTIVE_BUTTON_NONE(){ return 0; }
  static get ACTIVE_BUTTON_SCROLL_UP(){ return 1; }
  static get ACTIVE_BUTTON_SCROLL_DOWN(){ return 2; }

  static get SCROLL_SPEED_START() { return 2; }
  static get SCROLL_SPEED_MAX()  { return 10; }

  static get DIALOG_NONE() { return 0; }
  static get DIALOG_SHARE() { return 1; }

  initKeyboardInput(){
    this.keyboardInput = createInput();
    console.log('created input');
    this.keyboardInput.position(-500,-500);
  }

  initButtons(){
    let layoutPos = createVector();
    layoutPos.x = this.x + this.marginX;
    layoutPos.y = this.y + 5;
    this.shareButton = createButton("Share");
    this.shareButton.position(layoutPos.x, layoutPos.y);
    this.shareButton.mousePressed(this.handleShareButton);
    this.shareButton.hide();

    layoutPos.x += this.shareButton.width + this.marginX;
    this.clearButton = createButton("Clear");
    this.clearButton.position(layoutPos.x, layoutPos.y);
    this.clearButton.mousePressed(this.handleClearButton);
    this.clearButton.hide();

    layoutPos.x += this.clearButton.width + this.marginX;
    this.scrollUpButton = createButton("Up");
    this.scrollUpButton.position(layoutPos.x, layoutPos.y);
    this.scrollUpButton.mousePressed(this.handleScrollUpButton);
    this.scrollUpButton.touchStarted(this.handleScrollUpButton);
    this.scrollUpButton.hide();

    layoutPos.x += this.scrollUpButton.width + this.marginX;
    this.scrollDownButton = createButton("Down");
    this.scrollDownButton.position(layoutPos.x, layoutPos.y);
    this.scrollDownButton.mousePressed(this.handleScrollDownButton);
    this.scrollDownButton.touchStarted(this.handleScrollDownButton);
    this.scrollDownButton.hide();

    layoutPos.x += this.scrollDownButton.width + this.marginX;
    this.toggleFlagsButton = createButton("Toggle Flags");
    this.toggleFlagsButton.position(layoutPos.x, layoutPos.y);
    this.toggleFlagsButton.mousePressed(this.handleToggleFlagsButton);
    this.toggleFlagsButton.touchStarted(this.handleToggleFlagsButton);
    this.toggleFlagsButton.hide();

    this.dialogCloseButton = createButton("Close");
    this.dialogCloseButton.mousePressed(this.handleDialogCloseButton);
    this.dialogCloseButton.hide();
  }

  initTouchTracking(){
    this.activeTouchPos = createVector(0, 0);
    this.activeTouchId = undefined;
  }

  showMainButtons(){
    this.shareButton.show();
    this.clearButton.show();
    this.scrollUpButton.show();
    this.scrollDownButton.show();
    this.toggleFlagsButton.show();
  }

  handleKeyPressed(){
   if (ui.isShowingDialog()){
      if (key == 'Escape') {
        return this.handleEscapeKey();
      }
    } else {
      ui.showMainButtons();
      this.screen = UserInterface.SCREEN_INPUT;
      this.keyHandler.handleKeyPressed();
    }
  }

  handleKeyReleased(){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.keyHandler.handleKeyReleased();
    }
  }

  handleMouseReleased(){
    ui.activeButton = undefined;
    ui.scrollSpeed = UserInterface.SCROLL_SPEED_START;
  }

  handleMouseWheel(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      nfTypeset.shiftOffset(0, event.deltaY * -1);
      nfTypeset.requestFullRedraw();
    }
  }

  handleTouchStarted(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.touchMovedSinceStart = false;

      if (this.activeTouchId == undefined){
        let newActiveTouch = event.changedTouches[0];
        this.activeTouchId = newActiveTouch.identifier;
        this.activeTouchPos.x = newActiveTouch.pageX;
        this.activeTouchPos.y = newActiveTouch.pageY;
      }
    }
  }

  handleTouchMoved(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.touchMovedSinceStart = true;

      let activeTouch = event.changedTouches.item(this.activeTouchId);
      if (activeTouch){
        let newPos = createVector(activeTouch.pageX, activeTouch.pageY);

        // console.log('Scrolled: ');
        // console.log('this.activeTouchId: ' + this.activeTouchId);

        // logMessage('activeTouch: ');
        // logMessage(activeTouch);
        let deltaY = newPos.y - this.activeTouchPos.y;
        // logMessage('deltaY: ' + deltaY);
        if (abs(deltaY) < 50){
          nfTypeset.shiftOffset(0, deltaY);
          // logMessage('nfTypeset.offset.y: ' + nfTypeset.offset.y);
          nfTypeset.requestFullRedraw();
        }

        this.activeTouchPos.x = activeTouch.pageX;
        this.activeTouchPos.y = activeTouch.pageY;
      }
    }
  }

  handleTouchEnded(event){
    if (this.isShowingDialog()){
      // do nothing
    } else {
      if (this.touchMovedSinceStart == false){
        this.screen = UserInterface.SCREEN_INPUT;
        nfTypeset.requestFullRedraw();
        this.keyboardInput.elt.focus();
      }

      if (event.changedTouches) {
        let activeTouch = event.changedTouches.item(this.activeTouchId);
        if (activeTouch){
          this.activeTouchId == undefined;
        }
      }
    }
  }

  handleWindowResized(){
    this.initDefaultDialog();
    if (this.screen == UserInterface.SCREEN_INTRO){
      this.showIntroScreen();
    } else {
      nfTypeset.textSize(0.1 * height);
      nfTypeset.requestFullRedraw();
    }
  }

  handleShareButton(){
    console.log('share button pressed');
    ui.showDialog(UserInterface.DIALOG_SHARE);
  }

  handleScrollUpButton(){
    ui._scroll(10);
    ui.touchMovedSinceStart = true;
    ui.activeButton = UserInterface.ACTIVE_BUTTON_SCROLL_UP;
    return false;
  }

  handleScrollDownButton(){
    ui._scroll(-10);
    ui.touchMovedSinceStart = true;
    ui.activeButton = UserInterface.ACTIVE_BUTTON_SCROLL_DOWN;
    return false;
  }

  handleToggleFlagsButton(){
    nfTypeset.toggleFlags();
    nfTypeset.requestFullRedraw();
  }

  handleClearButton(){
    nfTypeset.clearPrintBuffer();
  }

  handleDialogCloseButton(){
    ui.closeDialog();
  }

  handleEscapeKey(){
    if (this.dialog){
      this.closeDialog();
    }
  }

  isShowingDialog(){
    return this.dialog !== UserInterface.DIALOG_NONE;
  }

  showDialog(dialog){
    this.dialog = dialog;
    this.dialogRender = this.renderDialogUpload;
  }

  closeDialog(){
    this.dialog = UserInterface.DIALOG_NONE;
    this.dialogCloseButton.hide();

    if (this.shareInput !== undefined){
      this.shareInput.remove();
      this.shareInput = undefined;
    }
    this.initialRender();
    nfTypeset.requestFullRedraw();
  }

  renderCurrentDialog(){
    switch (this.dialog) {
      case UserInterface.DIALOG_SHARE: return this.renderShareDialog();
    }
  }

  initDefaultDialog(){
    const dialogWidth = 0.6 * width;
    const dialogHeight = 0.3 * height;
    this.dialogRect = new Rect((width - dialogWidth) / 2,
                               height / 2 - dialogHeight / 2,
                               dialogWidth, dialogHeight);
  }

  renderShareDialog(){
    push();
    fill(255);
    let dialogRect
    P5JsUtils.drawRect(this.dialogRect);

    fill(0);
    textSize(20);
    textAlign(LEFT);
    text('Copy the URL', this.dialogRect.x + this.marginX, this.dialogRect.y + this.marginX,
                         this.dialogRect.width, 25);

    if (this.shareInput === undefined){
      let url = this.buildShareURL();
      this.shareInput = createInput('');
      this.shareInput.value(url);
    }
    this.shareInput.position(this.dialogRect.x + this.marginX - 3, this.dialogRect.y + 3 * this.marginX);
    this.shareWidth = this.dialogRect.width - 2 * this.marginX - 3;
    this.shareInput.size(this.shareWidth);

    this.dialogCloseButton.position(this.dialogRect.maxX - this.dialogCloseButton.width - this.marginX,
                                    this.dialogRect.maxY - 40);
    this.dialogCloseButton.show();
    pop();
  }

  buildShareURL(){
    let blocks64 = nfTypeset.getPrintBlocksInBase64();
    let fullUrl = window.location.href;
    let baseUrl = fullUrl.split("?")[0];
    let currentParams = getURLParams();
    let paramNames = Object.keys(currentParams);

    let otherParams = paramNames.filter(p => {return p != 'blocks';})
                                .map(p => `${p}=${currentParams[p]}`)
                                .join('&');
    otherParams = (otherParams) ? '&' + otherParams : '';

    return  baseUrl + "?blocks=" + blocks64 + otherParams;
  }

  initialRender(){}

  showIntroScreen(){
    this.screen = UserInterface.SCREEN_INTRO;

    background(50);
    fill(230);
    textFont('Verdana');
    textAlign(CENTER, TOP);
    const marginX = (width > 667) ? 0.2 * width : 0.05 * width;
    const lineHeight = 40;
    let yPos =  0.15 * height;
    let flagSize = 0.8 * width / (7 * 1.1);

    nfTypeset.push();
    nfTypeset.textSize(flagSize);
    nfTypeset.text('WELCOME', 0.1 * width, yPos, 0.8 * width);
    nfTypeset.pop();

    textSize(32);
    yPos += 1.5 * flagSize;
    text('Welcome', marginX, yPos, width - 2 * marginX, lineHeight);

    const instr1 = 'Type to see the corresponding nautical flags.';
    const instr2 = 'Press SHIFT + P to download an image of what you\'ve typed.';
    const instr3 = 'Click the SHARE button to get a shareable link to send a message to friend.';

    let lineSpacer = (width > 667) ? "\n\n" : "\n\n";
    let instructions;
    if (width > 667) {
      instructions = instr1 + lineSpacer + instr2 + lineSpacer + instr3;
    } else {
      instructions = instr1 + lineSpacer + instr3;
    }
    textSize(20);
    yPos += (width > 667) ? lineHeight * 2 : lineHeight;
    const mainBlockHeight = height - yPos;
    text(instructions, marginX, yPos, width - 2 * marginX, mainBlockHeight);
  }

  _scroll(deltaY){
    nfTypeset.shiftOffset(0, deltaY * -1);
    nfTypeset.requestFullRedraw();
  }

  _accelerateScroll(){
    // this.scrollSpeed = 1.05 * this.scrollSpeed;
    this.scrollSpeed = constrain(1.1 * this.scrollSpeed,
                          -1 * UserInterface.SCROLL_SPEED_MAX,
                          UserInterface.SCROLL_SPEED_MAX);
  }

  tick(){
    this.tickForActiveButon();
  }

  tickForActiveButon(){
    switch (this.activeButton) {
      case UserInterface.ACTIVE_BUTTON_SCROLL_UP:
        this._accelerateScroll();
        return this._scroll(-1 * this.scrollSpeed);
      case UserInterface.ACTIVE_BUTTON_SCROLL_DOWN:
        this._accelerateScroll();
        return this._scroll(this.scrollSpeed);
    }
  }

  render(){
    this.renderCurrentDialog();
  }
}
<commit_msg>p5js/nautical-flags-02 - Get holding down scroll buttons to work<commit_after>class UserInterface {
  constructor(p_xSizeAndPos){
    this.sizeAndPosition = p_xSizeAndPos;
    this.dialog = UserInterface.DIALOG_NONE;
    this.screen = undefined;
    this.keyHandler = undefined;
    this.activeButton = undefined;
    this.scrollSpeed = UserInterface.SCROLL_SPEED_START;

    this.marginX = 15;
    this.initDefaultDialog();
    this.initKeyboardInput();
    this.initButtons();
    this.initTouchTracking();
  }

  get x(){ return this.sizeAndPosition.x; }
  get y(){ return this.sizeAndPosition.y; }
  get width(){ return this.sizeAndPosition.width; }
  get height(){ return this.sizeAndPosition.height; }

  static get SCREEN_INTRO() { return 0; }
  static get SCREEN_INPUT() { return 1; }

  static get ACTIVE_BUTTON_NONE(){ return 0; }
  static get ACTIVE_BUTTON_SCROLL_UP(){ return 1; }
  static get ACTIVE_BUTTON_SCROLL_DOWN(){ return 2; }

  static get SCROLL_SPEED_START() { return 2; }
  static get SCROLL_SPEED_MAX()  { return 10; }

  static get DIALOG_NONE() { return 0; }
  static get DIALOG_SHARE() { return 1; }

  initKeyboardInput(){
    this.keyboardInput = createInput();
    console.log('created input');
    this.keyboardInput.position(-500,-500);
  }

  initButtons(){
    let layoutPos = createVector();
    layoutPos.x = this.x + this.marginX;
    layoutPos.y = this.y + 5;
    this.shareButton = createButton("Share");
    this.shareButton.position(layoutPos.x, layoutPos.y);
    this.shareButton.mousePressed(this.handleShareButton);
    this.shareButton.hide();

    layoutPos.x += this.shareButton.width + this.marginX;
    this.clearButton = createButton("Clear");
    this.clearButton.position(layoutPos.x, layoutPos.y);
    this.clearButton.mousePressed(this.handleClearButton);
    this.clearButton.hide();

    layoutPos.x += this.clearButton.width + this.marginX;
    this.scrollUpButton = createButton("Up");
    this.scrollUpButton.position(layoutPos.x, layoutPos.y);
    this.scrollUpButton.mousePressed(this.handleScrollUpButton);
    this.scrollUpButton.touchStarted(this.handleScrollUpButton);
    this.scrollUpButton.touchEnded(this.handleScrollEnded);
    this.scrollUpButton.hide();

    layoutPos.x += this.scrollUpButton.width + this.marginX;
    this.scrollDownButton = createButton("Down");
    this.scrollDownButton.position(layoutPos.x, layoutPos.y);
    this.scrollDownButton.mousePressed(this.handleScrollDownButton);
    this.scrollDownButton.touchStarted(this.handleScrollDownButton);
    this.scrollDownButton.touchEnded(this.handleScrollEnded);
    this.scrollDownButton.hide();

    layoutPos.x += this.scrollDownButton.width + this.marginX;
    this.toggleFlagsButton = createButton("Toggle Flags");
    this.toggleFlagsButton.position(layoutPos.x, layoutPos.y);
    this.toggleFlagsButton.mousePressed(this.handleToggleFlagsButton);
    this.toggleFlagsButton.hide();

    this.dialogCloseButton = createButton("Close");
    this.dialogCloseButton.mousePressed(this.handleDialogCloseButton);
    this.dialogCloseButton.hide();
  }

  initTouchTracking(){
    this.activeTouchPos = createVector(0, 0);
    this.activeTouchId = undefined;
  }

  showMainButtons(){
    this.shareButton.show();
    this.clearButton.show();
    this.scrollUpButton.show();
    this.scrollDownButton.show();
    this.toggleFlagsButton.show();
  }

  handleKeyPressed(){
   if (ui.isShowingDialog()){
      if (key == 'Escape') {
        return this.handleEscapeKey();
      }
    } else {
      ui.showMainButtons();
      this.screen = UserInterface.SCREEN_INPUT;
      this.keyHandler.handleKeyPressed();
    }
  }

  handleKeyReleased(){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.keyHandler.handleKeyReleased();
    }
  }

  handleMouseReleased(){
    ui.activeButton = undefined;
    ui.scrollSpeed = UserInterface.SCROLL_SPEED_START;
  }

  handleMouseWheel(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      nfTypeset.shiftOffset(0, event.deltaY * -1);
      nfTypeset.requestFullRedraw();
    }
  }

  handleTouchStarted(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.touchMovedSinceStart = false;

      if (this.activeTouchId == undefined){
        let newActiveTouch = event.changedTouches[0];
        this.activeTouchId = newActiveTouch.identifier;
        this.activeTouchPos.x = newActiveTouch.pageX;
        this.activeTouchPos.y = newActiveTouch.pageY;
      }
    }
  }

  handleTouchMoved(event){
    if (this.isShowingDialog()){
      // Do nothing
    } else {
      this.touchMovedSinceStart = true;

      let activeTouch = event.changedTouches.item(this.activeTouchId);
      if (activeTouch){
        let newPos = createVector(activeTouch.pageX, activeTouch.pageY);

        // console.log('Scrolled: ');
        // console.log('this.activeTouchId: ' + this.activeTouchId);

        // logMessage('activeTouch: ');
        // logMessage(activeTouch);
        let deltaY = newPos.y - this.activeTouchPos.y;
        // logMessage('deltaY: ' + deltaY);
        if (abs(deltaY) < 50){
          nfTypeset.shiftOffset(0, deltaY);
          // logMessage('nfTypeset.offset.y: ' + nfTypeset.offset.y);
          nfTypeset.requestFullRedraw();
        }

        this.activeTouchPos.x = activeTouch.pageX;
        this.activeTouchPos.y = activeTouch.pageY;
      }
    }
  }

  handleTouchEnded(event){
    if (this.isShowingDialog()){
      // do nothing
    } else {
      if (this.touchMovedSinceStart == false){
        this.screen = UserInterface.SCREEN_INPUT;
        nfTypeset.requestFullRedraw();
        this.keyboardInput.elt.focus();
      }

      if (event.changedTouches) {
        let activeTouch = event.changedTouches.item(this.activeTouchId);
        if (activeTouch){
          this.activeTouchId == undefined;
        }
      }
    }
  }

  handleWindowResized(){
    this.initDefaultDialog();
    if (this.screen == UserInterface.SCREEN_INTRO){
      this.showIntroScreen();
    } else {
      nfTypeset.textSize(0.1 * height);
      nfTypeset.requestFullRedraw();
    }
  }

  handleShareButton(){
    console.log('share button pressed');
    ui.showDialog(UserInterface.DIALOG_SHARE);
  }

  handleScrollUpButton(){
    ui._scroll(10);
    ui.touchMovedSinceStart = true;
    ui.activeButton = UserInterface.ACTIVE_BUTTON_SCROLL_UP;
    return false;
  }

  handleScrollDownButton(){
    ui._scroll(-10);
    ui.touchMovedSinceStart = true;
    ui.activeButton = UserInterface.ACTIVE_BUTTON_SCROLL_DOWN;
    return false;
  }

  handleScrollEnded(){
    ui.activeButton = UserInterface.ACTIVE_BUTTON_NONE;
    return false;
  }

  handleToggleFlagsButton(){
    nfTypeset.toggleFlags();
    nfTypeset.requestFullRedraw();
  }

  handleClearButton(){
    nfTypeset.clearPrintBuffer();
  }

  handleDialogCloseButton(){
    ui.closeDialog();
  }

  handleEscapeKey(){
    if (this.dialog){
      this.closeDialog();
    }
  }

  isShowingDialog(){
    return this.dialog !== UserInterface.DIALOG_NONE;
  }

  showDialog(dialog){
    this.dialog = dialog;
    this.dialogRender = this.renderDialogUpload;
  }

  closeDialog(){
    this.dialog = UserInterface.DIALOG_NONE;
    this.dialogCloseButton.hide();

    if (this.shareInput !== undefined){
      this.shareInput.remove();
      this.shareInput = undefined;
    }
    this.initialRender();
    nfTypeset.requestFullRedraw();
  }

  renderCurrentDialog(){
    switch (this.dialog) {
      case UserInterface.DIALOG_SHARE: return this.renderShareDialog();
    }
  }

  initDefaultDialog(){
    const dialogWidth = 0.6 * width;
    const dialogHeight = 0.3 * height;
    this.dialogRect = new Rect((width - dialogWidth) / 2,
                               height / 2 - dialogHeight / 2,
                               dialogWidth, dialogHeight);
  }

  renderShareDialog(){
    push();
    fill(255);
    let dialogRect
    P5JsUtils.drawRect(this.dialogRect);

    fill(0);
    textSize(20);
    textAlign(LEFT);
    text('Copy the URL', this.dialogRect.x + this.marginX, this.dialogRect.y + this.marginX,
                         this.dialogRect.width, 25);

    if (this.shareInput === undefined){
      let url = this.buildShareURL();
      this.shareInput = createInput('');
      this.shareInput.value(url);
    }
    this.shareInput.position(this.dialogRect.x + this.marginX - 3, this.dialogRect.y + 3 * this.marginX);
    this.shareWidth = this.dialogRect.width - 2 * this.marginX - 3;
    this.shareInput.size(this.shareWidth);

    this.dialogCloseButton.position(this.dialogRect.maxX - this.dialogCloseButton.width - this.marginX,
                                    this.dialogRect.maxY - 40);
    this.dialogCloseButton.show();
    pop();
  }

  buildShareURL(){
    let blocks64 = nfTypeset.getPrintBlocksInBase64();
    let fullUrl = window.location.href;
    let baseUrl = fullUrl.split("?")[0];
    let currentParams = getURLParams();
    let paramNames = Object.keys(currentParams);

    let otherParams = paramNames.filter(p => {return p != 'blocks';})
                                .map(p => `${p}=${currentParams[p]}`)
                                .join('&');
    otherParams = (otherParams) ? '&' + otherParams : '';

    return  baseUrl + "?blocks=" + blocks64 + otherParams;
  }

  initialRender(){}

  showIntroScreen(){
    this.screen = UserInterface.SCREEN_INTRO;

    background(50);
    fill(230);
    textFont('Verdana');
    textAlign(CENTER, TOP);
    const marginX = (width > 667) ? 0.2 * width : 0.05 * width;
    const lineHeight = 40;
    let yPos =  0.15 * height;
    let flagSize = 0.8 * width / (7 * 1.1);

    nfTypeset.push();
    nfTypeset.textSize(flagSize);
    nfTypeset.text('WELCOME', 0.1 * width, yPos, 0.8 * width);
    nfTypeset.pop();

    textSize(32);
    yPos += 1.5 * flagSize;
    text('Welcome', marginX, yPos, width - 2 * marginX, lineHeight);

    const instr1 = 'Type to see the corresponding nautical flags.';
    const instr2 = 'Press SHIFT + P to download an image of what you\'ve typed.';
    const instr3 = 'Click the SHARE button to get a shareable link to send a message to friend.';

    let lineSpacer = (width > 667) ? "\n\n" : "\n\n";
    let instructions;
    if (width > 667) {
      instructions = instr1 + lineSpacer + instr2 + lineSpacer + instr3;
    } else {
      instructions = instr1 + lineSpacer + instr3;
    }
    textSize(20);
    yPos += (width > 667) ? lineHeight * 2 : lineHeight;
    const mainBlockHeight = height - yPos;
    text(instructions, marginX, yPos, width - 2 * marginX, mainBlockHeight);
  }

  _scroll(deltaY){
    nfTypeset.shiftOffset(0, deltaY * -1);
    nfTypeset.requestFullRedraw();
  }

  _accelerateScroll(){
    // this.scrollSpeed = 1.05 * this.scrollSpeed;
    this.scrollSpeed = constrain(1.1 * this.scrollSpeed,
                          -1 * UserInterface.SCROLL_SPEED_MAX,
                          UserInterface.SCROLL_SPEED_MAX);
  }

  tick(){
    this.tickForActiveButon();
  }

  tickForActiveButon(){
    switch (this.activeButton) {
      case UserInterface.ACTIVE_BUTTON_SCROLL_UP:
        this._accelerateScroll();
        return this._scroll(-1 * this.scrollSpeed);
      case UserInterface.ACTIVE_BUTTON_SCROLL_DOWN:
        this._accelerateScroll();
        return this._scroll(this.scrollSpeed);
    }
  }

  render(){
    this.renderCurrentDialog();
  }
}
<|endoftext|>