Sık kullanılan bildirim kalıpları

Matt Gaunt

Web aktarımı için yaygın olarak kullanılan bazı uygulama kalıplarına göz atacağız.

Bu, Service Worker'da mevcut olan birkaç farklı API'nin kullanılmasını gerektirir.

Bildirimi kapatma etkinliği

Son bölümde notificationclick etkinliklerini nasıl dinleyebileceğimizi gördük.

Ayrıca, kullanıcı şunlardan birini kapatırsa çağrılan bir notificationclose etkinliği vardır: (ör. kullanıcı bildirimi tıklamak yerine çarpı işaretini tıklar veya bildirim uzakta).

Bu etkinlik genellikle bildirimlerle kullanıcı etkileşimini takip etmek amacıyla analizler için kullanılır.

self.addEventListener('notificationclose', function (event) {
  const dismissedNotification = event.notification;

  const promiseChain = notificationCloseAnalytics();
  event.waitUntil(promiseChain);
});

Bildirime veri ekleme

Bir push mesajı alındığında, genellikle yalnızca yararlı olabilir. Örneğin, URL'nin Bir bildirim tıklandığında açılması gereken bir dosya seçin.

Push etkinliğinden veri almanın ve bunu bir etkinliğe eklemenin en kolay yolu bildirim, iletilen seçenekler nesnesine bir data parametresi eklemektir showNotification() konumuna ekleyin. Örneğin:

const options = {
  body:
    'This notification has data attached to it that is printed ' +
    "to the console when it's clicked.",
  tag: 'data-notification',
  data: {
    time: new Date(Date.now()).toString(),
    message: 'Hello, World!',
  },
};
registration.showNotification('Notification with Data', options);

Tıklama işleyicinin içinde, verilere event.notification.data ile erişilebilir.

const notificationData = event.notification.data;
console.log('');
console.log('The notification data has the following parameters:');
Object.keys(notificationData).forEach((key) => {
  console.log(`  ${key}: ${notificationData[key]}`);
});
console.log('');

Pencere aç

Bildirimlere verilen en yaygın yanıtlardan biri pencere / sekme gibi URL'ler oluşturabilirsiniz. Bunu aynı zamanda clients.openWindow() API'ye gidin.

notificationclick etkinliğimizde aşağıdaki gibi bir kod çalıştırırız:

const examplePage = '/demos/notification-examples/example-page.html';
const promiseChain = clients.openWindow(examplePage);
event.waitUntil(promiseChain);

Bir sonraki bölümde, kullanıcıyı yönlendirmek istediğimiz sayfanın doğru bir şekilde web olup olmadığını kontrol edin. Bu şekilde, yeni sekme açmak yerine açık sekmeye odaklanabiliriz sekmelerinde görebilirsiniz.

Mevcut bir pencereye odaklan

Mümkün olduğunda, kullanıcı her oturum açtığında yeni bir pencere açmak yerine yeni bir pencereye odaklanmalıyız bir bildirimi tıkladığında

Bunun nasıl gerçekleştirileceğine bakmadan önce, yalnızca kaynağınızdaki sayfalar için kullanılabilir. Çünkü daha önce yalnızca sitemize ait hangi sayfaların açık olduğunu görebiliriz. Bu, geliştiricilerin, kullanıcılarının görüntülediği tüm siteleri görmesini engelleyebilir.

Önceki örneğe dönecek olursak, kodu "2002"den sonra /demos/notification-examples/example-page.html zaten açık.

const urlToOpen = new URL(examplePage, 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 windowClient = windowClients[i];
      if (windowClient.url === urlToOpen) {
        matchingClient = windowClient;
        break;
      }
    }

    if (matchingClient) {
      return matchingClient.focus();
    } else {
      return clients.openWindow(urlToOpen);
    }
  });

event.waitUntil(promiseChain);

Kodu adım adım inceleyelim.

Öncelikle URL API'sini kullanarak örnek sayfamızı ayrıştırırız. Bu, Jeff'ten aldığım harika bir numara. Posnick. location nesnesiyle new URL() çağrılırsa: aktarılan dize göreliyse mutlak bir URL döndürür (yani / https://example.com/) tıklayın.

Daha sonra pencere URL'leriyle eşleştirebilmek için URL'yi mutlak hale getiririz.

const urlToOpen = new URL(examplePage, self.location.origin).href;

Sonra, WindowClient nesnelerinin bir listesini elde ederiz. Bu, öğenin ait olduğu öğelerin listesidir. şu anda açık sekmeler ve pencereler var. (Bunların yalnızca kaynağınıza ait sekmeler olduğunu unutmayın.)

const promiseChain = clients.matchAll({
  type: 'window',
  includeUncontrolled: true,
});

matchAll içine iletilen seçenekler, tarayıcıya yalnızca veya "pencere" araması yapın istemciler (ör. yalnızca sekmelere ve pencerelere bakın) web çalışanlarını hariç tutabilirsiniz). includeUncontrolled, aşağıdakileri aramamıza olanak tanır: kaynağınızdaki mevcut hizmet tarafından kontrol edilmeyen tüm sekmeler çalışan, ör. bu kodu çalıştıran hizmet çalışanıdır. Genellikle, matchAll() çağrılırken her zaman includeUncontrolled değerinin doğru olmasını istiyorum.

