notification param in talent/me + delayed trigger on 3 times entreprise viewed

This commit is contained in:
2018-09-18 16:48:56 +02:00
parent b1185018de
commit 1e03451b37
19 changed files with 871 additions and 602 deletions
+3
View File
@@ -0,0 +1,3 @@
Todo:
☐ Item
@@ -166,6 +166,10 @@
<source>company.account.password.modify.label</source>
<target>Modifier le mot de passe</target>
</trans-unit>
<trans-unit id="company.account.notifications.title">
<source>company.account.notifications.title</source>
<target>Notifications</target>
</trans-unit>
<trans-unit id="profile.edit.submit">
<source>profile.edit.submit</source>
<target>Sauvegarder mon profil</target>
@@ -188,6 +188,10 @@
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script>
<script type="text/javascript">
$(document).ready(function(){
//asking for push
EdeclicLib = window.EdeclicLib || {};
EdeclicLib.delayedAsk();
//
$('.tooltipped').tooltip();
$.get( "{{ path('ad_ajaxRecStat',{'id': ad.id }) }}", function( data ) {});
if ($('#modal-answer').length > 0) {
@@ -1,5 +1,5 @@
<!-- Parameters used in EdeclicPushAndNotificationClient.js -->
<!-- props_settings.html.twig Parameters used in EdeclicPushAndNotificationClient.js -->
<div id="pushParams"
data-service-worker-url="{{ app.request.uriForPath('/Edeclic-service-worker.js') | replace({'/app_dev.php': ''}) }}"
data-delete-subscription-url="{{ url('delete-subscription') }}"
@@ -1,8 +1,8 @@
{% extends 'talent/base_dashboard_talent.html.twig' %}
{% block dashContent %}
{% include 'default/props_settings.html.twig' %}
{% include 'default/flash_message.html.twig' %}
<div class=" row bg-bordered p-20">
{#<h1 class="alttitle">{{ 'profile.talent.account.title'|trans }}</h1>#}
@@ -11,18 +11,71 @@
<h4>{{ 'company.account.password.modify'|trans }}</h4>
{% if form_errors(formPw) %}
<div class="card-panel">
<span class="red-text text-darken-2">
{{ form_errors(formPw) }}
</span>
<span class="red-text text-darken-2">
{{ form_errors(formPw) }}
</span>
</div>
{% endif %}
{{ form_start(formPw) }}
{{ form_rest(formPw) }}
<br/>
<input class="btn btn-default" type="submit"
value="{{ 'company.account.password.modify.label'|trans }}"/>
<input class="btn btn-default" type="submit" value="{{ 'company.account.password.modify.label'|trans }}"/>
{{ form_end(formPw) }}
</div>
</div>
</div>
<div class=" row bg-bordered p-20">
<div class="row flexcontainer">
<div class="col s12">
<h4>{{ 'company.account.notifications.title'|trans }}</h4>
<br/>
<input type="checkbox" id="notificationChecked" name="notificationChecked" {{isNotificationAllowed ? "checked=checked":""}}/>
<label for="notificationChecked">Autoriser les notificaitons</label>
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script type="text/javascript">
$('#notificationChecked').on('click', function (event) {
let EdeclicLib = window.EdeclicLib;
let notifConsent = $('#notificationChecked').is(":checked");
if (notifConsent == true) {
//ask for subscription
var promise1 = new Promise(EdeclicLib.askForNotifications)
.then(() => $('#notificationChecked').prop('checked', true), () => $('#notificationChecked').prop('checked', false))
.catch((err) => {
$('#notificationChecked').prop('checked', false);
alert(err);
});
} else {
//require unsubscription
EdeclicLib.unsubscribe();
$.ajax({
async: true,
type: 'POST',
url: '{{ url('talent_notification_consent') }}',
data: JSON.stringify({'notificationConsent': false}),
success: function (data) {
data = JSON.parse(data);
$('#notificationChecked').prop('checked', data['notificationConsent']);
},
contentType: "application/json",
dataType: 'json'
});
}
});
</script>
{% endblock %}
@@ -26,7 +26,7 @@ assetic:
- 'js/global.js'
- 'js/register.js'
- 'js/tags.js'
# - 'js/Edeclic-service-worker.js'
- 'js/EdeclicTools.js'
- 'js/EdeclicPushAndNotificationClient.js'
company:
@@ -95,17 +95,52 @@ class TalentController extends Controller
{
$userManager = $this->get('fos_user.user_manager');
$user = $this->getUser();
$formFactory = $this->container->get('fos_user.change_password.form.factory');
$formPw = $formFactory->createForm();
$formPw->setData($user);
if ($formPw->isSubmitted() && $formPw->isValid()) {
$userManager->updateUser($user);
}
$manager = $this->container->get("app.user_subscription_manager");
$subscriptions = $manager->findByUser($user);
$isNotificationAllowed = !empty($subscriptions);
return $this->render('talent/my_account.html.twig', [
'formPw' => $formPw->createView(),
'isNotificationAllowed' => $isNotificationAllowed
]);
}
/**
* @Route("/talent/me/notificationConsent", name="talent_notification_consent")
*/
public function notificationConsent(Request $request)
{
$data = json_decode($request->getContent(), true);
$consent = $data["notificationConsent"];
if($consent === false)
{
//delete all existing user_subscription
$user = $this->getUser();
$manager = $this->container->get("app.user_subscription_manager");
$subscriptions = $manager->findByUser($user);
foreach ($subscriptions as $key => $value) {
$manager->delete($value);
}
}
$encode = array('notificationConsent' => $consent);
return new JsonResponse(json_encode($encode));
}
/**
* @Route("/talent/me/espace-oe", name="talent_ad_space")
*/
@@ -0,0 +1,23 @@
<?php
// src/AppBundle/Form/TaskType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
class NotificationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$options['data'];
$builder
->add('notifications', CheckboxType::class, array(
'label' => 'Autoriser les notifications'
));
}
}
@@ -54,8 +54,8 @@ class UserSubscriptionRepository extends \Doctrine\ORM\EntityRepository
CASE WHEN u.lastname IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN u.photo IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN u.username IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.addresses IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.alias IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.brandName IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.businessName IS NOT NULL THEN 1 ELSE 0 END +
@@ -3,134 +3,145 @@
/// inspired by https://github.com/gauntface/web-push-book
///
; (function () {
"use strict";
"use strict";
function focusWindow(event) {
const url = event.notification.data["link"];
const urlToOpen = new URL(url, self.location.origin).href;
function focusWindow(event) {
const url = event.notification.data["link"];
const urlToOpen = new URL(url, self.location.origin).href;
const promiseChain = clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let matchingClient = null;
const promiseChain = clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let matchingClient = null;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
event.waitUntil(promiseChain);
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
event.waitUntil(promiseChain);
}
function isClientFocused() {
return clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.focused) {
clientIsFocused = true;
break;
}
}
return clientIsFocused;
});
}
function demoMustShowNotificationCheck(event) {
const promiseChain = isClientFocused()
.then((clientIsFocused) => {
if (clientIsFocused) {
console.log('Don\'t need to show a notification.');
//could alert
demoSendMessageToPage(event);
return;
}
// Client isn't focused, we need to show a notification.
return self.registration.showNotification(
event.data.json().notification.title,
event.data.json().notification);
});
event.waitUntil(promiseChain);
}
function demoSendMessageToPage(event) {
const promiseChain = isClientFocused()
.then((clientIsFocused) => {
if (clientIsFocused) {
clients.matchAll({
type: 'window',
includeUncontrolled: true
}).then((windowClients) => {
function isClientFocused() {
return clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.focused) {
console.log('Posting message to page');
windowClient.postMessage(event.data.json().notification
);
clientIsFocused = true;
break;
}
}
return clientIsFocused;
});
}
function demoMustShowNotificationCheck(event) {
const promiseChain = isClientFocused()
.then((clientIsFocused) => {
if (clientIsFocused) {
console.log('Don\'t need to show a notification.');
//could alert
demoSendMessageToPage(event);
return;
}
// Client isn't focused, we need to show a notification.
return self.registration.showNotification(
event.data.json().notification.title,
event.data.json().notification);
});
event.waitUntil(promiseChain);
}
function demoSendMessageToPage(event) {
const promiseChain = isClientFocused()
.then((clientIsFocused) => {
if (clientIsFocused) {
clients.matchAll({
type: 'window',
includeUncontrolled: true
}).then((windowClients) => {
let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.focused) {
console.log('Posting message to page');
windowClient.postMessage(event.data.json().notification
);
}
}
});
} else {
return self.registration.showNotification('No focused windows', {
body: 'Had to show a notification instead of messaging each page.'
});
}
});
} else {
return self.registration.showNotification('No focused windows', {
body: 'Had to show a notification instead of messaging each page.'
});
event.waitUntil(promiseChain);
}
self.addEventListener('push', function (event) {
demoMustShowNotificationCheck(event);
});
self.addEventListener('notificationclick', function (event) {
ga('send', 'event', {
eventCategory: 'Push clicked',
eventAction: 'click',
eventLabel: event.notification.data["link"]
});
event.notification.close();
switch (event.notification.tag) {
case 'open-window':
focusWindow(event);
break;
default:
//
break;
}
});
event.waitUntil(promiseChain);
}
const notificationCloseAnalytics = () => {
return Promise.resolve();
};
self.addEventListener('push', function(event) {
demoMustShowNotificationCheck(event);
});
self.addEventListener('notificationclick', function(event) {
event.notification.close();
switch(event.notification.tag) {
case 'open-window':
focusWindow(event);
break;
default:
//
break;
}
});
const notificationCloseAnalytics = () => {
return Promise.resolve();
};
self.addEventListener('notificationclose', function(event) {
const dismissedNotification = event.notification;
console.log('notificationclose.');
const promiseChain = notificationCloseAnalytics();
event.waitUntil(promiseChain);
});
self.addEventListener('notificationclose', function (event) {
const dismissedNotification = event.notification;
ga('send', 'event', {
eventCategory: 'Push close',
eventAction: 'click',
eventLabel: event.notification.data["link"]
});
const promiseChain = notificationCloseAnalytics();
event.waitUntil(promiseChain);
});
})()
+299 -230
View File
@@ -421,270 +421,339 @@ $('#ad_soft_publicTag').materialtags({
$('#ad_privateTag').materialtags({
maxTags: 5
});
///
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
d.extend(EdeclicLib, {
/* GESTION des cookies pour la modal du tuto */
setCookie: function (name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
},
getCookie: function (name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
},
eraseCookie: function (name) {
document.cookie = name + '=; Max-Age=-99999999;';
}
})
}(jQuery);
/// EdeclicPushAndNotificationClient.js
/// A push and notification client
/// inspired by https://github.com/gauntface/web-push-book
///
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
; (function () {
"use strict";
console.log("- A push and notification client - ");
var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
function AskForNotifications() {
console.log('AskForNotifications');
if (!IsFeatureDetected()) {
//alert feature unavailable
alert("Push feature not available on your side");
return;
}
d.extend(EdeclicLib, {
var conf = document.getElementById('pushParams');
if (conf === null) {
console.warn('The pushParams div is not found. can\'t get datadash config.');
return;
}
publicKey = conf.dataset.pushPublicKey;
saveUrl = conf.dataset.saveSubscriptionUrl;
deleteUrl = conf.dataset.deleteSubscriptionUrl;
serviceWorkerUrl = conf.dataset.serviceWorkerUrl;
askForNotifications: function (resolve, reject) {
var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
return Promise.all([
registerServiceWorker(),
getNotificationPermissionState()
])
.then(function (results) {
const registration = results[0];
const currentPermissionState = results[1];
if (currentPermissionState === 'denied') {
console.warn('The notification permission has been blocked. Nothing we can do.');
alert("The notification permission has been blocked. Please, review your settings.");
if (!IsFeatureDetected()) {
//alert feature unavailable
alert("Votre navigateur ne permet pas d'envoyer des push.");
reject();
return;
}
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
promiseChain
.then(subscribeUserToPush)
.then(function (subscription) {
if (subscription) {
return sendSubscriptionToBackEnd(subscription)
.then(function () {
return subscription;
});
var conf = document.getElementById('pushParams');
if (conf === null) {
console.warn('The pushParams div is not found. can\'t get datadash config.');
reject();
return;
}
publicKey = conf.dataset.pushPublicKey;
saveUrl = conf.dataset.saveSubscriptionUrl;
deleteUrl = conf.dataset.deleteSubscriptionUrl;
serviceWorkerUrl = conf.dataset.serviceWorkerUrl;
return Promise.all([
registerServiceWorker(),
getNotificationPermissionState()
])
.then(function (results) {
const registration = results[0];
const currentPermissionState = results[1];
if (currentPermissionState === 'denied') {
console.warn('The notification permission has been blocked. Nothing we can do.');
alert("Les notifications sont désactivés, veuillez modifier vos paramètres pour bénéficier de cette fonctionnalité.");
reject();
return;
}
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
return subscription;
})
.then(function (subscription) {
// We got a subscription AND it was sent to our backend,
// re-enable our UI and set up state.
console.log('SUBSCRIPTION', subscription);
})
.catch(function (err) {
console.error('Failed to subscribe the user.', err);
promiseChain
.then(subscribeUserToPush)
.then(function (subscription) {
if (subscription) {
return sendSubscriptionToBackEnd(subscription)
.then(function () {
return subscription;
});
}
return subscription;
})
.then(function (subscription) {
// We got a subscription AND it was sent to our backend,
// re-enable our UI and set up state.
console.log('SUBSCRIPTION', subscription);
resolve();
return;
})
.catch(function (err) {
console.error('Failed to subscribe the user.', err);
reject();
return;
});
// if (currentPermissionState !== 'granted') {
// // If permission isn't granted then we can't be subscribed for Push.
// console.log("permission isn't granted then we can't be subscribed for Push.");
// return;
// }
},
reject
).catch(function (err) {
console.log('Unable to register the service worker: ' + err);
reject();
return;
});
if (currentPermissionState !== 'granted') {
// If permission isn't granted then we can't be subscribed for Push.
console.log("permission isn't granted then we can't be subscribed for Push.");
}
}
).catch(function (err) {
console.log('Unable to register the service worker: ' + err);
});
function IsFeatureDetected() {
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
console.info("Service Worker isn't supported on this browser, disable or hide UI.");
return false;
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
console.info("Push isn't supported on this browser, disable or hide UI.");
return false;
}
console.info("Push and serviceWorker supported on this browser.");
return true;
}
//https://stackoverflow.com/questions/39136625/service-worker-registration-failed
function registerServiceWorker() {
console.log('registerServiceWorker');
return navigator.serviceWorker.register(serviceWorkerUrl)
.then(function (registration) {
console.log('Service worker successfully registered.');
registration.update();
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
function IsFeatureDetected() {
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
console.info("Service Worker isn't supported on this browser, disable or hide UI.");
return false;
}
});
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
console.info("Push isn't supported on this browser, disable or hide UI.");
return false;
}
console.info("Push and serviceWorker supported on this browser.");
return true;
}
//https://stackoverflow.com/questions/39136625/service-worker-registration-failed
function registerServiceWorker() {
console.log('registerServiceWorker');
return navigator.serviceWorker.register(serviceWorkerUrl)
.then(function (registration) {
console.log('Service worker successfully registered.');
registration.update();
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
function getNotificationPermissionState() {
if (navigator.permissions) {
return navigator.permissions.query({ name: 'notifications' })
.then((result) => {
return result.state;
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
}
});
}
function getNotificationPermissionState() {
if (navigator.permissions) {
return navigator.permissions.query({ name: 'notifications' })
.then((result) => {
return result.state;
});
}
return new Promise((resolve) => {
resolve(Notification.permission);
});
}
return new Promise((resolve) => {
resolve(Notification.permission);
});
}
}
function getSWRegistration() {
return navigator.serviceWorker.register('Edeclic-service-worker.js');
}
function getSWRegistration() {
return navigator.serviceWorker.register(serviceWorkerUrl);
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function subscribeUserToPush() {
console.log('subscribingUserToPush');
getSWRegistration();
return navigator.serviceWorker.ready.then(function (registration) {
const subscribeOptions = {
// At the moment you must pass in a value of true. If you dont include the
// userVisibleOnly key or pass in false youll get the following error:
// 9
// Chrome currently only supports the Push API for subscriptions that
// will result in user-visible messages. You can indicate this by calling
// pushManager.subscribe({userVisibleOnly: true}) instead.
// See https://goo.gl/yqv4Q4 for more details.
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
publicKey)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
function sendSubscriptionToBackEnd(subscription) {
console.log('sendSubscriptionToBackEnd: ', JSON.stringify(subscription));
return fetch(saveUrl, {
method: 'POST',
//edge requirements
credentials: "same-origin",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return response.json();
})
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
return outputArray;
}
function unsubscribeUserFromPush() {
function subscribeUserToPush() {
getSWRegistration();
return navigator.serviceWorker.ready.then(function (registration) {
const subscribeOptions = {
// At the moment you must pass in a value of true. If you dont include the
// userVisibleOnly key or pass in false youll get the following error:
// 9
// Chrome currently only supports the Push API for subscriptions that
// will result in user-visible messages. You can indicate this by calling
// pushManager.subscribe({userVisibleOnly: true}) instead.
// See https://goo.gl/yqv4Q4 for more details.
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
publicKey)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
return registration.pushManager.getSubscription()
return pushSubscription;
});
}
.then(function (subscription) {
if (subscription) {
function sendSubscriptionToBackEnd(subscription) {
return subscription.unsubscribe();
}
})
.then(function () {
return fetch(deleteUrl, {
method: 'GET'
return fetch(saveUrl, {
method: 'POST',
//edge requirements
credentials: "same-origin",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
///TODO bind UI
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
return response.json();
})
})
.catch(function (err) {
console.error('Failed to unsubscribe the user.', err);
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
navigator.serviceWorker.addEventListener('message', event => {
var toastHTML = '<div class="card white horizontal"><div class="card-image">' +
'<img style="max-height:100px;" src="' +
event.data.image + '"></div><div class="card-stacked"><div class="card-content dark-text">' +
'<span class="card-title dark-text">' +
event.data.title +
'</span>' +
'<p>' +
event.data.body +
'</p>' +
'</div><div class="card-action right-align">' +
'<a href="' + event.data.data.link + '">Voir</a>' +
'</div></div></div>'
Materialize.toast(toastHTML, 10000000);
});
}
}
},
delayedAsk: function () {
var pushTrigger = EdeclicLib.getCookie("pushTrigger") * 1;
if (pushTrigger == 3) {
new Promise(EdeclicLib.askForNotifications)
.then(() =>Materialize.toast("Vous êtes bien enregistré.", 4000));
navigator.serviceWorker.addEventListener('message', event => {
// var toastHTML = '<div >'+
// '<img style="max-height:100px;" src="'+event.data.image+'" alt="push received"/>'+
// '</br>'+
// '<span>'+event.data.title+' - </span>'+
// '<span>'+event.data.body+' </span>'+
// '<a href="'+event.data.data.link+'">Voir</a>'+
// '</div>'
// ;
var toastHTML = '<div class="card white horizontal"><div class="card-image">'+
'<img style="max-height:100px;" src="' +
event.data.image + '"></div><div class="card-stacked"><div class="card-content dark-text">' +
'<span class="card-title dark-text">' +
event.data.title +
'</span>' +
'<p>' +
event.data.body +
'</p>' +
'</div><div class="card-action right-align">' +
'<a href="'+event.data.data.link+'">Voir</a>'+
'</div></div></div>'
Materialize.toast(toastHTML, 10000000);
});
}
if (pushTrigger <= 3) {
EdeclicLib.setCookie("pushTrigger", pushTrigger + 1);
}
},
unsubscribe: function () {
navigator.serviceWorker.ready
.then((serviceWorkerRegistration) => {
serviceWorkerRegistration.pushManager.getSubscription()
.then((subscription) => {
if (!subscription) {
console.log("Not subscribed, nothing to do.");
return;
}
//TODO: to be set a the right place
AskForNotifications();
})()
subscription.unsubscribe()
.then(function () {
console.log("Successfully unsubscribed!.");
})
.catch((e) => {
logger.error('Error thrown while unsubscribing from push messaging', e);
});
});
});
},
unsubscribeUserFromPush: function () {
return registration.pushManager.getSubscription()
.then(function (subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.then(function () {
return fetch(deleteUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
///TODO bind UI
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
})
})
.catch(function (err) {
console.error('Failed to unsubscribe the user.', err);
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
});
});
}
});
}(jQuery)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,216 +2,196 @@
/// A push and notification client
/// inspired by https://github.com/gauntface/web-push-book
///
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
; (function () {
"use strict";
console.log("- A push and notification client - ");
var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
function AskForNotifications() {
console.log('AskForNotifications');
if (!IsFeatureDetected()) {
//alert feature unavailable
alert("Push feature not available on your side");
return;
}
d.extend(EdeclicLib, {
var conf = document.getElementById('pushParams');
if (conf === null) {
console.warn('The pushParams div is not found. can\'t get datadash config.');
return;
}
publicKey = conf.dataset.pushPublicKey;
saveUrl = conf.dataset.saveSubscriptionUrl;
deleteUrl = conf.dataset.deleteSubscriptionUrl;
serviceWorkerUrl = conf.dataset.serviceWorkerUrl;
askForNotifications: function (resolve, reject) {
var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
return Promise.all([
registerServiceWorker(),
getNotificationPermissionState()
])
.then(function (results) {
const registration = results[0];
const currentPermissionState = results[1];
if (currentPermissionState === 'denied') {
console.warn('The notification permission has been blocked. Nothing we can do.');
alert("The notification permission has been blocked. Please, review your settings.");
if (!IsFeatureDetected()) {
//alert feature unavailable
alert("Votre navigateur ne permet pas d'envoyer des push.");
reject();
return;
}
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
promiseChain
.then(subscribeUserToPush)
.then(function (subscription) {
if (subscription) {
return sendSubscriptionToBackEnd(subscription)
.then(function () {
return subscription;
});
var conf = document.getElementById('pushParams');
if (conf === null) {
console.warn('The pushParams div is not found. can\'t get datadash config.');
reject();
return;
}
publicKey = conf.dataset.pushPublicKey;
saveUrl = conf.dataset.saveSubscriptionUrl;
deleteUrl = conf.dataset.deleteSubscriptionUrl;
serviceWorkerUrl = conf.dataset.serviceWorkerUrl;
return Promise.all([
registerServiceWorker(),
getNotificationPermissionState()
])
.then(function (results) {
const registration = results[0];
const currentPermissionState = results[1];
if (currentPermissionState === 'denied') {
console.warn('The notification permission has been blocked. Nothing we can do.');
alert("Les notifications sont désactivés, veuillez modifier vos paramètres pour bénéficier de cette fonctionnalité.");
reject();
return;
}
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
return subscription;
})
.then(function (subscription) {
// We got a subscription AND it was sent to our backend,
// re-enable our UI and set up state.
console.log('SUBSCRIPTION', subscription);
})
.catch(function (err) {
console.error('Failed to subscribe the user.', err);
promiseChain
.then(subscribeUserToPush)
.then(function (subscription) {
if (subscription) {
return sendSubscriptionToBackEnd(subscription)
.then(function () {
return subscription;
});
}
return subscription;
})
.then(function (subscription) {
// We got a subscription AND it was sent to our backend,
// re-enable our UI and set up state.
console.log('SUBSCRIPTION', subscription);
resolve();
return;
})
.catch(function (err) {
console.error('Failed to subscribe the user.', err);
reject();
return;
});
// if (currentPermissionState !== 'granted') {
// // If permission isn't granted then we can't be subscribed for Push.
// console.log("permission isn't granted then we can't be subscribed for Push.");
// return;
// }
},
reject
).catch(function (err) {
console.log('Unable to register the service worker: ' + err);
reject();
return;
});
if (currentPermissionState !== 'granted') {
// If permission isn't granted then we can't be subscribed for Push.
console.log("permission isn't granted then we can't be subscribed for Push.");
}
}
).catch(function (err) {
console.log('Unable to register the service worker: ' + err);
});
function IsFeatureDetected() {
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
console.info("Service Worker isn't supported on this browser, disable or hide UI.");
return false;
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
console.info("Push isn't supported on this browser, disable or hide UI.");
return false;
}
console.info("Push and serviceWorker supported on this browser.");
return true;
}
//https://stackoverflow.com/questions/39136625/service-worker-registration-failed
function registerServiceWorker() {
console.log('registerServiceWorker');
return navigator.serviceWorker.register(serviceWorkerUrl)
.then(function (registration) {
console.log('Service worker successfully registered.');
registration.update();
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
function IsFeatureDetected() {
if (!('serviceWorker' in navigator)) {
// Service Worker isn't supported on this browser, disable or hide UI.
console.info("Service Worker isn't supported on this browser, disable or hide UI.");
return false;
}
});
}
if (!('PushManager' in window)) {
// Push isn't supported on this browser, disable or hide UI.
console.info("Push isn't supported on this browser, disable or hide UI.");
return false;
}
console.info("Push and serviceWorker supported on this browser.");
return true;
}
//https://stackoverflow.com/questions/39136625/service-worker-registration-failed
function registerServiceWorker() {
console.log('registerServiceWorker');
return navigator.serviceWorker.register(serviceWorkerUrl)
.then(function (registration) {
console.log('Service worker successfully registered.');
registration.update();
return registration;
})
.catch(function (err) {
console.error('Unable to register service worker.', err);
});
}
function getNotificationPermissionState() {
if (navigator.permissions) {
return navigator.permissions.query({ name: 'notifications' })
.then((result) => {
return result.state;
function askPermission() {
return new Promise(function (resolve, reject) {
const permissionResult = Notification.requestPermission(function (result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function (permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
}
});
}
function getNotificationPermissionState() {
if (navigator.permissions) {
return navigator.permissions.query({ name: 'notifications' })
.then((result) => {
return result.state;
});
}
return new Promise((resolve) => {
resolve(Notification.permission);
});
}
return new Promise((resolve) => {
resolve(Notification.permission);
});
}
}
function getSWRegistration() {
return navigator.serviceWorker.register('Edeclic-service-worker.js');
}
function getSWRegistration() {
return navigator.serviceWorker.register(serviceWorkerUrl);
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function subscribeUserToPush() {
console.log('subscribingUserToPush');
getSWRegistration();
return navigator.serviceWorker.ready.then(function (registration) {
const subscribeOptions = {
// At the moment you must pass in a value of true. If you dont include the
// userVisibleOnly key or pass in false youll get the following error:
// 9
// Chrome currently only supports the Push API for subscriptions that
// will result in user-visible messages. You can indicate this by calling
// pushManager.subscribe({userVisibleOnly: true}) instead.
// See https://goo.gl/yqv4Q4 for more details.
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
publicKey)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
function sendSubscriptionToBackEnd(subscription) {
console.log('sendSubscriptionToBackEnd: ', JSON.stringify(subscription));
return fetch(saveUrl, {
method: 'POST',
//edge requirements
credentials: "same-origin",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return response.json();
})
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
return outputArray;
}
function unsubscribeUserFromPush() {
function subscribeUserToPush() {
getSWRegistration();
return navigator.serviceWorker.ready.then(function (registration) {
const subscribeOptions = {
// At the moment you must pass in a value of true. If you dont include the
// userVisibleOnly key or pass in false youll get the following error:
// 9
// Chrome currently only supports the Push API for subscriptions that
// will result in user-visible messages. You can indicate this by calling
// pushManager.subscribe({userVisibleOnly: true}) instead.
// See https://goo.gl/yqv4Q4 for more details.
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
publicKey)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function (pushSubscription) {
return registration.pushManager.getSubscription()
return pushSubscription;
});
}
.then(function (subscription) {
if (subscription) {
function sendSubscriptionToBackEnd(subscription) {
return subscription.unsubscribe();
}
})
.then(function () {
return fetch(deleteUrl, {
return fetch(saveUrl, {
method: 'POST',
//edge requirements
credentials: "same-origin",
headers: {
'Content-Type': 'application/json'
},
@@ -221,44 +201,103 @@
if (!response.ok) {
throw new Error('Bad status code from server.');
}
///TODO bind UI
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
return response.json();
})
})
.catch(function (err) {
console.error('Failed to unsubscribe the user.', err);
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
navigator.serviceWorker.addEventListener('message', event => {
var toastHTML = '<div class="card white horizontal"><div class="card-image">' +
'<img style="max-height:100px;" src="' +
event.data.image + '"></div><div class="card-stacked"><div class="card-content dark-text">' +
'<span class="card-title dark-text">' +
event.data.title +
'</span>' +
'<p>' +
event.data.body +
'</p>' +
'</div><div class="card-action right-align">' +
'<a href="' + event.data.data.link + '">Voir</a>' +
'</div></div></div>'
Materialize.toast(toastHTML, 10000000);
});
}
}
},
delayedAsk: function () {
var pushTrigger = EdeclicLib.getCookie("pushTrigger") * 1;
if (pushTrigger == 3) {
new Promise(EdeclicLib.askForNotifications)
.then(() =>Materialize.toast("Vous êtes bien enregistré aux alertes.", 5000));
}
navigator.serviceWorker.addEventListener('message', event => {
if (pushTrigger <= 3) {
EdeclicLib.setCookie("pushTrigger", pushTrigger + 1);
}
},
unsubscribe: function () {
navigator.serviceWorker.ready
.then((serviceWorkerRegistration) => {
serviceWorkerRegistration.pushManager.getSubscription()
.then((subscription) => {
if (!subscription) {
console.log("Not subscribed, nothing to do.");
return;
}
var toastHTML = '<div class="card white horizontal"><div class="card-image">'+
'<img style="max-height:100px;" src="' +
event.data.image + '"></div><div class="card-stacked"><div class="card-content dark-text">' +
'<span class="card-title dark-text">' +
event.data.title +
'</span>' +
'<p>' +
event.data.body +
'</p>' +
'</div><div class="card-action right-align">' +
'<a href="'+event.data.data.link+'">Voir</a>'+
'</div></div></div>'
Materialize.toast(toastHTML, 10000000);
});
subscription.unsubscribe()
.then(function () {
console.log("Successfully unsubscribed!.");
})
.catch((e) => {
logger.error('Error thrown while unsubscribing from push messaging', e);
});
});
});
},
unsubscribeUserFromPush: function () {
return registration.pushManager.getSubscription()
//TODO: to be set a the right place
AskForNotifications();
})()
.then(function (subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.then(function () {
return fetch(deleteUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function (response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
///TODO bind UI
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
})
})
.catch(function (err) {
console.error('Failed to unsubscribe the user.', err);
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
});
});
}
});
}(jQuery)
@@ -0,0 +1,31 @@
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
d.extend(EdeclicLib, {
/* GESTION des cookies pour la modal du tuto */
setCookie: function (name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
},
getCookie: function (name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
},
eraseCookie: function (name) {
document.cookie = name + '=; Max-Age=-99999999;';
}
})
}(jQuery);
+4 -26
View File
@@ -1,6 +1,8 @@
EdeclicLib = window.EdeclicLib || {};
function closeModal(){
$('#modal-tuto').modal('close');
setCookie('ttcookie','modal_tuto',7);
EdeclicLib.setCookie('ttcookie','modal_tuto',7);
}
$('.next-slide').click(function() {
@@ -50,7 +52,7 @@ $(document).ready(function(){
});
}
});
var cookie = getCookie('ttcookie');
var cookie = EdeclicLib.getCookie('ttcookie');
if(!cookie) {
openModal();
}
@@ -74,30 +76,6 @@ $(document).ready(function(){
}
});
/* GESTION des cookies pour la modal du tuto */
function setCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
document.cookie = name+'=; Max-Age=-99999999;';
}
/* GESTON de la webcam */
var elementExists = document.getElementById("myCvVideo");