Notification API – sposób na powiadomienia w (nie)dalekiej przyszłości?


4 lutego 2014 / Michał Załęcki


Przeważnie lubimy być powiadamiani o różnych wydarzeniach. Powiadomienia pełnią rolę stricte informacyjną lub zachęcają nas do konkretnego działania: odpisanie na wiadomość, kliknięcie itd. W moim przypadku najczęściej powiadamia mnie Skype czy inne aplikacje dla Modern UI jak kalendarz no i mój smartfon.

Zarówno sam Modern UI jak i smartfony mają, czy raczej miały, przewagę nad stronami w kwestii powiadomień gdyż potrafią wyświetlić je „na interfejsie”. Powoli przeglądarki zaczynają do tego dojrzewać. W Google Chrome zaimplementowano nawet osobny zasobnik na powiadomienia. Mozilla Firefox za to sztywno trzyma się specyfikacji W3C, która nadal jest w fazie working draft.

Notification API pozwala nam na wykorzystanie funkcji powiadomień w nadzwyczaj prosty sposób. Google Chrome posiada dodatkowo własny obiekt do korzystania z powiadomień, jednak nie będę go omawiał w tym wpisie. Nie ma takiej potrzeby, gdyż rozwiązanie oparte o API od W3C działa wystarczająco dobrze.

Stworzyłem demo (UWAGA: dźwięk powiadomień), które pokaże w jaki sposób możemy wykorzystać Notification API na przykładzie powiadomień z jakimi spotykamy się na portalach społecznościach. Kod do pobrania znajdziecie, jak zawsze, na GitHub.

HTML

Jak zapewne zauważyłeś w demo korzystam z grafiki wektorowej. Jeżeli jesteś zainteresowany używaniem SVG na stronie pewnie zaciekawi Cię wpis, który poświęciłem wykonaniu takiego pliku i wykorzystaniu go w prostej animacji: Prosta animacja z wykorzystaniem SVG i JavaScript.

CSS

JavaScript

1. Definicja potrzebnych zmiennych

Na początek definiujemy potrzebne zmienne. Kwestię dźwięku w powiadomieniach rozwiążemy tworząc obiekt Audio jeżeli jest wspierany przez przeglądarkę.

2. Dodzwaniamy obiektem?

Tworzenie osobnej klasy tylko po to by wysłać powiadomienie? Na pierwszy rzut oka, pewnie i drugi, przerost formy nad treścią, ale pozwala to na sprytne obejście pewnego problemu. Jaki to problem? Analizując kod w ciemno możemy odpowiedzieć, że chodzi o uprawnienia.

Diabeł tkwi w szczegółach. By wyświetlić powiadomienie nie możemy po prostu zapytać o to użytkownika w momencie wejścia na stronę, to by było za proste. Pytanie o uprawnienia musi wystąpić w wyniku zdarzenia click. Zwróć na to uwagę gdy będziemy patrzyli jak wygląda to w przypadku Gmaila.

Dodatkowo Google Chrome komplikuje sprawę nie implementując właściwości permission.

3. Powiadamiamy

Trzy funkcje friendNotification, msgNotification i infoNotification odpowiadają za powiadomienia odnoście nowej znajomości, nowej wiadomości i jakiejś innej, bliżej nieokreślonej informacji. Nie ukrywam, że Facebook był tu pewną inspiracją.

Wszystkie trzy funkcje inkrementują licznik powiadomień odpowiedniego typu, wyświetlają powiadomienie i odtwarzają dźwięk (R.I.P. Headphone Users).

W konstruktorze powiadomienia przekazujemy tytuł i opcjonalnie w drugim parametrze inne opcje. Pełny opis obiektu powiadomienia znajdziecie na stronie MDN.

Ostatnia funkcja notificationsNotSupported wyświetla komunikat gdy powiadomienia nie są wspierane.

4. Reagujemy na zdarzenia

Teraz możemy przyjrzeć się działaniu instancji klasy OnNotifyReady. Pozwala ona na stworzenie prostego warunku jednocześnie wywołując funkcję przekazaną w parametrze w momencie uzyskania uprawnień lub od razu jeżeli uprawnienia zostały już przyznane. Obiekt nie jest nam do niczego potrzebny po sprawdzeniu warunku więc nie ma sensu przypisywać go do zmiennej i zaśmiecać pamięci.

Praktyczne podejście do tematu w wykonaniu Google

Powiadomienia są już wykorzystywane w środowisku produkcyjnym m. in. w usłudze Gmail. Po wejściu do skrzynki jesteśmy pytani czy chcemy korzystać z powiadomień czatu. Odpowiednie powiadomienia możemy włączyć również dla wiadomości email.

Działa? Działa!

Podsumowanie

Notification API nie jest może znaczącą zmianą jaką wprowadza HTML5 jak IndexedDB, ale jednocześnie jest na tyle proste w użyciu, że z powodzeniem możemy je zaimplementować bez użycia dodatkowej abstrakcji.

Przedstawione rozwiązanie jest sposobem zaprezentowania niektórych możliwości Notification API. Nie ulega wątpliwości, że nie jest to rozwiązanie, które można przenieść do wersji produkcyjnej jakiegoś serwisu, kwestia bezpieczeństwa nie była tutaj kluczowa.

