wip: APIv2, UI rework, js cleanup

Retirer jquery

etc.
This commit is contained in:
Victor Lacasse-Beaudoin 2025-02-11 21:24:42 -05:00
parent 37031749b4
commit 52dd5693fb
11 changed files with 126 additions and 218 deletions

View file

@ -32,7 +32,7 @@ const (
) )
func ServerCmdExecuter() error { func ServerCmdExecuter() error {
RunServer(app.Config.ServerContenuDir, app.Config.ServerPort) RunServer(app.Config)
return nil return nil
} }

View file

@ -9,6 +9,8 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
// pre-v2
type ContenuHandler struct { type ContenuHandler struct {
ContenuDir string ContenuDir string
} }
@ -43,3 +45,24 @@ func (h ContenuHandler) HandleAPIContenuFile(c echo.Context) error {
return c.File(fmt.Sprintf("%s/%s", contenu_dir, filename)) return c.File(fmt.Sprintf("%s/%s", contenu_dir, filename))
} }
// v2
func APIv2ListContenu(cfg Config) echo.HandlerFunc {
return func(c echo.Context) error {
files, err := ListContenu(cfg.ServerContenuDir)
if err != nil {
return c.JSON(http.StatusInternalServerError, ErrorResponse{Error: err.Error()})
}
return c.JSON(http.StatusOK, NewContenuResponse(files))
}
}
// ui
func UIContenuFichier(cfg Config) echo.HandlerFunc {
return func(c echo.Context) error {
return c.File(fmt.Sprintf("%s/%s", cfg.ServerContenuDir, c.Param("fichier")))
}
}

View file

@ -1,24 +1,42 @@
package babillard package babillard
import "os" import (
"fmt"
"os"
)
func ListContenu(path string) ([]string, error) { var forbiddenFiles = []string{".gitkeep", "messages.txt", "Thumbs.db"}
var files []string
f, err_open := os.Open(path)
defer f.Close()
if err_open != nil { func ListContenu(path string) (files []string, err error) {
return nil, err_open file, err := os.Open(path)
if err != nil {
return nil, err
} }
fileInfo, err_read := f.Readdir(-1) defer file.Close()
if err_read != nil {
return nil, err_read stats, err := file.Stat()
if err != nil {
return nil, err
} }
for _, file := range fileInfo { if !stats.IsDir() {
if file.Name() != ".gitkeep" && file.Name() != "messages.txt" { return nil, fmt.Errorf("contenu '%s' n'est pas un répertoire", path)
files = append(files, file.Name()) }
fileInfos, err := file.Readdir(-1)
if err != nil {
return nil, err
}
fileLoop:
for _, fileInfo := range fileInfos {
for _, forbiddenFile := range forbiddenFiles {
if fileInfo.Name() == forbiddenFile {
continue fileLoop
}
} }
files = append(files, fileInfo.Name())
} }
return files, nil return files, nil
} }

View file

@ -18,12 +18,16 @@ API Specifications
'/api' | GET | Affiche les spécifications API '/api' | GET | Affiche les spécifications API
'/api/contenu' | GET | Affiche le nom des fichiers dans 'contenu/' '/api/contenu' | GET | Affiche le nom des fichiers dans 'contenu/'
'/api/contenu/{filename}' | GET | Affiche le fichier 'contenu/{filename}' '/api/contenu/{filename}' | GET | Affiche le fichier 'contenu/{filename}'
-----` -----
v2
--
'/api/v2/contenu' | GET | Affiche les noms des fichiers dans 'contenu/'
`
return c.String(http.StatusOK, apispec) return c.String(http.StatusOK, apispec)
} }
func RunServer(contenuDir string, serverPort int) { func RunServer(cfg Config) {
log.Print("[I] Starting webserver") log.Print("[I] Starting webserver")
e := echo.New() e := echo.New()
@ -45,11 +49,17 @@ func RunServer(contenuDir string, serverPort int) {
groupAPI := e.Group("/api") groupAPI := e.Group("/api")
contenuHandler := NewContenuHandler(contenuDir) contenuHandler := NewContenuHandler(cfg.ServerContenuDir)
groupAPI.GET("/", HandleAPIShow) groupAPI.GET("/", HandleAPIShow)
groupAPI.GET("/contenu/", contenuHandler.HandleAPIContenuList) groupAPI.GET("/contenu/", contenuHandler.HandleAPIContenuList)
groupAPI.GET("/contenu/:filename/", contenuHandler.HandleAPIContenuFile) groupAPI.GET("/contenu/:filename/", contenuHandler.HandleAPIContenuFile)
e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", serverPort))) groupAPI.GET("/v2/contenu/", APIv2ListContenu(cfg))
groupUI := e.Group("/ui")
groupUI.GET("/contenu/:fichier/", UIContenuFichier(cfg))
e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", cfg.ServerPort)))
} }

20
pkg/babillard/response.go Normal file
View file

@ -0,0 +1,20 @@
package babillard
type ErrorResponse struct {
Error string
}
type MessageResponse struct {
Message string
}
type ContenuResponse struct {
Data struct {
Contenu []string
}
}
func NewContenuResponse(fichiers []string) (response ContenuResponse) {
response.Data.Contenu = fichiers
return
}

View file

@ -20,60 +20,3 @@ embed {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
} }
#bar {
width: 100%;
background-image: linear-gradient(to right, #033ead, #3093d1);
color: white;
font-family: 'Roboto', sans-serif;
font-weight: bold;
display: flex;
align-items: center;
min-height: 75px;
}
img#bar-bg {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
}
#time {
font-size: 300%;
height: 53px;
}
#text-content {
white-space: nowrap;
z-index: 1;
display: block;
height: 100%;
padding-top: 55px;
position: relative;
}
#text-container {
height: 100%;
background-image: linear-gradient(to right, #033ead, #3093d1);
display: flex;
align-items: center;
font-size: 20px;
flex-grow: 1;
}
#text-content div {
display: block;
position: fixed;
height: 100%;
}
#date-time {
display: flex;
flex-flow: column;
align-items: center;
height: 100%;
background-color: #033ead;
z-index: 1;
width: 225px;
}

