<commit_before>/**
 * @name ChannelExploreController
 * @desc Controller for the channel-explore view
 */

(function() {
    'use strict';

    angular.module('cometApp')
           .controller('ChannelExploreController', ChannelExploreController);

        ChannelExploreController.$inject = ['$log',
                                           '$rootScope',
                                           '$scope',
                                           '$state',
                                           '$modal',
                                           '$location',
                                           '$anchorScroll',
                                           'lodash',
                                           'moment',
                                           'ngToast',
                                           'constraints',
                                           'dialogService',
                                           'dashboardServiceModel',
                                           'chatService',
                                           'channelService',
                                           'user',
                                           'project',
                                           'channel',
                                           'isDirect'];

        function ChannelExploreController ($log,
                                          $rootScope,
                                          $scope,
                                          $state,
                                          $modal,
                                          $location,
                                          $anchorScroll,
                                          lodash,
                                          moment,
                                          ngToast,
                                          constraints,
                                          dialogService,
                                          dashboardServiceModel,
                                          chatService,
                                          channelService,
                                          user,
                                          project,
                                          channel,
                                          isDirect) {

          var vm = this;
          vm.project = project;
          vm.channel = channel;
          vm.isClosed = false;
          vm.isDirect = isDirect;
          vm.validationErrors = null;
          vm.isMember = false;
          vm.message = null;
          vm.messages = [];
          // messages
          vm.lastMessage = null;
          vm.getMember = getMember;
          vm.formatMessageDate = formatMessageDate;
          vm.sendMessage = sendMessage;
          // update info
          vm.edit = edit;
          // invite / delete members
          vm.showMembers = false;
          vm.invite = invite;
          vm.canInvite = canInvite;
          vm.deleteMember = deleteMember;
          // exit from the channel
          vm.exit = exit;
          //close channel
          vm.imSure = false;
          vm.closeChannel = closeChannel;
          //delete channel
          vm.imSureDelete = false;
          vm.deleteChannel = deleteChannel;

          // current message Id counter
          var lastMsgId = 0;

          activate();

          /**
           * @name activate
           * @desc controller activation logic
          */
          function activate () {

            setFlags();

            // load channel messages
            channelService.getMessages(vm.project.id, vm.channel.id, 0, 0, vm.isDirect).then(function (response) {
              response.data.messages.forEach(function(entry) {
                  processMessageReceived(entry);
                  scrollToLast();
              });
            });

            // listen to channel updates
            $scope.$on('channelUpdated', function(event, args) {
              if (vm.isDirect) {
                return;
              }
              vm.channel = args.channel;
              setFlags();
            });

            // initialize chat session
            chatService.emit('join-room', {
              room: getRoomId()
            });

            // listen to new messages
            chatService.on('message', function (data) {
              processMessageReceived(data);
              scrollToLast();
            });
          }

          /**
           * @name loadFlags
           * @desc sets the flags that enables/disables actions in the view
          */
          function setFlags() {

            if (vm.isDirect) {
              vm.isMember = true;
              vm.isClosed = false;
              return;
            }

            if (lodash.find(vm.channel.members, 'id', user.id) !== undefined) {
              vm.isMember = true;
            }

            vm.isClosed = (vm.channel.state === 'C');
          }

          /**
           * @name processMessageReceived
           * @desc process a message received on the channel
          */
          function processMessageReceived (data) {

            // data validation
            if (!data || !data.message) {
              $log.log('Mensaje recibido: invalido');
              return ;
            }

            var msgPayload = data.message;

            // convert server date to local date
            msgPayload.date = convertUTCDateToLocalDate(new Date(msgPayload.date));

            // add message to message list
            addMessageToList(msgPayload);

            lastMsgId = msgPayload.id;
          }

          /**
           * @name convertUTCDateToLocalDate
           * @desc converts a UTC date to local datetime
           *       http://stackoverflow.com/questions/6525538/convert-utc-date-time-to-local-date-time-using-javascript
          */
          function convertUTCDateToLocalDate(date) {

            var newDate = new Date(date.getTime() +
                          date.getTimezoneOffset() * 60 * 1000);

            var offset = date.getTimezoneOffset() / 60;
            var hours = date.getHours();

            newDate.setHours(hours - offset);

            return newDate;
          }

          /**
           * @name sendMessage
           * @desc send message to the channel
          */
          function sendMessage() {

            lastMsgId++;

            // construct the message payload
            var msgPayload = {
              id: lastMsgId,
              text: vm.message,
              user: user.id,
              destinationUser: (isDirect ? vm.channel.id : 0),
              date: new Date().getTime()  // for local use only, the server overwrites the date
            };

            // send the data to the server
            chatService.emit('message', {
              room: getRoomId(),
              message: {
                message: msgPayload
              }
            });

            // add the message to the view
            addMessageToList(msgPayload);
            vm.message = '';

            scrollToLast();
          }

          /**
           * @name scrollToLast
           * @desc scroll the window to the last message
          */
          function scrollToLast() {
            $location.hash('msg_' + lastMsgId);
            $anchorScroll();
          }

          /**
           * @name addMessageToList
           * @desc adds the message to the list so it can be viewed on the page
          */
          function addMessageToList(msg) {
            vm.messages.push(msg);
            vm.lastMessage = msg.date;
          }

          /**
           * @name getMember
           * @desc returns a member object by id
          */
          function getMember(memberId) {
            $log.log(vm.channel.members);
            return lodash.find(vm.channel.members, 'id', memberId);
          }

          /**
           * @name formatMessageDate
           * @desc returns the message timestamp in a readable format
          */
          function formatMessageDate (msgDate) {
            return moment(msgDate).calendar();
          }

          /**
           * @name getRoomId
           * @desc returns the room id used to broadcast the message
          */
          function getRoomId() {
            if (isDirect) {
              // the direct channel room is put together using
              // the users id's in ascending order
              var userIdFrom = user.id,
                  userIdTo = vm.channel.id;

              if (userIdFrom > userIdTo) {
                userIdTo = userIdFrom;
                userIdFrom = vm.channel.id;
              }

              return 'Direct_' + userIdFrom + '_' + userIdTo;
            }
            else {
              return vm.channel.id;
            }
          }

          /**
           * @name canInvite
           * @desc returns if the user can add members to the channel
          */
          function canInvite () {
            if (vm.isClosed) {
              return false;
            }
            return (vm.channel.members.length < vm.project.members.length);
          }

          /**
           * @name invite
           * @desc opens the 'add channel member' dialog
          */
          function invite () {
            if (!vm.isMember) {
              showAddCurrentMemberDialog();
            }
            else {
              if (vm.canInvite) {
                showAddMembersDialog();
              }
            }
          }

          /**
           * @name showAddCurrentMemberDialog
           * @desc shows the dialog to add the current logged in user to the
           *       the channel
          */
          function showAddCurrentMemberDialog () {
            var msg = '¿Desea agregarse como participante en este canal?';
            var dlg = dialogService.showModalConfirm('Agregar canal', msg);
            dlg.result.then(function () {
              var invites = {
                members: [
                    {
                      id: user.id
                    }
                  ]
              };

              channelService.invite(vm.project.id, vm.channel.id, invites)
                .error(channelInviteError)
                .then(function (response) {
                  console.log('add current', response.data);
                  $rootScope.$broadcast('channelUpdated', { channel: response.data });
                  $rootScope.$broadcast('channelsUpdated');
                  ngToast.success('Canal agregado.');
                });
            });
          }

          /**
           * @name channelInviteError
           * @desc shows the error message to the user
          */
          function channelInviteError (data) {
              vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
              if (vm.validationErrors === null)
              {
                ngToast.danger('Ocurrió un error al consultar al servidor.');
              }
          }

          /**
           * @name showAddMembersDialog
           * @desc shows the dialog to add members to the channel
          */
          function showAddMembersDialog () {
            var modalInstance = $modal.open({
              templateUrl: '/src/channels/channel-invite.html',
              controller: 'ChannelInviteController',
              controllerAs: 'vm',
              size: 'md',
              backdrop: 'static',
              resolve: {
                project: function () {
                  return vm.project;
                },
                user: function () {
                  return user;
                },
                channel: function () {
                  return vm.channel;
                }
             }
           });
           modalInstance.result.then(function (response) {
             $rootScope.$broadcast('channelUpdated', response.data);
           });
          }

          /**
           * @name edit
           * @desc channel update logic
          */
          function edit () {
            var modalInstance = $modal.open({
              templateUrl: '/src/channels/channel-edit.html',
              controller: 'ChannelEditController',
              controllerAs: 'vm',
              size: 'md',
              backdrop: 'static',
              resolve: {
                project: function () {
                  return vm.project;
                },
                channel: function () {
                  return vm.channel;
                }
             }
           });
           modalInstance.result.then(function (response) {
             $rootScope.$broadcast('channelUpdated', response.data);
           });
          }

          /**
           * @name exit
           * @desc opens the 'exit channel' dialog
          */
          function exit () {
            var msg = '¿Desea salir del canal?';
            var dlg = dialogService.showModalConfirm('Salir de canal', msg);
            dlg.result.then(function () {
              channelService
                .deleteMember(vm.project.id, vm.channel.id, user.id)
                .then(function (response) {
                  ngToast.success('Has salido del canal.');
                  $rootScope.$broadcast('channelUpdated', response.data);
                  $rootScope.$broadcast('channelsUpdated');
                  $state.go('dashboard.project.project-explore', { id: vm.project.id });
                });
              });
          }

          /**
           * @name deleteMember
           * @desc deletes selected members from channel
          */
          function deleteMember (member) {
            var msg = '¿Esta seguro que desea eliminar el participante?';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              channelService.deleteMember(vm.project.id, vm.channel.id, member.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null) {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              });
            }).then(function() {
                var index = vm.project.members.indexOf(member);
                vm.project.members.splice(index, 1);
                ngToast.success('El participante ha sido eliminado.');
            });
          }

          /**
           * @name closeChannel
           * @desc calls the endpoint to close the channel
          */
          function closeChannel() {
            $log.log('close', vm.channel.id);
            var msg = '¿Esta seguro que desea cerrar el canal?';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              channelService.close(vm.project.id, vm.channel.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null)
                {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              }).then(function() {
                ngToast.success('Canal cerrado.');
                $state.go('dashboard.project.project-explore', { id: vm.project.id });
              });
            });
          }

          /**
           * @name deleteChannel
           * @desc calls the endpoint to delete the channel
          */
          function deleteChannel() {
            var msg = '¿Esta seguro que desea eliminar el canal? Esta operación no puede revertirse.';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              $log.log('deleteChannel', vm.channel.id);
              channelService.deleteChannel(vm.project.id, vm.channel.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null)
                {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              }).then(function() {
                  ngToast.success('Canal eliminado.');
                  $state.go('dashboard.project.project-explore', { id: vm.project.id });
              });
            });
          }
      }
})();
<commit_msg>Explorar canal - Mejoras varias<commit_after>/**
 * @name ChannelExploreController
 * @desc Controller for the channel-explore view
 */

