 Hello, it's only the bonus round of developer dive for the Chrome Dev Summit website with me. Your host. No, I'm not going. I'm not taking it in that direction. We've got this far without me being ridiculous. Too ridiculous. Let's just move on. So good news. Yay. Thing that I've added to the website is this little button in the corner. However, when you click on the little button, out comes the notification settings for the Chrome Dev Summit website. Yay. So the idea we had was, well, obviously pushes a thing. Let's add it to the site so that people can be notified when any of the sessions start, or as you can see, event updates like, I don't know, sorry, we're running late, or don't forget to get your passes or whatever, whatever people need. So when you click on it, I guess I've already, yeah, there you go, show notifications. So I'll allow that. And it goes off on the back, sends the registration across to the back end server. And then doop, there we go. Once it's got a response back from the back end server that's storing these subscriptions, it does that. And tell you what, let me register for Darren's keynote. Like so. Over here on my other machine that you can't see, that I can see, that is down here. That's why I point it. I've got my admin interface for the back end server. Bear with me. And what I'm going to do is I'm going to, let's pretend. Let's pretend you and I, now, that it is in fact the day of the Chrome Dev Summit. And we're off, we're doing whatever, we're doing whatever. And we send out the notification for the keynote. And all being well, la, la, la, la. There we go, in the top corner. Chrome Dev Summit, the keynote with Darren Fisher is starting now. And then when you click on it, because it'll be the live, will actually take you into the Chrome Dev Summit site or whatever, and you'll have the live stream and off you go. Great. OK, let me show you around the code quickly for the things that I think are interesting. If you're interested, I can show you the back end code in another bonus dev diary. Just let us know in the comments. For now, I'm just going to be concentrating purely on the front end stuff. And a lot of it is actually state management. So I'm not going to dive into too much of that, because it is quite sort of nitty gritty how they click this button, how they do that. But I'll show you what I think hopefully makes sense. So the thing is, the first thing I suppose is in the service worker installation bit, I listen on the ready of the service worker installation. And if there is a push manager in the registration, then I initialize my push manager, which I changed this morning to push handler. But I haven't pushed the code to GitHub yet, so this is still the old name for it, because I didn't want to conflict with the actual push manager. I'm an idiot, like anybody needed a reminder. However, nonetheless, we have this init. And in the init, we have this setup, which is going to basically fetch from the remote server, which you'll see is the cdspush.appspot.com. And when it fetches that and pulls that back, I've set it so that cdspush.appspot.com will respond with the public key that it needs in order to do the registration. So we get that, and we basically store that back. Now, I'm using Jake's IDB key valve to do this, because his IDB key valve is basically is like this lightweight, super lightweight thing that sits on top of indexedDB that makes it behave more like local storage, because I just want to name value pairs, but I don't want to spend all my time. I don't want to use local storage, because it's synchronous, and it can be slow, apparently. And IDB is the right call here, but I don't want to do all the kind of transaction open-to-database, blah, blah, blah. I don't like that. It's not a nice API. And so Jake's written this IDB key valve, which kind of does the get, set, delete keys, all that kind of stuff, and it's really nice and lightweight. So I'm using that. So we basically store the app key, and then we basically do a bunch of updating of the initial view, which is set up the controls, make sure that any buttons that are on screen say the right thing, so that if you come back into the site. So for example, let's go actually, let me show you this. When we go to the schedule now, and I go to Darren's keynote, it says notifications enabled. It already says that, because that's what that function is doing. It's basically looking for any of those in the update current view. It's looking for any of the existing buttons in the page. And it says, switch them to notifications enabled or disabled, depending on what we've actually got in the key valve, the IDB key valve value for that session. Fair enough. And that's largely what that stuff is going to be doing. It's like, find the update current view, find the notification buttons, find from the IDB key valve whether it's disabled or enabled for that particular thing, and so on. Processing changes is not similar. It disables all the buttons, finds out what the current value is, updates it using this push manager, and then it does a bit of toasting and all the rest of it to kind of say what happened. The actual getting of a subscription is quite interesting. You ask the service worker, and if there is a subscription already, and the key hasn't changed, that public key on the server hasn't changed since. You can just return it. Otherwise, I set the key valve for the app key, and I ask the registration for a subscription. And you have to set this user visible only to true today in Chrome. It basically is the key that says, if I get a push message, I will definitely show a notification. And the other thing is the application server key, which is a base 64 encoded version of the public key or something. No, no, no. It's not. Actually, you have to convert the base 64 into a UNT8 array. I don't know why. I'll be honest with you. It was one of those moments when I saw that I was like, I mean, surely if I gave it a base 64 encoded string, it would be able to do it for me. Maybe I should give that feedback. Anyway, push manager handles the kind of global, do you have a subscription? If not, do you want one, all that kind of stuff? The push controls, not a lot to really talk about here. I mean, I know there's a, like it looks like there's a little bit of showbiz going on with that kind of woo. And the woo. But really, you know, mostly no. And so the way it actually works is, in fact, let me just slow it down in DevTools. And you'll see it's actually in Canary. It's a bit blurry. So I might take a look at that today. In fact, let's go at 10% speed. And OK. The elements that are doing things are these. There's this, which is basically is the button. And then there's the headline. And then there's the list. And the headline and the list are basically faded out. And they're transformed down by 100% of the containing element when it's collapsed like this. Whee, and faded out. So I have a ripple inside here. And the ripple basically expands to be big enough. So this, OK, let's go back. This containing element is however big it needs to be. And the ripple always expands. And it's overflow hidden. So as the ripple expands, it's just a circle that gets bigger. It basically hits the edge of that block and just disappears. That's one bit. Then the, meanwhile, the button and the headline and the list, they're just basically sliding up and fading in. And because of the timing of it, mostly you don't really see. There you go. And it's all scales, transforms, all the usual, and opacity. How do we make it friendly for the compositor? The usual tricks. A little smattering of world change or whatever. And you get that effect. There you go. And then picking up the buttons is, again, it just tells the push manager, oh, they clicked on this. And so it disables the buttons, makes the remote request. When it comes back, it enables all the buttons. Right. Final piece of the jigsaw today is what happens in the service worker when you know you got that message coming in. How does that work? Well, when you have a registration, there's an endpoint and some keys and that's mostly it that you send to your server. And there's a library called web-push, which we can link to in the notes. And it generates all the keys you need and does all the things you need to have a server in JavaScript to basically encrypt a payload, which is great, and ping the endpoint that you got from the subscription process. And that's what it does. So that means that on the client side, on the Chrome side, there's in the service worker you register this on-push so that when the endpoint gets pinged, so you make your registration, you get an endpoint, you send that to the server. The server then pings it with a payload. That causes whichever messaging service is actually underpinning all this to actually ping back your service worker and go, by the way, a thing happened. Yay, which we get in the on-push, right? So that's what happens. We ping the endpoint and the payload I give it is actually the slug of the session. So like, slash dev submit slash schedule slash keynote, something like that. And what I then do is I just sort of set up an initial payload for the push, then the notification. And then I basically look up the sessions and I go through and I look to see if the URL matches the slug that I was sent, right? Yeah, hope that makes sense. The session being what was actually posted from is part of the push notification. So if I see slash dev submit slash schedule slash keynote, I'll go, oh, it's the keynote with Darren Fisher is starting now. And I set the icon to be the image of the speaker, which takes me to the next part of the process, where I do something that I'm not that fond of. I'll be honest with you, it feels a bit funny, but all the same it works. I take that and I find the image in the cache and then I get a blob of the image and then I use a file reader to read that image as a data URL. And then I set the icon to be that base64 encoded image URL, which then means that I can show a notification with the title and a message that's been generated entirely from the cache. Your alternative is to just sort of assume that, hey, they had a good enough connection to get a push so they probably have enough data to go out and get the image and the text or whatever I feel like sending them. But that's a request that doesn't need to be made in my view. And also, it means that my server has to be able to go, OK, who are you? What do you need to know? Oh, here's the image you need and here's the whatever. It didn't seem like it was worth doing to me. It felt like it was sort of a case of, you know what? All I need to tell you is which session is starting and everything else will take care of itself. Now, if I send you a push without a message, as in without a session, then this bit will fail. I say fail. It won't do anything. It doesn't matter. And what I'll do is I just assume that whatever the literal text is that came in is what we should be sending. So that's how we do the event update. So in the back end, we just put in some random string or emoji or whatever. When it comes in, that text will not be matched to any of the sessions. So we just propagate it straight through as that's what they wanted to say, which is true. That's what they wanted to say. They didn't want to say one of the sessions was starting now. And the icon defaults to the Chrome Dev Summit 5.12 icon, which is, you probably remember, is this one here of general Chrome Dev Submitiness in an icon. So there you go. Good news is that I'm going to be pushing this out hopefully today unless I find any catastrophic bugs between now and actually pushing it live. But I've been working on this for quite a while. This has taken some work, not on the client side, surprisingly. On the server side, it's been quite an interesting process of just making sure everything's just aligned and trying to make sure that people don't get multi-notified and all that kind of stuff. Ooh, final bit that I will show you is on, you know, that user visible only. Is that what it was? What was the flag? It was in the push manager, wasn't it, when we did the subscription. Let me just find out which exact user visible only. Yeah, it was. Because that's set to true, if you remember I said, when you have that flag, you're promising to show a notification. Here's something I discovered. The event for the on push, you want it to wait until. So you're basically saying, OK, don't go away. I've got some stuff to do. And this will take a promise. And when the promise chain finishes, you must make sure that you've shown a notification by that point. And I was finding out that sometimes I'd get my notification. And then sometimes Chrome would say, this website's updated in the background, just so you know. And then I'd also get my notification. So I was getting a double notification and I was like, what is going on? Bit of a stack overflow search for me. And it turns out that it's because when you do the self.registration.show notification call, you must return it. It must be part of the promise chain. Otherwise, this promise chain will finish. And there'll be no notification shown. And so Chrome will say, oh, well, they said user visible only was true. So I better put that message up that says this site updated in the background. Fair enough. And then your show notification code actually then kicks in at some point. So you end up with two notifications. Whereas if you return it, you're basically saying that event.wait until will wait until I've shown a notification, which is actually what I wanted to do. So just an FYI, I don't recall seeing this much in various samples around the web about how to actually show notification. You must make sure that it is returned. So there you go. Codes up on GitHub. Have a proper look around. As always, thank you for joining me on the journey. We're getting very close to Chrome Dev Summit now. I think it's like two or three weeks away. So you can subscribe for notifications if you want to be notified now when the event's starting or a particular session of interest to you is actually starting. That's the whole point of this. And also, there's the code there so you can have a good old look through. Brilliant. Have a great day, and thank you very much for joining me on bonus round number one.