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> <source>company.account.password.modify.label</source>
<target>Modifier le mot de passe</target> <target>Modifier le mot de passe</target>
</trans-unit> </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"> <trans-unit id="profile.edit.submit">
<source>profile.edit.submit</source> <source>profile.edit.submit</source>
<target>Sauvegarder mon profil</target> <target>Sauvegarder mon profil</target>
@@ -188,6 +188,10 @@
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
//asking for push
EdeclicLib = window.EdeclicLib || {};
EdeclicLib.delayedAsk();
//
$('.tooltipped').tooltip(); $('.tooltipped').tooltip();
$.get( "{{ path('ad_ajaxRecStat',{'id': ad.id }) }}", function( data ) {}); $.get( "{{ path('ad_ajaxRecStat',{'id': ad.id }) }}", function( data ) {});
if ($('#modal-answer').length > 0) { 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" <div id="pushParams"
data-service-worker-url="{{ app.request.uriForPath('/Edeclic-service-worker.js') | replace({'/app_dev.php': ''}) }}" data-service-worker-url="{{ app.request.uriForPath('/Edeclic-service-worker.js') | replace({'/app_dev.php': ''}) }}"
data-delete-subscription-url="{{ url('delete-subscription') }}" data-delete-subscription-url="{{ url('delete-subscription') }}"
@@ -1,8 +1,8 @@
{% extends 'talent/base_dashboard_talent.html.twig' %} {% extends 'talent/base_dashboard_talent.html.twig' %}
{% block dashContent %} {% block dashContent %}
{% include 'default/props_settings.html.twig' %}
{% include 'default/flash_message.html.twig' %} {% include 'default/flash_message.html.twig' %}
<div class=" row bg-bordered p-20"> <div class=" row bg-bordered p-20">
{#<h1 class="alttitle">{{ 'profile.talent.account.title'|trans }}</h1>#} {#<h1 class="alttitle">{{ 'profile.talent.account.title'|trans }}</h1>#}
@@ -11,18 +11,71 @@
<h4>{{ 'company.account.password.modify'|trans }}</h4> <h4>{{ 'company.account.password.modify'|trans }}</h4>
{% if form_errors(formPw) %} {% if form_errors(formPw) %}
<div class="card-panel"> <div class="card-panel">
<span class="red-text text-darken-2"> <span class="red-text text-darken-2">
{{ form_errors(formPw) }} {{ form_errors(formPw) }}
</span> </span>
</div> </div>
{% endif %} {% endif %}
{{ form_start(formPw) }} {{ form_start(formPw) }}
{{ form_rest(formPw) }} {{ form_rest(formPw) }}
<br/> <br/>
<input class="btn btn-default" type="submit" <input class="btn btn-default" type="submit" value="{{ 'company.account.password.modify.label'|trans }}"/>
value="{{ 'company.account.password.modify.label'|trans }}"/>
{{ form_end(formPw) }} {{ form_end(formPw) }}
</div> </div>
</div> </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 %} {% endblock %}
@@ -26,7 +26,7 @@ assetic:
- 'js/global.js' - 'js/global.js'
- 'js/register.js' - 'js/register.js'
- 'js/tags.js' - 'js/tags.js'
# - 'js/Edeclic-service-worker.js' - 'js/EdeclicTools.js'
- 'js/EdeclicPushAndNotificationClient.js' - 'js/EdeclicPushAndNotificationClient.js'
company: company:
@@ -95,17 +95,52 @@ class TalentController extends Controller
{ {
$userManager = $this->get('fos_user.user_manager'); $userManager = $this->get('fos_user.user_manager');
$user = $this->getUser(); $user = $this->getUser();
$formFactory = $this->container->get('fos_user.change_password.form.factory'); $formFactory = $this->container->get('fos_user.change_password.form.factory');
$formPw = $formFactory->createForm(); $formPw = $formFactory->createForm();
$formPw->setData($user); $formPw->setData($user);
if ($formPw->isSubmitted() && $formPw->isValid()) { if ($formPw->isSubmitted() && $formPw->isValid()) {
$userManager->updateUser($user); $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', [ return $this->render('talent/my_account.html.twig', [
'formPw' => $formPw->createView(), '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") * @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.lastname IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN u.photo 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 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.addresses IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.alias 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.brandName IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN c.businessName IS NOT NULL THEN 1 ELSE 0 END + CASE WHEN c.businessName IS NOT NULL THEN 1 ELSE 0 END +
@@ -2,135 +2,146 @@
/// A generic service worker /// A generic service worker
/// inspired by https://github.com/gauntface/web-push-book /// inspired by https://github.com/gauntface/web-push-book
/// ///
; (function () { ; (function () {
"use strict"; "use strict";
function focusWindow(event) { function focusWindow(event) {
const url = event.notification.data["link"]; const url = event.notification.data["link"];
const urlToOpen = new URL(url, self.location.origin).href; const urlToOpen = new URL(url, self.location.origin).href;
const promiseChain = clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let matchingClient = null;
for (let i = 0; i < windowClients.length; i++) { const promiseChain = clients.matchAll({
const windowClient = windowClients[i]; type: 'window',
if (windowClient.url === urlToOpen) { includeUncontrolled: true
matchingClient = windowClient; })
break; .then((windowClients) => {
} let matchingClient = null;
}
if (matchingClient) { for (let i = 0; i < windowClients.length; i++) {
return matchingClient.focus(); const windowClient = windowClients[i];
} else { if (windowClient.url === urlToOpen) {
return clients.openWindow(urlToOpen); matchingClient = windowClient;
} break;
}); }
event.waitUntil(promiseChain); }
}
function isClientFocused() { if (matchingClient) {
return clients.matchAll({ return matchingClient.focus();
type: 'window', } else {
includeUncontrolled: true return clients.openWindow(urlToOpen);
}) }
.then((windowClients) => { });
let clientIsFocused = false; event.waitUntil(promiseChain);
}
for (let i = 0; i < windowClients.length; i++) { function isClientFocused() {
const windowClient = windowClients[i]; return clients.matchAll({
if (windowClient.focused) { type: 'window',
clientIsFocused = true; includeUncontrolled: true
break; })
} .then((windowClients) => {
}
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; let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) { for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i]; const windowClient = windowClients[i];
if (windowClient.focused) { if (windowClient.focused) {
console.log('Posting message to page'); clientIsFocused = true;
windowClient.postMessage(event.data.json().notification 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 { event.waitUntil(promiseChain);
return self.registration.showNotification('No focused windows', { }
body: 'Had to show a notification instead of messaging each page.'
}); 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) { self.addEventListener('notificationclose', function (event) {
const dismissedNotification = event.notification;
demoMustShowNotificationCheck(event); ga('send', 'event', {
eventCategory: 'Push close',
}); eventAction: 'click',
eventLabel: event.notification.data["link"]
self.addEventListener('notificationclick', function(event) { });
event.notification.close(); const promiseChain = notificationCloseAnalytics();
switch(event.notification.tag) { event.waitUntil(promiseChain);
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);
});
})() })()
+299 -230
View File
@@ -421,270 +421,339 @@ $('#ad_soft_publicTag').materialtags({
$('#ad_privateTag').materialtags({ $('#ad_privateTag').materialtags({
maxTags: 5 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 /// A push and notification client
/// inspired by https://github.com/gauntface/web-push-book /// inspired by https://github.com/gauntface/web-push-book
/// ///
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
; (function () { d.extend(EdeclicLib, {
"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;
}
var conf = document.getElementById('pushParams'); askForNotifications: function (resolve, reject) {
if (conf === null) { var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
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;
return Promise.all([ if (!IsFeatureDetected()) {
registerServiceWorker(), //alert feature unavailable
getNotificationPermissionState() alert("Votre navigateur ne permet pas d'envoyer des push.");
]) reject();
.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.");
return; return;
} }
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
promiseChain var conf = document.getElementById('pushParams');
.then(subscribeUserToPush) if (conf === null) {
.then(function (subscription) { console.warn('The pushParams div is not found. can\'t get datadash config.');
if (subscription) { reject();
return sendSubscriptionToBackEnd(subscription) return;
.then(function () { }
return subscription; 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; promiseChain
}) .then(subscribeUserToPush)
.then(function (subscription) { .then(function (subscription) {
// We got a subscription AND it was sent to our backend, if (subscription) {
// re-enable our UI and set up state. return sendSubscriptionToBackEnd(subscription)
console.log('SUBSCRIPTION', subscription); .then(function () {
}) return subscription;
.catch(function (err) { });
console.error('Failed to subscribe the user.', err); }
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') { function IsFeatureDetected() {
// If permission isn't granted then we can't be subscribed for Push. if (!('serviceWorker' in navigator)) {
console.log("permission isn't granted then we can't be subscribed for Push."); // 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;
).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.');
} }
}); 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() { function askPermission() {
if (navigator.permissions) { return new Promise(function (resolve, reject) {
return navigator.permissions.query({ name: 'notifications' }) const permissionResult = Notification.requestPermission(function (result) {
.then((result) => { resolve(result);
return result.state; });
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() { function getSWRegistration() {
return navigator.serviceWorker.register('Edeclic-service-worker.js'); return navigator.serviceWorker.register(serviceWorkerUrl);
} }
function urlBase64ToUint8Array(base64String) { function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4); const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding) const base64 = (base64String + padding)
.replace(/\-/g, '+') .replace(/\-/g, '+')
.replace(/_/g, '/'); .replace(/_/g, '/');
const rawData = window.atob(base64); const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length); const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) { for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(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.');
} }
return response.json(); return outputArray;
}) }
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
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) { function sendSubscriptionToBackEnd(subscription) {
if (subscription) {
return subscription.unsubscribe(); return fetch(saveUrl, {
} method: 'POST',
}) //edge requirements
.then(function () { credentials: "same-origin",
return fetch(deleteUrl, { headers: {
method: 'GET' 'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
}) })
.then(function (response) { .then(function (response) {
if (!response.ok) { if (!response.ok) {
throw new Error('Bad status code from server.'); throw new Error('Bad status code from server.');
} }
///TODO bind UI return response.json();
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
}) })
.then(function (responseData) {
}) if (!(responseData && responseData.success)) {
.catch(function (err) { throw new Error('Bad response from server.');
console.error('Failed to unsubscribe the user.', err); }
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
}); });
}
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 => { if (pushTrigger <= 3) {
// var toastHTML = '<div >'+ EdeclicLib.setCookie("pushTrigger", pushTrigger + 1);
// '<img style="max-height:100px;" src="'+event.data.image+'" alt="push received"/>'+ }
// '</br>'+ },
// '<span>'+event.data.title+' - </span>'+ unsubscribe: function () {
// '<span>'+event.data.body+' </span>'+ navigator.serviceWorker.ready
// '<a href="'+event.data.data.link+'">Voir</a>'+ .then((serviceWorkerRegistration) => {
// '</div>' serviceWorkerRegistration.pushManager.getSubscription()
// ; .then((subscription) => {
var toastHTML = '<div class="card white horizontal"><div class="card-image">'+ if (!subscription) {
'<img style="max-height:100px;" src="' + console.log("Not subscribed, nothing to do.");
event.data.image + '"></div><div class="card-stacked"><div class="card-content dark-text">' + return;
'<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 () {
//TODO: to be set a the right place return registration.pushManager.getSubscription()
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)
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 /// A push and notification client
/// inspired by https://github.com/gauntface/web-push-book /// inspired by https://github.com/gauntface/web-push-book
/// ///
EdeclicLib = window.EdeclicLib || {},
function (d) {
"use strict";
; (function () { d.extend(EdeclicLib, {
"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;
}
var conf = document.getElementById('pushParams'); askForNotifications: function (resolve, reject) {
if (conf === null) { var publicKey, saveUrl, deleteUrl, serviceWorkerUrl;
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;
return Promise.all([ if (!IsFeatureDetected()) {
registerServiceWorker(), //alert feature unavailable
getNotificationPermissionState() alert("Votre navigateur ne permet pas d'envoyer des push.");
]) reject();
.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.");
return; return;
} }
let promiseChain = Promise.resolve();
if (currentPermissionState !== 'granted') {
promiseChain = askPermission();
}
promiseChain var conf = document.getElementById('pushParams');
.then(subscribeUserToPush) if (conf === null) {
.then(function (subscription) { console.warn('The pushParams div is not found. can\'t get datadash config.');
if (subscription) { reject();
return sendSubscriptionToBackEnd(subscription) return;
.then(function () { }
return subscription; 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; promiseChain
}) .then(subscribeUserToPush)
.then(function (subscription) { .then(function (subscription) {
// We got a subscription AND it was sent to our backend, if (subscription) {
// re-enable our UI and set up state. return sendSubscriptionToBackEnd(subscription)
console.log('SUBSCRIPTION', subscription); .then(function () {
}) return subscription;
.catch(function (err) { });
console.error('Failed to subscribe the user.', err); }
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') { function IsFeatureDetected() {
// If permission isn't granted then we can't be subscribed for Push. if (!('serviceWorker' in navigator)) {
console.log("permission isn't granted then we can't be subscribed for Push."); // 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;
).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.');
} }
}); 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() { function askPermission() {
if (navigator.permissions) { return new Promise(function (resolve, reject) {
return navigator.permissions.query({ name: 'notifications' }) const permissionResult = Notification.requestPermission(function (result) {
.then((result) => { resolve(result);
return result.state; });
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() { function getSWRegistration() {
return navigator.serviceWorker.register('Edeclic-service-worker.js'); return navigator.serviceWorker.register(serviceWorkerUrl);
} }
function urlBase64ToUint8Array(base64String) { function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4); const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding) const base64 = (base64String + padding)
.replace(/\-/g, '+') .replace(/\-/g, '+')
.replace(/_/g, '/'); .replace(/_/g, '/');
const rawData = window.atob(base64); const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length); const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) { for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(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.');
} }
return response.json(); return outputArray;
}) }
.then(function (responseData) {
if (!(responseData && responseData.success)) {
throw new Error('Bad response from server.');
}
});
}
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) { function sendSubscriptionToBackEnd(subscription) {
if (subscription) {
return subscription.unsubscribe(); return fetch(saveUrl, {
}
})
.then(function () {
return fetch(deleteUrl, {
method: 'POST', method: 'POST',
//edge requirements
credentials: "same-origin",
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
@@ -221,44 +201,103 @@
if (!response.ok) { if (!response.ok) {
throw new Error('Bad status code from server.'); throw new Error('Bad status code from server.');
} }
///TODO bind UI return response.json();
// pushCheckbox.disabled = false;
// pushCheckbox.checked = false;
return true;
}) })
.then(function (responseData) {
}) if (!(responseData && responseData.success)) {
.catch(function (err) { throw new Error('Bad response from server.');
console.error('Failed to unsubscribe the user.', err); }
getNotificationPermissionState()
.then((permissionState) => {
// pushCheckbox.disabled = permissionState === 'denied';
// pushCheckbox.checked = false;
}); });
}
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);
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">' + unsubscribe: function () {
'<span class="card-title dark-text">' + navigator.serviceWorker.ready
event.data.title + .then((serviceWorkerRegistration) => {
'</span>' + serviceWorkerRegistration.pushManager.getSubscription()
'<p>' + .then((subscription) => {
event.data.body + if (!subscription) {
'</p>' + console.log("Not subscribed, nothing to do.");
'</div><div class="card-action right-align">' + return;
'<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 () {
//TODO: to be set a the right place return registration.pushManager.getSubscription()
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(){ function closeModal(){
$('#modal-tuto').modal('close'); $('#modal-tuto').modal('close');
setCookie('ttcookie','modal_tuto',7); EdeclicLib.setCookie('ttcookie','modal_tuto',7);
} }
$('.next-slide').click(function() { $('.next-slide').click(function() {
@@ -50,7 +52,7 @@ $(document).ready(function(){
}); });
} }
}); });
var cookie = getCookie('ttcookie'); var cookie = EdeclicLib.getCookie('ttcookie');
if(!cookie) { if(!cookie) {
openModal(); 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 */ /* GESTON de la webcam */
var elementExists = document.getElementById("myCvVideo"); var elementExists = document.getElementById("myCvVideo");