WhatsApp Clone with Meteor CLI and Ionic : 9. Send image messages

by - April 02, 2017

Our last step would be implementing image messages support. We will use the same package from the previous step to achieve that.
So we will use the same logic of taking the picture in the controller, and call the same newMessage() server method:


1
2
3
4
5
6
7
 
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

import Ionic from 'ionic-scripts';
import { _ } from 'meteor/underscore';
import { Meteor } from 'meteor/meteor';
import { MeteorCameraUI } from 'meteor/okland:camera-ui';
import { Controller } from 'angular-ecmascript/module-helpers';
import { Chats, Messages } from '../../../lib/collections';
 
...some lines skipped...
    this.autoScroll();
  }
 
  sendPicture() {
    MeteorCameraUI.getPicture({}, (err, data) => {
      if (err) return this.handleError(err);
 
      this.callMethod('newMessage', {
        picture: data,
        type: 'picture',
        chatId: this.chatId
      });
    });
  }
 
  sendMessage() {
    if (_.isEmpty(this.message)) return;
 
...some lines skipped...
      this.$ionicScrollDelegate.$getByHandle('chatScroll').scrollBottom(animate);
    }, 300);
  }
 
  handleError(err) {
    if (err.error == 'cancel') return;
    this.$log.error('Profile save error ', err);
 
    this.$ionicPopup.alert({
      title: err.reason || 'Save failed',
      template: 'Please try again',
      okType: 'button-positive button-clear'
    });
  }
}
 
ChatCtrl.$name = 'ChatCtrl';
ChatCtrl.$inject = ['$stateParams', '$timeout', '$ionicScrollDelegate', '$ionicPopup', '$log'];
And now we need to register an ng-click event to the image button on the view:
8.2 Invoke send picture logic on clickclient/templates/chat.html
28
29
30
31
32
33
34

      <button ng-click="chat.sendMessage()" class="button button-clear button-positive">Send</button>
    </span>
    <span ng-if="!chat.message || chat.message.length === 0">
      <button ng-click="chat.sendPicture()" class="button button-clear button-icon button-positive icon ion-ios-camera-outline"></button>
      <i class="buttons-seperator icon ion-android-more-vertical"></i>
      <button class="button button-clear button-icon button-positive icon ion-ios-mic-outline"></button>
    </span>
In the server, we need to add a validation scheme for image messages in the newMessage()method:
8.3 Add picture message validationlib/methods.js
1
2
3
4
5
 
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { Chats, Messages } from '../lib/collections';
 
Meteor.methods({
...some lines skipped...
        'Must be logged in to send message.');
    }
 
    check(message, Match.OneOf(
      {
        text: String,
        type: String,
        chatId: String
      },
      {
        picture: String,
        type: String,
        chatId: String
      }
    ));
 
    message.timestamp = new Date();
    message.userId = this.userId;
Our next step would be updating the chat view to support image messages:
8.4 Add picture message type to chat viewclient/templates/chat.html
6
7
8
9
10
11
12
13
14
15
16
17

    <div class="message-list">
      <div ng-repeat="message in chat.messages" class="message-wrapper">
        <div class="message" ng-class="message.userId === $root.currentUser._id ? 'message-mine' : 'message-other'">
          <ng-switch on="message.type">
            <div ng-switch-when="text" class="text">{{ message.text }}</div>
            <div ng-switch-when="picture" class="picture">
              <img ng-src="{{ message.picture }}">
            </div>
          </ng-switch>
          <span class="message-timestamp">{{ message.timestamp | amDateFormat: 'HH:mm' }}</span>
        </div>
      </div>
Let's add some css to prevent images from looking silly:
8.5 Add picture style to chat stylesheetclient/styles/chat.scss
66
67
68
69
70
71
72
 
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

    background-image: url(/message-mine.png)
  }
 
  .text {
    padding: 5px 7px;
    word-wrap: break-word;
 
...some lines skipped...
    }
  }
 
  .picture {
    padding: 4px 4px 0;
 
    img {
      width: 220px;
      height: 130px;
      border-radius: 6px;
    }
  }
 
  .message-timestamp {
    position: absolute;
    bottom: 2px;
We also want to add image icon on the chats list in case when the last message is an image message, so let's add it:

8.6 Add picture message indication in chats viewclient/templates/chats.html
11
12
13
14
15
16
17
18
19
20

                href="#/tab/chats/{{ chat._id }}">
        <img ng-src="{{ chat | chatPicture }}">
        <h2>{{ chat | chatName }}</h2>
        <ng-switch on="chat.lastMessage.type">
          <p ng-switch-when="text">{{ chat.lastMessage.text }}</p>
          <p ng-switch-when="picture">image</p>
        </ng-switch>
        <span class="last-message-timestamp">{{ chat.lastMessage.timestamp | calendar }}</span>
        <i class="icon ion-chevron-right icon-accessory"></i>
        <ion-option-button class="button-assertive" ng-click="chats.remove(chat)">

You May Also Like

0 comments