ui: rajouter jquery et slider, comment out carousel #26
10 changed files with 127 additions and 172 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
20
pkg/babillard/response.go
Normal 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
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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 }
|
||||||
|
|
|
@ -1,43 +1,17 @@
|
||||||
<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="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>--!>
|
||||||
|
<script src="/public/js/slider.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
32
ui/js/carousel.js
Normal 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();
|
|
@ -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();
|
|
||||||
});
|
|
Loading…
Add table
Reference in a new issue