Project proposals
Here are the development project that will be accepted for passing the course. The difficulty of each project is not the same: stars indicate how difficult each project is.
-
Projects must be developed in pairs.
-
You are expected to give an oral presentation of your project with a demonstration.
You can develop and host your projects on Glitch. Other (free) options for hosting your project are Heroku and Now.
Calendrier
- Difficulty:
- Keywords: ajax
Le but du projet est de définir une application permettant de gérer un calendrier personnel, un peu comme Google Calendar.
Description
Un calendrier est une suite d’événements, qui ne doivent jamais se chevaucher ou se superposer. Un événement a au moins :
- un titre,
- une date et heure de début,
- une date et heure de fin,
- un créateur.
Ces champs sont reflétés dans une table SQL. Une autre table SQL sera utilisée pour stocker les utilisateurs et leurs mots de passe.
L’application est composée de deux vues :
-
Une page pour enregistrer un nouvel utilisateur. Vous pouvez suivre le modèle déjà utilisé en TD.
-
Une page principale, présentant le planning de la semaine, et :
- soit un formulaire de login, si l’utilisateur n’est pas connecté,
- soit un lien de déconnexion, si l’utilisateur est connecté.
La page principale
Sur la page principale, le planning de la semaine courante apparaît sous la forme d’une grande table, avec une colonne par jour. En première approximation, vous pouvez découper chaque jour en 48 cases d’une demie heure chacune. Le tableau doit être généré par JavaScript. La hauteur des cases doit être fixe.
Les évènements sont représentés en colorant les plages horaires occupées, par exemple en rouge. Utilisez des classes CSS pour distinguer les cases libres des cases occupées. La première case d’un évènement doit contenir le titre et le créateur de l’évènement.
Des boutons/menus permettent de naviguer dans les semaines.
Note : Il existe d’autres solutions, que de diviser le jour en 48 plages. Par exemple vous pouvez utiliser du positionnement CSS et des hauteurs fixes. Les possibilités sont nombreuses, et permettent de réaliser des grains plus fin que la demie heure. Libre à vous de les explorer.
Ajout d’un nouvel évènement
Uniquement les utilisateurs connectés ont droit de modifier le calendrier. Il vont faire cela en interagissant avec le tableau de la semaine.
Un clic sur une case déjà occupé ne fait aucune action, ou donne un message d’erreur, au choix.
Un clic sur une case libre ouvre un formulaire (par exemple dans un modal ou dans un popup), pré-rempli avec la date et l’heure correspondant au clic, permettant en plus de préciser le titre de l’évènement, de modifier les heures de début et de fin, et éventuellement de renseigner d’autres informations (couleur, description, etc…). Après validation, une requête est envoyée au serveur et l’événement est inséré dans la base de données. Si l’insertion s’effectue avec succès, le nouvel évènement est affiché dans le tableau.
Une interaction de type AJAX et préférable pour cette action.
Attention : prêtez attention à vérifier la validité d’un évènement (format des dates, non-chevauchement, etc.) du côté serveur, et pas uniquement du côté client. Si plusieurs utilisateurs modifient en même temps le calendrier, rater cette vérification peut amener à des conflits. Affichez un message d’erreur significatif lorsque cette étape de validation ne passe pas.
Suppression d’un évènement
En plus d’afficher les informations décrites ci-dessus, uniquement pour les évènements créés par l’utilisateur connecté, donner un moyen (bouton, lien, croix, …) de supprimer l’évènement. Demander confirmation avant de supprimer. Lorsque l’utilisateur confirme, envoyer une requête, mettre à jour la base de données, et actualiser l’affichage en cas de succès.
Routes
Vous êtes libres de structurer la logique de l’application comme vous le souhaitez. Nous proposons ici un exemple de découpage en gestionnaires :
- Route
/
: présentant la page principale. - Route
/signin
: permettant de créer un nouvel utilisateur. - Route
/login
: permettant de se connecter. Redirige vers/
après un login réussi. - Route
/logout
: permettant de se déconnecter. Redirige vers/
après un logout réussi. - Route
/ajouter
: permettant d’ajouter un évènement.- Si AJAX, renvoie un code de succès/erreur.
- Si non-AJAX, redirige vers
/
après un ajout réussi.
- Route
/effacer
: permettant d’éliminer un évènement.- Si AJAX, renvoie un code de succès/erreur.
- Si non-AJAX, redirige vers
/
après un ajout réussi.
- Route
/liste
: renvoyant la liste des événements au format JSON (ou XML, ou autre), pour un traitement chez le client. Uniquement si AJAX.
Vous aurez en plus les routes statiques pour le téléchargement des contenus annexes : feuilles de style, scripts côté client, …
Ressources
Les guides des évènements
Parties optionnelles
-
Ajouter la possibilité de modifier ses propres évènements.
-
Gérer les clics glissés (clics qui commencent sur une case et qui terminent sur une autre). Les heures de début et de fin seront respectivement la plus petite et la plus grande parmi les deux cases. Utiliser des classes CSS pour visualiser la plage sélectionnée pendant le glissement.
-
Utiliser le CSS grid layout à la place d’un tableau HTML pour composer le calendrier.
-
Définir quatre niveaux d’accès au calendrier : création, modification, effacement, administration. Les administrateurs ont droit de modifier/effacer les évènements de tout le monde. Ajouter une page d’administration, accessible uniquement aux administrateurs, pour donner/enlever ces droits aux utilisateurs.
Créer un utilisateur spécial guest, qui correspond aux droits des utilisateurs non-connectés.
-
Gérer plusieurs calendriers : dans ce cas, chaque calendrier a un identifiant (par exemple toto, et sera accessible à l’adresse https://serveur-calendrier/toto).
-
Réaliser un affichage qui s’adapte à la taille de l’écran, notamment aux écrans mobiles. Ajouter de la gestion d’évènements tactiles, et tester avec un téléphone ou tablette.
-
Utiliser une base de données No-SQL (par exemple MongoDB) à la place de SQL.
-
Faire en sorte que 15 minutes avant un évènement, un message d’alerte soit affiché sur la page.
-
Utiliser AJAX pour ne télécharger de la base de données que les évènements de la semaine visualisée.
Ou, encore mieux : pour rendre l’interface plus fluide, vous pouvez télécharger en même temps la semaine courante, la semaine précédente et la semaine suivante. Lorsque l’utilisateur navigue dans les semaines, vous utilisez la liste d’évènements stockée en cache pour afficher la nouvelle semaine immédiatement, et vous lancez une nouvelle requête AJAX pour télécharger le contenu du nouveau bloc de trois semaines. Gardez à l’esprit que le contenu d’une semaine peut avoir changé entre le moment où les données ont été téléchargées, et le moment où l’utilisateur demande une navigation.
-
Faire en sorte qu’à chaque modification d’événement, tous les navigateurs qui affichent le même calendrier soient mis à jour automatiquement.
Find my Friends
- Difficulty:
- Keywords: mobile, geolocation, multi-user
Le but de ce projet est de développer une application similaire à l’application iPhone Find my friends.
Il s’agit d’une application pour appareils dotés de géolocalisation. L’application utilise ces données pour montrer en temps réel la distance et la direction des autres utilisateurs connectés.
Afin de pouvoir tester l’application, il est impératif de disposer de plusieurs appareils munis de géolocalisation. Puisque les APIs utilisées dans ce projet sont récentes, il est important que les appareils utilisés pour tester aient un navigateur relativement récent (Firefox, Chrome ou Safari).
L’utilisation d’une base de données n’est pas obligatoire pour cette application.
Description
En imitant le modèle des chats, l’application compartimente les utilisateurs dans des chambres. Chaque chambre sera identifiée par une URL du type
http://application.com/aeadfw23x
où aeadfw23x
est l’identifiant de la chambre. Les identifiants
peuvent être générés aléatoirement, ou créés par les utilisateurs.
-
Lorsque le client se connecte à l’application, deux possibilités lui sont offertes :
- Rejoindre une chambre déjà existante,
- Créer une nouvelle chambre.
Note : C’est votre responsabilité que définir le comportement lorsque un utilisateur essaye de créer une chambre déjà existante.
Note : Limitez le nombre d’utilisateurs par chambre à 2.
-
Chacun des deux utilisateurs connectés à une chambre communique en continu au serveur sa position GPS. Le serveur transmet cette information à l’autre utilisateur.
-
Chaque utilisateur, à la réception de la position de l’autre, visualise sa position avec une flèche pointant dans sa direction, et la distance de celui-ci.
Note : afin de pouvoir diriger la flèche, vous devez accéder aux données de la boussole de l’appareil. En première approximation, vous pouvez afficher un cap à la place de la flèche (par ex.: 20° Nord), ce qui ne nécessite pas de boussole.
Note : cette partie nécessite de savoir faire des calculs géodésiques. C’est des mathématiques de niveau L1, mais si vous y êtes allergiques, ce projet n’est pas pour vous.
L’API de géolocalisation n’étant activée que pour des sites en https, il est donc conseillé d’utiliser Glitch pour tester. D’autres options pour héberger votre application sont:
Resources
-
Pour la communication entre clients, il est conseillé d’utiliser les WebSockets.
-
Les données de géolocalisation doivent être interrogées avec l’API web https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation.
-
L’orientation de l’appareil doit être interrogée avec l’API web https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation.
Parties optionnelles
-
Faire vibrer les appareils lorsque la distance est inférieure à un seuil.
-
Permettre la privatisation d’une chambre avec mot de passe (nécessite l’ajout d’une base de données).
-
Autoriser plus de 2 utilisateurs par chambre, et afficher une flèche pour chacun.
-
Ajouter une visualisation des positions sur carte.
JSON-Twitter
- Difficulty:
- Keywords: ajax, json
The goal of this project is to code a Twitter-like application with no server-side rendering. The server only offers a JSON-based (REST) API to store and retrieve messages (tweets) from a database. All the HTML rendering is done on the client side using the DOM API, or a template engine such as nunjucks.
Description
A Twitter-clone is simply a bulletin-board where everyone can post and read messages. A message contains at least:
- a date,
- an author,
- a text.
These fields will be stored as columns in a SQL table. A second SQL table will be used for storing users, their name and their password.
The server-side only offers a JSON API for creating/verifying users, and for storing/retrieving messages.
The client interface must have the following views:
- A view for creating a new user;
- A view showing all the messages, from the most recent to the most ancient;
- A view to compose a new message.
Server API
The only non-JSON routes offered by the server will serve static assets:
/pub/client.js
, the JavaScript code of the client UI;/pub/client.css
, the CSS code of the client UI;/
, the HTML code to start the client (a mostly empty HTML document, linking toclient.js
andclient.css
;- any other needed asset, such as images, etc.
The rest of the server API will be JSON based. It will have, at least, the following routes:
/signin
(POST) for creating a new user;/messages
(GET) for getting the list of all messages, in chronological order;/login
(POST) for verifying the user credentials;/post
(POST) for posting a new message (this route must verify the user password).
Client API
Upon visiting the /
URL, the client-side code in client.js
loads
and builds the user interface.
All interactions with the server must be done via AJAX, using either
the XMLHttpRequest
interface,
or the fetch
API.
-
The main page shows the list of all messages, and menus to
- login/logout,
- create an account (hidden if the user is logged in),
- post a new message (hidden if the user is not logged in).
This page can be generated using the DOM API, or using a client-side nunjucks template.
-
When the user clicks on the create account menu, a form is shown (as a modal, or replacing the main page) asking to enter (at least) a username and a password. When the user submits the form, an AJAX request is sent to
/signin
, then a confirmation or error message is shown depending on the result. -
When the user clicks on the login menu, a form is shown asking to enter a username and a password. The data is sent to
/login
, if the request is successful the client stores the login and password in the local storage, otherwise it show an error message. -
When the user clicks on the compose message menu, a form is shown asking to enter text. Username and password are retrieved from the local storage, and everything is sent to
/post
. Then a message is shown according to whether the action was successful or not. -
When the user clicks on the logout menu, the username and password are wiped from the local storage, and the interface is updated.
It is very important that all these interactions are done through AJAX.
Resources
- Guide on the
XMLHttpRequest
interface; - Guide on the
fetch
API;
Optional improvements
-
Adapt your interface to small screens.
-
Use the
restify
module instead ofexpress
. -
It is very bad practice to store username and password in the local storage. Modify
/login
so that it returns a session identifier, and store this identifier in the local storage instead. When posting through/post
, send the session identifier to authenticate the request.Given that all interaction is done through AJAX, the module
express-session
will not help you. You can either write your own session store (in memory or in the database), or use a library such as Passport. -
Add the possibility to send private messages to users.
-
Limit the number of messages returned by
/messages
, dynamically load more messages when the user scrolls to the bottom of the list (see theonscroll
event). -
Automatically refresh the list of messages every 5 seconds.
-
Dynamically update the list of messages using WebSockets (no polling). Show a notification when a user receives a private message (see web notifications).
-
Use a No-SQL database (e.g., MongoDB) instead of a SQL one.
Multi-player Tetris
- Difficulty:
- Keywords: multi-player, real time, game
The goal of this project is to develop a real-time multi-player game. We will reinterpret the classic Tetris game in a multi-player fashion.
Description of the game
Tetris is a classic video game for one player (an arcade). You will find a detailed description of the game at its Wikipedia page.
We will implement a two-player variant of the game with a simplified game play. Each player will play on its own grid, while seeing both grids. The list of incoming blocks will be shared: the first player to land a block will receive the next one in line. Players control the game through the keyboard, with the usual controls: left/right to move the pieces, up/down to rotate them, space to land them immediately.
The game ends when one of the two players reaches the top of the grid, thus loosing the game.
Description of the project
You will create an online game similar to the one developed in the tutorials. It will contain:
- A page to register a new player;
- A page showing the list of online players, the number of wins/losses, and whatever other information may be of interest;
- A mechanism for logging in;
- A mechanism for defying an opponnent;
- An interface to play the game.
Be very careful when handling the state of the game. Tetris needs an internal clock for moving blocks down the grids. If the clients were solely responsible for keeping this clock, it would be very easy for them to get desynchronized, or, worse, cheat.
The game interface will be coded in JavaScript. To make things simpler, you can restrict the types of blocks available, and have a fixed timer that does not accelerate as the game progresses. Improvements to the game play are proposed in the optional section.
Resources
-
For the in game client-server communication it is best to use WebSockets. You are free to use whatever websocket library you like.
-
To draw the game, you can use any of the following techniques:
- An HTML table,
- A CSS grid layout,
- An
<svg>
element, possibily using a library, - A
<canvas>
element, see this tutorial.
Optional improvements
-
Implement the full list of tetris blocks.
-
Keep a score for each player during a game, computed as the number of lines won by that player. When the game ends, the winner earns the sum of the two scores.
-
Have the internal clock speed up as the player scores get higher. Weight the player scores by the clock speed (the faster the clock goes, the more valuable a line is).
-
Whenever a player wins n lines, add n-1 lines to the bottom of the opponent’s grid.
-
Implement a version of the game for up to four players.
-
Use a No-SQL database (e.g., MongoDB) instead of a SQL one.
-
Adapt the game for playing on a small touch screen (e.g., a smartphone), using Touch gestures.
-
Add the possibility of controlling the game through a gamepad or joystick (see the Gamepad API).
-
Implement a 3D version of the game, possibly using the three.js library.