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 });