Skip to content

Commit

Permalink
add chats page
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmnouira committed Dec 19, 2019
1 parent 853442e commit dcbef94
Show file tree
Hide file tree
Showing 24 changed files with 444 additions and 78 deletions.
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ Our chat application will show a login page withe _e-mail_ and _password_ fields

## Overview


![account](/img/account.png)
<img src="/img/account.png" width="375"/><img src="/img/users.png" width="375"/>

![register](/img/register.png)

![login](/img/login.png)


![users](/img/users.png)
![login](/img/login.png)
24 changes: 13 additions & 11 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [



{ path: '', redirectTo: '/login', pathMatch: 'full' },

{
path: 'register',
loadChildren:() => import('./register/register.module').then( m => m.RegisterPageModule)

},

{
path: 'login',
loadChildren: () => import('./login/login.module').then( m => m.LoginPageModule)
Expand All @@ -20,14 +15,18 @@ const routes: Routes = [
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
},

{ path: '**', redirectTo: '/login' },

{
path: 'register',
loadChildren: () => import('./register/register.module').then( m => m.RegisterPageModule)
}
},
{
path: 'chat-view',
loadChildren: () => import('./chat-view/chat-view.module').then( m => m.ChatViewPageModule)
},

{ path: '**', redirectTo: '/login' }



];
@NgModule({
Expand All @@ -36,4 +35,7 @@ const routes: Routes = [
],
exports: [RouterModule]
})
export class AppRoutingModule {}
export class AppRoutingModule {


}
17 changes: 16 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AuthService } from './services/auth/auth.service';
import { Router } from '@angular/router';

