Commit ea34d68a authored by  JosephK's avatar JosephK
Browse files

Init commit

parents
[![](https://framagit.org/assets/favicon-075eba76312e8421991a0c1f89a89ee81678bcde72319dd3e8047e2a47cd3a42.ico)](https://framagit.org)
![English:](https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Flag_of_the_United_Kingdom.svg/20px-Flag_of_the_United_Kingdom.svg.png) **Framasoft uses GitLab** for the development of its free softwares. Our Github repositories are only mirrors.
If you want to work with us, **fork us on [framagit.org](https://framagit.org)**. (no registration needed, you can sign in with your Github account)
![Français :](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Flag_of_France.svg/20px-Flag_of_France.svg.png) **Framasoft utilise GitLab** pour le développement de ses logiciels libres. Nos dépôts Github ne sont que des miroirs.
Si vous souhaitez travailler avec nous, **forkez-nous sur [framagit.org](https://framagit.org)**. (l'inscription n'est pas nécessaire, vous pouvez vous connecter avec votre compte Github)
* * *
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Framaestro - Orchestrez vos projets collaboratifs</title>
<meta charset="utf-8" />
<link href="https://framasoft.org/nav/lib/bootstrap/css/bootstrap.min.css" media="all" rel="stylesheet">
<link href="static/style.css" media="all" rel="stylesheet">
<script src="https://framasoft.org/nav/lib/jquery/jquery.min.js" type="text/javascript"></script>
<script src="https://framasoft.org/nav/lib/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="static/script.js" type="text/javascript"></script>
</head>
<body>
<script src="https://framasoft.org/nav/nav.js" type="text/javascript"></script>
<div class="container ombre">
<header role="banner">
<h1><b class="violet">Fra</b><b class="vert" lang="it">maestro</b></h1>
<p class="lead">Orchestrez vos projets collaboratifs</p>
<hr class="trait" role="presentation" />
</header>
<main>
<div class="row">
<div class="col-md-12">
<!-- Carousel -->
<div id="carousel-maestro" data-interval="7000" class="carousel slide" role="presentation">
<div class="carousel-inner">
<div class="item active">
<img src="static/slide-framaestro01.png" alt="" />
<div class="carousel-caption">
<p class="h3"><b class="violet">Fra</b><b class="vert" lang="it">maestro</b> : organisez une session de travail collaboratif</p>
</div>
</div>
<div class="item">
<img src="static/slide-framaestro02.png" alt=""/>
<div class="carousel-caption">
<p class="h3">Blablabla</p>
</div>
</div>
<div class="item">
<img src="static/slide-framaestro03.png" alt="" />
<div class="carousel-caption">
<p class="h3">Blablabla</p>
</div>
</div>
</div><!-- /.carousel-inner -->
<!-- Controls -->
<p class="text-center" id="play-pause"><a href="#play-pause" class="carousel-control" title="Pause"><span class="glyphicon glyphicon-pause"></span><span class="sr-only">Pause</span></a></p>
<a class="left carousel-control" href="#carousel-maestro" role="button" data-slide="prev" title="Diapo précédente">
<i class="glyphicon glyphicon-chevron-left"></i><span class="sr-only">Diapo précédente</span>
</a>
<a class="right carousel-control" href="#carousel-maestro" role="button" data-slide="next" title="Diapo suivante">
<i class="glyphicon glyphicon-chevron-right"></i><span class="sr-only">Diapo suivante</span>
</a>
</div><!-- /.carousel -->
<div class="col-md-8">
<form id="create-maestro">
<label for="maestro-name" class="sr-only">Nom du projet</label>
<div class="input-group input-group-lg maestro-options" id="create-maestro">
<input type="text" id="maestro-name" class="form-control maestro-name" value="" pattern="[a-zA-Z0-9_-]+" aria-describeby="maestroRegex"/>
<span class="input-group-btn">
<button class="btn btn-lg btn-primary maestro-create" type="submit">Créer<span class="sr-only"> un projet</span></button>
</span>
</div>
<p class="help-block text-center" id="maestroRegex"><small>(le nom du projet ne doit contenir que des lettres, des chiffres et des tirets (- ou _))</small></p>
<a id="maestro-url" href="https://localhost/" class="hidden" rel="nofollow"></a>
</form>
</div>
<div class="col-md-4">
<p>
<b class="violet">Fra</b><b class="vert" lang="it">maestro</b> vous permet de
afficher sur une même page différents site web ou outils collaboratifs en ligne.<br>
Blablabla</br>
Blablabla
</p>
</div>
</div>
</div>
<hr role="presentation" />
<div class="row">
<div class="col-md-3" id="tuto-video">
<h2>Prise en main</h2>
<p class="text-center" role="presentation"><i class="glyphicon glyphicon-question-sign"></i></p>
<ol>
<li>Créez un projet</li>
<li>Ajoutez les différents outils et site que vous voulez utiliser</li>
<li>Invitez vos collaborateurs à vous rejoindre en leur envoyant par courriel l’adresse du projet.</li>
</ol>
</div>
<div class="col-md-4" id="le-logiciel">
<h2>Le logiciel</h2>
<p class="text-center" role="presentation"><i class="glyphicon glyphicon-cloud"></i></p>
<p><b class="violet">Fra</b><b class="vert" lang="it">maestro</b> est développé par <b class="violet">Frama</b><b class="orange">soft</b> et fait appel à plusieurs bibliothèque javascript et notamment <a href="http://togetherjs.com/">TogetherJS</a>.</p>
<p>Le logiciel est sous licence <a href="">TBMC</a></p>
</div>
<div class="col-md-4" id="jardin">
<h2>Cultivez votre jardin</h2>
<p class="text-center" role="presentation"><i class="glyphicon glyphicon-tree-deciduous"></i></p>
<p>Pour participer au développement du logiciel, proposer des améliorations
ou simplement le télécharger, rendez-vous sur <a href="https://framagit.org/framasoft/framaestro">le site de développement</a>.</p>
<br>
<p>Si vous souhaitez installer ce logiciel pour votre propre usage et ainsi gagner en autonomie, nous vous aidons sur :</p>
<p class="text-center"><a href="http://framacloud.org/cultiver-son-jardin/installation-de-framaestro/" class="btn btn-success"><i class="glyphicon glyphicon-tree-deciduous"></i> framacloud.org</a></p>
</div>
</div>
</main>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex, follow" />
<title>Framaestro</title>
<link rel="stylesheet" href="resources/jquery-ui/jquery-ui.complete.min.css"/>
<link rel="stylesheet" href="resources/bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" href="resources/jspanel/jquery.jspanel.css"/>
<link rel="stylesheet" href="resources/font-awesome/css/font-awesome.min.css"/>
<link rel="stylesheet" href="style.css"/>
<script src="resources/jquery/jquery-2.1.4.min.js"></script>
<script src="resources/jquery-ui/jquery-ui-complete.min.js"></script>
<script src="togetherjs-config.js"></script>
<script src="resources/togetherjs-min.js"></script>
<!--<script src="https://togetherjs.com/togetherjs.js"></script>-->
<script src="resources/bootstrap/bootstrap.min.js"></script>
<script src="resources/jspanel/jquery.jspanel.min.js"></script>
<script src="maestro.js"></script>
</head>
<body>
<!--<script type="text/javascript" src="https://framasoft.org/nav/nav.js"></script>-->
<script type="text/javascript" src="../../nav/nav.js"></script>
<nav id="header" class="navbar navbar-default">
<div class="container-fluid ombre">
<div class="navbar-header">
<a href="#" class="navbar-toggle collapsed"
data-toggle="collapse" data-target=".sl-menu"
aria-expanded="false">
<span class="sr-only">Afficher/masquer le menu</span>
<i class="fa fa-fw fa-lg fa-chevron-down" aria-hidden="true"></i>
</a>
<a href="#" class="navbar-brand"><b class="violet">Fra</b><b class="vert">maestro</b></a>
</div>
<div class="collapse navbar-collapse sl-menu">
<ul class="list-inline pull-right navbar-nav navbar-brand">
<li><a href="#" id="btnTalk" title="Activer la discussion vidéo">
<i class="fa fa-fw fa-lg fa-video-camera" aria-hidden="true"></i><span class="sr-only">Activer la discussion vidéo</span>
</a></li>
<li><a href="#" id="btnAudio" title="Activer la discussion audio">
<i class="fa fa-fw fa-lg fa-microphone" aria-hidden="true"></i><span class="sr-only">Activer la discussion audio</span>
</a></li>
<li><a href="#" id="btnChat" title="Afficher le tchat">
<i class="fa fa-fw fa-lg fa-comment" aria-hidden="true"></i><span class="sr-only">Afficher le tchat</span>
</a></li>
<li><a href="#" id="minimizeAll" title="Tout minimiser">
<i class="fa fa-fw fa-lg fa-compress" aria-hidden="true"></i><span class="sr-only">Tout minimiser</span>
</a></li>
<!--<li><a href="#" id="sync" onclick="TogetherJS(this); return false;" title="Synchroniser">
<i class="fa fa-fw fa-lg fa-refresh" aria-hidden="true"></i><span class="sr-only">Synchroniser</span>
</a></li>-->
<li><a href="#share" data-toggle="modal" title="Partager">
<i class="fa fa-fw fa-lg fa-share-alt" aria-hidden="true"></i><span class="sr-only">Partager</span>
</a></li>
<li class="btn btn-success navbar-btn"><a href="#addWeb" data-toggle="modal">
<i class="fa fa-fw fa-lg fa-plus" aria-hidden="true"></i> Ajouter
</a></li>
</ul>
</div>
</div>
</nav>
<main class="container-fluid" id="board">
</main>
<!-- modale share -->
<div class="modal fade" id="share" tabindex="-1" role="dialog" aria-labelledby="shareLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fermer</span></button>
<h1 id="shareLabel">Partage</h1>
</div>
<div class="modal-body">
<form class="form col-sm-12">
<div class="form-group">
<label for="pLVal">Permalien</label>
<div class="input-group">
<div class="input-group-btn">
<a id="pLHref" class="btn btn-default" href="">
<i class="fa fa-lg fa-link" aria-hidden="true"></i>
</a>
<button class="btn btn-default" id="sLBtn" type="button">
<i class="fa fa-lg fa-bolt" aria-hidden="true" title="Raccourcir le lien"></i>
<span class="sr-only">Raccourcir le lien</span>
</button>
</div>
<input class="form-control" id="pLVal" readonly="" type="text" />
</div>
</div>
<div class="form-group" style="display:none">
<label for="sLVal">Lien raccourci</label>
<div class="input-group">
<div class="input-group-btn">
<a id="sLHref" class="btn btn-default" href="">
<i class="fa fa-lg fa-link" aria-hidden="true"></i>
</a>
</div>
<input class="form-control" id="sLVal" readonly="" type="text" />
</div>
</div>
<fieldset id="collabOptions">
<legend>Options collaboratives</legend>
<div class="form-group col-sm-6">
<input class="form-control" id="collabChat" type="checkbox" />
<label for="collabChat">Activer le tchat</label>
</div>
<div class="form-group col-sm-6">
<input class="form-control" id="collabAudio" type="checkbox" />
<label for="collabAudio">Activer la discussion audio</label>
</div>
<div class="form-group col-sm-6">
<input class="form-control" id="collabCursor" type="checkbox" />
<label for="collabCursor">Afficher les déplacements de souris</label>
</div>
<div class="form-group col-sm-6">
<input class="form-control" id="collabClic" type="checkbox" />
<label for="collabClic">Afficher les clics de souris</label>
</div>
<div class="form-group col-sm-6">
<input class="form-control" id="collabTile" type="checkbox" />
<label for="collabTile">Synchroniser les fenêtres</label>
</div>
</fieldset>
<div class="form-group">
<label for="pLCoVal">Permalien (collaboratif)</label>
<div class="input-group">
<div class="input-group-btn">
<a id="pLCoHref" class="btn btn-default" href="">
<i class="fa fa-lg fa-link" aria-hidden="true"></i>
</a>
<button class="btn btn-default" id="sLCoBtn" type="button">
<i class="fa fa-lg fa-bolt" aria-hidden="true" title="Raccourcir le lien"></i>
<span class="sr-only">Raccourcir le lien</span>
</button>
</div>
<input class="form-control" id="pLCoVal" readonly="" type="text" />
</div>
</div>
<div class="form-group" style="display:none">
<label for="sLCoVal">Lien raccourci (collaboratif)</label>
<div class="input-group">
<div class="input-group-btn">
<a id="sLCoHref" class="btn btn-default" href="">
<i class="fa fa-lg fa-link" aria-hidden="true"></i>
</a>
</div>
<input class="form-control" id="sLCoVal" readonly="" type="text" />
</div>
</div>
</form>
</div>
<div class="modal-footer"><a href="#" class="btn btn-default" data-dismiss="modal">Fermer</a></div>
</div>
</div>
</div>
<!-- /modale share -->
<!-- modale addWeb -->
<div class="modal fade" id="addWeb" tabindex="-1" role="dialog" aria-labelledby="addWebLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fermer</span></button>
<h1 id="addWebLabel">Ajouter</h1>
</div>
<form class="form" id="addWebForm" action="#">
<div class="modal-body">
<div class="col-sm-12">
<fieldset>
<legend>Une page web</legend>
<div class="form-group">
<label for="addWeb-url-input">URL</label>
<div class="input-group">
<input class="form-control" id="addWeb-url-input" type="text" placeholder="http(s)://…"/>
<div class="input-group-btn">
<button type="button" id="waybackMachine" class="btn btn-default" title="Remplacer par le lien Internet Archive"><i class="fa fa-lg fa-university" aria-hidden="true"></i><span class="sr-only">Internet Archive</span></button>
<button type="submit" class="btn btn-success">Ajouter</button>
</div>
</div>
</div>
</fieldset><br>
<fieldset>
<legend>Un service de <b class="violet">Frama</b><b class="orange">soft</b></legend>
<div id="framaServices">
</div>
</fieldset><br>
</div>
</div>
<div class="modal-footer"><a href="#" class="btn btn-default" data-dismiss="modal">Fermer</a></div>
</form>
</div>
</div>
</div>
<!-- /modale addWeb -->
</body>
</html>
\ No newline at end of file
// https://framaestro.org/#[a-zA-Z0-9]{8}/NomDuProjet/0,0,400,300,(urlencoded|framaservice);&togetherjs=[a-zA-Z0-9]{10}
function randomName() {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var string_length = 10;
var randomstring = '';
for (var i = 0; i < string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
var HASH = window.location.hash;
var maestro = HASH.replace('#','').split('/');
// Random string
var tonality = (maestro[0] != undefined) ? maestro[0] : randomName();
// Project name
var concerto = (maestro[1] != undefined) ? maestro[1] : '';
// All tiles
var movement = (maestro[2] != undefined) ? maestro[2].split(';') : '';
// Tiles with placement top,left,width,height,url
var tile = new Array();
for(i = 0; i < movement.length; i++) {
tile[i] = movement[i].split(',');
}
// Function to create a tile
function newTile(pTop,pLeft,sWidth,sHeight,url) {
var panel = ['primary', 'success', 'info', 'warning', 'danger'];
var bsClass = panel[Math.floor(Math.random()*panel.length)];
var parser = document.createElement('a');
parser.href = decodeURIComponent((url+'').replace(/\+/g, '%20'));
var frameLink = parser.href;
var panelTitle = parser.hostname.replace(/^(www|test)\./i,'').replace(/\.(com|net|org|fr|pro)$/i,'');
var panelId = $('.jsPanel').length + 1;
function template() {
var template = $(jsPanel.template);
var headerR = $('.jsPanel-hdr-r', template);
headerR.append('<div class="jsPanel-btn-reload"><i class="glyphicon glyphicon-refresh" aria-hidden="true"></i><span class="sr-only">Actualiser</span></div><div class="jsPanel-btn-edit"><i class="glyphicon glyphicon-pencil" aria-hidden="true"></i><span class="sr-only">Modifier</span></div>');
return template;
}
f$.jsPanel({
template: template(),
toolbarHeader: function( hdr ){
hdr.toolbar.addClass('bg-'+bsClass).hide();
return '<form id="editTile-'+panelId+'" action="#"><div class="input-group input-group-sm"><input id="url-'+panelId+'" type="text" class="form-control" value="'+frameLink+'"><span class="input-group-btn"><button class="btn btn-default" type="submit">Ok</button></span></div></form>';
},
selector: '#board',
bootstrap: bsClass,
position: {
of: '#board',
top: pTop,
left: pLeft
},
size: {
width: sWidth,
height: sHeight
},
title: panelTitle,
content: '<iframe id="frame-'+panelId+'" src="'+frameLink+'"></iframe>',
draggable: {
containment: "parent"
},
callback: function (panel) {
$('#jsPanel-'+panelId+' .jsPanel-btn-reload').click(function () {
refreshTile(panelId);
});
$('#jsPanel-'+panelId+' .jsPanel-btn-edit').click(function () {
if( $('#jsPanel-'+panelId+' .jsPanel-hdr-toolbar:visible').length == 0 ) {
$('#jsPanel-'+panelId+' .jsPanel-hdr-toolbar').show();
} else {
$('#jsPanel-'+panelId+' .jsPanel-hdr-toolbar').hide();
}
});
editTile(panelId);
}
});
f$('#addWeb').modal('hide'); $('#addWeb input').val('');
};
// Function to add a tile on the board
// and send it with TogetherJS if needed
function sendTile(pTop,pLeft,sWidth,sHeight,url) {
newTile(pTop,pLeft,sWidth,sHeight,url);
if (TogetherJS.running && !MaestroJSConfig_disableTile) {
TogetherJS.send({type: "newTile", pTop: pTop, pLeft: pLeft, sWidth: sWidth, sHeight: sHeight, url: url});
}
}
function editTile(id) {
$('#editTile-'+id).submit(function( event ) {
$('#frame-'+id).attr('src', $('#url-'+id).val());
$('#url-'+id).attr('value', $('#frame-'+id).attr('src')); // write URL in DOM (needed in refresh case)
$('#jsPanel-'+id+' .jsPanel-hdr-toolbar').hide();
if (TogetherJS.running && !MaestroJSConfig_disableTile) {
TogetherJS.send({type: "editTile", id: id, url: encodeURIComponent($('#frame-'+id).attr('src'))});
}
event.preventDefault();
});
}
function refreshTile(id) {
$('#frame-'+id).attr('src', $('#url-'+id).val());
}
/**----------------------------- TogetherJS -------------------------**/
TogetherJS.hub.on("newTile", function (msg) {
newTile(msg.pTop, msg.pLeft, msg.sWidth, msg.sHeight, msg.url);
});
TogetherJS.hub.on("editTile", function (msg) {
url = decodeURIComponent((msg.url+'').replace(/\+/g, '%20'))
$('#url-'+msg.id).val(url).attr('value',url);
$('#frame-'+msg.id).attr('src', url);
});
/**----------------------------- DOM Ready ---------------------------**/
$(document).ready(function() {
// Redirection vers l'accueil si le Maestro est en panne d'inspiration :)
if(HASH == '') {
window.location.href = window.location.href.replace('p/', '').replace('#','');
}
/**------------------------- Share & Link -------------------------- **/
// Update Maestro permalink
function updatePermalink() {
var a = document.createElement('a');
a.href = window.location.href;
var url = a.protocol+"//"+a.host+a.pathname+'#'+tonality+'/'+concerto+'/'
$('.jsPanel').each( function() {
url = url + $(this).css('top').replace('px','')+','+
$(this).css('left').replace('px','')+','+
$(this).children('.panel-body').css('width').replace('px','')+','+
$(this).children('.panel-body').css('height').replace('px','')+','+
encodeURIComponent($(this).find('iframe').attr('src').replace(a.protocol+"//"+a.host+a.pathname, ''))+
';';
});
// Permalink + Shortlink
$('#pLHref').attr('href',url);
$('#pLVal').val(url);
if( $('#sLVal').val() ) {
$('#sLVal').parent().parent('.form-group').show();
$('#sLHref').attr('href', $('#sLVal').val());
};
// Collaborative Permalink + Shortlink
// collabOptions are saved in a base36 number
// (= 2 last chars of the TogetherJS ShareID )
var collabConfig = 0;
if( $('#collabChat').is(':checked') ) { collabConfig += 1 }
if( $('#collabAudio').is(':checked') ) { collabConfig += 2 }
if( $('#collabCursor').is(':checked') ) { collabConfig += Math.pow(2, 2) }
if( $('#collabClic').is(':checked') ) { collabConfig += Math.pow(2, 3) }
if( $('#collabTile').is(':checked') ) { collabConfig += Math.pow(2, 4) }
collabConfig = collabConfig.toString(36);
if (collabConfig.length == 1) { collabConfig = '0'+collabConfig }
$('#pLCoHref').attr('href',url+'&togetherjs='+tonality+collabConfig);
$('#pLCoVal').val(url+'&togetherjs='+tonality+collabConfig);
if( $('#sLCoVal').val() ) {
$('#sLCoVal').parent().parent('.form-group').show();
$('#sLCoHref').attr('href', $('#sLCoVal').val());
};
}
$('title').append(' - '+concerto);
for(i = 0; i < movement.length; i++) {
if ( tile[i][0] != ''
&& tile[i][1] != ''
&& tile[i][2] != ''
&& tile[i][3] != ''
&& tile[i][4] != '' ) {
newTile(parseInt(tile[i][0]),parseInt(tile[i][1]),parseInt(tile[i][2]),parseInt(tile[i][3]),tile[i][4]);
}
}
updatePermalink();
$('a[href="#share"]').click( function() {
updatePermalink();
});
$('#sLBtn').on('click', function() {
shortLink = 'https://frama.link/'+tonality+'-'+(Math.floor(Date.now() / 1000).toString(36))+'-'+concerto;
/*
* FIXME
* Frama.link API ne fonctionne pas ou alors c'est la requête AJAX
*
$.ajax({
method: "POST",
url: "https://frama.link/a",
dataType: 'json',
data: { 'lsturl': $('#pLVal').val(), 'lsturl-custom': shortLink, 'format': 'json' }
})
.done(function( msg ) {
if(msg.success) {
$('#sLVal').val('https://frama.link/'+shortLink);
} else {
alert('Erreur :'+msg.msg);
}
});
*/
$('#sLVal').val(shortLink).parent().parent('.form-group').show();
$('#sLHref').attr('href', $('#sLVal').val());
});
$('#sLCoBtn').on('click', function() {
shortLink = 'https://frama.link/'+tonality+'-'+(Math.floor(Date.now() / 1000).toString(36))+'-'+concerto;
/*
* FIXME
* Frama.link API ne fonctionne pas ou alors c'est la requête AJAX
*
$.ajax({
method: "POST",
url: "https://frama.link/a",
dataType: 'json',
data: { 'lsturl': $('#pLCoVal').val(), 'lsturl-custom': shortLink, 'format': 'json' }
})
.done(function( msg ) {
if(msg.success) {
$('#sLCoVal').val('https://frama.link/'+shortLink);
} else {
alert('Erreur :'+msg.msg);
}
});
*/
$('#sLCoVal').val(shortLink).parent().parent('.form-group').show();
$('#sLCoHref').attr('href', $('#sLCoVal').val());
});
$('#collabOptions input').prop('checked',false).on('change', function() {
updatePermalink();
}); // Avoid browser prefill
$('#collabClic').on('change', function() {
if( $('#collabClic').is(':checked') ) {
$('#collabCursor').prop('checked', true);
$('label[for="collabCursor"]').addClass('text-muted');
} else {
$('label[for="collabCursor"]').removeClass('text-muted');
};
});
$('label[for="collabCursor"]').on('click', function() {
if( $(this).hasClass('text-muted') ) {
return false
}
});