(function() {
    'use strict';

    angular.module('cometApp')
           .controller('ChannelExploreController', ChannelExploreController);

        ChannelExploreController.$inject = ['$log',
                                           '$rootScope',
                                           '$scope',
                                           '$state',
                                           '$modal',
                                           '$location',
                                           '$anchorScroll',
                                           'lodash',
                                           'moment',
                                           'ngToast',
                                           'constraints',
                                           'dialogService',
                                           'dashboardServiceModel',
                                           'chatService',
                                           'channelService',
                                           'user',
                                           'project',
                                           'channel',
                                           'isDirect'];

        function ChannelExploreController ($log,
                                          $rootScope,
                                          $scope,
                                          $state,
                                          $modal,
                                          $location,
                                          $anchorScroll,
                                          lodash,
                                          moment,
                                          ngToast,
                                          constraints,
                                          dialogService,
                                          dashboardServiceModel,
                                          chatService,
                                          channelService,
                                          user,
                                          project,
                                          channel,
                                          isDirect) {

          var vm = this;
          vm.project = project;
          vm.channel = channel;
          vm.isClosed = false;
          vm.isDirect = isDirect;
          vm.validationErrors = null;
          vm.isMember = false;
          vm.message = null;
          vm.messages = [];
          // messages
          vm.lastMessage = null;
          vm.getMember = getMember;
          vm.formatMessageDate = formatMessageDate;
          vm.sendMessage = sendMessage;
          // update info
          vm.edit = edit;
          // invite / delete members
          vm.showMembers = false;
          vm.invite = invite;
          vm.canInvite = canInvite;
          vm.deleteMember = deleteMember;
          // exit from the channel
          vm.exit = exit;
          //close channel
          vm.imSure = false;
          vm.closeChannel = closeChannel;
          //delete channel
          vm.imSureDelete = false;
          vm.deleteChannel = deleteChannel;

          // current message Id counter
          var lastMsgId = 0;

          activate();

          /**
           * @name activate
           * @desc controller activation logic
          */
          function activate () {

            setFlags();

            // load channel messages
            channelService.getMessages(vm.project.id, vm.channel.id, 0, 0, vm.isDirect).then(function (response) {
              response.data.messages.forEach(function(entry) {
                  processMessageReceived(entry);
              });
              scrollToLast();
            });

            // listen to channel updates
            $scope.$on('channelUpdated', function(event, args) {
              if (vm.isDirect) {
                return;
              }

              vm.channel = args.channel;
              setFlags();
            });

            // initialize chat session
            chatService.emit('join-room', {
              room: getRoomId()
            });

            // listen to new messages
            chatService.on('message', function (data) {
              processMessageReceived(data);
              scrollToLast();
            });
          }

          /**
           * @name loadFlags
           * @desc sets the flags that enables/disables actions in the view
          */
          function setFlags() {

            if (vm.isDirect) {
              vm.isMember = true;
              vm.isClosed = false;
              return;
            }

            if (lodash.find(vm.channel.members, 'id', user.id) !== undefined) {
              vm.isMember = true;
            }

            vm.isClosed = (vm.channel.state === 'C');
          }

          /**
           * @name processMessageReceived
           * @desc process a message received on the channel
          */
          function processMessageReceived (data) {

            // data validation
            if (!data || !data.message) {
              $log.log('Mensaje recibido: invalido');
              return ;
            }

            var msgPayload = data.message;

            // convert server date to local date
            msgPayload.date = convertUTCDateToLocalDate(new Date(msgPayload.date));

            // add message to message list
            addMessageToList(msgPayload);

            lastMsgId = msgPayload.id;
          }

          /**
           * @name convertUTCDateToLocalDate
           * @desc converts a UTC date to local datetime
           *       http://stackoverflow.com/questions/6525538/convert-utc-date-time-to-local-date-time-using-javascript
          */
          function convertUTCDateToLocalDate(date) {

            var newDate = new Date(date.getTime() +
                          date.getTimezoneOffset() * 60 * 1000);

            var offset = date.getTimezoneOffset() / 60;
            var hours = date.getHours();

            newDate.setHours(hours - offset);

            return newDate;
          }

          /**
           * @name sendMessage
           * @desc send message to the channel
          */
          function sendMessage() {

            lastMsgId++;

            // construct the message payload
            var msgPayload = {
              id: lastMsgId,
              text: vm.message,
              user: user.id,
              destinationUser: (isDirect ? vm.channel.id : 0),
              date: new Date().getTime()  // for local use only, the server overwrites the date
            };

            // send the data to the server
            chatService.emit('message', {
              room: getRoomId(),
              message: {
                message: msgPayload
              }
            });

            // add the message to the view
            addMessageToList(msgPayload);
            vm.message = '';

            scrollToLast();
          }

          /**
           * @name scrollToLast
           * @desc scroll the window to the last message
          */
          function scrollToLast() {
            $location.hash('msg_' + lastMsgId);
            $anchorScroll();
          }

          /**
           * @name addMessageToList
           * @desc adds the message to the list so it can be viewed on the page
          */
          function addMessageToList(msg) {
            vm.messages.push(msg);
            vm.lastMessage = msg.date;
          }

          /**
           * @name getMember
           * @desc returns a member object by id
          */
          function getMember(memberId) {
            return lodash.find(vm.project.members, 'id', memberId);
          }

          /**
           * @name formatMessageDate
           * @desc returns the message timestamp in a readable format
          */
          function formatMessageDate (msgDate) {
            return moment(msgDate).calendar();
          }

          /**
           * @name getRoomId
           * @desc returns the room id used to broadcast the message
          */
          function getRoomId() {
            if (isDirect) {
              // the direct channel room is put together using
              // the users id's in ascending order
              var userIdFrom = user.id,
                  userIdTo = vm.channel.id;

              if (userIdFrom > userIdTo) {
                userIdTo = userIdFrom;
                userIdFrom = vm.channel.id;
              }

              return 'Direct_' + userIdFrom + '_' + userIdTo;
            }
            else {
              return vm.channel.id;
            }
          }

          /**
           * @name canInvite
           * @desc returns if the user can add members to the channel
          */
          function canInvite () {
            if (vm.isClosed) {
              return false;
            }
            return (vm.channel.members.length < vm.project.members.length);
          }

          /**
           * @name invite
           * @desc opens the 'add channel member' dialog
          */
          function invite () {
            if (!vm.isMember) {
              showAddCurrentMemberDialog();
            }
            else {
              if (vm.canInvite) {
                showAddMembersDialog();
              }
            }
          }

          /**
           * @name showAddCurrentMemberDialog
           * @desc shows the dialog to add the current logged in user to the
           *       the channel
          */
          function showAddCurrentMemberDialog () {
            var msg = '¿Desea agregarse como participante en este canal?';
            var dlg = dialogService.showModalConfirm('Agregar canal', msg);
            dlg.result.then(function () {
              var invites = {
                members: [
                    {
                      id: user.id
                    }
                  ]
              };

              channelService.invite(vm.project.id, vm.channel.id, invites)
                .error(channelInviteError)
                .then(function (response) {
                  console.log('add current', response.data);
                  $rootScope.$broadcast('channelUpdated', { channel: response.data });
                  $rootScope.$broadcast('channelsUpdated');
                  ngToast.success('Canal agregado.');
                });
            });
          }

          /**
           * @name channelInviteError
           * @desc shows the error message to the user
          */
          function channelInviteError (data) {
              vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
              if (vm.validationErrors === null)
              {
                ngToast.danger('Ocurrió un error al consultar al servidor.');
              }
          }

          /**
           * @name showAddMembersDialog
           * @desc shows the dialog to add members to the channel
          */
          function showAddMembersDialog () {
            var modalInstance = $modal.open({
              templateUrl: '/src/channels/channel-invite.html',
              controller: 'ChannelInviteController',
              controllerAs: 'vm',
              size: 'md',
              backdrop: 'static',
              resolve: {
                project: function () {
                  return vm.project;
                },
                user: function () {
                  return user;
                },
                channel: function () {
                  return vm.channel;
                }
             }
           });
           modalInstance.result.then(function (updatedChannel) {
             $rootScope.$broadcast('channelUpdated', { channel: updatedChannel });
           });
          }

          /**
           * @name edit
           * @desc channel update logic
          */
          function edit () {
            var modalInstance = $modal.open({
              templateUrl: '/src/channels/channel-edit.html',
              controller: 'ChannelEditController',
              controllerAs: 'vm',
              size: 'md',
              backdrop: 'static',
              resolve: {
                project: function () {
                  return vm.project;
                },
                channel: function () {
                  return vm.channel;
                }
             }
           });
           modalInstance.result.then(function (response) {
             $rootScope.$broadcast('channelUpdated', { channel: response.data });
           });
          }

          /**
           * @name exit
           * @desc opens the 'exit channel' dialog
          */
          function exit () {
            var msg = '¿Desea salir del canal?';
            var dlg = dialogService.showModalConfirm('Salir de canal', msg);
            dlg.result.then(function () {
              channelService
                .deleteMember(vm.project.id, vm.channel.id, user.id)
                .then(function () {
                  ngToast.success('Has salido del canal.');
                  $rootScope.$broadcast('channelsUpdated');
                  $state.go('dashboard.project.project-explore', { id: vm.project.id });
                });
              });
          }

          /**
           * @name deleteMember
           * @desc deletes selected members from channel
          */
          function deleteMember (member) {
            var msg = '¿Esta seguro que desea eliminar el participante?';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              channelService.deleteMember(vm.project.id, vm.channel.id, member.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null) {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              });
            }).then(function() {
                var index = vm.project.members.indexOf(member);
                vm.project.members.splice(index, 1);
                ngToast.success('El participante ha sido eliminado.');
            });
          }

          /**
           * @name closeChannel
           * @desc calls the endpoint to close the channel
          */
          function closeChannel() {
            $log.log('close', vm.channel.id);
            var msg = '¿Esta seguro que desea cerrar el canal?';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              channelService.close(vm.project.id, vm.channel.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null)
                {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              }).then(function() {
                ngToast.success('Canal cerrado.');
                $state.go('dashboard.project.project-explore', { id: vm.project.id });
              });
            });
          }

          /**
           * @name deleteChannel
           * @desc calls the endpoint to delete the channel
          */
          function deleteChannel() {
            var msg = '¿Esta seguro que desea eliminar el canal? Esta operación no puede revertirse.';
            var dlg = dialogService.showModalConfirm('Administrar proyecto', msg);
            dlg.result.then(function () {
              $log.log('deleteChannel', vm.channel.id);
              channelService.deleteChannel(vm.project.id, vm.channel.id).error(function(data) {
                vm.validationErrors = $rootScope.helpers.loadServerErrors(data);
                if (vm.validationErrors === null)
                {
                  ngToast.danger('Ocurrió un error al consultar al servidor.');
                }
              }).then(function() {
                  ngToast.success('Canal eliminado.');
                  $state.go('dashboard.project.project-explore', { id: vm.project.id });
              });
            });
          }
      }
})();
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import './App.css';