@Component({
selector: 'app-root',
Expand All @@ -13,8 +15,21 @@ export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar
private statusBar: StatusBar,
private authService : AuthService,
private router: Router
) {

let auth : firebase.auth.Auth = this.authService.getAuth();
auth.onAuthStateChanged((user : firebase.User) => {
// console.log('app auth: ', user)
if(user) {
this.router.navigateByUrl('/tabs')
} else {
this.router.navigateByUrl('/login')
}
});

this.initializeApp();
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { RouteReuseStrategy, RouterModule } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
Expand All @@ -15,7 +15,6 @@ import { AngularFireDatabaseModule } from "@angular/fire/database" // u
import { AngularFireAuthModule } from "@angular/fire/auth";
import { IonicStorageModule } from "@ionic/storage";
import { ServicesModule } from './services/services.module';

import { Camera } from '@ionic-native/camera/ngx';

@NgModule({
Expand All @@ -27,7 +26,8 @@ import { Camera } from '@ionic-native/camera/ngx';
AngularFireDatabaseModule,
AngularFireAuthModule,
IonicStorageModule.forRoot(),
ServicesModule
ServicesModule,
RouterModule
],
providers: [
StatusBar,
Expand Down
17 changes: 17 additions & 0 deletions src/app/chat-view/chat-view-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { ChatViewPage } from './chat-view.page';

const routes: Routes = [
{
path: '',
component: ChatViewPage
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ChatViewPageRoutingModule {}
20 changes: 20 additions & 0 deletions src/app/chat-view/chat-view.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

import { IonicModule } from '@ionic/angular';

import { ChatViewPageRoutingModule } from './chat-view-routing.module';

import { ChatViewPage } from './chat-view.page';

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ChatViewPageRoutingModule
],
declarations: [ChatViewPage]
})
export class ChatViewPageModule {}
47 changes: 47 additions & 0 deletions src/app/chat-view/chat-view.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<ion-header>
<ion-toolbar color="primary">
<ion-title>chat-app</ion-title>
<ion-buttons slot="end">
<ion-button (click)="sendPicture()"><ion-icon name="image" slot="end"></ion-icon>Send Image</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>

<ion-content class="chat-view">

<ion-card>
<ion-card-header>
<ion-card-title color="success">
<em>Chat View</em>
</ion-card-title>
</ion-card-header>
</ion-card>

<div class="messages">
<ion-item lines="none" color="{{ uid === chat.from ? 'primary' : 'light'}}" class="message" [ngClass]="{'me': uid === chat.from}" *ngFor="let chat of chats">
<ion-avatar slot="start">
<img src="{{interlocutorUIDData.picture}}" title="{{interlocutorUIDData.name}}" *ngIf="uid !== chat.from">
<img src="{{uidData.picture}}" *ngIf="uid === chat.from">
</ion-avatar>
<p>{{chat.message}}</p>
<img *ngIf="chat.picture" src="{{chat.picture}}">
</ion-item>
</div>

</ion-content>

<ion-footer>
<ion-toolbar color="light">
<ion-row>
<ion-col size="1">
<ion-spinner *ngIf="!(chats)"></ion-spinner>
</ion-col>
<ion-col size="7" [hidden]="!chats">
<ion-input type="text" [(ngModel)]="message" placeholder="Enter Message..."></ion-input>
</ion-col>
<ion-col size="4" [hidden]="!chats">
<ion-button color="dark" expand="block" (click)="sendMessage()"><ion-icon name="send"></ion-icon></ion-button>
</ion-col>
</ion-row>
</ion-toolbar>
</ion-footer>
18 changes: 18 additions & 0 deletions src/app/chat-view/chat-view.page.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.messages {
width: 100%;
position: absolute;
}
.message {
width: 65%;
padding: 5px 10px;
border-radius: 5px;
margin: 5px;
float: left
}
.message.me {
float: right;
text-align: right
}
ion-item {
--border-radius: 20px;
}
24 changes: 24 additions & 0 deletions src/app/chat-view/chat-view.page.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { ChatViewPage } from './chat-view.page';

describe('ChatViewPage', () => {
let component: ChatViewPage;
let fixture: ComponentFixture<ChatViewPage>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ChatViewPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();

fixture = TestBed.createComponent(ChatViewPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));

it('should create', () => {
expect(component).toBeTruthy();
});
});
73 changes: 73 additions & 0 deletions src/app/chat-view/chat-view.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChatsService } from '../services/chats/chats.service';
import { AngularFireDatabase, AngularFireList } from '@angular/fire/database';
import { CameraService } from '../services/camera/camera.service';
import { Chat } from '../models/chat';
import { User } from '../models/user';
import { UtilService } from '../services/util/util.service';

@Component({
selector: 'app-chat-view',
templateUrl: './chat-view.page.html',
styleUrls: ['./chat-view.page.scss'],
})
export class ChatViewPage implements OnInit {

message: string;
uid : string = '';
interlocutorUID : string = '';
chats: Array<Chat>;
chatsRef : AngularFireList<Chat>;

uidData: User;
interlocutorUIDData : User;

constructor(private chatsService: ChatsService, private db : AngularFireDatabase, private utilService : UtilService, private camera: CameraService) {
this.utilService.doLoading('Please Wait...');
// get uids
this.uid = this.chatsService.chatter.uid
this.interlocutorUID = this.chatsService.chatter.interlocutorUID;

// get chat Reference
chatsService.getChatRef(this.uid, this.interlocutorUID).then((chatRefPath : string) => {
console.log('chatRef: uid, interlocutorUID', chatRefPath);
this.chatsRef = this.db.list(chatRefPath);
this.db.list(chatRefPath).valueChanges().subscribe((chats : Chat[]) => { console.log('chats', chats); this.chats = chats }) ;

});
this.db.object(`/users/${this.uid}`).valueChanges().subscribe((user : User) => this.uidData = user);
this.db.object(`/users/${this.interlocutorUID}`).valueChanges().subscribe((user : User) => { console.log('interlo', user); this.interlocutorUIDData = user });
}

sendMessage() : void {
if(this.message) {
let chat : Chat = {
from: this.uid,
message : this.message,
type: 'message',
to: this.interlocutorUID,
picture : null
};
this.chatsRef.push(chat);
this.message ="";
}
};

sendPicture() : void {

this.camera.getPicture().then(imageData => {
let chat: Chat = {
from: this.uid,
message: '',
type: 'picture',
picture: 'data:image/jpeg;base64,' + imageData,
to: this.interlocutorUID,
};
this.chatsRef.push(chat);
}).catch(err => this.utilService.doAlert(`Error`, `This feature only works on Mobiles.`, 'OK'));
}
ngOnInit() {

}

}
7 changes: 7 additions & 0 deletions src/app/models/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class Chat {
from : string;
type: string;
message: string;
to: string;
picture: any;
}
4 changes: 4 additions & 0 deletions src/app/models/chatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export class Chatter {
uid : string;
interlocutorUID : string
}
32 changes: 11 additions & 21 deletions src/app/services/camera/camera.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,28 @@ export class CameraService {

}

getPicture() {
getPicture() : Promise<any> {

let options: CameraOptions = {

// quality: 100, // quality of the image
allowEdit: true, // alow simple editing of the image before selection
saveToPhotoAlbum: true,
destinationType : this.camera.DestinationType.DATA_URL,
sourceType : this.camera.PictureSourceType.PHOTOLIBRARY,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,

};
// select the user object
let pictureRef = this.db.object(`/users/${this.userSevice.getUID()}`);
// get the picture
this.camera.getPicture(options).then((imageData) => {
let base64Image ='data:image/jpeg;base64,' + imageData;
// save the image data:image on that db
pictureRef.update({picture: base64Image});
},(err) => {
console.log("Error ", err);
});

return this.camera.getPicture(options);
}









// getPicture() and updatePicture() returns promise ==> async
async updatePicture() : Promise<any> {
// select the user object
let pictureRef = this.db.object(`/users/${this.userSevice.getUID()}`);
const imageData = await this.getPicture();
let base64Image : string = 'data:image/jpeg;base64,' + imageData;
// save the image data:image on that db
pictureRef.update({ picture: base64Image });
}
}
Loading

0 comments on commit dcbef94

Please sign in to comment.