View file

@ -2,17 +2,17 @@ package ui
import "embed" import "embed"
//go:embed html/* //go:embed html/*.html
var htmlFS embed.FS var htmlFS embed.FS
func HTMLFS() embed.FS { return htmlFS } func HTMLFS() embed.FS { return htmlFS }
//go:embed css/* //go:embed css/*.css
var cssFS embed.FS var cssFS embed.FS
func CSSFS() embed.FS { return cssFS } func CSSFS() embed.FS { return cssFS }
//go:embed js/* //go:embed js/*.js
var jsFS embed.FS var jsFS embed.FS
func JSFS() embed.FS { return jsFS } func JSFS() embed.FS { return jsFS }

View file

@ -1,43 +1,15 @@
<html> <html>
<head> <head>
<title>AGECEM | slider</title> <title>AGECEM | babillard</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="/public/js/slider.js"></script>
<!-- BROKEN, brise slider.js quand inclu
<script src="text.js"></script>
!-->
<link rel="stylesheet" href="/public/css/style.css"> <link rel="stylesheet" href="/public/css/style.css">
<script src="/public/js/carousel.js"></script>
</head> </head>
<body> <body>
<p id="debug"></p>
<div id="contenu"> <div id="contenu">
<embed id="image"/> <embed id="image"/>
</div> </div>
<!-- BROKEN
<div id="bar">
<div id="date-time">
<div id="time"></div>
<div id="date"></div>
</div>
<div id="text-container">
<div id="text-content">
<div>Ce texte sera remplacé par jQuery!</div>
</div>
</div>
</div>
--!>
</body> </body>
</html> </html>

32
ui/js/carousel.js Normal file
View file

@ -0,0 +1,32 @@
// 2025-02 Victor Lacasse-Beaudoin, AGECEM
//
// Carousel d'images à afficher sur https://babillard.agecem.com/ ainsi que
// sur la télévision du Centre-Multi Services de l'AGECEM.
//
// WIP
async function getContenu() {
const url = "/api/v2/contenu/";
try {
const response = await fetch(url);
if (!response.ok) {
//TODO start interval then refresh page to try again
throw new Error(`Response status: ${response.status}`);
}
json = await response.json();
console.log("[i] got contenu");
console.log(json);
//startCarousel(json);
}
catch (error) {
console.error(error.message);
}
}
function run(){
console.log("[i] run");
getContenu();
}
run();

View file

@ -1,45 +0,0 @@
var images = [];
var indexImages = 0;
function afficherIndex() {
$('#debug').text(indexImages);
}
function afficherImage() {
$('#image').attr('src', "/api/contenu/"+images[indexImages]);
}
function augmenterIndex() {
if (indexImages >= images.length - 1) {
indexImages = 0;
} else {
indexImages ++;
}
}
function executionLoop(){
//afficherIndex();
afficherImage();
augmenterIndex();
}
function obtenirContenu(){
var response = '';
$.ajax({
type: "GET",
url: window.location.origin + "/api/contenu",
async: false,
success: function(text) {
response = text;
}
});
console.log(response);
images = response.split(';');
console.log(images);
}
$(function(){
obtenirContenu();
var executionInterval = setInterval(executionLoop, (Math.floor(Math.random() * 6)+15)*1000);
});

View file

@ -1,65 +0,0 @@
// VARS
// Vitesses
var vitesseTexte = 4000; // En millisecondes
// Coordonnées
var pointInitial = '100%';
var pointDestination = '-=2000px';
// Messages
var messageDiv = '#text-content div'
var messages = [];
var indexMessages = 0;
var fontSize;
var fontSizeLength;
// FUNCS
function animerTexte(){
// Diriger le texte vers la droite jusqu'à `pointDestination'.
// Récursivement reset la position du texte.
$(messageDiv).animate({left: pointDestination}, vitesseTexte, 'linear', resetTexte);
}
function resetTexte(){
// Remettre le texte au point initial
$(messageDiv).css('left', pointInitial);
// Récursivement animer le texte
animerTexte();
}
function updateTexte(){
var message = messages[indexMessages];
$(messageDiv).text(message);
augmenterIndex();
}
function augmenterIndex() {
if (indexMessages >= messages.length - 1) {
indexMessages = 0;
} else {
indexMessages ++;
}
}
function initialiserMessages(){
fontSize = $(messageDiv).css('fontSize');
fontSizeLength = fontSize.length;
// TODO Importer messages
messages = ['hello, world!'];
// TODO pointDestination = -1 * longueurMessage
//pointDestination = messages[0].width * fontSize.substring(fontSize.length-2);
pointDestination = messages[indexMessages].width;
}
// EXEC
$(function(){
//initialiserMessages();
resetTexte();
});