import {
    SearchBox,
    NoHits,
    Hits,
    HitsStats,
    ItemCheckboxList,
    SortingSelector,
    SelectedFilters,
    MenuFilter,
    Pagination,
    RefinementListFilter,
    ResetFilters,
    SearchkitManager,
    SearchkitProvider,
    Tabs,
    } from "searchkit";

import {
  Layout, TopBar, LayoutBody, LayoutResults,
  ActionBar, ActionBarRow, SideBar
} from "searchkit"

const searchkit = new SearchkitManager("https://kinto-ota.dev.mozaws.net/v1/buckets/build-hub/collections/releases/", {searchUrlPath: "search"})

const HitsTable = (toggleExpand, expandedEntry) => {
  return ({hits}) => {
    return (

              Product
              Version
              Platform
              Channel
              Locale
              Published on

            {hits.map(hit => {
              const revisionUrl = (hit._source.source.revision)
                ? ({hit._source.source.revision})
                : "";
              const filename = hit._source.download.url.split("/").reverse()[0];
              const clickHandler = (event, data) => toggleExpand(event, data, hit._id);
              if (expandedEntry === hit._id) {
                return (

Product: {hit._source.source.product}

Version: {hit._source.target.version}

Platform: {hit._source.target.platform}

Channel: {hit._source.target.channel}

Locale: {hit._source.target.locale}

Published on: {hit._source.build && hit._source.build.date}

Tree: {hit._source.source.tree}

Revision: {revisionUrl}

URL: {filename}

Mimetype: {hit._source.download.mimetype}

Size: {hit._source.download.size}

Date: {hit._source.download.date}

Id: {hit._source.build && hit._source.build.id}

                )
              } else {
                return (

                    {hit._source.source.product}
                    {hit._source.target.version}
                    {hit._source.target.platform}
                    {hit._source.target.channel}
                    {hit._source.target.locale}
                    {hit._source.build && hit._source.build.date}

                )
              }
            })}

    );
  };
};

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      expandedEntry: null
    };
  }

  toggleExpand(event, data, id) {
    if (this.state.expandedEntry === id) {
      this.setState({expandedEntry: null});
    } else {
      this.setState({expandedEntry: id});
    }
  }

  render() {
    return (

        <SearchkitProvider searchkit={searchkit}>
          <Layout>

            <TopBar>
              <SearchBox
              autofocus={true}
              searchOnChange={true}
              queryFields={["build.id"]}/>
            </TopBar>

            <LayoutBody>
              <SideBar>
                <RefinementListFilter field="target.version"
                            title="Version"
                            id="versions"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            orderDirection="desc"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All versions"}}/>
                <RefinementListFilter field="target.platform"
                            title="Platform"
                            id="platform"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All platforms"}}/>
                <RefinementListFilter field="target.channel"
                            title="Channel"
                            id="channel"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All channels"}}/>
                <RefinementListFilter field="target.locale"
                            title="Locale"
                            id="locale"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All locales"}}/>
              </SideBar>

              <LayoutResults>

                <ActionBar>
                  <ActionBarRow>
                    <HitsStats/>
                    <SortingSelector options={[
                      {label: "Latest Releases", field:"download.date", order: "desc", defaultOption: true},
                      {label: "Relevance", field: "_score", order: "desc"},
                    ]}/>
                  </ActionBarRow>

                  <ActionBarRow>
                    <SelectedFilters/>
                    <ResetFilters/>
                  </ActionBarRow>

                  <MenuFilter field="source.product"
                              title="Product"
                              id="products"
                              listComponent={Tabs}
                              translations={{"All":"All products"}}/>
                </ActionBar>

                <Hits hitsPerPage={30} listComponent={HitsTable(this.toggleExpand.bind(this), this.state.expandedEntry)}/>
                <NoHits translations={{
                  "NoHits.NoResultsFound":"No release found were found for {query}",
                  "NoHits.DidYouMean":"Search for {suggestion}",
                  "NoHits.SearchWithoutFilters":"Search for {query} without filters"}} suggestionsField="target.version"/>

                <Pagination showNumbers={true}/>

               </LayoutResults>
            </LayoutBody>
          </Layout>
        </SearchkitProvider>

    );
  }
}

export default App;
<commit_msg>Fix #151: add a placeholder to the search box to document on which field it searches<commit_after>import React, { Component } from 'react';
import './App.css';

import {
    SearchBox,
    NoHits,
    Hits,
    HitsStats,
    ItemCheckboxList,
    SortingSelector,
    SelectedFilters,
    MenuFilter,
    Pagination,
    RefinementListFilter,
    ResetFilters,
    SearchkitManager,
    SearchkitProvider,
    Tabs,
    } from "searchkit";

import {
  Layout, TopBar, LayoutBody, LayoutResults,
  ActionBar, ActionBarRow, SideBar
} from "searchkit"

const searchkit = new SearchkitManager("https://kinto-ota.dev.mozaws.net/v1/buckets/build-hub/collections/releases/", {searchUrlPath: "search"})

