Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Ionic Chat Screen

Miroslav Smukov edited this page Sep 10, 2016 · 16 revisions

Chat Screen

After we've implemented the elastic-textarea and chat-bubble components, it's time to use those new components and create our ionic2 Chat page.

Getting Started

As always, we'll create a chatPage directory in our app/pages project folder, and we'll create the 3 required files: chatPage.html, chatPage.js, and chatPage.scss.

View

Below you can see the content of the chatPage.html

Source Code

<ion-navbar *navbar primary>
  <ion-title>
    {{contactName}}
  </ion-title>
</ion-navbar>

<ion-content #content padding class="chatPage">

  <ion-list no-lines>
    <ion-item *ngFor="let msg of messages" >
      <chat-bubble [message]="msg"></chat-bubble>
    </ion-item>
  </ion-list>

</ion-content>

<ion-footer class="chatPageFooter">
  <ion-toolbar>

    <ion-item>
      <ion-label style="margin:0px;"></ion-label>
      <div item-content style="width:100%;">
        <elastic-textarea #txtChat placeholder="Type to compose" lineHeight="22"></elastic-textarea>
      </div>
    </ion-item>

    <ion-buttons right>
      <button style="min-width:45px;" (click)="sendMessage()">
        <ion-icon name="send"></ion-icon>
      </button>
    </ion-buttons>
  </ion-toolbar>
</ion-footer>

Important things to point out in this view is that we are marking the <ion-content> component with an id #content because we want to reference it later on in the controller.

Inside the ion-list we are rendering a list of our chat-bubble components that we previously defined.

We are using the ion-footer to stick the input part of the page - the elastic-textarea and the button - to the bottom of the screen.

ion-toolbar

A Toolbar is a generic bar that is positioned above or below content. Unlike a Navbar, a toolbar can be used as a subheader. When toolbars are placed within an <ion-header> or <ion-footer>, the toolbars stay fixed in their respective location. When placed within <ion-content>, toolbars will scroll with the content. More on toolbars in official ionic2 documentation.

ion-navbar

Using the ion-navbar at the top of the page, we automatically get the back button in our navigation bar, which is added by the ion-nav component that we already instantiated in our app.html. The back button gets added if there is a page before the one you are navigating to in the navigation stack.

Styling

The chatPage.scss is rather simple in this case. You can see it below.

Source Code

.chatPage {
  ion-label {
      margin: 0px 8px 13px 0;
  }
}

.chatPageFooter {
  .toolbar-background {
    background: map-get($colors, background-color);
  }
}

We are just adjusting the ion-label margins because chat-bubbles are wrapped inside ion-label when ion-item is rendered.

Controller

Let's see the code and then we'll cover the interesting bits.

Source Code

import {Component, ViewChild} from '@angular/core';
import {NavController, NavParams} from 'ionic-angular';

import {ChatBubble} from '../components/chatBubble/chatBubble';
import {ElasticTextarea} from '../components/elasticTextarea';

@Component({
  templateUrl: 'build/pages/chatPage/chatPage.html',
  directives: [ChatBubble, ElasticTextarea],
  queries: {
    txtChat: new ViewChild('txtChat'),
    content: new ViewChild('content')
  }
})
export class ChatPage {
  static get parameters() {
    return [[NavController], [NavParams]];
  }

  constructor(nav, navParams) {
    this.nav = nav;
    this.navParams = navParams;

    this.contactName = this.navParams.get('contactName');

    this.messages = [
      {
        img: 'build/img/hugh.png',
        position: 'left',
        content: 'Hello from the other side.',
        senderName: 'Gregory',
        time: '28-Jun-2016 21:53'
      },
      {
        img: 'build/img/hugh.png',
        position: 'right',
        content: 'Hi! How are?',
        senderName: 'Me',
        time: '28-Jun-2016 21:55'
      },
      {
        img: 'build/img/hugh.png',
        position: 'left',
        content: "This is some really long test that I'm writing here. Let's see how it wraps.",
        senderName: 'Gregory',
        time: '28-Jun-2016 21:57'
      }
    ];
  }

  sendMessage(){
    this.txtChat.setFocus();

    this.messages.push({
      img: 'build/img/hugh.png',
      position: 'right',
      content: this.txtChat.content,
      senderName: 'Me',
      time: new Date().toLocaleTimeString()
    });

    this.txtChat.clearInput();

    setTimeout(() => {
      this.content.scrollToBottom(300);//300ms animation speed
    });
  }

}

NavParameters

An interesting thing to point out here is our first use of NavParameters. We are injecting NavParameters and are then using it in the component's constructor to obtain the contactName:

this.navParams.get('contactName')

This code works because we have set this parameter with this exact key when we were navigating to the ChatPage from our ContactPage using the following code:

this.nav.push(ChatPage, {contactName: "Dr. Gregory House"});

scrollToBottom(..)

In our sendMessage() method we are pushing the new message to the messages array, we are also clearing the input with this.txtChat.clearInput(), but we are also scrolling our view to the last message (chat bubble) that was added to it. Here's the code for that bit:

setTimeout(() => {
   this.content.scrollToBottom(300);//300ms animation speed
});

We had to use setTimout(..) in this case because without it our view would only scroll to the second to last element in the view. Seems like the issue was that the scrolling was occurring prior to the new chat message being added to the view. setTimout(..) solved this issue

Conclusion

It definitely seemed simpler and quicker to create the Chat Screen in Android Native then it was in Ionic2. However, I'm contributing that to the maturity of Android platform, and the pure amount of ready made examples that are available for it. I did managed to find some good resources for Ionic implementation of the same screen, however, they were for the version 1 of the Ionic, and I had to put in some good work to adjust them so I would be able to use them.

After all was said and done, I would give a small advantage to Android Native in this particular scenario, but I also love the fact that I'm able to design this screen with pure code (HTML5, CSS, and Javascript) in Ionic2, without having to worry about creating custom images and resources like I did in Android Native.

Ionic2 Chat Bubbles

References

Commits

Clone this wiki locally