391 lines
11 KiB
JavaScript
391 lines
11 KiB
JavaScript
angular.module("FICApp", ["ngRoute", "ngSanitize"])
|
|
.config(function($routeProvider, $locationProvider) {
|
|
$routeProvider
|
|
.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, $timeout) {
|
|
$rootScope.current_theme = 0;
|
|
$rootScope.current_exercice = 0;
|
|
$rootScope.time = {};
|
|
|
|
function updTime() {
|
|
$timeout.cancel($rootScope.cbm);
|
|
$rootScope.cbm = $timeout(updTime, 1000);
|
|
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();
|
|
});
|
|
|
|
String.prototype.capitalize = function() {
|
|
return this
|
|
.toLowerCase()
|
|
.replace(
|
|
/(^|\s)([a-z])/g,
|
|
function(m,p1,p2) { return p1+p2.toUpperCase(); }
|
|
);
|
|
}
|
|
|
|
angular.module("FICApp")
|
|
.filter("capitalize", function() {
|
|
return function(input) {
|
|
return input.capitalize();
|
|
}
|
|
})
|
|
.filter("time", function() {
|
|
return function(input) {
|
|
if (input == undefined) {
|
|
return "--";
|
|
} else if (input >= 10) {
|
|
return input;
|
|
} else {
|
|
return "0" + input;
|
|
}
|
|
}
|
|
})
|
|
.filter("size", function() {
|
|
var units = [
|
|
"o",
|
|
"kio",
|
|
"Mio",
|
|
"Gio",
|
|
"Tio",
|
|
"Pio",
|
|
"Eio",
|
|
"Zio",
|
|
"Yio",
|
|
]
|
|
return function(input) {
|
|
var res = input;
|
|
var unit = 0;
|
|
while (res > 1024) {
|
|
unit += 1;
|
|
res = res / 1024;
|
|
}
|
|
return (Math.round(res * 100) / 100) + " " + units[unit];
|
|
}
|
|
})
|
|
.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("/themes.json").success(function(themes) {
|
|
$scope.themes = themes;
|
|
$scope.max_gain = 0;
|
|
angular.forEach(themes, function(theme, key) {
|
|
this[key].exercice_count = Object.keys(theme.exercices).length;
|
|
this[key].gain = 0;
|
|
angular.forEach(theme.exercices, function(ex, k) {
|
|
this.gain += ex.gain;
|
|
}, theme);
|
|
$scope.max_gain += theme.gain;
|
|
}, 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) {
|
|
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();
|
|
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 = false;
|
|
}
|
|
};
|
|
})
|
|
.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");
|
|
}
|
|
};
|