const HitsTable = (toggleExpand, expandedEntry) => {
  return ({hits}) => {
    return (

              Product
              Version
              Platform
              Channel
              Locale
              Published on

            {hits.map(hit => {
              const revisionUrl = (hit._source.source.revision)
                ? ({hit._source.source.revision})
                : "";
              const filename = hit._source.download.url.split("/").reverse()[0];
              const clickHandler = (event, data) => toggleExpand(event, data, hit._id);
              if (expandedEntry === hit._id) {
                return (

Product: {hit._source.source.product}

Version: {hit._source.target.version}

Platform: {hit._source.target.platform}

Channel: {hit._source.target.channel}

Locale: {hit._source.target.locale}

Published on: {hit._source.build && hit._source.build.date}

Tree: {hit._source.source.tree}

Revision: {revisionUrl}

URL: {filename}

Mimetype: {hit._source.download.mimetype}

Size: {hit._source.download.size}

Date: {hit._source.download.date}

Id: {hit._source.build && hit._source.build.id}

                )
              } else {
                return (

                    {hit._source.source.product}
                    {hit._source.target.version}
                    {hit._source.target.platform}
                    {hit._source.target.channel}
                    {hit._source.target.locale}
                    {hit._source.build && hit._source.build.date}

                )
              }
            })}

    );
  };
};

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      expandedEntry: null
    };
  }

  toggleExpand(event, data, id) {
    if (this.state.expandedEntry === id) {
      this.setState({expandedEntry: null});
    } else {
      this.setState({expandedEntry: id});
    }
  }

  render() {
    return (

        <SearchkitProvider searchkit={searchkit}>
          <Layout>

            <TopBar>
              <SearchBox
              autofocus={true}
              searchOnChange={true}
              placeholder="Search a build ID, eg: 201706*"
              queryFields={["build.id"]}/>
            </TopBar>

            <LayoutBody>
              <SideBar>
                <RefinementListFilter field="target.version"
                            title="Version"
                            id="versions"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            orderDirection="desc"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All versions"}}/>
                <RefinementListFilter field="target.platform"
                            title="Platform"
                            id="platform"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All platforms"}}/>
                <RefinementListFilter field="target.channel"
                            title="Channel"
                            id="channel"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All channels"}}/>
                <RefinementListFilter field="target.locale"
                            title="Locale"
                            id="locale"
                            size={10}
                            operator="OR"
                            orderKey="_term"
                            listComponent={ItemCheckboxList}
                            translations={{"All":"All locales"}}/>
              </SideBar>

              <LayoutResults>

                <ActionBar>
                  <ActionBarRow>
                    <HitsStats/>
                    <SortingSelector options={[
                      {label: "Latest Releases", field:"download.date", order: "desc", defaultOption: true},
                      {label: "Relevance", field: "_score", order: "desc"},
                    ]}/>
                  </ActionBarRow>

                  <ActionBarRow>
                    <SelectedFilters/>
                    <ResetFilters/>
                  </ActionBarRow>

                  <MenuFilter field="source.product"
                              title="Product"
                              id="products"
                              listComponent={Tabs}
                              translations={{"All":"All products"}}/>
                </ActionBar>

                <Hits hitsPerPage={30} listComponent={HitsTable(this.toggleExpand.bind(this), this.state.expandedEntry)}/>
                <NoHits translations={{
                  "NoHits.NoResultsFound":"No release found were found for {query}",
                  "NoHits.DidYouMean":"Search for {suggestion}",
                  "NoHits.SearchWithoutFilters":"Search for {query} without filters"}} suggestionsField="target.version"/>

                <Pagination showNumbers={true}/>

               </LayoutResults>
            </LayoutBody>
          </Layout>
        </SearchkitProvider>

    );
  }
}

export default App;
<|endoftext|>


<commit_before>var args = arguments[0] || {};
var radius = 20;

var letterCollection = getLetterCollection();
letterCollection.fetch();
var jsonCollection = letterCollection.toJSON();
Alloy.Globals.jsonCollection = jsonCollection;

showMap();
createMapRoute();
var familyMap;
displayTrailMarkers();
addClueZone();

function startInteractive() {
	getGPSpos();
	loadClue();
}

function loadClue() {
	$.btnStartQuiz.hide();
	$.txtLetter.show();
	$.lblLetters.show();
	$.lblCollectedLetters.show();

	if (foundId == !null) {

		$.lblWelcome.text = "Nästa ledtråd: ";
		$.lblInfoText.text = jsonCollection[foundId-1].clue;

	} else {
		Ti.API.info("foundId är null");
	}
}

function sendLetter() {
	checkLetter(getLetter());
	familyMap.removeAllAnnotations();
	addClueZone();
}

function getLetter() {
	var letter = $.txtLetter.value;
	return letter.toUpperCase();
	//};
}

function checkLetter(letterToCheck) {

	if (Alloy.Globals.jsonCollection[foundId-1].letter == letterToCheck) {
		lettersArray.push(Alloy.Globals.jsonCollection[foundId-1].letter);
		$.lblCollectedLetters.text += letterToCheck;
		Alloy.Globals.jsonCollection[foundId-1].found = 1;

	} else {
		alert("Är du säker på att det var rätt bokstav?");
	}
}

//-----------------------------------------------------------
// Kontrollerar det inskickade ordet mot "facit"
//-----------------------------------------------------------
function checkWord() {
	var check = $.word.value;
	check.toLowerCase();

	if (check == word) {
		alert("Bra jobbat!");
	} else {
		alert("Försök igen!");
	}
}

//MAP STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------
// Zoomar in kartan på äventyrsleden
//-----------------------------------------
function showMap() {
	try {
		familyMap = MapModule.createView({
			userLocation : true,
			mapType : MapModule.HYBRID_TYPE,
			animate : true,
			height : '100%',
			width : Ti.UI.FILL
		});
		$.showFamilyTrail.add(familyMap);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - showMap");
	}
}

//-----------------------------------------------------------
// Beräknar nivån av inzoomning på en vald led
//-----------------------------------------------------------
function calculateMapRegion(trailCoordinates) {
	try {
		if (trailCoordinates.length != 0) {
			var poiCenter = {};
			var delta = 0.02;
			var minLat = trailCoordinates[0].latitude,
			    maxLat = trailCoordinates[0].latitude,
			    minLon = trailCoordinates[0].longitude,
			    maxLon = trailCoordinates[0].longitude;
			for (var i = 0; i < trailCoordinates.length - 1; i++) {
				minLat = Math.min(trailCoordinates[i + 1].latitude, minLat);
				maxLat = Math.max(trailCoordinates[i + 1].latitude, maxLat);
				minLon = Math.min(trailCoordinates[i + 1].longitude, minLon);
				maxLon = Math.max(trailCoordinates[i + 1].longitude, maxLon);
			}

			var deltaLat = maxLat - minLat;
			var deltaLon = maxLon - minLon;

			delta = Math.max(deltaLat, deltaLon);
			// Ändra om det ska vara mer zoomat
			delta = delta * 0.6;

			poiCenter.lat = maxLat - parseFloat((maxLat - minLat) / 2);
			poiCenter.lon = maxLon - parseFloat((maxLon - minLon) / 2);

			region = {
				latitude : poiCenter.lat,
				longitude : poiCenter.lon,
				latitudeDelta : delta,
				longitudeDelta : delta

			};
		}
		return region;

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - calculateMapRegion");
	}

}

//-----------------------------------------------------------
// skapar vandringsleden och sätter den på kartan
//-----------------------------------------------------------
function createMapRoute() {
	try {
		var zoomedRoute = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + "/routes/adventureroute.json").read().text;
		var parsedRoute = JSON.parse(zoomedRoute);

		var geoArray = [];
		geoArray.push(parsedRoute);

		var coordArray = [];

		for (var u = 0; u < geoArray.length; u++) {
			var coords = geoArray[0].features[0].geometry.paths[u];

			for (var i = 0; i < coords.length; i++) {

				var point = {
					latitude : coords[i][1],
					longitude : coords[i][0]
				};
				coordArray.push(point);
			}

			var route = {
				name : 'Äventyrsleden',
				points : coordArray,
				color : 'purple',
				width : 4.0
			};

			familyMap.addRoute(MapModule.createRoute(route));
		}

		familyMap.region = calculateMapRegion(coordArray);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - createMapRoute");
	}
}

//-----------------------------------------------------------
// Visar marker för vandringsleden
//-----------------------------------------------------------
function displayTrailMarkers() {
	try {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : 58.893198,
			longitude : 11.047852,
			title : 'Äventyrsleden',
			pincolor : MapModule.ANNOTATION_PURPLE,
			subtitle : 'Vandringsleden startar här!',
			font : {
				fontFamily : 'Raleway-Light'
			}
		});

		familyMap.addAnnotation(markerAnnotation);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - displayTrailMarkers");
	}
}

function addClueZone() {

	for (var c = 0; c < Alloy.Globals.jsonCollection.length; c++) {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : Alloy.Globals.jsonCollection[c].latitude,
			longitude : Alloy.Globals.jsonCollection[c].longitude,
			title : Alloy.Globals.jsonCollection[c].id,
			subtitle : Alloy.Globals.jsonCollection[c].letter
		});

		if (Alloy.Globals.jsonCollection[c].found == 0) {
			markerAnnotation.image = '/images/red.png';
		} else {
			markerAnnotation.image = '/images/green.png';
		}

		familyMap.addAnnotation(markerAnnotation);
	}
}

//GEO STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

function getGPSpos() {
	try {

		Ti.Geolocation.getCurrentPosition(function(e) {
			if (e.error) {
				alert('Get current position' + e.error);
			} else {
			}
		});

		if (Ti.Geolocation.locationServicesEnabled) {
			Titanium.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
			Titanium.Geolocation.distanceFilter = 10;

			Ti.Geolocation.addEventListener('location', function(e) {
				if (e.error) {
					Ti.API.info('Kan inte sätta eventListener ' + e.error);
				} else {
					getPosition(e.coords);
				}
			});

		} else {
			alert('Tillåt gpsen, tack');
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "Map - get current position GPS");
	}

}

//-----------------------------------------------------------
// Hämtar enhetens position och kontrollerar mot punkter
//-----------------------------------------------------------
function getPosition(coordinatesObj) {
	try {
		gLat = coordinatesObj.latitude;
		gLon = coordinatesObj.longitude;

		isNearPoint();
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - getPosition");
	}
}