İade edilen taahhüdü, iletebilmek için promiseChain olarak kaydederiz. event.waitUntil() daha sonra hizmet çalışanımızı aktif tutacak.

matchAll() sözü yerine getirildiğinde, iade edilen pencerelerde tekrarlayan istemciler üzerinden tekrar tekrar URL'lerini, açmak istediğimiz URL ile karşılaştırmalarına olanak tanır. Eşleşme bulduğumuzda, o eşleşmeye bu da bu pencereyi kullanıcıların dikkatine sunar. Odaklanma matchingClient.focus() arama.

Eşleşen bir müşteri bulamazsak önceki bölümde olduğu gibi yeni bir pencere açarız.

.then((windowClients) => {
  let matchingClient = null;

  for (let i = 0; i < windowClients.length; i++) {
    const windowClient = windowClients[i];
    if (windowClient.url === urlToOpen) {
      matchingClient = windowClient;
      break;
    }
  }

  if (matchingClient) {
    return matchingClient.focus();
  } else {
    return clients.openWindow(urlToOpen);
  }
});
.

Bildirimleri birleştirme

Bir bildirime etiket eklemenin, aynı etikete sahip mevcut bildirim değiştirilir.

Ancak Bildirimler API'si. Geliştiricinin yeni bir bildirim isteyebileceği bir sohbet uygulaması "Mehmet'ten iki mesajınız var" benzeri bir mesaj göster en güncel bilgileri göstermek yerine mesajını alırsınız.

Bunu yapabilir veya registration.getNotifications() Web uygulamanız için görünür durumda olan tüm bildirimlere erişmenizi sağlayan API.

Şimdi, sohbet örneğini uygulamak için bu API'yi nasıl kullanabileceğimize bakalım.

Sohbet uygulamamızda her bildirimde kullanıcı adı da dahil bazı verilerin olduğunu varsayalım.

Yapacağımız ilk şey, belirli bir kullanıcıya ait açık bildirimleri bulmak kullanıcı adı. registration.getNotifications() alıp ilgili sorunu kontrol edip Belirli bir kullanıcı adı için notification.data:

const promiseChain = registration.getNotifications().then((notifications) => {
  let currentNotification;

  for (let i = 0; i < notifications.length; i++) {
    if (notifications[i].data && notifications[i].data.userName === userName) {
      currentNotification = notifications[i];
    }
  }

  return currentNotification;
});

Sonraki adım, bu bildirimi yeni bir bildirimle değiştirmektir.

Bu sahte mesaj uygulamasında yeni iletilerimize sayı ekleyerek yeni iletilerin sayısını ve her yeni bildirimle birlikte bu verileri artırır.

.then((currentNotification) => {
  let notificationTitle;
  const options = {
    icon: userIcon,
  }

  if (currentNotification) {
    // We have an open notification, let's do something with it.
    const messageCount = currentNotification.data.newMessageCount + 1;

    options.body = `You have ${messageCount} new messages from ${userName}.`;
    options.data = {
      userName: userName,
      newMessageCount: messageCount
    };
    notificationTitle = `New Messages from ${userName}`;

    // Remember to close the old notification.
    currentNotification.close();
  } else {
    options.body = `"${userMessage}"`;
    options.data = {
      userName: userName,
      newMessageCount: 1
    };
    notificationTitle = `New Message from ${userName}`;
  }

  return registration.showNotification(
    notificationTitle,
    options
  );
});

Görüntülenen bir bildirim varsa, mesaj sayısını artırır ve başlık ve gövde mesajını buna göre ayarlayın. Varsa bildirim gönderilmezse newMessageCount/1 ile yeni bir bildirim oluştururuz.

Sonuç olarak ilk mesaj aşağıdaki gibi görünür:

Birleştirme içermeyen ilk bildirim.

İkinci bir bildirim ise bildirimleri şu şekilde daraltır:

Birleştirmeyle ilgili ikinci bildirim.

Bu yaklaşımın iyi tarafı, kullanıcınız üst üste geldiğinde, daha tutarlı görünür ve hissedersiniz. Bunun yerine bildirimi en son mesajla değiştirmek zorunda kalmazsınız.

Kuralın istisnası

