إبلاغك بالتغييرات التي تطرأ على الإشعارات

في البداية، أعتذر عن هذا العنوان الرديء، ولكنني لم أ التعبير عنه.

في Chrome 44، تتم إضافة Notfication.data وServiceWorkerRegistration.getNotifications() وفتح / تبسيط بعض حالات الاستخدام الشائعة عند التعامل مع الإشعارات التي تتضمّن رسائل فورية.

بيانات الإشعارات

تتيح لك Notification.data ربط كائن JavaScript بإشعار.

ويتلخص ذلك بشكل أساسي في أنه عندما تتلقّى رسالة فورية، يمكنك إنشاء إشعار يحتوي على بعض البيانات، ثم في حدث notifications click، يمكنك الحصول على الإشعار الذي تمّ النقر عليه والحصول على بياناته.

على سبيل المثال، يمكنك إنشاء كائن بيانات وإضافته إلى خيارات الإشعارات، كما يلي:

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    var title = 'Yay a message.';
    var body = 'We have received a push message.';
    var icon = '/images/icon-192x192.png';
    var tag = 'simple-push-demo-notification-tag';
    var data = {
    doge: {
        wow: 'such amaze notification data'
    }
    };

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag,
        data: data
    })
    );
});

يعني أنه يمكننا الحصول على المعلومات في حدث notificationsclick:

self.addEventListener('notificationclick', function(event) {
    var doge = event.notification.data.doge;
    console.log(doge.wow);
});

قبل ذلك، كان عليك تخزين البيانات في IndexDB أو وضع شيء في نهاية عنوان URL للرمز.

ServiceWorkerRegistration.getNotifications()

من بين الطلبات الشائعة التي يرسلها المطوّرون الذين يعملون على تطوير الإشعارات الفورية التحكّم بشكل أفضل في الإشعارات التي يعرضونها.

ومن أمثلة حالات الاستخدام تطبيق الدردشة حيث يرسل المستخدم رسائل متعددة ويعرض المستلم إشعارات متعددة. من المفترض أن يتمكن تطبيق الويب من ملاحظة أن لديك العديد من الإشعارات التي لم يتم عرضها ثم تصغيرها في إشعار واحد.

بدون getNotifications() أفضل ما يمكنك القيام به هو استبدال الإشعار السابق بآخر رسالة. باستخدام getNotifications() ، يمكنك "تصغير" الإشعارات إذا كان هناك إشعار معروضًا، مما يؤدي إلى تجربة مستخدم أفضل.

مثال على تجميع الإشعارات معًا

التعليمة البرمجية للقيام بذلك بسيطة نسبيًا. داخل حدث الإشعارات الفورية، استدعِ ServiceWorkerRegistration.getNotifications() للحصول على مجموعة من الإشعارات الحالية، ومن هناك حدِّد السلوك الصحيح، سواء كان ذلك تصغير جميع الإشعارات أو باستخدام Notification.tag.

function showNotification(title, body, icon, data) {
    var notificationOptions = {
    body: body,
    icon: icon ? icon : 'images/touch/chrome-touch-icon-192x192.png',
    tag: 'simple-push-demo-notification',
    data: data
    };

    self.registration.showNotification(title, notificationOptions);
    return;
}

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    // Since this is no payload data with the first version
    // of Push notifications, here we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        console.log('Looks like there was a problem. Status Code: ' +
            response.status);
        // Throw an error so the promise is rejected and catch() is executed
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        var title = 'You have a new message';
        var message = data.message;
        var icon = 'images/notification-icon.png';
        var notificationTag = 'chat-message';

        var notificationFilter = {
            tag: notificationTag
        };
        return self.registration.getNotifications(notificationFilter)
            .then(function(notifications) {
            if (notifications && notifications.length > 0) {
                // Start with one to account for the new notification
                // we are adding
                var notificationCount = 1;
                for (var i = 0; i < notifications.length; i++) {
                var existingNotification = notifications[i];
                if (existingNotification.data &&
                    existingNotification.data.notificationCount) {
                    notificationCount +=
existingNotification.data.notificationCount;
                } else {
                    notificationCount++;
                }
                existingNotification.close();
                }
                message = 'You have ' + notificationCount +
                ' weather updates.';
                notificationData.notificationCount = notificationCount;
            }

            return showNotification(title, message, icon, notificationData);
            });
        });
    }).catch(function(err) {
        console.error('Unable to retrieve data', err);

        var title = 'An error occurred';
        var message = 'We were unable to get the information for this ' +
        'push message';

        return showNotification(title, message);
    })
    );
});

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event);

    if (Notification.prototype.hasOwnProperty('data')) {
    console.log('Using Data');
    var url = event.notification.data.url;
    event.waitUntil(clients.openWindow(url));
    } else {
    event.waitUntil(getIdb().get(KEY_VALUE_STORE_NAME,
event.notification.tag).then(function(url) {
        // At the moment you cannot open third party URL's, a simple trick
        // is to redirect to the desired URL from a URL on your domain
        var redirectUrl = '/redirect.html?redirect=' +
        url;
        return clients.openWindow(redirectUrl);
    }));
    }
});

أول ما يجب التركيز عليه باستخدام مقتطف الرمز هذا هو أننا نجري فلترة إشعاراتنا عن طريق تمرير كائن فلتر إلى getNotifications(). وهذا يعني أنه يمكننا الحصول على قائمة بالإشعارات لعلامة معينة (في هذا المثال لمحادثة معينة).

