In this series, I will guide you into building a simple WhatsApp UI clone. In part 1, we will have a small introduction to the Ionic Framework and then start building our project using Ionic. In part 2, I will introduce React Native and, with it, build a similar project. Finally in part 3, I will compare between Ionic Framework and React Native and share my experience with both technologies. We will only build a simple one-page clone to showcase the ease of use of both Ionic and React Native.
Part 1: Ionic Framework
If you are a web developer moving towards mobile development, chances are you’ve heard of the Ionic Framework. For those who haven’t heard of Ionic, its a UI framework that allows you to build hybrid mobile applications that look and feel like native apps. Basically, the app that you build with Ionic is a web app displayed within webview and wrapped by a native app. This architecture allows web developers to build native mobile apps that can be published to Google Store and the App Store, and downloaded and installed on Android and iOS devices. The framework actually supports development for Windows and Blackberry applications, as well.
Enabled by Cordova and Capacitor, Ionic apps can have features with native functionality, such as using the camera, microphone, location-based services, and so on. The best part about all of this, is that you get to write your app’s UI in HTML/CSS, and it’s business logic in Javascript, just as you would in a traditional web app! Ionic supports development in pure Vanilla Javascript, Angular, Vue and even React. Additionally, the framework has a long list of ready-to-use UI components that are displayed appropriately, depending on the running mobile device, to give the end-user a native feel. For native functions, a Ionic Native is a library of native plugins that are wrappers to Cordova plugins with cleaner and seamless APIs. All you have to do is import the plugin and call the API to perform native functionalities on the device.
You you will find the complete code of this tutorial in this repository:
Now let’s get started with our project.
Prerequisites
Setup
Open the terminal and navigate into a directory of your choice, then run the following command to create a new blank Ionic project:
ionic start whatsapp-clone blank
When prompted, select Angular as the framework that will be used with Ionic in this project. When the process is finished, your new Ionic project should be ready. Run the following command to set your project as the working directory in this terminal instance:
cd whatsapp-clone
I like to work with VS Code, but you can use any IDE or text editor of your choice. To open VS Code in our newly created project, run the following:
code .
Theming
Inside src/theme/variables.scss you will find the CSS variables that represent the theme colors of the current app. In particular, we care about the first two: primary and secondary. We can make use of the Ionic Color Generator to generate WhatsApp-like primary and secondary theme colors. On the color generator page, type in #084943 in the primary color field and #00c749 in the secondary field. Scroll down to the CSS Variables section and replace the first two sets of generated variables with the ones in your project’s variables.scss. The primary and secondary variable sets should now look like this:
UI Implementation
Let’s run the app and start our implementation. We will run our app on Android. You can either connect your Android device to your machine, or the Android emulator, and run the following command.
ionic cordova run android -l
This command will build and run the app on Android in live reload mode. In essence, we will use the automatically-generated home page as the main page that is displayed when the app is running, and simply render a specific component based on the user’s selection. We will not dive into all the views that the real WhatsApp application has, so we will stick with the main views for simplicity. For that, we initially need a header and four tabs (camera, chats, status & calls).
We can use ion-header
to implement the header. For the tabs, we will need two different ionic components: ion-segment
and ion-slides
. The header and the tabs will always be displayed. The content displayed within the tabs will need to change based on the user’s tab selection. Hence, we can code that as separate components and render them accordingly. Let’s get started! In src/app/home.page.html, replace the ion-header
tag with the following code:
So what is happening here? Within the ion-header
tag, we set the color of both ion-toolbar
tags to the primary color we previously edited in variables.scss. This will set the header to a similar shade of green to that of WhatsApp’s. Inside the first ion-toolbar
, we set two icon buttons and wrap them with ion-buttons
. Setting the slot
attribute on ion-buttons
to end places the icon buttons on the far right of the header.
The second ion-toolbar
wraps the tabs. When the tabs (ion-segment
) change, the segmentChanged($event)
function is invoked and the details of the event triggering the change is passed on to it. We will code that function to sync between the active tab (ion-segment-button
) and the active tab content (ion-slide
).
Don’t worry! We will get to the logic in a second. Let’s complete constructing the view first.
As mentioned earlier, the content that is displayed when a tab is selected will be in a separate component and not in the home page. We can simply nest that component inside the page for better readability and extensibility. For that, we will need to generate components by running the following commands in the terminal:
ionic g component components/chats
ionic g component components/status
ionic g component components/calls
ionic g module components/
Open up src/components/components.module.ts and replace its content with the following code:
In home.module.ts, add the following lines to recognize the new components in this Angular project:
...
import { ComponentsModule } from "../components/components.module";@NgModule({imports: [
...
ComponentsModule,
...
Now that the app recognizes our components, lets add them to home.page.html. Open the file and replace ion-content
with the following code:
We are using ion-slides
here to wrap the components and give the desired behavior of switching components when the user swipes. slideChanged()
will be invoked whenever the user swipes between slides. In that function, we’ll handle synchronizing the active ion-slide with the active ion-segment
as the user swipes.
Now, open up home.page.ts and replace the content with the following code:
In our Typescript, we are referencing the ion-slides
and ion-segment
components to evaluate their active children when the segments or slides are changed by the user. If the segment was changed, we set the active slide to the slide corresponding to that segment, and vice-versa.
To make sure our UI looks consistent and more similar to the real WhatsApp, copy the following styles in home.page.scss:
Adding Mock Data
In chats.component.ts, status.component.ts and calls.component.ts, import ContactsService
and inject it into the constructor:
...
import { ContactsService } from "src/app/services/contacts.service";...
constructor(public contactsService: ContactsService) {}
...
Now edit contacts.service.ts, and replace its content with the following:
This should be enough mock data for us to display in the app. getData()
returns an array of type ContactModel
. We will use the properties of ContactModel
to be displayed in our custom components.
Custom components
We can start with chats.component.html. Replace its content with the following:
Inside ion-list
, we use Angular’s ngFor
structural directive to iterate over contacts
array from ContactsService
, and render an ion-item
for each entry in that array. Then, we display inside each ion-item
the properties of the corresponding entry. By using the Angular DatePipe and some CSS classes, our chats list looks similar to that of WhatsApp.
The ion-fab
’s position is dictated using the vertical
and horizontal attributes to place it in the bottom right corner of the screen. We set its color to the secondary variable, which we edited in variables.scss.
Now open up status.component.html and copy in there the following:
The implementation here is pretty much the same as the previous component. A noticeable difference here is the format of the date displayed under each name. We simply pass a different parameter, medium, to the DatePipe in order to display the date in the needed format.
A main addition here is the second FAB from the bottom, with the pencil icon. For that, we implement another ion-fab
at the bottom-end position, and add some basic CSS styling to make it appear right above the first FAB. Adding .pen-fab
as a class on its tag should do the trick. Now open up status.component.scss and add the definition of this CSS class:
The second CSS class is used to change the background color of ion-item-divider
. So we add it the class list of that element in the status.component.html.
Finally, open up calls.component.html and replace its content with the
The main addition in this component is the call button at the end of each item in the list. An ion-button
with an ion-icon
should do the trick. We add that inside the ion-item
tag, and set the slot
value to end.
And that is it!
Up to this point, we should have a decent clone of WhatsApp’s main page including the tabs. Congrats! You should have now a good idea on how easy it is to build apps using Ionic.
Again, here you will find the complete code of this tutorial.
Follow the steps in README to set it up. If you have any questions or comments, drop them below.
Don’t forget to CLAP, if you liked this tutorial.
See you in part 2!