diff --git a/admin/api/public.go b/admin/api/public.go
new file mode 100644
index 00000000..ceccf230
--- /dev/null
+++ b/admin/api/public.go
@@ -0,0 +1,80 @@
+package api
+
+import (
+ "encoding/json"
+ "os"
+ "path"
+
+ "github.com/julienschmidt/httprouter"
+)
+
+func init() {
+ router.GET("/api/public.json", apiHandler(getPublic))
+ router.DELETE("/api/public.json", apiHandler(deletePublic))
+ router.PUT("/api/public.json", apiHandler(savePublic))
+}
+
+type FICPublicScene struct {
+ Type string `json:"type"`
+ Params map[string]interface{} `json:"params"`
+}
+
+func readPublic(path string) ([]FICPublicScene, error) {
+ var s []FICPublicScene
+ if fd, err := os.Open(path); err != nil {
+ return s, err
+ } else {
+ defer fd.Close()
+ jdec := json.NewDecoder(fd)
+
+ if err := jdec.Decode(&s); err != nil {
+ return s, err
+ }
+
+ return s, nil
+ }
+}
+
+func savePublicTo(path string, s []FICPublicScene) error {
+ if fd, err := os.Create(path); err != nil {
+ return err
+ } else {
+ defer fd.Close()
+ jenc := json.NewEncoder(fd)
+
+ if err := jenc.Encode(s); err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+func getPublic(_ httprouter.Params, body []byte) (interface{}, error) {
+ if _, err := os.Stat(path.Join(TeamsDir, "_public", "public.json")); !os.IsNotExist(err) {
+ return readPublic(path.Join(TeamsDir, "_public", "public.json"))
+ } else {
+ return []FICPublicScene{}, nil
+ }
+}
+
+func deletePublic(_ httprouter.Params, body []byte) (interface{}, error) {
+ if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), []FICPublicScene{}); err != nil {
+ return nil, err
+ } else {
+ return []FICPublicScene{}, err
+ }
+}
+
+func savePublic(_ httprouter.Params, body []byte) (interface{}, error) {
+ var scenes []FICPublicScene
+ if err := json.Unmarshal(body, &scenes); err != nil {
+ return nil, err
+ }
+
+ if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), scenes); err != nil {
+ return nil, err
+ } else {
+ return scenes, err
+ }
+}
diff --git a/admin/index.go b/admin/index.go
index 85c7448c..7e1270f2 100644
--- a/admin/index.go
+++ b/admin/index.go
@@ -23,6 +23,7 @@ const indextpl = `
Équipes
Thèmes
Exercices
+ Public
Événements
Paramètres
diff --git a/admin/static.go b/admin/static.go
index ba2bebf5..9d1bb918 100644
--- a/admin/static.go
+++ b/admin/static.go
@@ -19,6 +19,9 @@ func init() {
api.Router().GET("/events/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
+ api.Router().GET("/public", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
+ http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
+ })
api.Router().GET("/settings/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
http.ServeFile(w, r, path.Join(StaticDir, "index.html"))
})
diff --git a/admin/static/index.html b/admin/static/index.html
index dcbd3374..631dd44a 100644
--- a/admin/static/index.html
+++ b/admin/static/index.html
@@ -21,6 +21,7 @@
Équipes
Thèmes
Exercices
+ Public
Événements
Paramètres
diff --git a/admin/static/js/app.js b/admin/static/js/app.js
index 007d2c43..c7a12993 100644
--- a/admin/static/js/app.js
+++ b/admin/static/js/app.js
@@ -37,6 +37,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"])
controller: "TeamNewController",
templateUrl: "views/team-new.html"
})
+ .when("/public", {
+ controller: "PublicController",
+ templateUrl: "views/public.html"
+ })
.when("/events", {
controller: "EventsListController",
templateUrl: "views/event-list.html"
@@ -65,6 +69,11 @@ angular.module("FICApp")
'update': {method: 'PUT'},
})
})
+ .factory("Scene", function($resource) {
+ return $resource("/api/public.json", null, {
+ 'update': {method: 'PUT'},
+ })
+ })
.factory("Team", function($resource) {
return $resource("/api/teams/:teamId", { teamId: '@id' }, {
'update': {method: 'PUT'},
@@ -228,6 +237,77 @@ angular.module("FICApp")
}
})
+ .controller("PublicController", function($scope, Scene, Theme, Teams, Exercice) {
+ $scope.scenes = Scene.query();
+ $scope.themes = Theme.query();
+ $scope.teams = Teams.get();
+
+ $scope.types = {
+ "welcome": "Messages de bienvenue",
+ "message": "Message",
+ "panel": "Boîte",
+ "exercice": "Exercice",
+ "table": "Tableau",
+ "rank": "Classement",
+ };
+ $scope.welcome_types = {
+ "init": "Accueil des équipes",
+ "public": "Accueil du public",
+ "countdown": "Compte à rebours lancement",
+ };
+ $scope.panel_types = {
+ "panel-default": "Default",
+ "panel-info": "Info",
+ "panel-success": "Success",
+ "panel-warning": "Warning",
+ "panel-danger": "Danger",
+ };
+ $scope.rank_types = {
+ "general": "Classement général",
+ };
+ $scope.table_types = {
+ "levels": "Niveaux d'exercices",
+ "teams": "Équipes",
+ };
+ $scope.exercices = Exercice.query();
+
+ $scope.clearScene = function() {
+ Scene.delete(function() {
+ $scope.scenes = [];
+ });
+ };
+ $scope.saveScenes = function() {
+ Scene.update($scope.scenes);
+ };
+ $scope.addScene = function() {
+ $scope.scenes.push({params: {}});
+ };
+ $scope.delScene = function(s) {
+ angular.forEach($scope.scenes, function(scene, k) {
+ if (scene == s)
+ $scope.scenes.splice(k, 1);
+ });
+ };
+ $scope.upScene = function(s) {
+ angular.forEach($scope.scenes, function(scene, k) {
+ if (scene == s && k > 0) {
+ $scope.scenes.splice(k, 1);
+ $scope.scenes.splice(k - 1, 0, scene);
+ }
+ });
+ };
+ $scope.downScene = function(s) {
+ var move = true;
+ angular.forEach($scope.scenes, function(scene, k) {
+ if (move && scene == s) {
+ $scope.scenes.splice(k, 1);
+ $scope.scenes.splice(k + 1, 0, scene);
+ move = false;
+ }
+ });
+ };
+ })
+
.controller("EventsListController", function($scope, Event, $location) {
$scope.events = Event.query();
$scope.fields = ["id", "kind", "txt", "time"];
diff --git a/admin/static/views/public.html b/admin/static/views/public.html
new file mode 100644
index 00000000..435d30bd
--- /dev/null
+++ b/admin/static/views/public.html
@@ -0,0 +1,129 @@
+