var notificationFilter = {
    tag: notificationTag
};
return self.registration.getNotifications(notificationFilter)

بعد ذلك، نلقي نظرة على الإشعارات المرئية ونتحقق مما إذا كان هناك عدد الإشعارات مرتبط بهذا الإشعار وزيادته استنادًا إلى ذلك. بهذه الطريقة، إذا كان هناك إشعار واحد يخبر المستخدم بأن هناك رسالتين غير مقروءتين، فسنرغب في الإشارة إلى أن هناك ثلاث رسائل غير مقروءة عند وصول دفعة جديدة.

var notificationCount = 1;
for (var i = 0; i < notifications.length; i++) {
    var existingNotification = notifications[i];
    if (existingNotification.data && existingNotification.data.notificationCount) {
    notificationCount += existingNotification.data.notificationCount;
    } else {
    notificationCount++;
    }
    existingNotification.close();
}

ونؤكد على أهمية طلب المساعدة من خلال استدعاء close() على الإشعار للتأكد من إزالته من قائمة الإشعارات. هذا خطأ في Chrome نظرًا لأن كل إشعار يتم استبداله بالإشعار التالي بسبب استخدام العلامة نفسها. في الوقت الحالي، لا يظهر هذا الاستبدال في الصفيف المعروض من getNotifications().

هذا مثال واحد فقط على getNotifications() ، وكما يمكنك أن تتخيل، تفتح واجهة برمجة التطبيقات هذه مجموعة من حالات الاستخدام الأخرى.

NotificationOptions.vibrate

بدءًا من Chrome 45، يمكنك تحديد نمط الاهتزاز عند إنشاء إشعار. على الأجهزة التي تتوافق مع Vibration API - الموجودة حاليًا فقط في Chrome لنظام Android - يتيح لك ذلك تخصيص نمط الاهتزاز الذي سيتم استخدامه عند عرض الإشعار.

قد يكون نمط الاهتزاز إما صفيفًا من الأرقام أو رقمًا فرديًا يتم التعامل معه كصفيف من رقم واحد. تمثل القيم في الصفيفة الأوقات بالمللي ثانية، والفهارس الزوجية (0، 2، 4، ...) هي مدة الاهتزاز، والمؤشرات الفردية هي المدة التي تتوقف مؤقتًا قبل الاهتزاز التالي.

self.registration.showNotification('Buzz!', {
    body: 'Bzzz bzzzz',
    vibrate: [300, 100, 400] // Vibrate 300ms, pause 100ms, then vibrate 400ms
});

طلبات الميزات الشائعة المتبقية

والطلب الوحيد المتبقي من المطوّرين هو إغلاق إشعار بعد فترة زمنية معيّنة، أو إمكانية إرسال إشعار فوري بهدف إغلاق الإشعار إذا كان مرئيًا فقط.

وحاليًا ليست هناك طريقة تتيح لك ذلك، ولا شيء في المواصفات يسمح بذلك :( إلا أن فريق هندسة Chrome على علم بحالة الاستخدام هذه.

إشعارات Android

على سطح المكتب، يمكنك إنشاء إشعار باستخدام الرمز التالي:

new Notification('Hello', {body: 'Yay!'});

لم يكن ذلك متاحًا مطلقًا على Android بسبب القيود المفروضة على النظام الأساسي: لا يمكن تحديدًا في Chrome إتاحة عمليات الاستدعاء في كائن الإشعار، مثل click. ولكن يُستخدم على سطح المكتب لعرض الإشعارات لتطبيقات الويب التي قد تكون مفتوحة لديك حاليًا.

السبب الوحيد الذي أذكره هو أنه في البداية، يساعدك اكتشاف ميزة بسيطة مثل الميزة أدناه في دعم سطح المكتب وعدم التسبب في أي أخطاء على Android:

if (!'Notification' in window) {
    // Notifications aren't supported
    return;
}

ومع ذلك، مع إتاحة الإشعارات الفورية في Chrome لنظام Android، يمكن إنشاء الإشعارات من ServiceWorker، ولكن ليس من صفحة ويب، ما يعني أن ميزة اكتشاف هذه الميزة لم تعد مناسبة. إذا حاولت إنشاء إشعار على Chrome لنظام Android، فإنك ستتلقى رسالة الخطأ هذه:

_Uncaught TypeError: Failed to construct 'Notification': Illegal constructor.
Use ServiceWorkerRegistration.showNotification() instead_

أفضل طريقة لميزة الرصد على أجهزة Android وأجهزة الكمبيوتر المكتبي في الوقت الحالي هي تنفيذ ما يلي:

    function isNewNotificationSupported() {
        if (!window.Notification || !Notification.requestPermission)
            return false;
        if (Notification.permission == 'granted')
            throw new Error('You must only call this \*before\* calling
    Notification.requestPermission(), otherwise this feature detect would bug the
    user with an actual notification!');
        try {
            new Notification('');
        } catch (e) {
            if (e.name == 'TypeError')
                return false;
        }
        return true;
    }

يمكن استخدام هذا على النحو التالي:

    if (window.Notification && Notification.permission == 'granted') {
        // We would only have prompted the user for permission if new
        // Notification was supported (see below), so assume it is supported.
        doStuffThatUsesNewNotification();
    } else if (isNewNotificationSupported()) {
        // new Notification is supported, so prompt the user for permission.
        showOptInUIForNotifications();
    }