Przydatne linki



5 odpowiedzi na “Notification API – sposób na powiadomienia w (nie)dalekiej przyszłości?”

  1. Tomasz Piątek pisze:

    Całkiem fajne :) kiedyś się przyda na pewno :)

  2. Comandeer pisze:

    >Notification API nie jest może znaczącą zmianą jaką wprowadza HTML5 jak IndexedDB
    IMO więcej się znajdzie zastosowań dla powiadomień niźli dla IndexedDB ;)
    Skoro już chcesz się bawić w ładne opakowanie tego klasami, to polecam zrobić klasę Notifier, która zarządzałaby ładnie wszystkimi powiadomieniami + np. implementowałaby jakieś queue. Następnie poszczególny rodzaj powiadomień byłby odpowiednią klasą potomną z odpowiednimi metodami (albo po prostu wywołanie Notifier przyjmowałoby inne wartości). Wówczas całość sprowadziłaby się do czegoś postaci Notifier.push(notka); i już – ładne zunifikowane rozwiązanie
    co do odpalania dźwięku – czemu nie jest to jako część callbacku, np onshow? Miałoby to wówczas większy sens. ogólnie nie podoba mi się aktualna klasa OnNotifyReady – jej nazwa wskazuje, że to event handler – a raczej tak nie jest (to już raczej NotifyPermissionPrompt). no i w obecnej postaci niespecjalnie ułatwia ;)
    btw repo na gh jest puste

    • > IMO więcej się znajdzie zastosowań dla powiadomień niźli dla IndexedDB ;)
      Nie powiedziałbym. Notification API pozwala… stworzyć powiadomienie, na IndexedDB na upartego można oprzeć logikę biznesową. Potraktuje to jako uszczypliwość w kontekście durnego API IndexedDB.

      > Skoro już chcesz się bawić w ładne opakowanie tego klasami
      Nie przypominam sobie bym coś takiego proponował. Nie jestem zwolennikiem pakowanie każdej nowej funkcjonalności w biblioteki – nie po to powstają API. Moje rozwiązanie rozwiązuje mój, jeden problem – cel osiągnięty. Wszystko można zawsze zrobić inaczej, lepiej lub gorzej.

      > czemu nie jest to jako część callbacku, np onshow
      Bo to zmieni działanie w Chrome? Odpal parę powiadomień, konsola prawdę Ci powie. Dźwięk odpalałby się po zamknięciu powiadomienia jeżeli w kolejce czekałoby kolejne, a nie w momencie wystąpienia jakiejś akcji (np. nowa wiadomość, zaproszenie itd.)

      > ogólnie nie podoba mi się aktualna klasa OnNotifyReady
      Nie jest to najbardziej fortunna nazwa, ale: 1) Zaczyna się wielką literą więc widać, że to nie event handler, a przynajmniej nie tak jak sobie to możemy wyobrażać, jeżeli znamy popularne konwencje. 2) NotifyPermissionPrompt sugeruje, że jest to pytanie, ale zwraca wartość true/false jak prompt()? Nie, bo jest asynchroniczne. Tak czy inaczej nazwa klasy pozostaje, przynajmniej dla mnie, w kategoriach kosmetyki.

      • Comandeer pisze:

        >Notification API pozwala… stworzyć powiadomienie, na IndexedDB na upartego można oprzeć logikę biznesową.
        z tym, że większość stron w Sieci wciąż raczej potrzebuje tylko czegoś tak nieskomplikowanego, jak powiadomienia – prawdziwych webappów jest na tyle mało, że mało kto wykorzysta IndexedDB. o to mi chodziło

        >Nie jestem zwolennikiem pakowanie każdej nowej funkcjonalności w biblioteki – nie po to powstają API.
        umówmy się: czyste API, w formie, w jakiej serwuje nam je W3C, są po prostu niestrawne w większości zastosowań. dlatego ja wolę mieć ładną klasę na tym, która a) dawałaby mi sensowny sposób na wykorzystanie API b) rozwiązywałaby crossbrowserowe problemy/dawała polyfill

        >Bo to zmieni działanie w Chrome?
        jak dla mnie takie działanie byłoby poprawne – dźwięk w momencie pojawienia się danego powiadomienia. osobiście nie uznaję tego za błąd. ale ok, jeśli chodzi Ci o odpalenie danej rzeczy przy wystąpieniu akcji a nie powiadomienia – wówczas obecne rozwiązanie jest lepsze

        >Zaczyna się wielką literą więc widać, że to nie event handler, a przynajmniej nie tak jak sobie to możemy wyobrażać, jeżeli znamy popularne konwencje.
        owszem, konwencja Crockforda mówi, że to konstruktor, ale w specce DOM pisze również, że handlerem nie musi być funkcja a obiekt ;) wówczas po pobieżnym rzucie okiem na kod, dalej wygląda to na event handler :P

        >NotifyPermissionPrompt sugeruje, że jest to pytanie, ale zwraca wartość true/false jak prompt()? Nie, bo jest asynchroniczne
        faktycznie, NotifyPermissionRequest brzmiałoby lepiej w tym kontekście

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *