Implement saving polls in localstorage and finding them

Also, this brings VueJS and MomentJS in Framadate, 🍾 🎉

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2018-04-06 16:01:09 +02:00
parent 6dd8fb1723
commit c1ea6ae2a8
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
9 changed files with 317 additions and 16 deletions

View File

@ -55,5 +55,6 @@ if (!empty($_POST['mail'])) {
$smarty->assign('title', __('Homepage', 'Where are my polls'));
$smarty->assign('message', $message);
$smarty->assign('locale', $locale);
$smarty->display('find_polls.tpl');

View File

@ -1,9 +1,62 @@
$(document).ready(function() {
/**
* Markdown Editor
* @type {MDEWrapper}
*/
wrapper = new MDEWrapper($('.js-desc textarea')[0], $('#rich-editor-button'), $('#simple-editor-button'));
var firstOpening = true;
/**
* Save a list of admin polls inside LocalStorage
* @param adminPolls
*/
function setAdminPolls(adminPolls) {
localStorage.setItem('admin_polls', JSON.stringify(adminPolls));
}
/**
* Add an admin poll inside LocalStorage
* @param adminPoll
*/
function addAdminPoll(adminPoll) {
var adminPolls = JSON.parse(localStorage.getItem('admin_polls'));
/**
* Test if the poll is already inside the list
*/
var index = adminPolls.findIndex(function (existingPoll) {
return existingPoll.url === adminPoll.url;
});
if (index === -1) {
adminPolls.push(adminPoll);
} else { // if the poll is already present, we need to update the last access date
adminPolls[index] = adminPoll;
}
setAdminPolls(adminPolls);
}
var adminPoll = {
url: window.location.href,
title: $('#title-form h3').get(0).childNodes[0].nodeValue,
accessed: (new Date()).toISOString()
};
if (!localStorage.getItem('admin_polls')) {
setAdminPolls([adminPoll]);
} else {
addAdminPoll(adminPoll);
}
/**
* Initiate popovers
*/
$('[data-toggle="popover"]').popover();
/**
* Create node with text to use the Clipboard API
* @param text
* @returns {HTMLPreElement}
*/
function createNode(text) {
var node = document.createElement('pre');
node.style.width = '1px';
@ -14,6 +67,10 @@ $(document).ready(function() {
return node;
}
/**
* Copy a Node to use for Clipboard API
* @param node
*/
function copyNode(node) {
var selection = getSelection();
selection.removeAllRanges();
@ -26,6 +83,10 @@ $(document).ready(function() {
selection.removeAllRanges();
}
/**
* Copy a text inside the clipboard
* @param text
*/
function copyText(text) {
var node = createNode(text);
document.body.appendChild(node);

View File

@ -18,6 +18,54 @@
$(document).ready(function () {
/**
* Save a list of polls inside LocalStorage
* @param polls
*/
function setPolls(polls) {
localStorage.setItem('polls', JSON.stringify(polls));
}
/**
* Add an poll inside LocalStorage
* @param poll
*/
function addPoll(poll) {
var polls = JSON.parse(localStorage.getItem('polls'));
/**
* Test if the poll is already inside the list
*/
var index = polls.findIndex(function (existingPoll) {
return existingPoll.url === poll.url;
});
if (index === -1) {
polls.push(poll);
} else { // if the poll is already present, we need to update the last access date
polls[index] = poll;
}
setPolls(polls);
}
var poll = {
url: window.location.href,
title: $('#title-form h3').get(0).childNodes[0].nodeValue,
accessed: (new Date()).toISOString()
};
function isAdmin() {
return $('.jumbotron').hasClass('bg-danger');
}
if (!isAdmin()) {
if (!localStorage.getItem('polls')) {
setPolls([poll]);
} else {
addPoll(poll);
}
}
$('#poll_form').submit(function (event) {
var name = $('#name').val().trim();

1
js/moment-with-locales.min.js vendored Normal file

File diff suppressed because one or more lines are too long

6
js/vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -165,7 +165,20 @@
"List of your polls": "List of your polls",
"PS: this email has been sent because you or someone else asked to get back the polls created with your email address.": "PS: this email has been sent because you or someone else asked to get back the polls created with your email address.",
"Polls sent": "Polls sent",
"Send me my polls": "Send me my polls"
"Send me my polls": "Send me my polls",
"Send my polls by email": "Send my polls by email",
"Polls saved inside this browser": "Polls saved inside this browser",
"Local Storage Help": "To help you find your previous polls, we save inside your browser each poll you create or access to. These informations are saved only inside this browser. The informations saved are the following:",
"Local Storage Help Information Title": "The title of the poll",
"Local Storage Help Information Address": "It's address",
"Local Storage Help Information Accessed": "The date on which you accessed or created the poll",
"Local Storage Help Delete": "To delete this information, you can click the bin matching each line or click the « delete my polls index » option. This won't delete your polls.",
"Title": "Title",
"Address": "Address",
"Last access date": "Last access date",
"Remove poll from index": "Remove poll from index",
"There are no polls saved inside your browser yet": "There are no polls saved inside your browser yet",
"Remove all polls from this browser": "Remove all my polls from this browser's index"
},
"Generic": {
"(in the format name@mail.com)": "(in the format name@mail.com)",

View File

@ -165,7 +165,20 @@
"List of your polls": "Liste de vos sondages",
"PS: this email has been sent because you or someone else asked to get back the polls created with your email address.": "PS : ce mail a été envoyé parce que vous ou quelqu'un d'autre avez demandé la récupération des sondages créés à l'aide de votre adresse email.",
"Polls sent": "Sondages envoyés",
"Send me my polls": "Envoyer mes sondages"
"Send me my polls": "Envoyer mes sondages",
"Send my polls by email": "Envoyer mes sondages par courriel",
"Polls saved inside this browser": "Sondages stockés dans ce navigateur",
"Local Storage Help": "Afin de vous aider à retrouver vos sondages précédents, nous sauvegardons dans votre navigateur internet chaque sondage que vous créez ou auquel vous accédez. Ces informations sont sauvegardées uniquement dans ce navigateur. Les informations sauvegardées sont les suivantes:",
"Local Storage Help Information Title": "Le titre du sondage",
"Local Storage Help Information Address": "Son adresse",
"Local Storage Help Information Accessed": "La date à laquelle vous avez créé ou avez accédé au sondage",
"Local Storage Help Delete": "Pour supprimer ces informations, vous pouvez cliquer sur la poubelle en face de chaque sondage ou bien cliquer sur le bouton « supprimer l'index de mes sondages ». Cela ne supprimera pas vos sondages",
"Title": "Titre",
"Address": "Adresse",
"Last access date": "Date de dernier accès",
"Remove poll from index": "Supprimer le sondage de l'index",
"There are no polls saved inside your browser yet": "Il n'y a pas encore de sondages sauvegardés dans votre navigateur",
"Remove all polls from this browser": "Supprimer tous mes sondages de l'index de ce navigateur"
},
"Generic": {
"(in the format name@mail.com)": "(au format nom@mail.com)",

View File

@ -165,7 +165,20 @@
"List of your polls": "Liste de vos sondages",
"PS: this email has been sent because you or someone else asked to get back the polls created with your email address.": "PS : ce mail a été envoyé parce que vous ou quelqu'un d'autre avez demandé la récupération des sondages créés à l'aide de votre adresse email.",
"Polls sent": "Sondages envoyés",
"Send me my polls": "Envoyer mes sondages"
"Send me my polls": "Envoyer mes sondages",
"Send my polls by email": "Envoyer mes sondages par courriel",
"Polls saved inside this browser": "Sondages stockés dans ce navigateur",
"Local Storage Help": "Afin de vous aider à retrouver vos sondages précédents, nous sauvegardons dans votre navigateur internet chaque sondage que vous créez ou auquel vous accédez. Ces informations sont sauvegardées uniquement dans ce navigateur. Les informations sauvegardées sont les suivantes:",
"Local Storage Help Information Title": "Le titre du sondage",
"Local Storage Help Information Address": "Son adresse",
"Local Storage Help Information Accessed": "La date à laquelle vous avez créé ou avez accédé au sondage",
"Local Storage Help Delete": "Pour supprimer ces informations, vous pouvez cliquer sur la poubelle en face de chaque sondage ou bien cliquer sur le bouton « supprimer l'index de mes sondages ». Cela ne supprimera pas vos sondages",
"Title": "Titre",
"Address": "Adresse",
"Last access date": "Date de dernier accès",
"Remove poll from index": "Supprimer le sondage de l'index",
"There are no polls saved inside your browser yet": "Il n'y a pas encore de sondages sauvegardés dans votre navigateur",
"Remove all polls from this browser": "Supprimer tous mes sondages de l'index de ce navigateur"
},
"Generic": {
"(in the format name@mail.com)": "(au format nom@mail.com)",

View File

@ -1,22 +1,167 @@
{extends file='page.tpl'}
{block name="header"}
<script src="{'js/vue.min.js'|resource}"></script>
<script src="{'js/moment-with-locales.min.js'|resource}"></script>
{/block}
{block name=main}
{if !empty($message)}
<div class="alert alert-dismissible alert-{$message->type|html}" role="alert">{$message->message|html}{if $message->link != null}<br/><a href="{$message->link}">{$message->link}</a>{/if}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">&times;</span></button></div>
{/if}
<form action="" method="post">
<div id="local-poll">
<h3>
{__('FindPolls', 'Polls saved inside this browser')}
<a href="#" data-toggle="modal" data-target="#localstorage_help_modal"><i class="glyphicon glyphicon-info-sign"></i></a><!-- TODO Add accessibility -->
</h3>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<div class="form-group">
<div class="input-group">
<label for="mail" class="input-group-addon">{__('Generic', 'Your email address')}</label>
<input type="email" class="form-control" id="mail" name="mail" autofocus>
<div class="pull-right">
<button @click="removeAllPolls" class="btn btn-sm btn-danger">{__('FindPolls', 'Remove all polls from this browser')}</button>
</div>
</div>
<div v-if="polls.length > 0">
<h4>Sondages votés</h4>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<thead>
<tr>
<td>{__('FindPolls', 'Title')}</td>
<td>{__('FindPolls', 'Address')}</td>
<td>{__('FindPolls', 'Last access date')}</td>
<td>{__('FindPolls', 'Remove poll from index')}</td>
</tr>
</thead>
<tbody>
<tr v-for="poll in polls">
<td>%% poll.title %%</td>
<td><a :href="poll.url">%% poll.url %%</a></td>
<td>%% poll.accessed | date %%</td>
<td><button class="btn btn-sm btn-danger" @click="removePoll(poll.url)"><i class="glyphicon glyphicon-trash"></i><span class="sr-only">{__('Generic', 'Remove')}</span></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="adminPolls.length > 0">
<h4>Sondages créés</h4>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<thead>
<tr>
<td>{__('FindPolls', 'Title')}</td>
<td>{__('FindPolls', 'Address')}</td>
<td>{__('FindPolls', 'Last access date')}</td>
<td>{__('FindPolls', 'Remove poll from index')}</td>
</tr>
</thead>
<tbody>
<tr v-for="poll in adminPolls">
<td>%% poll.title %%</td>
<td><a :href="poll.url">%% poll.url %%</a></td>
<td>%% poll.accessed | date %%</td>
<td><button class="btn btn-sm btn-danger" @click="removeAdminPoll(poll.url)"><i class="glyphicon glyphicon-trash"></i><span class="sr-only">{__('Generic', 'Remove')}</span></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="polls.length === 0 && adminPolls.length === 0" class="alert alert-info">
{__('FindPolls', 'There are no polls saved inside your browser yet')}
</div>
</div>
<div>
<h3>{__('FindPolls', 'Send my polls by email')}</h3>
{if !empty($message)}
<div class="alert alert-dismissible alert-{$message->type|html}" role="alert">{$message->message|html}{if $message->link != null}<br/><a href="{$message->link}">{$message->link}</a>{/if}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">&times;</span></button></div>
{/if}
<form action="" method="post">
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<div class="form-group">
<div class="input-group">
<label for="mail" class="input-group-addon">{__('Generic', 'Your email address')}</label>
<input type="email" class="form-control" id="mail" name="mail" autofocus>
</div>
</div>
</div>
<div class="col-md-6 col-md-offset-3 text-center">
<button type="submit" class="btn btn-success">{__('FindPolls', 'Send me my polls')}</button>
</div>
</div>
</form>
</div>
<div id="localstorage_help_modal" class="modal fade">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">{__('FindPolls', 'Polls saved inside this browser')}</h4>
</div>
<div class="modal-body">
<div class="alert alert-info">
<p>{__('FindPolls', 'Local Storage Help')}</p>
<ul>
<li>{__('FindPolls', 'Local Storage Help Information Title')}</li>
<li>{__('FindPolls', 'Local Storage Help Information Address')}</li>
<li>{__('FindPolls', 'Local Storage Help Information Accessed')}</li>
</ul>
<p>{__('FindPolls', 'Local Storage Help Delete')}</p>
</div>
</div>
</div>
<div class="col-md-6 col-md-offset-3 text-center">
<button type="submit" class="btn btn-success">{__('FindPolls', 'Send me my polls')}</button>
</div>
<!-- /.modal-content -->
</div>
</form>
<!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
moment.locale('{$locale}');
var app = new Vue({
delimiters: ['%%', '%%'],
el: '#local-poll',
data() {
return {
polls: [],
adminPolls: [],
};
},
created() {
this.polls = JSON.parse(localStorage.getItem('polls'));
this.adminPolls = JSON.parse(localStorage.getItem('admin_polls'));
},
filters: {
date: function(value) {
return moment(value).format('LLLL');
}
},
methods: {
removePoll(pollKey) {
var index = this.polls.findIndex(function (existingPoll) {
return existingPoll.url === pollKey;
});
if (index === -1) {
console.error('Oh no, the poll doesn\'t exist !');
} else { // if the poll is already present, we need to update the last access date
this.polls.splice(index, 1);
localStorage.setItem('polls', JSON.stringify(this.polls));
}
},
removeAdminPoll(pollKey) {
var index = this.adminPolls.findIndex(function (existingPoll) {
return existingPoll.url === pollKey;
});
if (index === -1) {
console.error('Oh no, the admin poll doesn\'t exist !');
} else { // if the poll is already present, we need to update the last access date
this.adminPolls.splice(index, 1);
localStorage.setItem('admin_polls', JSON.stringify(this.adminPolls));
}
},
removeAllPolls() {
this.polls.splice(0, this.polls.length);
this.adminPolls.splice(0, this.adminPolls.length);
localStorage.setItem('admin_polls', JSON.stringify(this.adminPolls));
localStorage.setItem('polls', JSON.stringify(this.polls));
}
}
});
</script>
{/block}