From ccbe330d6bbf3c6049a57af809b648c2c4a2155e Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Fri, 9 Dec 2022 10:46:23 +0100 Subject: Fix qdoc warnings As JavaScript parsing issue got fixed , the limit was not changed, meaning there where 4 "unused" warnings possibilities. In the meantime another change e6a13d97898f3f4b19f61006d0716ca9e1b9f037 was merged which had 3 qdoc issues, which got therefore unnoticed. Fix those issues. Do not use underscore in example name and rename push_notification to push-notifications (like qtbase network-chat). Change-Id: I2635424e24d3b9a0a02c2e6fe8ac383eec95c112 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit cbc622f158a94fea9c6af8d675a8743e98267109) Reviewed-by: Qt Cherry-pick Bot --- examples/webenginewidgets/CMakeLists.txt | 2 +- .../doc/src/clientcertificate.qdoc | 4 +- .../push-notifications/CMakeLists.txt | 7 + .../push-notifications/content/index.html | 26 + .../push-notifications/content/ping.js | 84 +++ .../push-notifications/content/style.css | 29 + .../push-notifications/content/worker.js | 7 + .../push-notifications/doc/images/notification.png | Bin 0 -> 1279 bytes .../push-notifications/doc/images/permissions.png | Bin 0 -> 4749 bytes .../doc/images/push-notifications.png | Bin 0 -> 10573 bytes .../push-notifications/doc/images/website.png | Bin 0 -> 7539 bytes .../doc/src/push-notifications.qdoc | 191 +++++ .../doc/src/push-notifications.qmodel | 837 +++++++++++++++++++++ .../webenginewidgets/push-notifications/server.js | 65 ++ .../push_notifications/CMakeLists.txt | 7 - .../push_notifications/content/index.html | 26 - .../push_notifications/content/ping.js | 84 --- .../push_notifications/content/style.css | 29 - .../push_notifications/content/worker.js | 7 - .../push_notifications/doc/images/notification.png | Bin 1279 -> 0 bytes .../push_notifications/doc/images/permissions.png | Bin 4749 -> 0 bytes .../doc/images/push_notifications.png | Bin 10573 -> 0 bytes .../push_notifications/doc/images/website.png | Bin 7539 -> 0 bytes .../doc/src/push_notifications.qdoc | 191 ----- .../doc/src/push_notifications.qmodel | 837 --------------------- .../push_notifications/push_notifications.pro | 1 - .../webenginewidgets/push_notifications/server.js | 65 -- examples/webenginewidgets/webenginewidgets.pro | 2 +- .../doc/snippets/push-notifications/commands | 19 + .../doc/snippets/push_notifications/commands | 19 - 30 files changed, 1269 insertions(+), 1270 deletions(-) create mode 100644 examples/webenginewidgets/push-notifications/CMakeLists.txt create mode 100644 examples/webenginewidgets/push-notifications/content/index.html create mode 100644 examples/webenginewidgets/push-notifications/content/ping.js create mode 100644 examples/webenginewidgets/push-notifications/content/style.css create mode 100644 examples/webenginewidgets/push-notifications/content/worker.js create mode 100644 examples/webenginewidgets/push-notifications/doc/images/notification.png create mode 100644 examples/webenginewidgets/push-notifications/doc/images/permissions.png create mode 100644 examples/webenginewidgets/push-notifications/doc/images/push-notifications.png create mode 100644 examples/webenginewidgets/push-notifications/doc/images/website.png create mode 100644 examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc create mode 100644 examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel create mode 100644 examples/webenginewidgets/push-notifications/server.js delete mode 100644 examples/webenginewidgets/push_notifications/CMakeLists.txt delete mode 100644 examples/webenginewidgets/push_notifications/content/index.html delete mode 100644 examples/webenginewidgets/push_notifications/content/ping.js delete mode 100644 examples/webenginewidgets/push_notifications/content/style.css delete mode 100644 examples/webenginewidgets/push_notifications/content/worker.js delete mode 100644 examples/webenginewidgets/push_notifications/doc/images/notification.png delete mode 100644 examples/webenginewidgets/push_notifications/doc/images/permissions.png delete mode 100644 examples/webenginewidgets/push_notifications/doc/images/push_notifications.png delete mode 100644 examples/webenginewidgets/push_notifications/doc/images/website.png delete mode 100644 examples/webenginewidgets/push_notifications/doc/src/push_notifications.qdoc delete mode 100644 examples/webenginewidgets/push_notifications/doc/src/push_notifications.qmodel delete mode 100644 examples/webenginewidgets/push_notifications/push_notifications.pro delete mode 100644 examples/webenginewidgets/push_notifications/server.js create mode 100644 src/webenginewidgets/doc/snippets/push-notifications/commands delete mode 100644 src/webenginewidgets/doc/snippets/push_notifications/commands diff --git a/examples/webenginewidgets/CMakeLists.txt b/examples/webenginewidgets/CMakeLists.txt index c94f71fb4..c3d466558 100644 --- a/examples/webenginewidgets/CMakeLists.txt +++ b/examples/webenginewidgets/CMakeLists.txt @@ -7,7 +7,7 @@ qt_internal_add_example(cookiebrowser) qt_internal_add_example(notifications) qt_internal_add_example(simplebrowser) qt_internal_add_example(stylesheetbrowser) -qt_internal_add_example(push_notifications) +qt_internal_add_example(push-notifications) qt_internal_add_example(videoplayer) qt_internal_add_example(webui) if(QT_FEATURE_webengine_geolocation) diff --git a/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc b/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc index 5f4eeb848..b2b67b2e2 100644 --- a/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc +++ b/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc @@ -2,10 +2,10 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! - \example webenginewidgets/clientcertificatesi + \example webenginewidgets/clientcertificate \title WebEngine Widgets Client Certificate Example \ingroup webengine-widgetexamples - \brief A simple client certificate authentication scenario using \QWE and \l QSslServer + \brief A simple client certificate authentication scenario using \QWE and \l QSslServer. \image selection.png diff --git a/examples/webenginewidgets/push-notifications/CMakeLists.txt b/examples/webenginewidgets/push-notifications/CMakeLists.txt new file mode 100644 index 000000000..bbb585c9b --- /dev/null +++ b/examples/webenginewidgets/push-notifications/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(simplebrowser LANGUAGES CXX) + +message("\nPlease use simplebrowser to see notifiactions.\n") diff --git a/examples/webenginewidgets/push-notifications/content/index.html b/examples/webenginewidgets/push-notifications/content/index.html new file mode 100644 index 000000000..cce3055cd --- /dev/null +++ b/examples/webenginewidgets/push-notifications/content/index.html @@ -0,0 +1,26 @@ + + + + Push Notification Using Node and FCM + + + +

Push Notification Using NodeJS and QtWebEngine

