In the last month I worked on my side project, a web application that allows you to encrypt and decrypt text messages (DoCrypt.org). It’s still a work in progress, but I’ve already implemented some features I’d like to share. I think it’s an interesting project, and I intend to dedicate a few posts to it. For now, I want to focus on one feature I’ve recently implemented: notifications.
I want to visually confirm the success of some operations. In particular, the action of “copying to the device clipboard” of the encrypted text. This is a feature I have implemented to allow users to copy ciphertext to an external application, such as a text message. For this reason, I decided to implement a notification confirming the copy to the device clipboard.
Visually, this is the result I want to achieve:
As you can see, the notification is a small bar that appears at the top right. The bar is green, and contains a text message. The bar remains visible for a short time, and then disappears. The interesting thing is that I can use the same method to show different notifications, of different colors and with different messages.
I create a notification store
To solve this problem I used a Svelte component. The idea behind it is not mine, I was inspired by this @kevmodrome repl. I customized everything according to my needs.
I need two things: an html element to use on the screen to show notifications, and something that keeps track of the notifications themselves and their life cycle. I begin with this aspect. And to solve it I use a store.
I create the
Notification.ts file and start by setting up some interfaces and creating a simple store:
As you can see, I have created a
Msg interface which represents a notification. The notification has a type, which can be
success. The type of notification determines the color of the bar. The message is the text that is shown in the bar. Finally, the timeout is the time that the notification remains visible. If not specified, the default is 3000 milliseconds.
For each notification I assign an ID; I need a unique identifier to be able to interact with the notification itself at a later time. I cannot use a counter based on the length of the array, because I could cancel a notification and then the counter would no longer be valid. For this reason, I use the
idGenerator() function to generate a unique ID.
So I need a method to add notifications to the store:
I use the store’s
update() method to add a new notification to the array. The
update() method accepts a function that receives the current state of the store, and returns the updated state. In this case, I add a new notification to the array.
I am interested in passing the id explicitly because there may be cases in which I am interested in accessing the notification from outside the component. If instead I choose not to pass the id, then I generate it internally.
Now I need a method to remove a notification from the store:
I use the
update() method, combined with the filter() method, to remove the notification from the array.
To manage the disappearing notifications I need a timer, or something similar. I use SetTimeout() method:
Combining it all I get the complete
Having fixed the store part, I move on to the component part.
I create a component for display notifications
I create the
Notification.svelte file and start importing the store:
To access the store values I can use the reactive
$store syntax. Also to show all the values contained in the store, I use
As you can see, I use the
each method to iterate over all the store values. For each value, I create a div with the notification text.
The per component is complete, but I’m interested in adding some style to make it juicier.
This way I show the notifications at the top right of the screen, one above the other.
But how do I show the notifications in a different color depending on the type? To do this, I add a class to the
toast div based on the notification type and an object to use as a color reference:
I can make it more beautiful by adding an animation to highlight the appearance and disappearance of notifications. To do this I use svelte/transition and svelte/animate:
By combining it all I finally get my
Now all that remains is to use it in our app.
I add the component to the pages
To add the component to the pages, I need to import it into the
I only need to import it once, on the main page of the app. This way I can show a notification starting from any page of the app.
For example, to show a notification when I have copied the ciphertext, I add the following code to the component:
Or, if I want to show a notification of a different color, I just need to change the
type of the message:
Well, that’s all for now. If you want to see the full code, you can find it on GitHub. The application is available on docrypt.org.