Push aldığınızda bildirim göstermeniz gerektiğini belirtmiştim. Bu da çoğu zaman çoğunda doğru olur. Bildirim göstermediğiniz tek senaryo, Kullanıcı, sitenizi açık ve odaklanmış olmalıdır.

Push etkinliğinizde, bildirim göstermenizin gerekip gerekmediğini ve belirli bir noktaya odaklanılan bir pencere arayanlar var.

Tüm pencereleri alma ve odaklanmış bir pencere arama kodu aşağıdaki gibi görünür:

function isClientFocused() {
  return clients
    .matchAll({
      type: 'window',
      includeUncontrolled: true,
    })
    .then((windowClients) => {
      let clientIsFocused = false;

      for (let i = 0; i < windowClients.length; i++) {
        const windowClient = windowClients[i];
        if (windowClient.focused) {
          clientIsFocused = true;
          break;
        }
      }

      return clientIsFocused;
    });
}

clients.matchAll() kullanıyoruz. önce tüm pencere istemcilerimizi alır ve sonra focused parametresini kontrol ederek bunların üzerinden geçeriz.

Push etkinliğimizde bir bildirim göstermemiz gerekip gerekmediğine karar vermek için bu işlevi kullanırız:

const promiseChain = isClientFocused().then((clientIsFocused) => {
  if (clientIsFocused) {
    console.log("Don't need to show a notification.");
    return;
  }

  // Client isn't focused, we need to show a notification.
  return self.registration.showNotification('Had to show a notification.');
});

event.waitUntil(promiseChain);

Push etkinliğinden bir sayfaya mesaj gönderme

Kullanıcı o anda sitenizdeyse bildirim gösterme adımını atlayabileceğinizi tespit ettik. Ama Kullanıcının bir etkinlik gerçekleştiğini hâlâ bilmesini istiyorsanız ancak bir bildirim eli çok mu ağır?

Yaklaşımlardan biri, Service Worker'dan sayfaya bir mesaj göndermektir. Böylece web sayfası kullanıcıya etkinlik hakkında bilgi veren bir bildirim veya güncelleme gösterebilir. Bu, özellikle sayfadaki küçük bir bildirimin kullanıcı için daha iyi ve dostane olduğu durumlar olabilir.

Diyelim ki push aldık, web uygulamamızın şu anda odaklanmış olup olmadığını kontrol ettik. "mesaj gönderebiliriz" Örneğin:

const promiseChain = isClientFocused().then((clientIsFocused) => {
  if (clientIsFocused) {
    windowClients.forEach((windowClient) => {
      windowClient.postMessage({
        message: 'Received a push message.',
        time: new Date().toString(),
      });
    });
  } else {
    return self.registration.showNotification('No focused windows', {
      body: 'Had to show a notification instead of messaging each page.',
    });
  }
});

event.waitUntil(promiseChain);

Sayfaların her birinde bir mesaj etkinliği ekleyerek mesajları dinliyoruz dinleyici:

navigator.serviceWorker.addEventListener('message', function (event) {
  console.log('Received a message from service worker: ', event.data);
});

Bu mesaj işleyicide istediğiniz her şeyi yapabilirsiniz, istediğiniz her şeyi veya iletiyi tamamen yoksayabilirsiniz.

Ayrıca, web sayfanızda bir mesaj dinleyici tanımlamazsanız, hizmet çalışanı tarafından gönderilen mesajların hiçbiri hiçbir şey yapmaz.

Bir sayfayı önbelleğe alma ve pencere açma

Bu kılavuzun kapsamı dışında kalan ancak tartışmaya değer bir senaryo da Kullanıcıların ziyaret etmelerini beklediğiniz web sayfalarını önbelleğe alarak, web uygulamanızın genel kullanıcı deneyimini iyileştirir. bildiriminizi tıklayın.

Bunun için hizmet çalışanınızın fetch etkinliklerini işleyecek şekilde ayarlanması gerekir. ancak bir fetch etkinlik işleyicisi uygularsanız sayfayı ve öğeleri önbelleğe alarak push etkinliğinizde bundan yararlanabilirsiniz. sağlamanız gerekir.

Tarayıcı uyumluluğu

notificationclose etkinliği

Tarayıcı Desteği

  • 50
  • 17
  • 44
  • 16

Kaynak

Clients.openWindow()

Tarayıcı Desteği

  • 40
  • 17
  • 44
  • 11.1

Kaynak

ServiceWorkerRegistration.getNotifications()

Tarayıcı Desteği

  • 40
  • 17
  • 44
  • 16

Kaynak

clients.matchAll()

Tarayıcı Desteği

  • 42
  • 17
  • 54
  • 11.1

Kaynak

Daha fazla bilgi için hizmet çalışanları hakkındaki bu girişe göz atın yayın.

Yakında gidilecek yerler

Kod laboratuvarları