Commit 61e8fd25 authored by DarthGege's avatar DarthGege

Rendu du projet

parent e7f06ad8
# DTY Board Game Toolbox
### Sommaire
1. [Principe](#introduction)
2. [Liste des outils](#outils)
3. [Installation](#installation)
4. [Utilisation](#utilisation)
5. [Remarques](#remarques)
6. [TODO](#todo)
### 1. Principe <a name="introduction"></a>
L'objectif était de créer une application permettant de mettre à disposition des joueurs un certain nombres d'outils pour les jeux de sociétés. L’application a pour but de rendre accessible et numérique les accessoires nécessaires pour jouer à des jeux de société, tant pour les joueurs classiques que pour les joueurs par internet et d’en ajouter d’autre. Cela se sous la forme d’une page personnelle sur laquelle on peut ajouter des rubriques et en supprimer.
### 2. Liste des outils <a name="outils"></a>
* Une note (simple zone de texte)
* Un dé paramétrable (nombre de faces, nombre de dés)
* Un compteur paramétrable
todo:
* Une liste à cocher
* Un chronomètre paramétrable (temps)
* Un minuteur paramétrable (temps)
* Une image
* Un tableau modifiable
### 3. Installation <a name="installation"></a>
Lancer depuis un terminal dans le dossier souhaité les commandes suivantes :
```
npm init
npm install express
npm install sqlite3
npm install framework7
git clone https://github.com/framework7io/framework7-template-single-view my-board-game-toolbox
cd ./my-board-game-toolbox
npm install
```
Remplacer le dossier www par celui présent sur ce git ainsi que le fichier index.js
Ajouter la base de données board_game_toolbox.db présent sur ce git
```
node index.js
```
### 4. Utilisation <a name="utilisation"></a>
Lancer depuis un terminal dans le dossier my-board-game-toolbox la commande suivante :
```
node index.js
```
A l'adresse `localhost`, le site affiche les rubriques contenu dans la base de données.
### 5. Remarques <a name="remarques"></a>
### 6. TODO <a name="todo"></a>
*
\ No newline at end of file
const express = require('express')
const server = express()
const sqlite3 = require('sqlite3')
const port = 80
//server.get('/', (req, res) => res.send('Hello World!'))
server.use(express.static('www'))
server.get('/dice/:nb_dices/:nb_sides', async function (req, res) {
var nb_sides = req.params.nb_sides
var nb_dices = req.params.nb_dices
var main = 0
var full = []
for(var i=0; i<nb_dices; i++){
var rndNumber = Math.floor(Math.random() * nb_sides) + 1
full.push(rndNumber)
main += rndNumber
}
res.send({"main":main,"full":full.join(" + ")})
})
server.get('/component/:id', async function (req, res) {
var db = new sqlite3.Database('board_game_toolbox.db', (err) => {
if (err) { console.error(err.message); }
console.log('Connected to the chinook database.');
});
db.serialize(() => {
db.each("SELECT * FROM widget WHERE id = " + parseInt(req.params.id), (err, row) => {
if (err) { console.error(err.message); }
console.log(row);
res.send({
type: row.type,
title: row.title,
data: JSON.parse(row.data)
});
});
});
/*
res.send({
children:[
{type:"dice",title:"Simulateur de dé",data:{last:"25",side:"6",amount:"5"}},
{type:"dice",title:"Simulateur de dé",data:{last:"5",side:"6",amount:"1"}},
{type:"dice",title:"Simulateur de dé",data:{last:"259",side:"6",amount:"60"}},
{type:"counter",title:"Barre de vie",data:{life:"10",on:"100"}},
{type:"text",title:"Ma note",data:"blablabla"},
]
})
*/
/*
res.send({
type:"board",
title:"My Board Game Toolbox",
data:{
children:[
"/component/1",
"/component/2",
"/component/3",
"/component/4",
"/component/5",
]
}
});
*/
// /component/01
/*
res.send({
type:"dice",title:"Simulateur de dé",data:{last:"25",side:"6",amount:"5"}
});
*/
})
server.get('/newcomponent/:type/:title', async function (req, res) {
var type = req.params.type
var title = req.params.title
var data = {}
switch(type){
case "dice": data = {"last":6,"side":6,"amount":5} ;break
case "text": data = {"text":""} ;break
case "counter": data = {"value":10,"max":100} ;break
case "bar": data = {"value":10,"max":100} ;break
}
data = JSON.stringify(data)
var db = new sqlite3.Database('board_game_toolbox.db', (err) => {
if (err) { console.error(err.message); }
console.log('Connected to the chinook database.');
});
db.run("INSERT INTO widget(type,title,data) VALUES(?,?,?)", [type,title,data], function(err) {
if (err) { console.error(err.message); }
res.send({id:this.lastID});
});
})
/**
* server.get('/newcomponent/:type/:title/:data', async function (req, res) {
var type = req.params.type
var title = req.params.title
var data = req.params.data
var db = new sqlite3.Database('board_game_toolbox.db', (err) => {
if (err) { console.error(err.message); }
console.log('Connected to the chinook database.');
});
db.run("INSERT INTO widget (id,type,title,data) VALUES (7,?,?,?)", [type,title,data], function(err) {
if (err) { console.error(err.message); }
});
})
*/
/**
* server.get('/dice/:nb_dices/:nb_sides', async function (req, res) {
var nb_sides = req.params.nb_sides
var nb_dices = req.params.nb_dices
var main = 0
var full = []
for(var i=0; i<nb_dices; i++){
var rndNumber = Math.floor(Math.random() * nb_sides) + 1
full.push(rndNumber)
main += rndNumber
}
res.send({"main":main,"full":full.join(" + ")})
})
server.get('/newcomponent/', async function (req, res) {
var db = new sqlite3.Database('board_game_toolbox.db', (err) => {
if (err) { console.error(err.message); }
console.log('Connected to the chinook database.');
});
var elements = req.params;
var newForm = {};
for (var i = 0; i < formRecieved.length; i++) {
var elementName = elements[i].name;
newForm[elementName] = elements[i].value;
}
newForm[data] = {};
var jsonString = JSON.stringify(newForm);
db.serialize(() => {
db.each("INSERT INTO widget SELECT MAX( id ) + 1, ? FROM widget", [JSON.stringify(newForm)], (err, row) => {
if (err) { console.error(err.message); }
console.log(row);
});
});
})
server.post('/newcomponent/:id', async function (req, res) {
var db = new sqlite3.Database('board_game_toolbox.db', (err) => {
if (err) { console.error(err.message); }
console.log('Connected to the chinook database.');
});
db.serialize(() => {
db.each("INSERT INTO widget SELECT MAX( id ) + 1, ?, ?, ? FROM widget", [parseInt(req.params.type),parseInt(req.params.title),parseInt(req.params.data)], (err, row) => {
if (err) { console.error(err.message); }
console.log(row);
});
});
}) */
server.listen(port, () => console.log(`Example app listening on port ${port}!`))
/* Your app styles here */
.masonry {
display:flex;
flex-direction: row;
justify-content:center;
flex-wrap:wrap;
}
.masonry>div {
flex-grow:1;
flex-shrink:1;
min-width:370px;
/*
width: 100%;
*/
}
.masonry .card-content-padding {
overflow-x: hidden;
}
.card-expandable:not(.card-tablet-fullscreen):not(.card-expandable-animate-width) .card-content {
width: 100%;
}
.full-width{
width:100%;
}
.flex-responsive{
display:flex;
flex-direction: row;
justify-content:space-around !important;
flex-wrap:wrap;
}
.board-number {
text-align: center;
font-size:30px;
}
\ No newline at end of file
#placeholder,
.maindice {
box-sizing: border-box;
text-align: center;
height: 200px;
width: 200px;
padding: 50px 0;
margin: 25px auto;
border: 1px solid gray;
border-radius: 20px;
font-size:80px;
}
\ No newline at end of file
/* Material Icons Font (for MD theme) */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(../fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
src: local('Material Icons'),
local('MaterialIcons-Regular'),
url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),
url(../fonts/MaterialIcons-Regular.woff) format('woff'),
url(../fonts/MaterialIcons-Regular.ttf) format('truetype');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}
/* Framework7 Icons Font (for iOS theme) */
@font-face {
font-family: 'Framework7 Icons';
font-style: normal;
font-weight: 400;
src: url("../fonts/Framework7Icons-Regular.eot");
src: url("../fonts/Framework7Icons-Regular.woff2") format("woff2"),
url("../fonts/Framework7Icons-Regular.woff") format("woff"),
url("../fonts/Framework7Icons-Regular.ttf") format("truetype");
}
.f7-icons {
font-family: 'Framework7 Icons';
font-weight: normal;
font-style: normal;
font-size: 25px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
-webkit-font-feature-settings: "liga";
-moz-font-feature-settings: "liga=1";
-moz-font-feature-settings: "liga";
font-feature-settings: "liga";
text-align: center;
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
db = window.sqlitePlugin.openDatabase({
name: 'ambdb',
location: 'default'
}, function (db) {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS FORMS (form BLOB)');
}, function (err) {
alert('Open database ERROR: ' + JSON.stringify(err));
});
});
function storeForms(formRecieved) {
var elements = formRecieved.elements;
var newForm = {};
for (var i = 0; i < formRecieved.length; i++) {
var elementName = elements[i].name;
newForm[elementName] = elements[i].value;
}
var jsonString = JSON.stringify(newForm);
db.transaction(function (tx) {
tx.executeSql('INSERT INTO FORMS (form) VALUES (?)', [JSON.stringify(newForm)]);
}, function (err) {
alert('StoreForms ERROR: ' + JSON.stringify(err));
});
}
function readForms(cb) {
var submittedForms = [];
db.transaction(function (tx) {
tx.executeSql('SELECT form FROM FORMS', [], function (tx, results) {
var row, formToSubmit, input, jsonRow = {};
for (var i = 0; i < results.rows.length; i++) {
row = results.rows.item(i)['form'];
jsonRow = JSON.parse(row);
formToSubmit = createFormToSubmit(jsonRow);
submittedForms.push(formToSubmit);
}
cb.call(this, submittedForms);
});
});
}
document.addEventListener("online", function (e) {
alert('I am online');
isConnected = true;
var promise1 = new Promise(function (resolve, reject) {
readForms(function (forms) {
resolve(forms);
});
}).then(function (submittedForms) {
var numberOfRows = submittedForms.length;
alert('submittedForms.length: ' + numberOfRows);
if (numberOfRows > 0) {
for (var i = 0; i < numberOfRows; i++) {
alert('Single row: '+ JSON.stringify(submittedForms[i]));
submittedForms[i].submit();
}
//deleteForms();
return false;
}
})
}, false);
function createFormToSubmit(jsonData) {
var formToSubmit = document.createElement("form");
var keys = Object.keys(jsonData);
var fieldName, input;
for (var i = 0; i < keys.length; i++) {
fieldName = keys[i];
input = document.createElement("input");
input.type = "text";
input.name = keys[i];
input.value = jsonData[fieldName];
formToSubmit.appendChild(input);
}
formToSubmit.setAttribute('method', "post");
formToSubmit.setAttribute('action', "https:url");
formToSubmit.setAttribute('target', "transFrame");
return formToSubmit;
}
\ No newline at end of file
// TODO Add collections type
// TODO Add collextions in left panel
// TODO Selecting collection clean the board and add elements of the collection
var $$ = Dom7;
// Framework7 App main instance
var app = new Framework7({
root: '#app', // App root element
id: 'io.framework7.testapp', // App bundle ID
name: 'Framework7', // App name
theme: 'auto', // Automatic theme detection
// App root data
data: function () {
return {
user: {
firstName: 'John',
lastName: 'Doe',
},
};
},
// App root methods
methods: {
helloWorld: function () {
app.dialog.alert('Hello World!');
},
},
// App routes
routes: routes,
});
// Init/Create main view
var mainView = app.views.create('.view-main', {
url: '/'
});
// Login Screen Demo
$$('#my-login-screen .login-button').on('click', function () {
var username = $$('#my-login-screen [name="username"]').val();
var password = $$('#my-login-screen [name="password"]').val();
// Close login screen
app.loginScreen.close('#my-login-screen');
// Alert username and password
app.dialog.alert('Username: ' + username + '<br>Password: ' + password);
});
/*
var dice = new Dice("#pagearea",2,"Simulateur de dé",{"last":"Dé","side":6,"amount":1});
var text = new Text("#pagearea",3,"Ma note",{"text":"yolo"});
var dicen = new Dice("#pagearea",2,"Autre dé",{"last":"Dé","side":6,"amount":1});
var textn = new Text("#pagearea",3,"Ma note","yolo");
*/
async function components(url) {
var data = await Framework7.request.promise({"url":url,"dataType":"json"})
switch(data.type){
case "board":
for(var i in data.data.children){
await components(data.data.children[i])
}
break;
case "text":
new Text("#pagearea",data.id,data.title,data.data)
break
case "dice":
new Dice("#pagearea",data.id,data.title,data.data)
break
case "counter":
new Counter("#pagearea",data.id,data.title,data.data)
break;
}
return
}
components("/component/1")
var newcomponent = document.getElementById('newcomponent');
newcomponent.onclick = function() {
var type = document.forms["newcomponent"].elements["type"].value
var title = document.forms["newcomponent"].elements["title"].value
console.log("test")
Framework7.request.get('/newcomponent/'+type+"/"+title);
};
/**
*
var newcomponent = document.getElementById('newcomponent');
newcomponent.onclick = function() {
var type = document.forms["newcomponent"].elements["type"].value
var title = document.forms["newcomponent"].elements["title"].value
if(type=="dice")
var data = {"last":"dé","side":6,"amount":1}
else if(type=="text")
var data = {"text":""}
else if(type=="counter")
var data = {"value":"50","max":"100"}
else
var data = {}
Framework7.request.get('/newcomponent/'+type.value+"/"+title.value+"/"+data.value);
};
*/
// TODO add buttons in reduced view to quickly add and remove to counter
class Counter {
constructor(target, id, title, data) {
for (let listener of ["close","update"])
this[listener] = this[listener].bind(this)
this.id = id
this.DOMelement =
_('div.card.card-expandable',
_('div.card-content',
_('div.bg-color-white[style="height: 300px"]',
_('div.card-header.text-color-black.display-block',
title,
_('br'),
_('br'),
_('div.row',
_('div.col.text-align-center',
this.range=_('div.gauge'),
),
),
),
this.closebtn = _('a.link card-close.card-opened-fade-in.color-black[href="#" style="position: absolute; right: 15px; top: 15px"]',
_('i.icon.f7-icons',"close_round_fill"),
),
),
_('div.card-content-padding.text-align-center.flex-responsive',
_('div',
_('p','Valeur :'),
this.value = _('div.stepper.stepper-raised.stepper-large.stepper-init[]',
_('div.stepper-button-minus'),
_('div.stepper-input-wrap',
_('input[type="text"]',{"attrs":{"value":data.value,"max":data.max}})
),
_('div.stepper-button-plus'),
),
),
_('div',
_('p','Max :'),
this.max = _('div.stepper.stepper-raised.stepper-large.stepper-init[]',
_('div.stepper-button-minus'),
_('div.stepper-input-wrap',
_('input[type="text"]',{"attrs":{"value":data.max}})
),
_('div.stepper-button-plus'),
),
),
)
),
);
this.closebtn.addEventListener("click", this.close)
document.querySelector(target).appendChild(this.DOMelement)
app.stepper.create({
"el":this.value,
"value":data.value,
"min":0,
"max":data.max,
"step":1,
"wraps":false,
"autorepeat":true,
"autorepeatDynamic":true,
"manualInputMode":true
})
app.stepper.create({
"el":this.max,
"value":data.max,
"min":1,
"max":10000,
"step":1,
"wraps":true,
"autorepeat":true,
"autorepeatDynamic":true,
"manualInputMode":true
})
app.stepper.setValue(this.value, data.value)
app.stepper.setValue(this.max, data.max)
var value = app.stepper.get(this.value).value
var max = app.stepper.get(this.max).value
app.gauge.create({
"el":this.range,
"type":"semicircle",
"value":value/max,
"size":250,
"valueText":value,
"valueTextColor":"#2196f3",
"borderColor":"#2196f3",
"labelText":"sur "+ max +" total",
"labelTextColor":"#333"
})
this.value.addEventListener("stepper:change", this.update)
this.max.addEventListener("stepper:change", this.update)
this.update()
return this
}
close() {
app.card.close(this.DOMelement, true)
}
update(ev) {
var maxel = app.stepper.get(this.max)
var valel = app.stepper.get(this.value)
var range = app.gauge.get(this.range)
valel.max = maxel.value
valel.setValue(Math.min(valel.value, maxel.value))
range.update({
value: valel.value / valel.max,
valueText: valel.value,
labelText: "sur "+ valel.max +" total",
});
}
}
// TODO add event on dice to roll the dice on reduced view
//Prints dice roll to the page
function localroll(nb_dices,nb_sides) {
var main = 0
var full = []
for(var i=0; i<nb_dices; i++){
var rndNumber = Math.floor(Math.random() * nb_sides) + 1
full.push(rndNumber)
main += rndNumber
}
return {"main":main,"full":full.join(" + ")}
}