//-----------------------------------------------------------
// Beräknar avståndet mellan enhetens koordinater och de punkter som håller info
//-----------------------------------------------------------
function distanceInM(lat1, lon1, GLat, GLon) {
	try {
		if (lat1 == null || lon1 == null || GLat == null || GLat == null) {
			alert("Det finns inga koordinater att titta efter");
		}

		var R = 6371;
		var a = 0.5 - Math.cos((GLat - lat1) * Math.PI / 180) / 2 + Math.cos(lat1 * Math.PI / 180) * Math.cos(GLat * Math.PI / 180) * (1 - Math.cos((GLon - lon1) * Math.PI / 180)) / 2;
		var distance = (R * 2 * Math.asin(Math.sqrt(a))) * 1000;

		return distance;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - distanceInM");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enhetens position är inom radien för en utsatt punkt
//-----------------------------------------------------------
function isInsideRadius(lat1, lon1, rad) {
	try {

		var isInside = false;
		var distance = distanceInM(lat1, lon1, gLat, gLon);

		if (distance <= rad) {
			isInside = true;
		}
		return isInside;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isInsideRadius");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enheten är innanför en punkt, sänder ut dialog om true
//-----------------------------------------------------------
function isNearPoint() {
	try {

		for (var i = 0; i < Alloy.Globals.jsonCollection.length; i++) {

			if (Alloy.Globals.jsonCollection[i].found == 0) {
				var lat = Alloy.Globals.jsonCollection[i].latitude;
				var lon = Alloy.Globals.jsonCollection[i].longitude;

				if (isInsideRadius(lat, lon, radius)) {
					alert("Du är i punkt : " + Alloy.Globals.jsonCollection[i].id + " och bokstaven är: " + Alloy.Globals.jsonCollection[i].letter);
					foundId = Alloy.Globals.jsonCollection[i].id;

					$.lblInfoText.text = Alloy.Globals.jsonCollection[i].clue;
				}
			}
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isNearPoint");
	}
}<commit_msg>jhgfd<commit_after>var args = arguments[0] || {};
var radius = 20;

var letterCollection = getLetterCollection();
letterCollection.fetch();
var jsonCollection = letterCollection.toJSON();
Alloy.Globals.jsonCollection = jsonCollection;

showMap();
createMapRoute();
var familyMap;
displayTrailMarkers();
addClueZone();

function startInteractive() {
	getGPSpos();
	loadClue();
}

function loadClue() {
	$.btnStartQuiz.hide();
	$.txtLetter.show();
	$.lblLetters.show();
	$.lblCollectedLetters.show();

	if (foundId == !null) {

		$.lblWelcome.text = "Nästa ledtråd: ";
		$.lblInfoText.text = jsonCollection[foundId-1].clue;

	} else {
		Ti.API.info("foundId är null");
	}
}

function sendLetter() {
	checkLetter(getLetter());
	familyMap.removeAllAnnotations();
	addClueZone();
}

function getLetter() {
	var letter = $.txtLetter.value;
	return letter.toUpperCase();
	//};
}

function checkLetter(letterToCheck) {

	if (Alloy.Globals.jsonCollection[foundId-1].letter == letterToCheck) {
		lettersArray.push(Alloy.Globals.jsonCollection[foundId-1].letter);
		$.lblCollectedLetters.text += letterToCheck;
		Alloy.Globals.jsonCollection[foundId-1].found = 1;

	} else {
		alert("Är du säker på att "+letterToCheck+ " är rätt bokstav?");
	}
}

//-----------------------------------------------------------
// Kontrollerar det inskickade ordet mot "facit"
//-----------------------------------------------------------
function checkWord() {
	var check = $.word.value;
	check.toLowerCase();

	if (check == word) {
		alert("Bra jobbat!");
	} else {
		alert("Försök igen!");
	}
}

//MAP STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------
// Zoomar in kartan på äventyrsleden
//-----------------------------------------
function showMap() {
	try {
		familyMap = MapModule.createView({
			userLocation : true,
			mapType : MapModule.HYBRID_TYPE,
			animate : true,
			height : '100%',
			width : Ti.UI.FILL
		});
		$.showFamilyTrail.add(familyMap);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - showMap");
	}
}

//-----------------------------------------------------------
// Beräknar nivån av inzoomning på en vald led
//-----------------------------------------------------------
function calculateMapRegion(trailCoordinates) {
	try {
		if (trailCoordinates.length != 0) {
			var poiCenter = {};
			var delta = 0.02;
			var minLat = trailCoordinates[0].latitude,
			    maxLat = trailCoordinates[0].latitude,
			    minLon = trailCoordinates[0].longitude,
			    maxLon = trailCoordinates[0].longitude;
			for (var i = 0; i < trailCoordinates.length - 1; i++) {
				minLat = Math.min(trailCoordinates[i + 1].latitude, minLat);
				maxLat = Math.max(trailCoordinates[i + 1].latitude, maxLat);
				minLon = Math.min(trailCoordinates[i + 1].longitude, minLon);
				maxLon = Math.max(trailCoordinates[i + 1].longitude, maxLon);
			}

			var deltaLat = maxLat - minLat;
			var deltaLon = maxLon - minLon;

			delta = Math.max(deltaLat, deltaLon);
			// Ändra om det ska vara mer zoomat
			delta = delta * 0.6;

			poiCenter.lat = maxLat - parseFloat((maxLat - minLat) / 2);
			poiCenter.lon = maxLon - parseFloat((maxLon - minLon) / 2);

			region = {
				latitude : poiCenter.lat,
				longitude : poiCenter.lon,
				latitudeDelta : delta,
				longitudeDelta : delta

			};
		}
		return region;

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - calculateMapRegion");
	}

}

//-----------------------------------------------------------
// skapar vandringsleden och sätter den på kartan
//-----------------------------------------------------------
function createMapRoute() {
	try {
		var zoomedRoute = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + "/routes/adventureroute.json").read().text;
		var parsedRoute = JSON.parse(zoomedRoute);

		var geoArray = [];
		geoArray.push(parsedRoute);

		var coordArray = [];

		for (var u = 0; u < geoArray.length; u++) {
			var coords = geoArray[0].features[0].geometry.paths[u];

			for (var i = 0; i < coords.length; i++) {

				var point = {
					latitude : coords[i][1],
					longitude : coords[i][0]
				};
				coordArray.push(point);
			}

			var route = {
				name : 'Äventyrsleden',
				points : coordArray,
				color : 'purple',
				width : 4.0
			};

			familyMap.addRoute(MapModule.createRoute(route));
		}

		familyMap.region = calculateMapRegion(coordArray);
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - createMapRoute");
	}
}

//-----------------------------------------------------------
// Visar marker för vandringsleden
//-----------------------------------------------------------
function displayTrailMarkers() {
	try {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : 58.893198,
			longitude : 11.047852,
			title : 'Äventyrsleden',
			pincolor : MapModule.ANNOTATION_PURPLE,
			subtitle : 'Vandringsleden startar här!',
			font : {
				fontFamily : 'Raleway-Light'
			}
		});

		familyMap.addAnnotation(markerAnnotation);

	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "interactive - displayTrailMarkers");
	}
}

function addClueZone() {

	for (var c = 0; c < Alloy.Globals.jsonCollection.length; c++) {
		var markerAnnotation = MapModule.createAnnotation({
			latitude : Alloy.Globals.jsonCollection[c].latitude,
			longitude : Alloy.Globals.jsonCollection[c].longitude,
			title : Alloy.Globals.jsonCollection[c].id,
			subtitle : Alloy.Globals.jsonCollection[c].letter
		});

		if (Alloy.Globals.jsonCollection[c].found == 0) {
			markerAnnotation.image = '/images/red.png';
		} else {
			markerAnnotation.image = '/images/green.png';
		}

		familyMap.addAnnotation(markerAnnotation);
	}
}

//GEO STUFF
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------

function getGPSpos() {
	try {

		Ti.Geolocation.getCurrentPosition(function(e) {
			if (e.error) {
				alert('Get current position' + e.error);
			} else {
			}
		});

		if (Ti.Geolocation.locationServicesEnabled) {
			Titanium.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
			Titanium.Geolocation.distanceFilter = 10;

			Ti.Geolocation.addEventListener('location', function(e) {
				if (e.error) {
					Ti.API.info('Kan inte sätta eventListener ' + e.error);
				} else {
					getPosition(e.coords);
				}
			});

		} else {
			alert('Tillåt gpsen, tack');
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "Map - get current position GPS");
	}

}

//-----------------------------------------------------------
// Hämtar enhetens position och kontrollerar mot punkter
//-----------------------------------------------------------
function getPosition(coordinatesObj) {
	try {
		gLat = coordinatesObj.latitude;
		gLon = coordinatesObj.longitude;

		isNearPoint();
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - getPosition");
	}
}

//-----------------------------------------------------------
// Beräknar avståndet mellan enhetens koordinater och de punkter som håller info
//-----------------------------------------------------------
function distanceInM(lat1, lon1, GLat, GLon) {
	try {
		if (lat1 == null || lon1 == null || GLat == null || GLat == null) {
			alert("Det finns inga koordinater att titta efter");
		}

		var R = 6371;
		var a = 0.5 - Math.cos((GLat - lat1) * Math.PI / 180) / 2 + Math.cos(lat1 * Math.PI / 180) * Math.cos(GLat * Math.PI / 180) * (1 - Math.cos((GLon - lon1) * Math.PI / 180)) / 2;
		var distance = (R * 2 * Math.asin(Math.sqrt(a))) * 1000;

		return distance;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - distanceInM");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enhetens position är inom radien för en utsatt punkt
//-----------------------------------------------------------
function isInsideRadius(lat1, lon1, rad) {
	try {

		var isInside = false;
		var distance = distanceInM(lat1, lon1, gLat, gLon);

		if (distance <= rad) {
			isInside = true;
		}
		return isInside;
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isInsideRadius");
	}
}

//-----------------------------------------------------------
// Kontrollerar om enheten är innanför en punkt, sänder ut dialog om true
//-----------------------------------------------------------
function isNearPoint() {
	try {

		for (var i = 0; i < Alloy.Globals.jsonCollection.length; i++) {

			if (Alloy.Globals.jsonCollection[i].found == 0) {
				var lat = Alloy.Globals.jsonCollection[i].latitude;
				var lon = Alloy.Globals.jsonCollection[i].longitude;

				if (isInsideRadius(lat, lon, radius)) {
					alert("Du börjar närma dig en bokstav! För test:  " + Alloy.Globals.jsonCollection[i].letter);
					foundId = Alloy.Globals.jsonCollection[i].id;
					$.lblInfoText.text = Alloy.Globals.jsonCollection[i].clue;
					Alloy.Globals.jsonCollection[i].found == 1;
				}
			}
		}
	} catch(e) {
		newError("Något gick fel när sidan skulle laddas, prova igen!", "map - isNearPoint");
	}
}<|endoftext|>


<commit_before>// manages auto-incrementing of internal ID
var ATKMatcherCollection = Backbone.Collection.extend({
  initialize: function() {
    this.currentId = 0;

    var self = this;
    this.bind('add', function(model, collection) {
      self.currentId++;
      model.id = self.currentId;
      self._byId[model.id] = model;
    });
  },

  lastModelAdded: function() {
    return this.at(this.length - 1);
  }
});

var ATKMatcherView = Backbone.View.extend({
  initialize: function(options) {
    var self = this,
        manditoryProperties = [
          'objectPaths',
          'resourceData',
          'objectPaneCSSId',
          'objectPaneSearchCSSId',
          'objectPanePathsCSSId',
          'resourcePaneCSSId',
          'resourcePaneSearchCSSId',
          'resourcePaneItemsCSSId',
          'matchButtonCSSId',
          'matchPaneCSSId',
          'matchPanePairsCSSId',
          'saveButtonCSSId',
          'confirmButtonCSSId',
          'cancelButtonCSSId'
        ];

    // set mandatory properties
    manditoryProperties.forEach(function(property) {
      self[property] = options[property] || alert(property + ' required.');
    });

    // set up matcher template methods
    this.matcherLayoutTemplate  = _.template(options.matcherLayoutTemplate);
    this.objectPathTemplate     = _.template(options.objectPathTemplate);
    this.resourceItemTemplate   = _.template(options.resourceItemTemplate);
    this.matchItemTemplate      = _.template(options.matchItemTemplate);

    // set matcher state maintenance properties
    this.resourceCollection = new ATKMatcherCollection();
    this.selectedResourceCSSId = false; // resource currently selected in UI

    this.pairCollection = new ATKMatcherCollection();
  },

  render: function() {
    $(this.el).append(this.matcherLayoutTemplate());

    // render initial data
    this.renderObjectPaths();
    this.renderResourceData(this.resourceData);

    // activate interface behaviour
    this.activateObjectFiltering();
    this.activateResourceSelection();
    this.activateResourceFiltering();
    this.activateMatchButtonAndKeypressResponse();
    this.activateSaveButton();
    this.activateConfirmButton();
    this.activateCancelButton();
  },

  renderObjectPaths: function() {
    var self = this,
        index = 0;

    // add each path to object pane
    this.objectPaths.forEach(function(path) {
      $('#' + self.objectPanePathsCSSId).append(
        self.objectPathTemplate({'index': index, 'path': path})
      );
      index++;
    });
  },

  renderResourceData: function(resourceData, level) {
    level = level || 0;

    var padding = '';

    for (var index = 0; index < level; index++) {
      padding = padding + '  ';
    }

    // store internal representation for reference
    this.resourceCollection.add(resourceData);

    var resourceModel = this.resourceCollection.lastModelAdded();

    // display resource
    $('#' + this.resourcePaneItemsCSSId).append(
      this.resourceItemTemplate({
        'tempId':             resourceModel.id,
        'padding':            padding,
        'title':              resourceData.title,
        'levelOfDescription': resourceData.levelOfDescription,
        'identifier':         resourceData.identifier,
        'dates':              resourceData.dates
      })
    );

    // recurse if children are found
    if (resourceData.children) {
      var self = this;

      resourceData.children.forEach(function(child) {
        self.renderResourceData(child, level + 1);
      });
    }
  },

  activateObjectFiltering: function() {
    var self = this;
    $('#' + this.objectPaneSearchCSSId + ' > input').keyup(function() {
      var filterTerm = $(this).val().toLowerCase();

      // cycle through each object path, hiding or showing based on the filter term
      $('#' + self.objectPanePathsCSSId)
        .children()
        .each(function() {
          if ($(this).children('label').text().toLowerCase().indexOf(filterTerm) == -1) {
            $(this).hide();
          } else {
            $(this).show();
          }
        });
    });
  },

  activateResourceSelection: function() {
    var self = this;

    $('#' + this.resourcePaneItemsCSSId + ' > tr').click(function() {
      var newSelectionCSSId = $(this).attr('id');

      // reset background of resource table rows
      self.resetBackgroundOfResourceTableRows();

      // if a new selection, highlight clicked row and set current selection to its CSS ID
      if (self.selectedResourceCSSId != newSelectionCSSId) {
        $(this).css('background-color', '#ffcc00');
        self.selectedResourceCSSId = newSelectionCSSId;
      } else {
        // ...otherwise, set to no selection
        self.selectedResourceCSSId = false;
      }
    });
  },

  resetBackgroundOfResourceTableRows: function() {
    $('#' + this.resourcePaneItemsCSSId + ' > tr').css('background-color', '');
  },

  activateResourceFiltering: function() {
    var self = this;

    $('#' + this.resourcePaneSearchCSSId + ' > input').keyup(function() {
      var filterTerm = $(this).val().toLowerCase();

      // cycle through each item, hiding or showing based on the filter term
      $('#' + self.resourcePaneItemsCSSId)
        .children()
        .each(function() {
          if ($(this).text().toLowerCase().indexOf(filterTerm) == -1) {
            $(this).hide();
          } else {
            $(this).show();
          }
        });
    });
  },

  activateMatchButtonAndKeypressResponse: function() {
    var self = this;

    var doMatch = function() {
      // if a resource is highlighted, attempt to add selected paths
      if (self.selectedResourceCSSId) {
        var selectedPaths = self.getSelectedPaths();

        // if any paths have been selected
        if(selectedPaths.length) {
          selectedPaths.forEach(function(item) {
            // disable the checkbox on the path being matched
            $('#' + item.id + ' > input').attr('disabled', 'disabled');
            $('#' + item.id + ' > label').addClass('atk-matcher-disabled-object-label');

            var resource = self.resourceCollection.get(
              self.indexNumberFromCSSId(self.selectedResourceCSSId)
            );

            // visually indicate that resource has had objects assigned to it
            $('#' + self.selectedResourceCSSId + ' > td').css('color', 'red');

            // store pair in collection for easy retrieval
            self.pairCollection.add({
              'objectPath':           item.path,
              'resourceCSSId':        self.selectedResourceCSSId,
              'resourceIdentifier':   resource.get('identifier'),
              'resourceSortPosition': resource.get('sortPosition')
            });

            // get the pair model that was added
            var pairModel = self.pairCollection.lastModelAdded();

            var $newMatchEl = $(self.matchItemTemplate({
              'tempId': pairModel.id,
              'path': item.path,
              'title': resource.get('title'),
              'identifier': resource.get('identifier'),
              'levelOfDescription': resource.get('levelOfDescription'),
              'dates': resource.get('dates')
            }));

            // hide new pair, add it to the pane, then fade it in
            $newMatchEl.hide();

            // logic to place it according to sort position
            var pairPlaced = false;
            $('#' + self.matchPanePairsCSSId).children().each(function() {
              var pairCSSId = $(this).attr('id'),
                  pairId = self.indexNumberFromCSSId(pairCSSId),
                  pairPosition = self.pairCollection.get(pairId).get('resourceSortPosition');

              if (pairPosition > pairModel.get('resourceSortPosition')) {
                $('#' + pairCSSId).parent().prepend($newMatchEl);
                pairPlaced = true;
              }
            });

            // if the pair hasn't been placed, add it to the end
            if (!pairPlaced) {
              $('#' + self.matchPanePairsCSSId).append($newMatchEl);
            }

            // hack to fix Firefox issue
            $('tr').css('display', 'table-row');

            // fade added element in and show Save button
            $newMatchEl.fadeIn('slow');
            $('#' + self.saveButtonCSSId).show();

            // enable deletion of match
            (function(index, pathId) {
              $('#match_delete_' + index).click(function() {
                // enable checkbox and remove greying out of associated label
                $('#' + pathId + ' > input').removeAttr('disabled');
                $('#' + item.id + ' > label').removeClass('atk-matcher-disabled-object-label');

                // un-check checkbox
                $('#' + item.id + ' > input').removeAttr('checked');

                // remove visual and internal pair representations
                $('#match_' + index).remove();
                var pair = self.pairCollection.get(index);
                self.pairCollection.remove(pair);

                // see if the resource in the pairing is still associated with any objects
                var found = self.pairCollection.find(function(item) {
                  return item.get('resourceCSSId') === pair.get('resourceCSSId');
                });

                // if the resource isn't associated with any objects, remove usage highlighting
                if (found == undefined) {
                  $('#' + pair.get('resourceCSSId') + ' > td').css('color', '');
                }

                // hide save button if no pairs now exist
                if (self.pairCollection.length == 0) {
                  $('#' + self.saveButtonCSSId).hide();
                }
              });
            })(pairModel.id, item.id)
            self.matchIndex++;
          });

          // deselect resource
          self.selectedResourceCSSId = false;
          self.resetBackgroundOfResourceTableRows();
        } else {
          self.notify('No objects selected.');
        }
      } else {
        self.notify('No resource selected.');
      }
    };

    $(document).bind('keypress', function(e){
       if(e.which === 13) {
         doMatch();
       }
    });

    $('#' + this.matchButtonCSSId).click(doMatch);
  },

  fadeElementsByCSSIds: function(ids, type, speed) {
    ids.forEach(function(id) {
      if (type == 'in') {
        $('#' + id).fadeIn(speed);
      } else {
        $('#' + id).fadeOut(speed);
      }
    });
  },

  activateSaveButton: function() {
    var self = this,
        fadeOutElementCSSIds = [
          this.objectPaneCSSId,
          this.resourcePaneCSSId,
          this.saveButtonCSSId
        ],
        fadeInElementCSSIds = [
          this.confirmButtonCSSId,
          this.cancelButtonCSSId
        ];

    $('#' + self.saveButtonCSSId).click(function () {
      self.fadeElementsByCSSIds(fadeOutElementCSSIds, 'out', 'fast');
      self.fadeElementsByCSSIds(fadeInElementCSSIds, 'in', 'fast');
    });
  },

  activateConfirmButton: function() {
    var self = this,
        url = window.location.href.split('/').slice(0, 7).join('/') + '/';

    $('#' + self.confirmButtonCSSId).click(function() {
      $.ajax({
        context: this,
        type: 'POST',
        dataType: 'json',
        data: self.pairCollection.toJSON(),
        success: function(result)
          {
            alert(result.message);
          },
        error: function()
          {
            alert("Error submitting data.");
          },
        url: url
      });
      console.log(self.pairCollection.toJSON());
    });
  },

  activateCancelButton: function() {
    var self = this,
        fadeInElementCSSIds = [
          this.objectPaneCSSId,
          this.resourcePaneCSSId,
          this.saveButtonCSSId
        ],
        fadeOutElementCSSIds = [
          this.confirmButtonCSSId,
          this.cancelButtonCSSId
        ];

    $('#' + self.cancelButtonCSSId).click(function() {
      self.fadeElementsByCSSIds(fadeInElementCSSIds, 'in', 'fast');
      self.fadeElementsByCSSIds(fadeOutElementCSSIds, 'out', 'fast');
    });
  },

  getSelectedPaths: function() {
    var self = this,
        selectedPaths = [];

    $('#' + self.objectPanePathsCSSId + ' > div').each(function() {
      if (
        $(this).children('input').attr('checked') == 'checked'
        && $(this).children('input').attr('disabled') != 'disabled'
      ) {
        selectedPaths.push({
          'id': $(this).attr('id'),
          'path': $(this).children('label').text()
        });
      }
    });

    return selectedPaths;
  },

  indexNumberFromCSSId: function(CSSId) {
    return parseInt(CSSId.substring(
      CSSId.indexOf('_') + 1
    ));
  },

  notify: function(text) {
    var dialog = $('<div>' + text + '</div>');

    setTimeout(function() {
      $(dialog).dialog('close');
    }, 2000);

    dialog.dialog({
      title: 'Warning',
      width: 640,
      height: 200,
      buttons: [{
        text: 'Dismiss',
        click: function() { $(this).dialog('close'); }
      }]
    });
  }
});
<commit_msg>Added return to ingest after ATK upload.<commit_after>// manages auto-incrementing of internal ID
var ATKMatcherCollection = Backbone.Collection.extend({
  initialize: function() {
    this.currentId = 0;

    var self = this;
    this.bind('add', function(model, collection) {
      self.currentId++;
      model.id = self.currentId;
      self._byId[model.id] = model;
    });
  },

  lastModelAdded: function() {
    return this.at(this.length - 1);
  }
});

var ATKMatcherView = Backbone.View.extend({
  initialize: function(options) {
    var self = this,
        manditoryProperties = [
          'objectPaths',
          'resourceData',
          'objectPaneCSSId',
          'objectPaneSearchCSSId',
          'objectPanePathsCSSId',
          'resourcePaneCSSId',
          'resourcePaneSearchCSSId',
          'resourcePaneItemsCSSId',
          'matchButtonCSSId',
          'matchPaneCSSId',
          'matchPanePairsCSSId',
          'saveButtonCSSId',
          'confirmButtonCSSId',
          'cancelButtonCSSId'
        ];

    // set mandatory properties
    manditoryProperties.forEach(function(property) {
      self[property] = options[property] || alert(property + ' required.');
    });

    // set up matcher template methods
    this.matcherLayoutTemplate  = _.template(options.matcherLayoutTemplate);
    this.objectPathTemplate     = _.template(options.objectPathTemplate);
    this.resourceItemTemplate   = _.template(options.resourceItemTemplate);
    this.matchItemTemplate      = _.template(options.matchItemTemplate);

    // set matcher state maintenance properties
    this.resourceCollection = new ATKMatcherCollection();
    this.selectedResourceCSSId = false; // resource currently selected in UI

    this.pairCollection = new ATKMatcherCollection();
  },

  render: function() {
    $(this.el).append(this.matcherLayoutTemplate());

    // render initial data
    this.renderObjectPaths();
    this.renderResourceData(this.resourceData);

    // activate interface behaviour
    this.activateObjectFiltering();
    this.activateResourceSelection();
    this.activateResourceFiltering();
    this.activateMatchButtonAndKeypressResponse();
    this.activateSaveButton();
    this.activateConfirmButton();
    this.activateCancelButton();
  },

  renderObjectPaths: function() {
    var self = this,
        index = 0;

    // add each path to object pane
    this.objectPaths.forEach(function(path) {
      $('#' + self.objectPanePathsCSSId).append(
        self.objectPathTemplate({'index': index, 'path': path})
      );
      index++;
    });
  },

  renderResourceData: function(resourceData, level) {
    level = level || 0;

    var padding = '';

    for (var index = 0; index < level; index++) {
      padding = padding + '  ';
    }

    // store internal representation for reference
    this.resourceCollection.add(resourceData);

    var resourceModel = this.resourceCollection.lastModelAdded();

    // display resource
    $('#' + this.resourcePaneItemsCSSId).append(
      this.resourceItemTemplate({
        'tempId':             resourceModel.id,
        'padding':            padding,
        'title':              resourceData.title,
        'levelOfDescription': resourceData.levelOfDescription,
        'identifier':         resourceData.identifier,
        'dates':              resourceData.dates
      })
    );

    // recurse if children are found
    if (resourceData.children) {
      var self = this;

      resourceData.children.forEach(function(child) {
        self.renderResourceData(child, level + 1);
      });
    }
  },

  activateObjectFiltering: function() {
    var self = this;
    $('#' + this.objectPaneSearchCSSId + ' > input').keyup(function() {
      var filterTerm = $(this).val().toLowerCase();

      // cycle through each object path, hiding or showing based on the filter term
      $('#' + self.objectPanePathsCSSId)
        .children()
        .each(function() {
          if ($(this).children('label').text().toLowerCase().indexOf(filterTerm) == -1) {
            $(this).hide();
          } else {
            $(this).show();
          }
        });
    });
  },

  activateResourceSelection: function() {
    var self = this;

    $('#' + this.resourcePaneItemsCSSId + ' > tr').click(function() {
      var newSelectionCSSId = $(this).attr('id');

      // reset background of resource table rows
      self.resetBackgroundOfResourceTableRows();

      // if a new selection, highlight clicked row and set current selection to its CSS ID
      if (self.selectedResourceCSSId != newSelectionCSSId) {
        $(this).css('background-color', '#ffcc00');
        self.selectedResourceCSSId = newSelectionCSSId;
      } else {
        // ...otherwise, set to no selection
        self.selectedResourceCSSId = false;
      }
    });
  },

  resetBackgroundOfResourceTableRows: function() {
    $('#' + this.resourcePaneItemsCSSId + ' > tr').css('background-color', '');
  },

  activateResourceFiltering: function() {
    var self = this;

    $('#' + this.resourcePaneSearchCSSId + ' > input').keyup(function() {
      var filterTerm = $(this).val().toLowerCase();

      // cycle through each item, hiding or showing based on the filter term
      $('#' + self.resourcePaneItemsCSSId)
        .children()
        .each(function() {
          if ($(this).text().toLowerCase().indexOf(filterTerm) == -1) {
            $(this).hide();
          } else {
            $(this).show();
          }
        });
    });
  },

  activateMatchButtonAndKeypressResponse: function() {
    var self = this;

    var doMatch = function() {
      // if a resource is highlighted, attempt to add selected paths
      if (self.selectedResourceCSSId) {
        var selectedPaths = self.getSelectedPaths();

        // if any paths have been selected
        if(selectedPaths.length) {
          selectedPaths.forEach(function(item) {
            // disable the checkbox on the path being matched
            $('#' + item.id + ' > input').attr('disabled', 'disabled');
            $('#' + item.id + ' > label').addClass('atk-matcher-disabled-object-label');

            var resource = self.resourceCollection.get(
              self.indexNumberFromCSSId(self.selectedResourceCSSId)
            );

            // visually indicate that resource has had objects assigned to it
            $('#' + self.selectedResourceCSSId + ' > td').css('color', 'red');

            // store pair in collection for easy retrieval
            self.pairCollection.add({
              'objectPath':           item.path,
              'resourceCSSId':        self.selectedResourceCSSId,
              'resourceIdentifier':   resource.get('identifier'),
              'resourceSortPosition': resource.get('sortPosition')
            });

            // get the pair model that was added
            var pairModel = self.pairCollection.lastModelAdded();

            var $newMatchEl = $(self.matchItemTemplate({
              'tempId': pairModel.id,
              'path': item.path,
              'title': resource.get('title'),
              'identifier': resource.get('identifier'),
              'levelOfDescription': resource.get('levelOfDescription'),
              'dates': resource.get('dates')
            }));

            // hide new pair, add it to the pane, then fade it in
            $newMatchEl.hide();

            // logic to place it according to sort position
            var pairPlaced = false;
            $('#' + self.matchPanePairsCSSId).children().each(function() {
              var pairCSSId = $(this).attr('id'),
                  pairId = self.indexNumberFromCSSId(pairCSSId),
                  pairPosition = self.pairCollection.get(pairId).get('resourceSortPosition');

              if (pairPosition > pairModel.get('resourceSortPosition')) {
                $('#' + pairCSSId).parent().prepend($newMatchEl);
                pairPlaced = true;
              }
            });

            // if the pair hasn't been placed, add it to the end
            if (!pairPlaced) {
              $('#' + self.matchPanePairsCSSId).append($newMatchEl);
            }

            // hack to fix Firefox issue
            $('tr').css('display', 'table-row');

            // fade added element in and show Save button
            $newMatchEl.fadeIn('slow');
            $('#' + self.saveButtonCSSId).show();

            // enable deletion of match
            (function(index, pathId) {
              $('#match_delete_' + index).click(function() {
                // enable checkbox and remove greying out of associated label
                $('#' + pathId + ' > input').removeAttr('disabled');
                $('#' + item.id + ' > label').removeClass('atk-matcher-disabled-object-label');

                // un-check checkbox
                $('#' + item.id + ' > input').removeAttr('checked');

                // remove visual and internal pair representations
                $('#match_' + index).remove();
                var pair = self.pairCollection.get(index);
                self.pairCollection.remove(pair);

                // see if the resource in the pairing is still associated with any objects
                var found = self.pairCollection.find(function(item) {
                  return item.get('resourceCSSId') === pair.get('resourceCSSId');
                });

                // if the resource isn't associated with any objects, remove usage highlighting
                if (found == undefined) {
                  $('#' + pair.get('resourceCSSId') + ' > td').css('color', '');
                }

                // hide save button if no pairs now exist
                if (self.pairCollection.length == 0) {
                  $('#' + self.saveButtonCSSId).hide();
                }
              });
            })(pairModel.id, item.id)
            self.matchIndex++;
          });

          // deselect resource
          self.selectedResourceCSSId = false;
          self.resetBackgroundOfResourceTableRows();
        } else {
          self.notify('No objects selected.');
        }
      } else {
        self.notify('No resource selected.');
      }
    };

    $(document).bind('keypress', function(e){
       if(e.which === 13) {
         doMatch();
       }
    });

    $('#' + this.matchButtonCSSId).click(doMatch);
  },

  fadeElementsByCSSIds: function(ids, type, speed) {
    ids.forEach(function(id) {
      if (type == 'in') {
        $('#' + id).fadeIn(speed);
      } else {
        $('#' + id).fadeOut(speed);
      }
    });
  },

  activateSaveButton: function() {
    var self = this,
        fadeOutElementCSSIds = [
          this.objectPaneCSSId,
          this.resourcePaneCSSId,
          this.saveButtonCSSId
        ],
        fadeInElementCSSIds = [
          this.confirmButtonCSSId,
          this.cancelButtonCSSId
        ];

    $('#' + self.saveButtonCSSId).click(function () {
      self.fadeElementsByCSSIds(fadeOutElementCSSIds, 'out', 'fast');
      self.fadeElementsByCSSIds(fadeInElementCSSIds, 'in', 'fast');
    });
  },

  activateConfirmButton: function() {
    var self = this,
        url = window.location.href.split('/').slice(0, 7).join('/') + '/';

    $('#' + self.confirmButtonCSSId).click(function() {
      $.ajax({
        context: this,
        type: 'POST',
        dataType: 'json',
        data: self.pairCollection.toJSON(),
        success: function(result)
          {
            alert(result.message);
            window.location = '/ingest';
          },
        error: function()
          {
            alert("Error submitting data.");
          },
        url: url
      });
      console.log(self.pairCollection.toJSON());
    });
  },

  activateCancelButton: function() {
    var self = this,
        fadeInElementCSSIds = [
          this.objectPaneCSSId,
          this.resourcePaneCSSId,
          this.saveButtonCSSId
        ],
        fadeOutElementCSSIds = [
          this.confirmButtonCSSId,
          this.cancelButtonCSSId
        ];

    $('#' + self.cancelButtonCSSId).click(function() {
      self.fadeElementsByCSSIds(fadeInElementCSSIds, 'in', 'fast');
      self.fadeElementsByCSSIds(fadeOutElementCSSIds, 'out', 'fast');
    });
  },

  getSelectedPaths: function() {
    var self = this,
        selectedPaths = [];

    $('#' + self.objectPanePathsCSSId + ' > div').each(function() {
      if (
        $(this).children('input').attr('checked') == 'checked'
        && $(this).children('input').attr('disabled') != 'disabled'
      ) {
        selectedPaths.push({
          'id': $(this).attr('id'),
          'path': $(this).children('label').text()
        });
      }
    });

    return selectedPaths;
  },

  indexNumberFromCSSId: function(CSSId) {
    return parseInt(CSSId.substring(
      CSSId.indexOf('_') + 1
    ));
  },

  notify: function(text) {
    var dialog = $('<div>' + text + '</div>');

    setTimeout(function() {
      $(dialog).dialog('close');
    }, 2000);

    dialog.dialog({
      title: 'Warning',
      width: 640,
      height: 200,
      buttons: [{
        text: 'Dismiss',
        click: function() { $(this).dialog('close'); }
      }]
    });
  }
});
<|endoftext|>


<commit_before>import { EventEmitter } from 'iron-beam';

var ib = new EventEmitter();

ib.on('a.*', (msg) => {
    var h = document.createElement("h1")                // Create a <h1> element
    var t = document.createTextNode(msg);
    h.appendChild(t);
    document.body.appendChild(h);
});

ib.emit('a.b','Hello, World!');<commit_msg>cleaned up app.js<commit_after>import { EventEmitter } from 'iron-beam';

const ib = new EventEmitter();

ib.on('a.*', (msg) => {
    let h = document.createElement("h1");
    let t = document.createTextNode(msg);
    h.appendChild(t);
    document.body.appendChild(h);
});

ib.emit('a.b','Hello, World!');<|endoftext|>


<commit_before>import getCoordinatesFromLocation from './actions/facebookcoordsservice';
import getImagesFromCoords from './actions/instagramservice';

const express = require('express');

const path = require('path');

// const webpack = require('webpack');
// const webpackConfig = require('./webpack.config.js');

// const compiler = webpack(webpackConfig);
// const webpackDevMiddleware = require('webpack-dev-middleware')(compiler, { noInfo: false, publicPath: webpackConfig.output.publicPath });

const port = process.env.PORT || 8080;

// const http = require('http');
const app = express();

// app.use(webpackDevMiddleware);
// app.use(require('webpack-hot-middleware')(compiler));

app.use(express.static(path.join(__dirname, '/public')));

// if you want whole app to be available, you need webpack as well. this file should only serve api.
// where is webpack configuration?
// app.get('*', (request, response) => {
//   response.sendFile(path.resolve(__dirname, 'public', 'index.html'));
// });
// const server = http.createServer(app);

// I'm installing "nodemon", this shit restarts node when file changed automaticly ohhh nice
// At least don't have to wait hours to recompile:0
app.get('/test', async (request, response) => {
  const location = request.query.location;

  try {
    const coords = await getCoordinatesFromLocation(location);
    const images = await getImagesFromCoords(coords);
    response.json({ images, coords });
  //  response.json(images);
  } catch (err) {
    throw new Error(err);
  }
});

if (process.env.NODE_ENV !== 'production') {
  const webpack = require('webpack');
  const webpackDevMiddleware = require('webpack-dev-middleware');
  const webpackHotMiddleware = require('webpack-hot-middleware');
  const config = require('../webpack.dev.config.js');
  const compiler = webpack(config);

  app.use(webpackHotMiddleware(compiler));
  app.use(webpackDevMiddleware(compiler, {
    noInfo: true,
    publicPath: config.output.publicPath
  }));
}

app.listen(port);
<commit_msg>new file update<commit_after>import getCoordinatesFromLocation from './actions/facebookcoordsservice';
import getImagesFromCoords from './actions/instagramservice';

const express = require('express');

const path = require('path');

// const webpack = require('webpack');
// const webpackConfig = require('./webpack.config.js');

// const compiler = webpack(webpackConfig);
// const webpackDevMiddleware = require('webpack-dev-middleware')(compiler, { noInfo: false, publicPath: webpackConfig.output.publicPath });

const port = process.env.PORT || 8080;

// const http = require('http');
const app = express();

// app.use(webpackDevMiddleware);
// app.use(require('webpack-hot-middleware')(compiler));

app.use(express.static(path.join(__dirname, '/public')));

// if you want whole app to be available, you need webpack as well. this file should only serve api.
// where is webpack configuration?
// app.get('*', (request, response) => {
//   response.sendFile(path.resolve(__dirname, 'public', 'index.html'));
// });
// const server = http.createServer(app);

// I'm installing "nodemon", this shit restarts node when file changed automaticly ohhh nice
// At least don't have to wait hours to recompile:0
app.get('/test', async (request, response) => {
  const location = request.query.location;

  try {
    const coords = await getCoordinatesFromLocation(location);
    const images = await getImagesFromCoords(coords);
    response.json({ images, coords });
  //  response.json(images);
  } catch (err) {
    throw new Error(err);
  }
});

if (process.env.NODE_ENV !== 'production') {
  const webpack = require('webpack');
  const webpackDevMiddleware = require('webpack-dev-middleware');
  const webpackHotMiddleware = require('webpack-hot-middleware');
  const config = require('../webpack.config.js');
  const compiler = webpack(config);

  app.use(webpackHotMiddleware(compiler));
  app.use(webpackDevMiddleware(compiler, {
    noInfo: true,
    publicPath: config.output.publicPath
  }));
}

app.listen(port);
<|endoftext|>