angular.module("FICApp", ["ngRoute", "ngSanitize"]) .config(function($routeProvider, $locationProvider) { $routeProvider .when("/rules", { controller: "HomeController", templateUrl: "views/rules.html" }) .when("/edit", { controller: "MyTeamController", templateUrl: "views/team-edit.html" }) .when("/rank", { controller: "RankController", templateUrl: "views/rank.html" }) .when("/:theme", { controller: "ExerciceController", templateUrl: "views/theme.html" }) .when("/:theme/:exercice", { controller: "ExerciceController", templateUrl: "views/theme.html" }) .when("/", { controller: "HomeController", templateUrl: "views/home.html" }) .otherwise({ redirectTo: "/" }); $locationProvider.html5Mode(true); }) .run(function($rootScope, $interval) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; $rootScope.time = {}; function updTime() { if (sessionStorage.userService) { var time = angular.fromJson(sessionStorage.userService); var srv_cur = (Date.now() + (time.cu * 1000 - time.he)) / 1000; var remain = time.du; if (time.st == Math.floor(srv_cur)) { $rootScope.refresh(true); } if (time.st > 0 && time.st <= srv_cur) { remain = time.st + time.du - srv_cur; } if (remain < 0) { remain = 0; $rootScope.time.end = true; $rootScope.time.expired = true; } else if (remain < 60) { $rootScope.time.end = false; $rootScope.time.expired = true; } else { $rootScope.time.end = false; $rootScope.time.expired = false; } $rootScope.time.start = time.st * 1000; $rootScope.time.duration = time.du; $rootScope.time.remaining = remain; $rootScope.time.hours = Math.floor(remain / 3600); $rootScope.time.minutes = Math.floor((remain % 3600) / 60); $rootScope.time.seconds = Math.floor(remain % 60); } } updTime(); $interval(updTime, 1000); }) .controller("DataController", function($sce, $scope, $http, $rootScope, $timeout) { var actMenu = function() { if ($scope.my && $scope.themes) { angular.forEach($scope.themes, function(theme, key) { $scope.themes[key].exercice_solved = 0; angular.forEach(theme.exercices, function(exercice, k) { if ($scope.my.exercices[k] && $scope.my.exercices[k].solved) { $scope.themes[key].exercice_solved++; } }); }); } } $rootScope.refresh = function(justMy) { if (!justMy) { $timeout.cancel($scope.cbr); $scope.cbr = $timeout($rootScope.refresh, 42000); $http.get("/time.json").success(function(time) { time.he = (new Date()).getTime(); sessionStorage.userService = angular.toJson(time); }); $http.get("/settings.json").success(function(settings) { $scope.settings = settings; }); $http.get("/themes.json").success(function(themes) { $scope.themes = themes; $scope.max_gain = 0; $scope.max_solved = 0; angular.forEach(themes, function(theme, key) { this[key].exercice_count = Object.keys(theme.exercices).length; this[key].exercice_coeff_max = 0; this[key].gain = 0; this[key].solved = 0; angular.forEach(theme.exercices, function(ex, k) { this.gain += ex.gain; this.solved += ex.solved; this.exercice_coeff_max = Math.max(this.exercice_coeff_max, ex.curcoeff); }, theme); $scope.max_gain += theme.gain; $scope.max_solved = Math.max($scope.max_solved, theme.solved); }, themes); actMenu(); }); $http.get("/teams.json").success(function(teams) { $scope.teams_count = Object.keys(teams).length $scope.teams = teams; $scope.rank = []; angular.forEach($scope.teams, function(team, tid) { team.id = tid; this.push(team); }, $scope.rank); }); } $http.get("/my.json").success(function(my) { $scope.my = my; angular.forEach($scope.my.exercices, function(exercice, eid) { exercice.solved = exercice.solved_rank > 0; if (exercice.video_uri) { exercice.video_uri = $sce.trustAsResourceUrl(exercice.video_uri); } }); actMenu(); }); console.log("refresh!"); } $rootScope.refresh(); }) .controller("ExerciceController", function($scope, $routeParams, $http, $rootScope, $timeout) { $rootScope.current_theme = $routeParams.theme; if ($routeParams.exercice) { $rootScope.current_exercice = $routeParams.exercice; } else { if ($scope.themes && $scope.my && $scope.themes[$scope.current_theme]) { var exos = Object.keys($scope.themes[$scope.current_theme].exercices); var i = 0; for (; i < exos.length; i++) { if (!$scope.my.exercices[exos[i]] || !$scope.my.exercices[exos[i]].solved) break; } if (i < exos.length) { $rootScope.current_exercice = exos[i]; } else { $rootScope.current_exercice = exos[0]; } } else { $rootScope.current_exercice = 0; } } $scope.hsubmit = function(hint) { hint.submitted = true; $http({ url: "/openhint/" + $rootScope.current_exercice, method: "POST", data: { id: hint.id } }).success(function(data, status, header, config) { var checkDiffHint = function() { $http.get("/my.json").success(function(my) { angular.forEach(my.exercices[$rootScope.current_exercice].hints, function(h,hid){ if (hint.id == h.id) { if (hint.content != h.content) { $rootScope.refresh(); } else { $timeout.cancel($scope.cbh); $scope.cbh = $timeout(checkDiffHint, 750); } } }); }); }; checkDiffHint(); }).error(function(data, status, header, config) { hint.submitted = false; console.error(data.errmsg); }); }; }) .controller("SubmissionController", function($scope, $http, $rootScope, $timeout) { $scope.flags = []; $rootScope.sberr = ""; var waitMy = function() { if (!$scope.my || !$scope.my.exercices || !$scope.my.exercices[$rootScope.current_exercice]) { $timeout.cancel($scope.cbs); $scope.cbs = $timeout(waitMy, 420); } else { $scope.flags = []; angular.forEach($scope.my.exercices[$rootScope.current_exercice].keys, function(key,kid) { var o = { id: kid, name: key, value: "" }; if ($scope.my.exercices[$rootScope.current_exercice].solved_matrix != null) o.found = $scope.my.exercices[$rootScope.current_exercice].solved_matrix[kid]; this.push(o); }, $scope.flags); } } waitMy(); $scope.ssubmit = function() { var flgs = {} angular.forEach($scope.flags, function(flag,kid) { flgs[flag.name] = flag.value; }); $http({ url: "/submit/" + $rootScope.current_exercice, method: "POST", data: flgs }).success(function(data, status, header, config) { $rootScope.messageClass = {"text-success": true}; $rootScope.message = data.errmsg; $rootScope.sberr = ""; angular.forEach($scope.flags, function(flag,kid) { flag.value = ""; }); var checkDiff = function() { $http.get("/my.json").success(function(my) { if ($scope.my.exercices[$rootScope.current_exercice].solved_time != my.exercices[$rootScope.current_exercice].solved_time) { $rootScope.refresh(); $scope.my = my; waitMy(); } else { $timeout.cancel($scope.cbd); $scope.cbd = $timeout(checkDiff, 750); } }); }; checkDiff(); }).error(function(data, status, header, config) { if (status >= 500) { $scope.my.exercices[$rootScope.current_exercice].submitted = false; } $rootScope.messageClass = {"text-danger": true}; $rootScope.message = data.errmsg; if (status != 402) { $rootScope.sberr = "Une erreur est survenue lors de l'envoi. Veuillez réessayer dans quelques instants."; } }); $scope.my.exercices[$rootScope.current_exercice].submitted = true; }; }) .controller("MyTeamController", function($scope, $http, $rootScope, $timeout) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; if ($scope.my) { $rootScope.title = $scope.my.name; $rootScope.authors = $scope.my.members.map(function (cur) { return cur.firstname.capitalize() + " " + cur.lastname.capitalize(); }).join(", "); } $scope.newName = ""; $rootScope.message = ""; $rootScope.sberr = ""; $scope.tsubmit = function() { $rootScope.sberr = ""; if ($scope.newName.length < 1) { $rootScope.messageClass = {"text-danger": true}; $rootScope.sberr = "Nom d'équipe invalide: pas d'entrée."; return false; } else if ($scope.newName.length > 32) { $rootScope.messageClass = {"text-danger": true}; $rootScope.sberr = "Nom d'équipe invalide: pas plus de 32 caractères."; return false; } else if (!$scope.newName.match(/^[A-Za-z0-9 àéèêëîïôùûü_-]+$/)) { $rootScope.messageClass = {"text-danger": true}; $rootScope.sberr = "Nom d'équipe invalide: seuls les caractères alpha-numériques sont autorisés."; return false; } $http({ url: "/submit/name", method: "POST", data: {newName: $scope.newName} }).success(function(data, status, header, config) { $rootScope.messageClass = {"text-success": true}; $rootScope.message = data.errmsg; var checkDiff = function() { $http.get("/my.json").success(function(my) { console.log(my.name); if ($scope.my.name != my.name) { $scope.newName = ""; $rootScope.message = ""; $rootScope.refresh(); } else { $timeout.cancel($scope.cbt); $scope.cbt = $timeout(checkDiff, 750); } }); }; checkDiff(); }).error(function(data, status, header, config) { $rootScope.messageClass = {"text-danger": true}; $rootScope.message = data.errmsg; if (status != 402) { $rootScope.sberr = "Une erreur est survenue lors de l'envoi. Veuillez réessayer dans quelques instants."; } }); }; }) .controller("RankController", function($scope, $rootScope) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; $rootScope.title = "Classement général"; $rootScope.authors = ""; $scope.fields = ["rank", "name", "score"]; $scope.rankOrder = "rank"; $scope.reverse = false; $scope.order = function(fld) { if ($scope.rankOrder == fld) { $scope.reverse = !$scope.reverse; } else { $scope.rankOrder = fld; $scope.reverse = (fld == "score"); } }; }) .controller("HomeController", function($scope, $rootScope) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; $rootScope.title = ""; $rootScope.authors = ""; }); function sready() { if ($("#solution").val().length) { $("#sbmt").removeClass("disabled"); } else { $("#sbmt").addClass("disabled"); } };