+
+
+
+
+ Ping Me Every [sec]: +
+
+ +
+
+
+
+
+
+
+ + + diff --git a/examples/webenginewidgets/push-notifications/content/ping.js b/examples/webenginewidgets/push-notifications/content/ping.js new file mode 100644 index 000000000..285a57019 --- /dev/null +++ b/examples/webenginewidgets/push-notifications/content/ping.js @@ -0,0 +1,84 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +const publicVapidKey = + "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg"; + +async function setup(delay) +{ + console.log('>> register service worker...'); + const register = await navigator.serviceWorker.register('/worker.js', { scope : '/' }); + console.log('>> service worker registered...'); + + console.log('>> subscribe push subscription to FCM'); + var subscription = await register.pushManager.subscribe( + { userVisibleOnly : true, applicationServerKey : publicVapidKey }); + console.log('>> subscription created...'); + + console.log('>> subscribe to push service...'); + await fetch('/subscribe', { + method : 'POST', + body : JSON.stringify(subscription), + headers : { 'content-type' : 'application/json', 'ping-time' : delay } + }); + console.log('>> push subscription created...') +} + +async function clear() +{ + const register = await navigator.serviceWorker.getRegistration(); + var subscription = await register.pushManager.getSubscription(); + console.log('>> unsubscribe to push service...'); + await fetch('/unsubscribe', { + method : 'POST', + body : JSON.stringify(subscription), + headers : { 'content-type' : 'application/json' } + }); + console.log('>> push unsubscription removed...') + + console.log('>> unsubscribe push subscription to FCM'); + await subscription.unsubscribe(); + console.log('>> subscription removed...'); +} + +function displaySetup(delay = null) +{ + const pingSetup = document.getElementById('ping-setup'); + const pingClear = document.getElementById('ping-clear'); + const pingText = document.getElementById('ping-text'); + if (delay) { + pingClear.style.display = 'block'; + pingSetup.style.display = 'none'; + pingText.innerHTML = 'Ping Me Every ' + delay + ' seconds'; + } else { + pingClear.style.display = 'none'; + pingSetup.style.display = 'block'; + pingText.innerHTML = ""; + } +} + +function handleSetupPing(event) +{ + event.preventDefault(); + + const seconds = document.forms[0].seconds.value; + document.forms[0].reset(); + + // check for service worker support + if ('serviceWorker' in navigator) { + setup(seconds).catch(err => console.error(err)); + } + + displaySetup(seconds); +}; + +function handleClearPing(event) +{ + event.preventDefault(); + clear(); + displaySetup(); +}; + +document.forms[0].addEventListener('submit', handleSetupPing); +const clearButton = document.getElementById('ping-clear-button'); +clearButton.addEventListener('click', handleClearPing); diff --git a/examples/webenginewidgets/push-notifications/content/style.css b/examples/webenginewidgets/push-notifications/content/style.css new file mode 100644 index 000000000..8176462a2 --- /dev/null +++ b/examples/webenginewidgets/push-notifications/content/style.css @@ -0,0 +1,29 @@ +body { + font-family: monaco; + height: 100vh; + flex-direction: column; + align-items: center; + justify-content: center; + display: flex; +} +#ping-clear, +#ping-setup { + font-size: 32px; + text-align: center; +} +.form-inputs{ + margin-top: 20px; +} +input { + width: 100px; + height: 30px; +} +button { + font-size: 16px; +} +#ping-text { + margin-bottom: 30px; +} +#ping-clear { + display: none; +} diff --git a/examples/webenginewidgets/push-notifications/content/worker.js b/examples/webenginewidgets/push-notifications/content/worker.js new file mode 100644 index 000000000..ed660a6e9 --- /dev/null +++ b/examples/webenginewidgets/push-notifications/content/worker.js @@ -0,0 +1,7 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +self.addEventListener('push', event => { + const data = event.data.json(); + self.registration.showNotification(data.title, { body : data.text }); +}); diff --git a/examples/webenginewidgets/push-notifications/doc/images/notification.png b/examples/webenginewidgets/push-notifications/doc/images/notification.png new file mode 100644 index 000000000..ec5c67457 Binary files /dev/null and b/examples/webenginewidgets/push-notifications/doc/images/notification.png differ diff --git a/examples/webenginewidgets/push-notifications/doc/images/permissions.png b/examples/webenginewidgets/push-notifications/doc/images/permissions.png new file mode 100644 index 000000000..dedb6e472 Binary files /dev/null and b/examples/webenginewidgets/push-notifications/doc/images/permissions.png differ diff --git a/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png new file mode 100644 index 000000000..c5ba5f589 Binary files /dev/null and b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png differ diff --git a/examples/webenginewidgets/push-notifications/doc/images/website.png b/examples/webenginewidgets/push-notifications/doc/images/website.png new file mode 100644 index 000000000..10a4a6150 Binary files /dev/null and b/examples/webenginewidgets/push-notifications/doc/images/website.png differ diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc new file mode 100644 index 000000000..90b5212c8 --- /dev/null +++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc @@ -0,0 +1,191 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + +\example webenginewidgets/push-notifications +\title WebEngine Push Notifications Example +\ingroup webengine-widgetexamples +\brief Demonstrates how to subscribe to and unsubscribe from push notifications. + +In this example we are going to send push notifications from a web push service to the user. +This is the typical scenario where messages are sent from the application server i.e. website +back-end through a 3rd-party push service, to finally arrive at the user's browser in form of +notifications. To demonstrate this flow, we will implement a simple push service server +application, to which the user can subscribe to receive \e ping messages. + +As already mentioned, in such a workflow there are three different parties involved: + +\list + \li the user's web browser where they receive push notifications + \li 3rd-party push service, which is defined by a subscription endpoint and is a part + of a browser's push service implementation + \li application server, which will store user's subscriptions and initiate push messages + using a subscription endpoint +\endlist + +The user visits a website, where a JavaScript web application uses the JavaScript Push API +to create a push notification subscription. The user is then asked to grant a permission +to receive and display push notifications. Once accepted, the Push API establishes a push channel +with a 3rd-party push service, which in case of QtWebEngine is \l {https://firebase.google.com} +{Firebase Cloud Messaging (FCM)}. The unique push subscription is created that +includes the subscription endpoint URL. The browser then sends a subscription message +to the application server forwarding the endpoint setup. The application server can now +use the subscription endpoint to send notifications to the browser. The browser push service +implementation will deliver a push message. However, to show it, a service worker must +be registered. As the service worker runs in the background, it allows displaying notifications +even if a website, which has installed it, is no longer opened. + +\image push-notifications.png + +Let's go more into implementation details. We start with implementing our custom +push service using NodeJS with two modules: + +\list + \li \l {https://github.com/web-push-libs/web-push} {web-push} - provides the web-push protocol + implementation + \li \l {https://github.com/expressjs/express} {express} - provides the web application framework +\endlist + +Let's initialize a new project and install the required modules in the root directory of this +example: + +\snippet /push-notifications/commands 0 + +These commands should create package.js, which defines the start command: + +\snippet /push-notifications/commands 1 + +Now let's move on to the push service back-end implementation in server.js. + +We start by including the required modules and doing basic \e express framework setup, which +we use to create our custom push server. For simplicity we are going to handle only one +subscription at a time. To do that we need to create \e VAPID keys which we are going to +generate with \e web-push libs. The public key is going to be used by the front-end and authenticate +to the service. + +\quotefromfile webenginewidgets/push-notifications/server.js +\skipto const express +\printto add subscribe route + +\note We are not going to cover the encryption of messages in this example. + +To generate keys, we can use the tool shipped with \e web-push lib, that is installed by +\c npm in our example's root directory. + +\snippet /push-notifications/commands 2 + +Now we add two \c routes to the push server. One to \c subscribe and one to \c unsubscribe, +so that our front-end can send an HTTP POST request to handle the push subscription. +In the subscribe request we will get \c subscription in the request body and we also retrieve +the custom header \c ping-time that defines how often the ping messages should be pushed to +the user. We keep around the \c subscription to be able to send push notifications later. +As a confirmation, we send the 201 status code and schedule the first push notification based on +the \c ping-time value. The \c unsubscribe request simply removes a subscription. + +\quotefromfile webenginewidgets/push-notifications/server.js +\skipto add subscribe route +\printto function sendNotification + +The \c sendNotication() function sends push messages using the web-push lib. We create the payload +with the message we want to present to a user and schedule the next push message. + +\quotefromfile webenginewidgets/push-notifications/server.js +\skipto function sendNotification +\printto server.listen + +In the end we start the server to listen on the given port. + +\quotefromfile webenginewidgets/push-notifications/server.js +\skipto server.listen +\printline started + +Let's move now to our front-end. We create a simple page index.html, where the user can enter how +often they want to receive ping notification messages. We will have two buttons: +\e {Ping Me} to subscribe for push notifications and \e Clear to unsubscribe. +In the end we load ping.js, which we cover next. + +\quotefromfile webenginewidgets/push-notifications/content/index.html +\skipto +\printuntil + +The last piece is creating the logic for the push subscription within the front-end. Here we have two +functions, \c setup and \c clear, to handle subscriptions. When the user clicks on the \e {Ping Me} +button, \c setup is called. To be able to receive notifications, the service worker is needed. +This way the user can leave the website and still get notified as the service worker works +in the background and handles incoming messages. To achieve that, we have to first register +one with: + +\quotefromfile webenginewidgets/push-notifications/content/ping.js +\skipto const register +\printline worker.js + +The call to \c cpushManager.subscribe() will trigger a permission prompt, which is displayed to the +user. If the permission is granted, the push subscription is returned. It includes a URL endpoint +that allows sending notifications to the browser, where the registered service worker waits for +push messages. + +\quotefromfile webenginewidgets/push-notifications/content/ping.js +\skipto var subscription +\printto console.log + +As mentioned the subscription is created for FCM and should be now sent to our custom server +with an HTTP POST request. In addition, we add to the post request the HTTP header with the +\c ping-time the user entered on our website. + +\quotefromfile webenginewidgets/push-notifications/content/ping.js +\skipto await fetch +\printto console.log + +The function \c clear call unsubscribes first from our push server by sending an HTTP POST request +and later from the 3rd-party push service (FCM). + +\quotefromfile webenginewidgets/push-notifications/content/ping.js +\skipuntil async function clear() +\skipuntil { +\printto console.log +\dots +\skipto await fetch +\printto console.log +\dots +\skipto await subscription +\printto console.log + +The rest of code in ping.js is just boilerplate code to read a user provided value +and call \c setup() or \c clear(). + +As the last part of the front-end let's look inside a service worker script, where we simply +register an event listener for \e push events. + +\quotefromfile webenginewidgets/push-notifications/content/worker.js +\skipto self +\printuntil }); +\printuntil }); + +When a push event comes we simply use the Notification JavaScript API to display a notification. + +\note QtWebEngine Notification Example shows how to provide your own handler and customize +the look and feel of a notification message. + +Having the implementation in place, we can start the server on localhost at the port 5000. +To do that, we can simply enter in the console in the project's root directory: + +\snippet /push-notifications/commands 3 + +Now we can fire up \e simplebrowser and enter \c http:\\localhost:5000 as a URL. + +\image website.png + +\note \c QWebEngineProfile cannot be set to \e off-the-record, because push messages would be +disabled. + +After granting the permission we can send our ping request: + +\image permissions.png + +We should see the coming push notification: + +\image notification.png + +\note To troubleshoot errors, open \e {Developer Tools} from Tools menu. +*/ diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel new file mode 100644 index 000000000..048a55911 --- /dev/null +++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel @@ -0,0 +1,837 @@ + + + + {9fd14f7e-7b67-4e13-9980-ef8fbe24b780} + + + + + + + + {a26e0efd-1b21-4fba-96ce-a607bbcdb4f7} + + + push_notifications + + + + + + + {6b1a06e9-960b-4a10-872e-5504d8c0b127} + + + + + + + + + + {6b1a06e9-960b-4a10-872e-5504d8c0b127} + + + push_notifications + + + + + + + + + + {d50762f2-c7f4-4d52-9592-8bcc07274ba1} + + + Browser / User Agent + x:415;y:390 + x:-105;y:-125;w:210;h:250 + + + + + + + + + + + {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} + + + {121189af-36df-4efa-b451-3f1f85ef339f} + JavaScript Web Application + x:410;y:395 + x:-75;y:-15;w:150;h:30 + 0 + + + false + + + + + + + + + + + {8bde1815-304a-41f6-8528-c754dc3d1eda} + + + {13c69399-5587-4169-a012-8d86216139fd} + Push Manager API + x:410;y:320 + x:-75;y:-15;w:150;h:30 + false + 0 + + + false + + + + + + + + + + + {75431119-9e8e-4e3e-a539-9d7bad6dbf81} + + + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + Service Worker + x:410;y:470 + x:-75;y:-15;w:150;h:30 + false + 0 + + + false + + + + + + + + + + + {0a7b0146-d34b-4c39-a1af-df15a1b4108d} + + + {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} + {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} + {8bde1815-304a-41f6-8528-c754dc3d1eda} + subscribe + + + + + + + + + + + + + {e7d4a675-ddbd-41aa-a802-32221a56dae2} + + + {afae2401-ea81-4514-aa80-da53d61a8516} + {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} + {75431119-9e8e-4e3e-a539-9d7bad6dbf81} + register + + + + + + + + + + + + + {998e7d36-3416-4b2f-843a-a437449f09f1} + + + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + Firebase Cloud Messaging + x:770;y:320 + x:-75;y:-15;w:150;h:30 + 6 + + + false + + + + + + + + + + + {28c1fccd-c50e-458c-865d-4ba41d55690b} + + + {d9959769-74a4-40ad-bf00-904c12a67309} + {8bde1815-304a-41f6-8528-c754dc3d1eda} + {998e7d36-3416-4b2f-843a-a437449f09f1} + create subscription + + + 2 + + + + + + + + + + + {ba581e41-cc00-4129-adae-0a1208bb3222} + + + {13d79379-1727-46a3-947c-e3f2f6eb3a87} + Push Application Server + x:770;y:390 + x:-75;y:-15;w:150;h:30 + false + 6 + + + false + + + + + + + + + + + {e796d1cc-f574-45db-a440-7e47d7560d71} + + + {373c492c-0b9a-4032-9ff4-b3a7cc442883} + {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} + {ba581e41-cc00-4129-adae-0a1208bb3222} + subscribe with endpoint + + + + + + + + + + + + + {6332f8ae-ef9d-4c15-9fbf-d6ee06ba3f84} + + + {94241d64-4e88-4855-8e78-365be237108b} + {ba581e41-cc00-4129-adae-0a1208bb3222} + {998e7d36-3416-4b2f-843a-a437449f09f1} + push notification + + + + + x:770;y:335 + + + + + + + + + + + + + + + + + {582af542-5f2d-4660-a6d0-a3bd983d9682} + + + {00b8f12d-e08b-426a-83b8-83fea8907fab} + User + x:185;y:395 + x:-10;y:-20;w:20;h:40 + 0 + + + actor + false + + + + + + + + + + + {66ca12e1-84a1-4247-82e5-ae6891f3f376} + + + {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} + {582af542-5f2d-4660-a6d0-a3bd983d9682} + {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} + subscribe + + + + + + + + + + + + + {7657479a-a855-4d97-8c61-098690da9023} + + + {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} + {75431119-9e8e-4e3e-a539-9d7bad6dbf81} + {582af542-5f2d-4660-a6d0-a3bd983d9682} + notify + + + + + x:340;y:430 + + + + + + + + + + + + + + + + + {97f3e5b0-93ca-4351-98d6-ad88567979f7} + + + {963ad9f9-ecad-430f-8233-b7897fa630bd} + {75431119-9e8e-4e3e-a539-9d7bad6dbf81} + {998e7d36-3416-4b2f-843a-a437449f09f1} + push notification + + + + + x:535;y:470 + + + + + x:590;y:470 + + + + + x:615;y:470 + + + + + x:670;y:470 + + + + + x:670;y:365 + + + + + + + 1 + + + + + + 1665083804306 + UseCases + + + + + + + + + + {121189af-36df-4efa-b451-3f1f85ef339f} + + + + + + + + {121189af-36df-4efa-b451-3f1f85ef339f} + + + JavaScript Web Application + + + + + + + {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} + + + + + + + + {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} + + + subscribe + {121189af-36df-4efa-b451-3f1f85ef339f} + {13c69399-5587-4169-a012-8d86216139fd} + + + + + + + + + + {afae2401-ea81-4514-aa80-da53d61a8516} + + + + + + + + {afae2401-ea81-4514-aa80-da53d61a8516} + + + register + {121189af-36df-4efa-b451-3f1f85ef339f} + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + + + + + + + + + + {373c492c-0b9a-4032-9ff4-b3a7cc442883} + + + + + + + + {373c492c-0b9a-4032-9ff4-b3a7cc442883} + + + subscribe with endpoint + {121189af-36df-4efa-b451-3f1f85ef339f} + {13d79379-1727-46a3-947c-e3f2f6eb3a87} + + + + + + + + + + + + + + + + + + + + + {13c69399-5587-4169-a012-8d86216139fd} + + + + + + + + {13c69399-5587-4169-a012-8d86216139fd} + + + Push Manager API + + + + + + + {d9959769-74a4-40ad-bf00-904c12a67309} + + + + + + + + {d9959769-74a4-40ad-bf00-904c12a67309} + + + create subscription + {13c69399-5587-4169-a012-8d86216139fd} + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + 2 + + + + + + + + + + + + + + + + + + + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + + + + + + + + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + + + Service Worker + + + + + + + {bfebbc32-3541-4c1a-b3c6-a3652f700767} + + + + + + + + {bfebbc32-3541-4c1a-b3c6-a3652f700767} + + + push notification + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + 1 + + + + + + + + {89d5f886-1913-4bb7-be32-cdd5cb61eebc} + + + + + + + + {89d5f886-1913-4bb7-be32-cdd5cb61eebc} + + + notify + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + {00b8f12d-e08b-426a-83b8-83fea8907fab} + + + + + + + + + + {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} + + + + + + + + {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} + + + notify + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + {00b8f12d-e08b-426a-83b8-83fea8907fab} + + + + + + + + + + {963ad9f9-ecad-430f-8233-b7897fa630bd} + + + + + + + + {963ad9f9-ecad-430f-8233-b7897fa630bd} + + + push notification + {3f1676be-d3a4-4751-8bcb-400b11c88ada} + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + 1 + + + + + + + + + + + + + + + + + + + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + + + + + + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + Firebase Cloud Messaging + + + + + + + {560fb941-261e-4f45-8909-2106283fdb3e} + + + + + + + + {560fb941-261e-4f45-8909-2106283fdb3e} + + + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + {13c69399-5587-4169-a012-8d86216139fd} + + + + + + + + + + + + + + + + + + + + + {13d79379-1727-46a3-947c-e3f2f6eb3a87} + + + + + + + + {13d79379-1727-46a3-947c-e3f2f6eb3a87} + + + Push Application Server + + + + + + + {94241d64-4e88-4855-8e78-365be237108b} + + + + + + + + {94241d64-4e88-4855-8e78-365be237108b} + + + push notification + {13d79379-1727-46a3-947c-e3f2f6eb3a87} + {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} + + + + + + + + + + + + + + + + + + + + + {00b8f12d-e08b-426a-83b8-83fea8907fab} + + + + + + + + {00b8f12d-e08b-426a-83b8-83fea8907fab} + + + User + + + + + + + {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} + + + + + + + + {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} + + + subscribe + {00b8f12d-e08b-426a-83b8-83fea8907fab} + {121189af-36df-4efa-b451-3f1f85ef339f} + + + + + + + + + + + + + + false + actor + + + + + + + + + + + + + + + + diff --git a/examples/webenginewidgets/push-notifications/server.js b/examples/webenginewidgets/push-notifications/server.js new file mode 100644 index 000000000..fc7deb08a --- /dev/null +++ b/examples/webenginewidgets/push-notifications/server.js @@ -0,0 +1,65 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +const express = require('express'); +const webpush = require('web-push'); + +// setup server +const port = 5000; +const server = express(); +server.use(express.json()); +server.use(express.static('content')); + +// we support only one subscription at the time +var subscription = null; + +// setup vapid keys +const vapidKeys = { + publicKey : + "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg", + privateKey : "HqhrzsRfG5-SB3j45lyUmV7cYZuy-71r2Bb0tgaOefk" +}; + +// set vapid keys for webpush libs +webpush.setVapidDetails('mailto:push@qt.io', vapidKeys.publicKey, vapidKeys.privateKey); + +// add subscribe route +server.post('/subscribe', (req, res) => { + + // subscription request + subscription = req.body; + const delay = req.headers['ping-time']; + console.log('Got subscription with endpoint: ' + subscription.endpoint); + console.log('Ping delay is at: ' + delay); + + // confirm resource created + res.status(201).json({}); + + // schedule notification + setTimeout(() => { sendNotification(delay) }, delay * 1000); +}); + +// add unsubscribe route +server.post('/unsubscribe', (req, res) => { + console.log('Got unsubscribe with endpoint: ' + req.body.endpoint); + subscription = null; + res.status(201).json({}); +}); + +function sendNotification(delay) +{ + if (!subscription) + return; + + // create payload text + const payload = JSON.stringify({ title : 'Ping !', text : 'Visit qt.io', url : 'www.qt.io' }); + + // send notification + console.log('Sending notification !'); + webpush.sendNotification(subscription, payload).catch(err => console.error(err)); + + // schedule next notification + setTimeout(() => { sendNotification(delay) }, delay * 1000); +} + +server.listen(port, () => console.log(`Push server started at port ${port}`)); diff --git a/examples/webenginewidgets/push_notifications/CMakeLists.txt b/examples/webenginewidgets/push_notifications/CMakeLists.txt deleted file mode 100644 index bbb585c9b..000000000 --- a/examples/webenginewidgets/push_notifications/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(simplebrowser LANGUAGES CXX) - -message("\nPlease use simplebrowser to see notifiactions.\n") diff --git a/examples/webenginewidgets/push_notifications/content/index.html b/examples/webenginewidgets/push_notifications/content/index.html deleted file mode 100644 index cce3055cd..000000000 --- a/examples/webenginewidgets/push_notifications/content/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Push Notification Using Node and FCM - - - -

Push Notification Using NodeJS and QtWebEngine

-
-
-
-
- Ping Me Every [sec]: -
-
- -
-
-
-
-
-
-
- - - diff --git a/examples/webenginewidgets/push_notifications/content/ping.js b/examples/webenginewidgets/push_notifications/content/ping.js deleted file mode 100644 index 285a57019..000000000 --- a/examples/webenginewidgets/push_notifications/content/ping.js +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -const publicVapidKey = - "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg"; - -async function setup(delay) -{ - console.log('>> register service worker...'); - const register = await navigator.serviceWorker.register('/worker.js', { scope : '/' }); - console.log('>> service worker registered...'); - - console.log('>> subscribe push subscription to FCM'); - var subscription = await register.pushManager.subscribe( - { userVisibleOnly : true, applicationServerKey : publicVapidKey }); - console.log('>> subscription created...'); - - console.log('>> subscribe to push service...'); - await fetch('/subscribe', { - method : 'POST', - body : JSON.stringify(subscription), - headers : { 'content-type' : 'application/json', 'ping-time' : delay } - }); - console.log('>> push subscription created...') -} - -async function clear() -{ - const register = await navigator.serviceWorker.getRegistration(); - var subscription = await register.pushManager.getSubscription(); - console.log('>> unsubscribe to push service...'); - await fetch('/unsubscribe', { - method : 'POST', - body : JSON.stringify(subscription), - headers : { 'content-type' : 'application/json' } - }); - console.log('>> push unsubscription removed...') - - console.log('>> unsubscribe push subscription to FCM'); - await subscription.unsubscribe(); - console.log('>> subscription removed...'); -} - -function displaySetup(delay = null) -{ - const pingSetup = document.getElementById('ping-setup'); - const pingClear = document.getElementById('ping-clear'); - const pingText = document.getElementById('ping-text'); - if (delay) { - pingClear.style.display = 'block'; - pingSetup.style.display = 'none'; - pingText.innerHTML = 'Ping Me Every ' + delay + ' seconds'; - } else { - pingClear.style.display = 'none'; - pingSetup.style.display = 'block'; - pingText.innerHTML = ""; - } -} - -function handleSetupPing(event) -{ - event.preventDefault(); - - const seconds = document.forms[0].seconds.value; - document.forms[0].reset(); - - // check for service worker support - if ('serviceWorker' in navigator) { - setup(seconds).catch(err => console.error(err)); - } - - displaySetup(seconds); -}; - -function handleClearPing(event) -{ - event.preventDefault(); - clear(); - displaySetup(); -}; - -document.forms[0].addEventListener('submit', handleSetupPing); -const clearButton = document.getElementById('ping-clear-button'); -clearButton.addEventListener('click', handleClearPing); diff --git a/examples/webenginewidgets/push_notifications/content/style.css b/examples/webenginewidgets/push_notifications/content/style.css deleted file mode 100644 index 8176462a2..000000000 --- a/examples/webenginewidgets/push_notifications/content/style.css +++ /dev/null @@ -1,29 +0,0 @@ -body { - font-family: monaco; - height: 100vh; - flex-direction: column; - align-items: center; - justify-content: center; - display: flex; -} -#ping-clear, -#ping-setup { - font-size: 32px; - text-align: center; -} -.form-inputs{ - margin-top: 20px; -} -input { - width: 100px; - height: 30px; -} -button { - font-size: 16px; -} -#ping-text { - margin-bottom: 30px; -} -#ping-clear { - display: none; -} diff --git a/examples/webenginewidgets/push_notifications/content/worker.js b/examples/webenginewidgets/push_notifications/content/worker.js deleted file mode 100644 index ed660a6e9..000000000 --- a/examples/webenginewidgets/push_notifications/content/worker.js +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -self.addEventListener('push', event => { - const data = event.data.json(); - self.registration.showNotification(data.title, { body : data.text }); -}); diff --git a/examples/webenginewidgets/push_notifications/doc/images/notification.png b/examples/webenginewidgets/push_notifications/doc/images/notification.png deleted file mode 100644 index ec5c67457..000000000 Binary files a/examples/webenginewidgets/push_notifications/doc/images/notification.png and /dev/null differ diff --git a/examples/webenginewidgets/push_notifications/doc/images/permissions.png b/examples/webenginewidgets/push_notifications/doc/images/permissions.png deleted file mode 100644 index dedb6e472..000000000 Binary files a/examples/webenginewidgets/push_notifications/doc/images/permissions.png and /dev/null differ diff --git a/examples/webenginewidgets/push_notifications/doc/images/push_notifications.png b/examples/webenginewidgets/push_notifications/doc/images/push_notifications.png deleted file mode 100644 index c5ba5f589..000000000 Binary files a/examples/webenginewidgets/push_notifications/doc/images/push_notifications.png and /dev/null differ diff --git a/examples/webenginewidgets/push_notifications/doc/images/website.png b/examples/webenginewidgets/push_notifications/doc/images/website.png deleted file mode 100644 index 10a4a6150..000000000 Binary files a/examples/webenginewidgets/push_notifications/doc/images/website.png and /dev/null differ diff --git a/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qdoc b/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qdoc deleted file mode 100644 index 1d12a9cc1..000000000 --- a/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qdoc +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - -\example webenginewidgets/push-notifications -\title WebEngine Push Notifications Example -\ingroup webengine-widgetexamples -\brief Demonstrates how to subscribe to and unsubscribe from push notifications. - -In this example we are going to send push notifications from a web push service to the user. -This is the typical scenario where messages are sent from the application server i.e. website -back-end through a 3rd-party push service, to finally arrive at the user's browser in form of -notifications. To demonstrate this flow, we will implement a simple push service server -application, to which the user can subscribe to receive \e ping messages. - -As already mentioned, in such a workflow there are three different parties involved: - -\list - \li the user's web browser where they receive push notifications - \li 3rd-party push service, which is defined by a subscription endpoint and is a part - of a browser's push service implementation - \li application server, which will store user's subscriptions and initiate push messages - using a subscription endpoint -\endlist - -The user visits a website, where a JavaScript web application uses the JavaScript Push API -to create a push notification subscription. The user is then asked to grant a permission -to receive and display push notifications. Once accepted, the Push API establishes a push channel -with a 3rd-party push service, which in case of QtWebEngine is \l {https://firebase.google.com} -{Firebase Cloud Messaging (FCM)}. The unique push subscription is created that -includes the subscription endpoint URL. The browser then sends a subscription message -to the application server forwarding the endpoint setup. The application server can now -use the subscription endpoint to send notifications to the browser. The browser push service -implementation will deliver a push message. However, to show it, a service worker must -be registered. As the service worker runs in the background, it allows displaying notifications -even if a website, which has installed it, is no longer opened. - -\image push_notifications.png - -Let's go more into implementation details. We start with implementing our custom -push service using NodeJS with two modules: - -\list - \li \l {https://github.com/web-push-libs/web-push} {web-push} - provides the web-push protocol - implementation - \li \l {https://github.com/expressjs/express} {express} - provides the web application framework -\endlist - -Let's initialize a new project and install the required modules in the root directory of this -example: - -\snippet /push_notifications/commands 0 - -These commands should create package.js, which defines the start command: - -\snippet /push_notifications/commands 1 - -Now let's move on to the push service back-end implementation in server.js. - -We start by including the required modules and doing basic \e express framework setup, which -we use to create our custom push server. For simplicity we are going to handle only one -subscription at a time. To do that we need to create \e VAPID keys which we are going to -generate with \e web-push libs. The public key is going to be used by the front-end and authenticate -to the service. - -\quotefromfile webenginewidgets/push_notifications/server.js -\skipto const express -\printto add subscribe route - -\note We are not going to cover the encryption of messages in this example. - -To generate keys, we can use the tool shipped with \e web-push lib, that is installed by -\c npm in our example's root directory. - -\snippet /push_notifications/commands 2 - -Now we add two \c routes to the push server. One to \c subscribe and one to \c unsubscribe, -so that our front-end can send an HTTP POST request to handle the push subscription. -In the subscribe request we will get \c subscription in the request body and we also retrieve -the custom header \c ping-time that defines how often the ping messages should be pushed to -the user. We keep around the \c subscription to be able to send push notifications later. -As a confirmation, we send the 201 status code and schedule the first push notification based on -the \c ping-time value. The \c unsubscribe request simply removes a subscription. - -\quotefromfile webenginewidgets/push_notifications/server.js -\skipto add subscribe route -\printto function sendNotification - -The \c sendNotication() function sends push messages using the web-push lib. We create the payload -with the message we want to present to a user and schedule the next push message. - -\quotefromfile webenginewidgets/push_notifications/server.js -\skipto function sendNotification -\printto server.listen - -In the end we start the server to listen on the given port. - -\quotefromfile webenginewidgets/push_notifications/server.js -\skipto server.listen -\printline started - -Let's move now to our front-end. We create a simple page index.html, where the user can enter how -often they want to receive ping notification messages. We will have two buttons: -\e {Ping Me} to subscribe for push notifications and \e Clear to unsubscribe. -In the end we load ping.js, which we cover next. - -\quotefromfile webenginewidgets/push_notifications/content/index.html -\skipto -\printuntil - -The last piece is creating the logic for the push subscription within the front-end. Here we have two -functions, \c setup and \c clear, to handle subscriptions. When the user clicks on the \e {Ping Me} -button, \c setup is called. To be able to receive notifications, the service worker is needed. -This way the user can leave the website and still get notified as the service worker works -in the background and handles incoming messages. To achieve that, we have to first register -one with: - -\quotefromfile webenginewidgets/push_notifications/content/ping.js -\skipto const register -\printline worker.js - -The call to \c cpushManager.subscribe() will trigger a permission prompt, which is displayed to the -user. If the permission is granted, the push subscription is returned. It includes a URL endpoint -that allows sending notifications to the browser, where the registered service worker waits for -push messages. - -\quotefromfile webenginewidgets/push_notifications/content/ping.js -\skipto var subscription -\printto console.log - -As mentioned the subscription is created for FCM and should be now sent to our custom server -with an HTTP POST request. In addition, we add to the post request the HTTP header with the -\c ping-time the user entered on our website. - -\quotefromfile webenginewidgets/push_notifications/content/ping.js -\skipto await fetch -\printto console.log - -The function \c clear call unsubscribes first from our push server by sending an HTTP POST request -and later from the 3rd-party push service (FCM). - -\quotefromfile webenginewidgets/push_notifications/content/ping.js -\skipuntil async function clear() -\skipuntil { -\printto console.log -\dots -\skipto await fetch -\printto console.log -\dots -\skipto await subscription -\printto console.log - -The rest of code in ping.js is just boilerplate code to read a user provided value -and call \c setup() or \c clear(). - -As the last part of the front-end let's look inside a service worker script, where we simply -register an event listener for \e push events. - -\quotefromfile webenginewidgets/push_notifications/content/worker.js -\skipto self -\printuntil }); -\printuntil }); - -When a push event comes we simply use the Notification JavaScript API to display a notification. - -\note QtWebEngine Notification Example shows how to provide your own handler and customize -the look and feel of a notification message. - -Having the implementation in place, we can start the server on localhost at the port 5000. -To do that, we can simply enter in the console in the project's root directory: - -\snippet /push_notifications/commands 3 - -Now we can fire up \e simplebrowser and enter \c http:\\localhost:5000 as a URL. - -\image website.png - -\note \c QWebEngineProfile cannot be set to \e off-the-record, because push messages would be -disabled. - -After granting the permission we can send our ping request: - -\image permissions.png - -We should see the coming push notification: - -\image notification.png - -\note To troubleshoot errors, open \e {Developer Tools} from Tools menu. -*/ diff --git a/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qmodel b/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qmodel deleted file mode 100644 index 048a55911..000000000 --- a/examples/webenginewidgets/push_notifications/doc/src/push_notifications.qmodel +++ /dev/null @@ -1,837 +0,0 @@ - - - - {9fd14f7e-7b67-4e13-9980-ef8fbe24b780} - - - - - - - - {a26e0efd-1b21-4fba-96ce-a607bbcdb4f7} - - - push_notifications - - - - - - - {6b1a06e9-960b-4a10-872e-5504d8c0b127} - - - - - - - - - - {6b1a06e9-960b-4a10-872e-5504d8c0b127} - - - push_notifications - - - - - - - - - - {d50762f2-c7f4-4d52-9592-8bcc07274ba1} - - - Browser / User Agent - x:415;y:390 - x:-105;y:-125;w:210;h:250 - - - - - - - - - - - {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} - - - {121189af-36df-4efa-b451-3f1f85ef339f} - JavaScript Web Application - x:410;y:395 - x:-75;y:-15;w:150;h:30 - 0 - - - false - - - - - - - - - - - {8bde1815-304a-41f6-8528-c754dc3d1eda} - - - {13c69399-5587-4169-a012-8d86216139fd} - Push Manager API - x:410;y:320 - x:-75;y:-15;w:150;h:30 - false - 0 - - - false - - - - - - - - - - - {75431119-9e8e-4e3e-a539-9d7bad6dbf81} - - - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - Service Worker - x:410;y:470 - x:-75;y:-15;w:150;h:30 - false - 0 - - - false - - - - - - - - - - - {0a7b0146-d34b-4c39-a1af-df15a1b4108d} - - - {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} - {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} - {8bde1815-304a-41f6-8528-c754dc3d1eda} - subscribe - - - - - - - - - - - - - {e7d4a675-ddbd-41aa-a802-32221a56dae2} - - - {afae2401-ea81-4514-aa80-da53d61a8516} - {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} - {75431119-9e8e-4e3e-a539-9d7bad6dbf81} - register - - - - - - - - - - - - - {998e7d36-3416-4b2f-843a-a437449f09f1} - - - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - Firebase Cloud Messaging - x:770;y:320 - x:-75;y:-15;w:150;h:30 - 6 - - - false - - - - - - - - - - - {28c1fccd-c50e-458c-865d-4ba41d55690b} - - - {d9959769-74a4-40ad-bf00-904c12a67309} - {8bde1815-304a-41f6-8528-c754dc3d1eda} - {998e7d36-3416-4b2f-843a-a437449f09f1} - create subscription - - - 2 - - - - - - - - - - - {ba581e41-cc00-4129-adae-0a1208bb3222} - - - {13d79379-1727-46a3-947c-e3f2f6eb3a87} - Push Application Server - x:770;y:390 - x:-75;y:-15;w:150;h:30 - false - 6 - - - false - - - - - - - - - - - {e796d1cc-f574-45db-a440-7e47d7560d71} - - - {373c492c-0b9a-4032-9ff4-b3a7cc442883} - {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} - {ba581e41-cc00-4129-adae-0a1208bb3222} - subscribe with endpoint - - - - - - - - - - - - - {6332f8ae-ef9d-4c15-9fbf-d6ee06ba3f84} - - - {94241d64-4e88-4855-8e78-365be237108b} - {ba581e41-cc00-4129-adae-0a1208bb3222} - {998e7d36-3416-4b2f-843a-a437449f09f1} - push notification - - - - - x:770;y:335 - - - - - - - - - - - - - - - - - {582af542-5f2d-4660-a6d0-a3bd983d9682} - - - {00b8f12d-e08b-426a-83b8-83fea8907fab} - User - x:185;y:395 - x:-10;y:-20;w:20;h:40 - 0 - - - actor - false - - - - - - - - - - - {66ca12e1-84a1-4247-82e5-ae6891f3f376} - - - {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} - {582af542-5f2d-4660-a6d0-a3bd983d9682} - {cc80cad6-2e47-4913-aeb1-0c6f41de44bb} - subscribe - - - - - - - - - - - - - {7657479a-a855-4d97-8c61-098690da9023} - - - {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} - {75431119-9e8e-4e3e-a539-9d7bad6dbf81} - {582af542-5f2d-4660-a6d0-a3bd983d9682} - notify - - - - - x:340;y:430 - - - - - - - - - - - - - - - - - {97f3e5b0-93ca-4351-98d6-ad88567979f7} - - - {963ad9f9-ecad-430f-8233-b7897fa630bd} - {75431119-9e8e-4e3e-a539-9d7bad6dbf81} - {998e7d36-3416-4b2f-843a-a437449f09f1} - push notification - - - - - x:535;y:470 - - - - - x:590;y:470 - - - - - x:615;y:470 - - - - - x:670;y:470 - - - - - x:670;y:365 - - - - - - - 1 - - - - - - 1665083804306 - UseCases - - - - - - - - - - {121189af-36df-4efa-b451-3f1f85ef339f} - - - - - - - - {121189af-36df-4efa-b451-3f1f85ef339f} - - - JavaScript Web Application - - - - - - - {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} - - - - - - - - {648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d} - - - subscribe - {121189af-36df-4efa-b451-3f1f85ef339f} - {13c69399-5587-4169-a012-8d86216139fd} - - - - - - - - - - {afae2401-ea81-4514-aa80-da53d61a8516} - - - - - - - - {afae2401-ea81-4514-aa80-da53d61a8516} - - - register - {121189af-36df-4efa-b451-3f1f85ef339f} - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - - - - - - - - - - {373c492c-0b9a-4032-9ff4-b3a7cc442883} - - - - - - - - {373c492c-0b9a-4032-9ff4-b3a7cc442883} - - - subscribe with endpoint - {121189af-36df-4efa-b451-3f1f85ef339f} - {13d79379-1727-46a3-947c-e3f2f6eb3a87} - - - - - - - - - - - - - - - - - - - - - {13c69399-5587-4169-a012-8d86216139fd} - - - - - - - - {13c69399-5587-4169-a012-8d86216139fd} - - - Push Manager API - - - - - - - {d9959769-74a4-40ad-bf00-904c12a67309} - - - - - - - - {d9959769-74a4-40ad-bf00-904c12a67309} - - - create subscription - {13c69399-5587-4169-a012-8d86216139fd} - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - 2 - - - - - - - - - - - - - - - - - - - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - - - - - - - - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - - - Service Worker - - - - - - - {bfebbc32-3541-4c1a-b3c6-a3652f700767} - - - - - - - - {bfebbc32-3541-4c1a-b3c6-a3652f700767} - - - push notification - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - 1 - - - - - - - - {89d5f886-1913-4bb7-be32-cdd5cb61eebc} - - - - - - - - {89d5f886-1913-4bb7-be32-cdd5cb61eebc} - - - notify - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - {00b8f12d-e08b-426a-83b8-83fea8907fab} - - - - - - - - - - {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} - - - - - - - - {eef542f5-e2cf-40a8-92c9-9892f3d06e1f} - - - notify - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - {00b8f12d-e08b-426a-83b8-83fea8907fab} - - - - - - - - - - {963ad9f9-ecad-430f-8233-b7897fa630bd} - - - - - - - - {963ad9f9-ecad-430f-8233-b7897fa630bd} - - - push notification - {3f1676be-d3a4-4751-8bcb-400b11c88ada} - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - 1 - - - - - - - - - - - - - - - - - - - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - - - - - - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - Firebase Cloud Messaging - - - - - - - {560fb941-261e-4f45-8909-2106283fdb3e} - - - - - - - - {560fb941-261e-4f45-8909-2106283fdb3e} - - - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - {13c69399-5587-4169-a012-8d86216139fd} - - - - - - - - - - - - - - - - - - - - - {13d79379-1727-46a3-947c-e3f2f6eb3a87} - - - - - - - - {13d79379-1727-46a3-947c-e3f2f6eb3a87} - - - Push Application Server - - - - - - - {94241d64-4e88-4855-8e78-365be237108b} - - - - - - - - {94241d64-4e88-4855-8e78-365be237108b} - - - push notification - {13d79379-1727-46a3-947c-e3f2f6eb3a87} - {5a7b90ea-801e-43ea-a0b5-edaa59761b5b} - - - - - - - - - - - - - - - - - - - - - {00b8f12d-e08b-426a-83b8-83fea8907fab} - - - - - - - - {00b8f12d-e08b-426a-83b8-83fea8907fab} - - - User - - - - - - - {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} - - - - - - - - {6d0ce78f-28e1-4a82-a443-59f4efcb8e66} - - - subscribe - {00b8f12d-e08b-426a-83b8-83fea8907fab} - {121189af-36df-4efa-b451-3f1f85ef339f} - - - - - - - - - - - - - - false - actor - - - - - - - - - - - - - - - - diff --git a/examples/webenginewidgets/push_notifications/push_notifications.pro b/examples/webenginewidgets/push_notifications/push_notifications.pro deleted file mode 100644 index f88018da2..000000000 --- a/examples/webenginewidgets/push_notifications/push_notifications.pro +++ /dev/null @@ -1 +0,0 @@ -message("Please use simplebrowser example to see notificationsi.") diff --git a/examples/webenginewidgets/push_notifications/server.js b/examples/webenginewidgets/push_notifications/server.js deleted file mode 100644 index fc7deb08a..000000000 --- a/examples/webenginewidgets/push_notifications/server.js +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -const express = require('express'); -const webpush = require('web-push'); - -// setup server -const port = 5000; -const server = express(); -server.use(express.json()); -server.use(express.static('content')); - -// we support only one subscription at the time -var subscription = null; - -// setup vapid keys -const vapidKeys = { - publicKey : - "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg", - privateKey : "HqhrzsRfG5-SB3j45lyUmV7cYZuy-71r2Bb0tgaOefk" -}; - -// set vapid keys for webpush libs -webpush.setVapidDetails('mailto:push@qt.io', vapidKeys.publicKey, vapidKeys.privateKey); - -// add subscribe route -server.post('/subscribe', (req, res) => { - - // subscription request - subscription = req.body; - const delay = req.headers['ping-time']; - console.log('Got subscription with endpoint: ' + subscription.endpoint); - console.log('Ping delay is at: ' + delay); - - // confirm resource created - res.status(201).json({}); - - // schedule notification - setTimeout(() => { sendNotification(delay) }, delay * 1000); -}); - -// add unsubscribe route -server.post('/unsubscribe', (req, res) => { - console.log('Got unsubscribe with endpoint: ' + req.body.endpoint); - subscription = null; - res.status(201).json({}); -}); - -function sendNotification(delay) -{ - if (!subscription) - return; - - // create payload text - const payload = JSON.stringify({ title : 'Ping !', text : 'Visit qt.io', url : 'www.qt.io' }); - - // send notification - console.log('Sending notification !'); - webpush.sendNotification(subscription, payload).catch(err => console.error(err)); - - // schedule next notification - setTimeout(() => { sendNotification(delay) }, delay * 1000); -} - -server.listen(port, () => console.log(`Push server started at port ${port}`)); diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro index c22df271d..cfddfdaae 100644 --- a/examples/webenginewidgets/webenginewidgets.pro +++ b/examples/webenginewidgets/webenginewidgets.pro @@ -9,7 +9,7 @@ SUBDIRS += \ notifications \ simplebrowser \ stylesheetbrowser \ - push_notifications \ + push-notifications \ videoplayer \ webui diff --git a/src/webenginewidgets/doc/snippets/push-notifications/commands b/src/webenginewidgets/doc/snippets/push-notifications/commands new file mode 100644 index 000000000..aee9761c1 --- /dev/null +++ b/src/webenginewidgets/doc/snippets/push-notifications/commands @@ -0,0 +1,19 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [0] +npm init -y +npm install web-push express +//! [0] + +//! [1] +"start": "node server.js" +//! [1] + +//! [2] +./node_odules/.bin/web-push generate-vapid-keys +//! [2] + +//! [3] +npm start +//! [3] diff --git a/src/webenginewidgets/doc/snippets/push_notifications/commands b/src/webenginewidgets/doc/snippets/push_notifications/commands deleted file mode 100644 index aee9761c1..000000000 --- a/src/webenginewidgets/doc/snippets/push_notifications/commands +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -//! [0] -npm init -y -npm install web-push express -//! [0] - -//! [1] -"start": "node server.js" -//! [1] - -//! [2] -./node_odules/.bin/web-push generate-vapid-keys -//! [2] - -//! [3] -npm start -//! [3] -- cgit v1.2.3