github.com/hzck/speedroute@v0.0.0-20201115191102-403b7d0e443f/old-public/js/speedroute.js (about)

     1  var app = angular.module('speedrunRouting', ['ngVis', 'ngAnimate', 'ui.bootstrap']);
     2  
     3  app.controller('RouteCtrl', function($log, $http, VisDataSet, $location) {
     4  
     5      var DEBUG = true;
     6  
     7      var g = this;
     8  
     9      g.rewards = [];
    10      g.nodes = []
    11      g.edges = [];
    12      g.startNode = "";
    13      g.endNode = "";
    14      g.password = "";
    15      g.shortestPath = [];
    16  
    17      g.rewardBeingEdited = undefined;
    18      g.nodeBeingEdited = undefined;
    19      g.edgeBeingEdited = undefined;
    20  
    21      /* vis network data start */
    22      var networkNodes = new VisDataSet();
    23      var networkEdges = new VisDataSet();
    24      g.network = {
    25          nodes: networkNodes,
    26          edges: networkEdges
    27      };
    28      g.options = {
    29          height: '100%'
    30      };
    31      g.events = {};
    32      /* vis network data end */
    33  
    34      g.resetReward = function() {
    35          g.rewardBeingEdited = undefined;
    36          g.reward = {
    37              edit: true,
    38              id: "",
    39              unique: false,
    40              isA: "",
    41              errors: []
    42          }
    43      };
    44  
    45      resetRewardRef = function(obj) {
    46          obj.rewardRef = {
    47              rewardId: "",
    48              quantity: ""
    49          }
    50      };
    51  
    52      g.resetNode = function() {
    53          g.nodeBeingEdited = undefined;
    54          g.node = {
    55              edit: true,
    56              id: "",
    57              revisitable: false,
    58              rewards: [],
    59              errors: []
    60          }
    61          resetRewardRef(g.node);
    62      };
    63  
    64      resetEdgeWeight = function() {
    65          g.edge.weight = {
    66              description: ""
    67          }
    68          resetRewardRef(g.edge.weight);
    69      };
    70  
    71      g.resetEdge = function() {
    72          g.edgeBeingEdited = undefined;
    73          g.edge = {
    74              edit: true,
    75              from: "",
    76              to: "",
    77              weights: [],
    78              errors: []
    79          }
    80          resetEdgeWeight();
    81      };
    82  
    83      containsEdge = function(list, from, to) {
    84          for(var i = 0; i < list.length; i++) {
    85              if(list[i].from === from && list[i].to === to) {
    86                  return true;
    87              }
    88          }
    89          return false;
    90      };
    91  
    92      contains = function(list, id) {
    93          for(var i = 0; i < list.length; i++) {
    94              if(list[i].id === id) {
    95                  return true;
    96              }
    97          }
    98          return false;
    99      };
   100  
   101      containsReward = function(list, id) {
   102          for(var i = 0; i < list.length; i++) {
   103              if(list[i].rewardId === id) {
   104                  return true;
   105              }
   106          }
   107          return false;
   108      };
   109  
   110      removeObj = function(list, obj) {
   111          var index = list.indexOf(obj);
   112          if(index > -1) {
   113              list.splice(index, 1);
   114          }
   115      };
   116  
   117      g.canRewardBeRemoved = function(id) {
   118          for(var i = 0; i < g.edges.length; i++) {
   119              var edge = g.edges[i];
   120              for(var j = 0; j < edge.weights.length; j++) {
   121                  var weight = edge.weights[j];
   122                  for(var k = 0; k < weight.requirements.length; k++) {
   123                      if(weight.requirements[k].rewardId === id) {
   124                          return false;
   125                      }
   126                  }
   127              }
   128          }
   129          for(var i = 0; i < g.nodes.length; i++) {
   130              var node = g.nodes[i];
   131              for(var j = 0; j < node.rewards.length; j++) {
   132                  if(node.rewards[j].rewardId === id) {
   133                      return false;
   134                  }
   135              }
   136          }
   137          for(var i = 0; i < g.rewards.length; i++) {
   138              if(g.rewards[i].isA === id) {
   139                  return false;
   140              }
   141          }
   142          return true;
   143      };
   144  
   145      g.canNodeBeRemoved = function(id) {
   146          for(var i = 0; i < g.edges.length; i++) {
   147              if(g.edges[i].from === id || g.edges[i].to === id) {
   148                  return false;
   149              }
   150          }
   151          return true;
   152      };
   153  
   154      toggleEdit = function(reward, node, edge) {
   155          g.reward.edit = reward;
   156          g.node.edit = node;
   157          g.edge.edit = edge;
   158      };
   159  
   160      log = function(msg) {
   161          if(DEBUG) {
   162              console.log(msg);
   163          }
   164      };
   165  
   166      updateNodeRewardReferences = function(oldId, newId) {
   167          for(var i = 0; i < g.nodes.length; i++) {
   168              var node = g.nodes[i];
   169              for(var j = 0; j < node.rewards.length; j++) {
   170                  var nodeRew = node.rewards[j];
   171                  if(nodeRew.rewardId === oldId) {
   172                      nodeRew.rewardId = newId;
   173                      log("updated node reward reference");
   174                  }
   175              }
   176          }
   177      };
   178  
   179      updateEdgeRequirementReferences = function(oldId, newId) {
   180          for(var i = 0; i < g.edges.length; i++) {
   181              var edge = g.edges[i];
   182              for(var j = 0; j < edge.weights.length; j++) {
   183                  var weight = edge.weights[j];
   184                  for(var k = 0; k < weight.requirements.length; k++) {
   185                      var weightReq = weight.requirements[k];
   186                      if(weightReq.rewardId === oldId) {
   187                          weightReq.rewardId = newId;
   188                          log("updated edge weight requirement reference");
   189                      }
   190                  }
   191              }
   192          }
   193      };
   194  
   195      updateEdgeNodesReferences = function(oldId, newId) {
   196          for(var i = 0; i < g.edges.length; i++) {
   197              var edge = g.edges[i];
   198              if(edge.from === oldId) {
   199                  edge.from = newId;
   200                  log("updated edge from node reference");
   201              }
   202              if(edge.to === oldId) {
   203                  edge.to = newId;
   204                  log("updated edge to node reference");
   205              }
   206          }
   207      };
   208  
   209      getNodeIndex = function(id) {
   210          for(var i = 0; i < g.nodes.length; i++) {
   211              var node = g.nodes[i];
   212              if(node.id === id) {
   213                  return i;
   214              }
   215          }
   216          return -1;
   217      };
   218  
   219      getEdgeIndex = function(from, to) {
   220          for(var i = 0; i < g.edges.length; i++) {
   221              var edge = g.edges[i];
   222              if(edge.from === from && edge.to === to) {
   223                  return i;
   224              }
   225          }
   226          return -1;
   227      };
   228  
   229      g.len = function(list) {
   230          if (list) {
   231              return list.length;
   232          }
   233          return 0;
   234      };
   235  
   236      g.addReward = function() {
   237          g.reward.errors = [];
   238          var error = false;
   239          var id = g.reward.id;
   240          var isA = g.reward.isA;
   241          if(!id) {
   242              g.reward.errors.push("The reward name is not set.");
   243              error = true;
   244          }
   245          if(isA && !contains(g.rewards, isA)){
   246              g.reward.errors.push(isA + " is not a valid reward reference.");
   247              error = true;
   248          }
   249  
   250          if(g.rewardBeingEdited) {
   251              log("EDIT MODE");
   252              var oldId = g.rewardBeingEdited.id;
   253              var hasChanged = oldId !== id;
   254              if(hasChanged && contains(g.rewards, id)) {
   255                  g.reward.errors.push("The updated reward name already exists.");
   256                  error = true;
   257              }
   258              if(error) {
   259                  return;
   260              }
   261  
   262              g.rewardBeingEdited.unique = g.reward.unique;
   263              g.rewardBeingEdited.isA = isA;
   264              if(hasChanged) {
   265                  g.rewardBeingEdited.id = id;
   266                  updateNodeRewardReferences(oldId, id);
   267                  updateEdgeRequirementReferences(oldId, id);
   268              }
   269              g.resetReward();
   270          } else {
   271              log("ADD MODE");
   272              if(contains(g.rewards, id)){
   273                  g.reward.errors.push("The reward name already exists.");
   274                  error = true;
   275              }
   276              if(error) {
   277                  return;
   278              }
   279  
   280              g.rewards.push({
   281                  id: id,
   282                  unique: g.reward.unique,
   283                  isA: isA
   284              });
   285              g.resetReward();
   286          }
   287      };
   288  
   289      g.removeNodeReward = function(index) {
   290          g.node.rewards.splice(index, 1);
   291      };
   292  
   293      g.removeEdgeWeight = function(index) {
   294          g.edge.weights.splice(index, 1);
   295      };
   296  
   297      g.removeEdgeWeightRequirement = function(wIndex, index) {
   298          g.edge.weights[wIndex].requirements.splice(index, 1);
   299      };
   300  
   301      g.addNodeReward = function() {
   302          g.node.errors = [];
   303          var error = false;
   304          var id = g.node.rewardRef.rewardId;
   305  
   306          if(!id) {
   307              g.node.errors.push("The reward name cannot be empty.");
   308              error = true;
   309          }
   310          if(id && !contains(g.rewards, id)) {
   311              g.node.errors.push(id + " is not a valid reward reference.");
   312              error = true;
   313          }
   314          if(id && containsReward(g.node.rewards, id)) {
   315              g.node.errors.push(id + " is already defined in the list.");
   316              error = true;
   317          }
   318          if(error) {
   319              return;
   320          }
   321  
   322          g.node.rewards.push({
   323              rewardId: id,
   324              quantity: (parseInt(g.node.rewardRef.quantity) || 1)//check if this can be removed if not set
   325          });
   326          resetRewardRef(g.node);
   327      };
   328  
   329      g.addEdgeWeightRequirement = function(wIndex) {
   330          var id = g.edge.weight.rewardRef.rewardId;
   331          if(id && !containsReward(g.edge.weights[wIndex].requirements, id) && contains(g.rewards, id)) {
   332              g.edge.weights[wIndex].requirements.push({
   333                  rewardId: id,
   334                  quantity: (parseInt(g.edge.weight.rewardRef.quantity) || 1)//check if this can be removed if not set
   335              });
   336              resetRewardRef(g.edge.weight);
   337          } else {
   338              log("Error, containsReward or contains something something")
   339          }
   340      };
   341  
   342      g.addEdgeWeight = function() {
   343          var weight = g.edge.weight;
   344          g.edge.weights.push({
   345              requirements: [],
   346              description: weight.description,
   347              time: ""
   348          });
   349          resetEdgeWeight();
   350      };
   351  
   352      g.addNode = function() {
   353          g.node.errors = [];
   354          var error = false;
   355          var id = g.node.id;
   356  
   357          if(!id) {
   358              g.node.errors.push("The node name cannot be empty.");
   359              error = true;
   360          }
   361          if(g.node.rewardRef.rewardId !== ""){
   362              g.node.errors.push("There cannot be an unfinished reward.");
   363              error = true;
   364          }
   365  
   366          if(g.nodeBeingEdited) {
   367              log("EDIT MODE");
   368              var oldId = g.nodeBeingEdited.id;
   369              var isNewIdOk = oldId !== id && !contains(g.nodes, id);
   370  
   371              if(!(oldId === id || isNewIdOk)) {
   372                  g.node.errors.push("The updated node name already exists.");
   373                  error = true;
   374              }
   375              if(error) {
   376                  return;
   377              }
   378  
   379              g.nodeBeingEdited.revisitable = g.node.revisitable;
   380              g.nodeBeingEdited.rewards = g.node.rewards;
   381              if(isNewIdOk) {
   382                  log("newId ok");
   383                  g.nodeBeingEdited.id = id;
   384                  updateEdgeNodesReferences(oldId, id);
   385                  networkNodes.update({
   386                      id: g.nodes.indexOf(g.nodeBeingEdited),
   387                      label: id,
   388                      color: 'lightblue'
   389                  });
   390              }
   391              g.resetNode();
   392          } else {
   393              log("ADD MODE");
   394  
   395              if(contains(g.nodes, id)) {
   396                  g.node.errors.push("The node name already exists.");
   397                  error = true;
   398              }
   399              if(error) {
   400                  return;
   401              }
   402  
   403              g.nodes.push({
   404                  id: id,
   405                  revisitable: g.node.revisitable,
   406                  rewards: g.node.rewards
   407              });
   408              networkNodes.add({
   409                  id: g.nodes.length-1,
   410                  label: id,
   411                  color: 'lightblue'
   412              });
   413              g.resetNode();
   414          }
   415      };
   416  
   417      g.addEdge = function() {
   418          g.edge.errors = [];
   419          var error = false;
   420          var from = g.edge.from;
   421          var to = g.edge.to;
   422  
   423          if(!from) {
   424              g.edge.errors.push("From node cannot be empty.");
   425              error = true;
   426          }
   427          if(!to) {
   428              g.edge.errors.push("To node cannot be empty.");
   429              error = true;
   430          }
   431          if(!contains(g.nodes, from)) {
   432              g.edge.errors.push("From node " + from + " doesn't exist.");
   433              error = true;
   434          }
   435          if(!contains(g.nodes, to)) {
   436              g.edge.errors.push("To node " + to + " doesn't exist.");
   437              error = true;
   438          }
   439          if(g.edge.weight.description) {
   440              g.edge.errors.push("There cannot be an unfinished weight.");
   441              error = true;
   442          }
   443          for(var i = 0; i < g.edge.weights.length; i++) {
   444              var weight = g.edge.weights[i];
   445              if(!/^\d*[:]{0,1}\d*[:]{0,1}\d*[.]{0,1}\d*$/.test(weight.time)) {
   446                  g.edge.errors.push("The time of the weight " + weight.description + " is not on the correct format.");
   447                  error = true;
   448              }
   449          }
   450  
   451          if(g.edgeBeingEdited) {
   452              log("EDIT MODE");
   453              var oldFrom = g.edgeBeingEdited.from;
   454              var oldTo = g.edgeBeingEdited.to;
   455              var hasChanged = (oldFrom !== from) || (oldTo !== to);
   456  
   457              if(hasChanged && containsEdge(g.edges, from, to)) {
   458                  g.edge.errors.push("The edge from " + from + " to " + to + " already exists.");
   459                  error = true;
   460              }
   461              if(error) {
   462                  return;
   463              }
   464  
   465              g.edgeBeingEdited.weights = g.edge.weights;
   466              if(hasChanged) {
   467                  g.edgeBeingEdited.from = from;
   468                  g.edgeBeingEdited.to = to;
   469                  networkEdges.update({
   470                      id: g.edges.indexOf(g.edgeBeingEdited),
   471                      from: getNodeIndex(g.edgeBeingEdited.from),
   472                      to: getNodeIndex(g.edgeBeingEdited.to),
   473                      arrows: 'to',
   474                      color: 'lightblue'
   475                  });
   476              }
   477              g.resetEdge();
   478          } else {
   479              log("ADD MODE");
   480  
   481              if(containsEdge(g.edges, from, to)) {
   482                  g.edge.errors.push("The edge from " + from + " to " + to + " already exists.");
   483                  error = true;
   484              }
   485              if(error) {
   486                  return;
   487              }
   488  
   489              var edge = {
   490                  from: from,
   491                  to: to,
   492                  weights: g.edge.weights
   493              };
   494              g.edges.push(edge);
   495              networkEdges.add({
   496                  id: g.edges.length-1,
   497                  from: getNodeIndex(edge.from),
   498                  to: getNodeIndex(edge.to),
   499                  arrows: 'to',
   500                  color: 'lightblue'
   501              });
   502              g.resetEdge();
   503          }
   504      };
   505  
   506      g.edgeRowSpan = function(weights) {
   507          var span = 0;
   508          for (var i = 0; i < g.len(weights); i++) {
   509              for (var j = 1; j < g.len(weights[i].requirements); j++) {
   510                  span++;
   511              }
   512              span++;
   513          }
   514          return span;
   515      };
   516  
   517      g.removeReward = function(reward) {
   518          if(g.canRewardBeRemoved(reward.id)) {
   519              removeObj(g.rewards, reward);
   520          }
   521      };
   522  
   523      g.removeNode = function(node) {
   524          if(g.canNodeBeRemoved(node.id)) {
   525              networkNodes.remove({
   526                  id: g.nodes.indexOf(node)
   527              });
   528              removeObj(g.nodes, node);
   529          } else {
   530              log("Nonono");
   531          }
   532      };
   533  
   534      g.removeEdge = function(edge) {
   535          networkEdges.remove({
   536              id: g.edges.indexOf(edge)
   537          });
   538          removeObj(g.edges, edge);
   539      };
   540  
   541      g.editReward = function(reward) {
   542          g.resetReward();
   543          toggleEdit(true, false, false);
   544          g.rewardBeingEdited = reward;
   545          g.reward.id = reward.id;
   546          g.reward.unique = reward.unique;
   547          g.reward.isA = reward.isA;
   548      };
   549  
   550      g.editNode = function(node) {
   551          g.resetNode();
   552          toggleEdit(false, true, false);
   553          g.nodeBeingEdited = node;
   554          g.node.id = node.id;
   555          g.node.revisitable = node.revisitable;
   556          g.node.rewards = angular.copy(node.rewards);
   557      };
   558  
   559      g.editEdge = function(edge) {
   560          g.resetEdge();
   561          toggleEdit(false, false, true);
   562          g.edgeBeingEdited = edge;
   563          g.edge.from = edge.from;
   564          g.edge.to = edge.to;
   565          g.edge.weights = angular.copy(edge.weights);
   566      };
   567  
   568      resetColors = function() {
   569          for(var i = 0; i < networkNodes.length; i++) {
   570              networkNodes.update({
   571                  id: i,
   572                  color: 'lightblue'
   573              });
   574          }
   575          for(var i = 0; i < networkEdges.length; i++) {
   576              networkEdges.update({
   577                  id: i,
   578                  color: 'lightblue'
   579              });
   580          }
   581      }
   582  
   583      g.saveGraph = function() {
   584          resetColors();
   585          g.shortestPath = [];
   586          $http({
   587              method: 'POST',
   588              url: '/graph/' + g.name + '/' + g.password,
   589              data: {
   590                  rewards: g.rewards,
   591                  nodes: g.nodes,
   592                  edges: g.edges,
   593                  startId: g.startNode,
   594                  endId: g.endNode
   595              }
   596          }).then(function successCallback(response) {
   597              var data = response.data;
   598              if(!data) {
   599                  return;
   600              }
   601              g.shortestPath = data;
   602              for(var i = 0; i < data.length; i++) {
   603                  if(i != 0) {
   604                      networkEdges.update({
   605                          id: getEdgeIndex(data[i-1], data[i]),
   606                          color: 'lime'
   607                      });
   608                  }
   609                  networkNodes.update({
   610                      id: getNodeIndex(data[i]),
   611                      color: 'lime'
   612                  });
   613              }
   614          }, function errorCallback(response) {
   615              log("404 I guess...");
   616          });
   617      }
   618  
   619      loadGraph = function() {
   620          $http({
   621              method: 'GET',
   622              url: '/graph/' + g.name
   623          }).then(function successCallback(response) {
   624              var data = response.data;
   625              if(data.rewards) {
   626                  g.rewards = data.rewards;
   627              }
   628              if(data.nodes) {
   629                  g.nodes = data.nodes;
   630              }
   631              if(data.edges) {
   632                  g.edges = data.edges;
   633              }
   634              if(data.startId) {
   635                  g.startNode = data.startId;
   636              }
   637              if(data.endId) {
   638                   g.endNode = data.endId;
   639              }
   640              for(var i = 0; i < g.nodes.length; i++) {
   641                  networkNodes.add({
   642                      id: i,
   643                      label: g.nodes[i].id,
   644                      color: 'lightblue'
   645                  });
   646              }
   647              for(var i = 0; i < g.edges.length; i++) {
   648                  networkEdges.add({
   649                      id: i,
   650                      from: getNodeIndex(g.edges[i].from),
   651                      to: getNodeIndex(g.edges[i].to),
   652                      arrows: 'to',
   653                      color: 'lightblue'
   654                  });
   655              }
   656          }, function errorCallback(response) {
   657              log("404 I guess...");
   658          });
   659      }
   660  
   661      init = function() {
   662          var url = window.location.href;
   663          var parameter = 'g';
   664          var regex = new RegExp("[?&]" + parameter + "(=([^&#]*)|&|#|$)", "i");
   665          var results = regex.exec(url);
   666          if (!results || !results[2]) {
   667              log("Couldn't find key");
   668              return;
   669          }
   670          g.name = decodeURIComponent(results[2].replace(/\+/g, " "));
   671          loadGraph();
   672          g.reward.edit = false;
   673          g.node.edit = false;
   674          g.edge.edit = false;
   675      }
   676  
   677      g.resetReward();
   678      g.resetNode();
   679      g.resetEdge();
   680      init();
   681  });
   682  
   683  app.controller('CreateCtrl', function($http) {
   684  
   685      var c = this;
   686  
   687      c.name = "";
   688      c.password = "";
   689      c.livesplit = "";
   690      c.createError = 0;
   691  
   692      c.createGraph = function() {
   693          c.createError = 0;
   694          if(!c.name || !/^[A-Za-z0-9-_]*$/.test(c.name)) {
   695              c.createError = 1;
   696              return;
   697          }
   698          $http({
   699              method: 'POST',
   700              url: '/create/' + c.name + '/' + c.password,
   701              data: c.livesplit
   702          }).then(function successCallback(response) {
   703              window.location.href = window.location.href + "route.html?g=" + c.name;
   704          }, function errorCallback(response) {
   705              c.createError = response.status;
   706          });
   707      };
   708  });
   709  
   710  app.controller('ListCtrl', function($http) {
   711  
   712      var l = this;
   713  
   714      l.list = [];
   715  
   716      init = function() {
   717          $http({
   718              method: 'GET',
   719              url: '/graphs'
   720          }).then(function successCallback(response) {
   721              l.list = response.data;
   722          }, function errorCallback(response) {
   723              log("404 I guess...");
   724          });
   725      }
   726  
   727      init();
   728  });