From 817292760af1e9010511b216b646dd7369da778c Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 16:55:27 -0700 Subject: [PATCH 01/18] Changed the app settings to include our app settings name --- .../app/providers/app-settings/app-settings.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/secureChatIonic/app/providers/app-settings/app-settings.ts b/client/secureChatIonic/app/providers/app-settings/app-settings.ts index e354a1c..5cd5044 100644 --- a/client/secureChatIonic/app/providers/app-settings/app-settings.ts +++ b/client/secureChatIonic/app/providers/app-settings/app-settings.ts @@ -11,7 +11,11 @@ export class AppSettings { //Can be stored on the client: http://stackoverflow.com/questions/6709883/facebook-app-security-what-if-someone-uses-my-appid static facebookAppId = '2867455650741445'; - //Add our server URL - static serverUrl = 'http://localhost:4780'; + static shushItemName = 'shushUser'; + + + + //Add our server URL (Local testing not actual) + static serverUrl = 'http://192.168.86.43:4780/api/v1'; } From 6922a2e5c4b7ee70948f3566ce648ddd4c9e5619 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 17:02:37 -0700 Subject: [PATCH 02/18] Commented on SushItemName, and fixed testing local url --- .../app/providers/app-settings/app-settings.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/secureChatIonic/app/providers/app-settings/app-settings.ts b/client/secureChatIonic/app/providers/app-settings/app-settings.ts index 5cd5044..116b087 100644 --- a/client/secureChatIonic/app/providers/app-settings/app-settings.ts +++ b/client/secureChatIonic/app/providers/app-settings/app-settings.ts @@ -9,13 +9,15 @@ export class AppSettings { //Fake key for now, to get the dialog working //Can be stored on the client: http://stackoverflow.com/questions/6709883/facebook-app-security-what-if-someone-uses-my-appid - static facebookAppId = '2867455650741445'; + static facebookAppId = '2365441780952680'; + //The name of the json object stored on the device static shushItemName = 'shushUser'; //Add our server URL (Local testing not actual) - static serverUrl = 'http://192.168.86.43:4780/api/v1'; + //Must end with a slash + static serverUrl = 'http://192.168.43.86:4780/api/v1/'; } From 3f3979e048dd3ded64fd876c1cbdf91e88af9261 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 17:04:55 -0700 Subject: [PATCH 03/18] Created a provider to handle messaging it will contain logic for all external messaging requests --- .../app/pages/all-messages/all-messages.ts | 14 +------------- .../providers/app-messaging/app-messaging.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 client/secureChatIonic/app/providers/app-messaging/app-messaging.ts diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.ts b/client/secureChatIonic/app/pages/all-messages/all-messages.ts index 5516871..2b7d52b 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.ts +++ b/client/secureChatIonic/app/pages/all-messages/all-messages.ts @@ -26,19 +26,7 @@ export class AllMessagesPage { //Set our nav controller this.location = navCtrl; - //Recent messages from all conversations (template for now) - this.recentMessages = [ - { - user: "Kumin In", - text: "Sup dude!", - conversationId: "1457" - }, - { - user: "Bob Smith", - text: "What's the homework?", - conversationId: "1243" - } - ]; + //Make a request to get the messages } //Get shortened text with elipses diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts new file mode 100644 index 0000000..891b183 --- /dev/null +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; + +/* + Generated class for the AppMessaging provider. + + See https://angular.io/docs/ts/latest/guide/dependency-injection.html + for more info on providers and Angular 2 DI. +*/ +@Injectable() +export class AppMessaging { + + constructor(private http: Http) {} + +} + From 75e7c6e5ac2fc12249e9f880f2352cb599cbf251 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 17:24:15 -0700 Subject: [PATCH 04/18] Started making GET requests for the messages Needs to be tested with Kumins server --- client/secureChatIonic/app/app.ts | 3 +- .../app/pages/all-messages/all-messages.ts | 8 ++- .../providers/app-messaging/app-messaging.ts | 51 ++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/client/secureChatIonic/app/app.ts b/client/secureChatIonic/app/app.ts index cd8efbe..b36a5f1 100644 --- a/client/secureChatIonic/app/app.ts +++ b/client/secureChatIonic/app/app.ts @@ -10,12 +10,13 @@ import { AuthLoginPage } from './pages/auth-login/auth-login'; //Import our providers (services) import { AppSettings } from './providers/app-settings/app-settings'; import { AppAuth } from './providers/app-auth/app-auth'; +import { AppMessaging } from './providers/app-messaging/app-messaging'; import { AppNotification } from './providers/app-notification/app-notification'; import { AppLoading } from './providers/app-loading/app-loading'; @Component({ templateUrl: 'build/app.html', - providers: [AppAuth, AppSettings, AppNotification, AppLoading] + providers: [AppSettings, AppAuth, AppMessaging, AppNotification, AppLoading] }) class MyApp { @ViewChild(Nav) nav: Nav; diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.ts b/client/secureChatIonic/app/pages/all-messages/all-messages.ts index 2b7d52b..d1d5f86 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.ts +++ b/client/secureChatIonic/app/pages/all-messages/all-messages.ts @@ -4,6 +4,9 @@ import { NavController } from 'ionic-angular'; //Import to conversation view import { ConversationPage } from '../../pages/conversation/conversation'; +//Import our providers +import { AppMessaging } from '../../providers/app-messaging/app-messaging' + /* Generated class for the AllMessagesPage page. @@ -19,14 +22,15 @@ export class AllMessagesPage { location: NavController; //Our recent conversations - recentMessages: Array; + recentMessages: any; - constructor(private navCtrl: NavController) { + constructor(private navCtrl: NavController, private appMessaging: AppMessaging) { //Set our nav controller this.location = navCtrl; //Make a request to get the messages + this.recentMessages = this.appMessaging.getConversations(); } //Get shortened text with elipses diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts index 891b183..bb0d312 100644 --- a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -2,6 +2,12 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; +//Import our providers +import { AppSettings } from '../../providers/app-settings/app-settings'; +import { AppAuth } from '../../providers/app-auth/app-auth'; +import { AppNotification } from '../../providers/app-notification/app-notification'; +import { AppLoading } from '../../providers/app-loading/app-loading'; + /* Generated class for the AppMessaging provider. @@ -11,7 +17,48 @@ import 'rxjs/add/operator/map'; @Injectable() export class AppMessaging { - constructor(private http: Http) {} + constructor(private http: Http, private appSettings: AppSettings, private appAuth: AppAuth, private appNotification: AppNotification, private appLoading: AppLoading) { } -} + //Return all the conversations for a user + public getConversations() { + + //Start Loading + this.appLoading.startLoading('Getting Messages...'); + + //Our access_token header + let headers = { + access_token: this.appAuth.user.access_token + }; + + //Send the request with the payload to the server + var response = this.http.get(AppSettings.serverUrl + 'conversation', headers).map(res => res.json()); + + //Get a reference to this + let self = this; + + response.subscribe(function(success) { + //Success! + console.log(success); + //Stop loading + return self.appLoading.stopLoading().then(function() { + return success; + }); + }, function(error) { + //Error! + + //Stop Loading + self.appLoading.stopLoading().then(function() { + //Pass to Error Handler + self.appLoading.handleError(error); + }); + + }, function() { + //Completed + }) + + + } + + +} From 54355145798b17c2843f2781b8797478092c89ca Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 18:00:14 -0700 Subject: [PATCH 05/18] Cleaning up the way we handle providers Fixed alot of circular dependcies with the appnotification and apploading --- client/secureChatIonic/app/app.ts | 16 ++++---- .../app/pages/all-messages/all-messages.ts | 5 ++- .../app/providers/app-auth/app-auth.ts | 26 ++++++------ .../providers/app-messaging/app-messaging.ts | 18 ++++---- .../app-notification/app-notification.ts | 32 --------------- .../app-notify.ts} | 41 ++++++++++++------- 6 files changed, 57 insertions(+), 81 deletions(-) delete mode 100644 client/secureChatIonic/app/providers/app-notification/app-notification.ts rename client/secureChatIonic/app/providers/{app-loading/app-loading.ts => app-notify/app-notify.ts} (61%) diff --git a/client/secureChatIonic/app/app.ts b/client/secureChatIonic/app/app.ts index b36a5f1..f8acc70 100644 --- a/client/secureChatIonic/app/app.ts +++ b/client/secureChatIonic/app/app.ts @@ -2,21 +2,21 @@ import { Component, ViewChild } from '@angular/core'; import { ionicBootstrap, Platform, Nav } from 'ionic-angular'; import { StatusBar } from 'ionic-native'; -//Import our pages -import { Home } from './pages/home/home'; -import { AllMessagesPage } from './pages/all-messages/all-messages'; -import { AuthLoginPage } from './pages/auth-login/auth-login'; - //Import our providers (services) import { AppSettings } from './providers/app-settings/app-settings'; +import { AppNotify } from './providers/app-notify/app-notify'; import { AppAuth } from './providers/app-auth/app-auth'; import { AppMessaging } from './providers/app-messaging/app-messaging'; -import { AppNotification } from './providers/app-notification/app-notification'; -import { AppLoading } from './providers/app-loading/app-loading'; + +//Import our pages +import { Home } from './pages/home/home'; +import { AllMessagesPage } from './pages/all-messages/all-messages'; +import { AuthLoginPage } from './pages/auth-login/auth-login'; +import { ConversationPage } from './pages/conversation/conversation'; @Component({ templateUrl: 'build/app.html', - providers: [AppSettings, AppAuth, AppMessaging, AppNotification, AppLoading] + providers: [AppSettings, AppAuth, AppMessaging, AppNotify] }) class MyApp { @ViewChild(Nav) nav: Nav; diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.ts b/client/secureChatIonic/app/pages/all-messages/all-messages.ts index d1d5f86..ab4ccb0 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.ts +++ b/client/secureChatIonic/app/pages/all-messages/all-messages.ts @@ -6,6 +6,7 @@ import { ConversationPage } from '../../pages/conversation/conversation'; //Import our providers import { AppMessaging } from '../../providers/app-messaging/app-messaging' +import { AppAuth } from '../../providers/app-auth/app-auth'; /* Generated class for the AllMessagesPage page. @@ -24,13 +25,13 @@ export class AllMessagesPage { //Our recent conversations recentMessages: any; - constructor(private navCtrl: NavController, private appMessaging: AppMessaging) { + constructor(private navCtrl: NavController, private appMessaging: AppMessaging, private appAuth: AppAuth) { //Set our nav controller this.location = navCtrl; //Make a request to get the messages - this.recentMessages = this.appMessaging.getConversations(); + this.recentMessages = this.appMessaging.getConversations(this.appAuth.user.access_token); } //Get shortened text with elipses diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index 30c532f..0b71683 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -5,12 +5,10 @@ import 'rxjs/add/operator/map'; //Import Pages we navigate to import { Home } from '../../pages/home/home'; -import { AllMessagesPage } from '../../pages/all-messages/all-messages'; //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; -import { AppNotification } from '../../providers/app-notification/app-notification'; -import { AppLoading } from '../../providers/app-loading/app-loading'; +import { AppNotify } from '../../providers/app-notify/app-notify'; /* Generated class for the AppAuth provider. @@ -40,7 +38,7 @@ export class AppAuth { user: any; //Class constructor - constructor(private app: App, private http: Http, private appNotification: AppNotification, private appLoading: AppLoading) { + constructor(private app: App, private http: Http, private appNotify: AppNotify) { //Initialize the user //Grab our user from localstorage if (localStorage.getItem(AppSettings.shushItemName)) { @@ -103,7 +101,7 @@ export class AppAuth { private serverLogin(payload) { //Start Loading - this.appLoading.startLoading('Logging in...'); + this.appNotify.startLoading('Logging in...'); //Save a reference to this let self = this; @@ -125,24 +123,24 @@ export class AppAuth { localStorage.setItem(AppSettings.shushItemName, JSON.stringify(self.user)); //Stop Loading - self.appLoading.stopLoading().then(function() { + self.appNotify.stopLoading().then(function() { //Toast What Happened //In a timeout to avoid colliding with loading setTimeout(function() { - self.appNotification.showToast('Login Successful!'); + self.appNotify.showToast('Login Successful!'); }, 250) }); //Redirect to messages page - let nav = self.app.getRootNav(); - nav.setRoot(AllMessagesPage); + // let nav = self.app.getRootNav(); + // nav.setRoot(AllMessagesPage); }, function(error) { //Error //Stop Loading - self.appLoading.stopLoading().then(function() { + self.appNotify.stopLoading().then(function() { //Pass to Error Handler - self.appLoading.handleError(error); + self.appNotify.handleError(error); }); }, function() { //Subscription has completed @@ -153,7 +151,7 @@ export class AppAuth { private serverLogout(payload) { //Start Loading - this.appLoading.startLoading('Logging out...'); + this.appNotify.startLoading('Logging out...'); //No work is needed by the server, since the token will invalidate itself in OAuth @@ -166,11 +164,11 @@ export class AppAuth { let self = this; //Stop Loading - this.appLoading.stopLoading().then(function() { + this.appNotify.stopLoading().then(function() { //Toast What Happened //In a timeout to avoid colliding with loading setTimeout(function() { - self.appNotification.showToast('Logout Successful!'); + self.appNotify.showToast('Logout Successful!'); }, 250) }); diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts index bb0d312..2678b55 100644 --- a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -4,9 +4,7 @@ import 'rxjs/add/operator/map'; //Import our providers import { AppSettings } from '../../providers/app-settings/app-settings'; -import { AppAuth } from '../../providers/app-auth/app-auth'; -import { AppNotification } from '../../providers/app-notification/app-notification'; -import { AppLoading } from '../../providers/app-loading/app-loading'; +import { AppNotify } from '../../providers/app-notify/app-notify'; /* Generated class for the AppMessaging provider. @@ -17,17 +15,17 @@ import { AppLoading } from '../../providers/app-loading/app-loading'; @Injectable() export class AppMessaging { - constructor(private http: Http, private appSettings: AppSettings, private appAuth: AppAuth, private appNotification: AppNotification, private appLoading: AppLoading) { } + constructor(private http: Http, private appSettings: AppSettings, private appNotify: AppNotify) { } //Return all the conversations for a user - public getConversations() { + public getConversations(token) { //Start Loading - this.appLoading.startLoading('Getting Messages...'); + this.appNotify.startLoading('Getting Messages...'); //Our access_token header let headers = { - access_token: this.appAuth.user.access_token + access_token: token }; //Send the request with the payload to the server @@ -41,16 +39,16 @@ export class AppMessaging { console.log(success); //Stop loading - return self.appLoading.stopLoading().then(function() { + return self.appNotify.stopLoading().then(function() { return success; }); }, function(error) { //Error! //Stop Loading - self.appLoading.stopLoading().then(function() { + self.appNotify.stopLoading().then(function() { //Pass to Error Handler - self.appLoading.handleError(error); + self.appNotify.handleError(error); }); }, function() { diff --git a/client/secureChatIonic/app/providers/app-notification/app-notification.ts b/client/secureChatIonic/app/providers/app-notification/app-notification.ts deleted file mode 100644 index 6b7e0e1..0000000 --- a/client/secureChatIonic/app/providers/app-notification/app-notification.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Injectable } from '@angular/core'; -import { ToastController } from 'ionic-angular'; - -/* - Generated class for the AppNotification provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ - -//Handle All Notifications to be shown to the user -@Injectable() -export class AppNotification { - - constructor(private toastCtrl: ToastController) { } - - //Show a Static toast - showToast(toastContent) { - //Ensure we aren't toasting nothing - if (!toastContent) return; - - let toast = this.toastCtrl.create({ - message: toastContent, - showCloseButton: true, - position: 'bottom', - duration: 2000, - closeButtonText: 'Ok' - }); - toast.present(); - } - -} diff --git a/client/secureChatIonic/app/providers/app-loading/app-loading.ts b/client/secureChatIonic/app/providers/app-notify/app-notify.ts similarity index 61% rename from client/secureChatIonic/app/providers/app-loading/app-loading.ts rename to client/secureChatIonic/app/providers/app-notify/app-notify.ts index c0f2af7..97e45a8 100644 --- a/client/secureChatIonic/app/providers/app-loading/app-loading.ts +++ b/client/secureChatIonic/app/providers/app-notify/app-notify.ts @@ -1,12 +1,8 @@ import { Injectable } from '@angular/core'; -import { App, LoadingController } from 'ionic-angular'; - -//Pages -import { AuthLoginPage } from '../../pages/auth-login/auth-login'; +import { App, LoadingController, ToastController } from 'ionic-angular'; //Our Providers import { AppSettings } from '../../providers/app-settings/app-settings'; -import { AppNotification } from '../../providers/app-notification/app-notification'; /* @@ -16,9 +12,9 @@ import { AppNotification } from '../../providers/app-notification/app-notificati for more info on providers and Angular 2 DI. */ -//Handle Async requests, loading spinners, and general errors +//Handle Async requests, loading spinners, Toasts, and general errors @Injectable() -export class AppLoading { +export class AppNotify { //Our Loader loader: any; @@ -26,7 +22,22 @@ export class AppLoading { //Our default loading string defaultMessage: 'Loading, please wait...'; - constructor(private app: App, private loadingCtrl: LoadingController, private appNotification: AppNotification) { + constructor(private app: App, private loadingCtrl: LoadingController, private toastCtrl: ToastController) { + } + + //Show a Static toast + showToast(toastContent) { + //Ensure we aren't toasting nothing + if (!toastContent) return; + + let toast = this.toastCtrl.create({ + message: toastContent, + showCloseButton: true, + position: 'bottom', + duration: 2000, + closeButtonText: 'Ok' + }); + toast.present(); } //Function to start loading @@ -57,7 +68,7 @@ export class AppLoading { if (status == 400) { //400 Bad Request - this.appNotification.showToast('Bad Request. Please ensure your input is correct.'); + this.showToast('Bad Request. Please ensure your input is correct.'); } else if (status == 401) { //401 Unauthorized @@ -67,23 +78,23 @@ export class AppLoading { localStorage.setItem(AppSettings.shushItemName, JSON.stringify(user)) //Force the user to the login page - let nav = this.app.getRootNav(); - nav.setRoot(AuthLoginPage); + // let nav = this.app.getRootNav(); + // nav.setRoot(AuthLoginPage); //Toast the user - this.appNotification.showToast('Unauthorized. Please log back in.'); + this.showToast('Unauthorized. Please log back in.'); } else if (status == 404) { //Toast the user - this.appNotification.showToast('Could not be found. Please ensure your input is complete and correct.'); + this.showToast('Could not be found. Please ensure your input is complete and correct.'); } else if (status == 500) { //Internal Server Error //Toast the user - this.appNotification.showToast('Internal Server Error. Please try making the request again, or at a later time.'); + this.showToast('Internal Server Error. Please try making the request again, or at a later time.'); } else { - this.appNotification.showToast('Error ' + status + ': Please Contact Developers for help.'); + this.showToast('Error ' + status + ': Please Contact Developers for help.'); } From e73e0428812f41937074e750705d11b109d753da Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 19:06:43 -0700 Subject: [PATCH 06/18] Got Message Requests working Need to do a major refactoring before moving forward --- .../app/pages/all-messages/all-messages.html | 6 +- .../app/pages/all-messages/all-messages.ts | 42 +++++++- .../app/providers/app-auth/app-auth.ts | 97 +++++++++---------- .../providers/app-messaging/app-messaging.ts | 43 ++------ 4 files changed, 95 insertions(+), 93 deletions(-) diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.html b/client/secureChatIonic/app/pages/all-messages/all-messages.html index 7dfa91d..69e6156 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.html +++ b/client/secureChatIonic/app/pages/all-messages/all-messages.html @@ -19,11 +19,11 @@ - diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.ts b/client/secureChatIonic/app/pages/all-messages/all-messages.ts index ab4ccb0..b697147 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.ts +++ b/client/secureChatIonic/app/pages/all-messages/all-messages.ts @@ -5,7 +5,9 @@ import { NavController } from 'ionic-angular'; import { ConversationPage } from '../../pages/conversation/conversation'; //Import our providers -import { AppMessaging } from '../../providers/app-messaging/app-messaging' +import { AppSettings } from '../../providers/app-settings/app-settings'; +import { AppNotify } from '../../providers/app-notify/app-notify'; +import { AppMessaging } from '../../providers/app-messaging/app-messaging'; import { AppAuth } from '../../providers/app-auth/app-auth'; /* @@ -23,15 +25,47 @@ export class AllMessagesPage { location: NavController; //Our recent conversations - recentMessages: any; + allConversations: any; - constructor(private navCtrl: NavController, private appMessaging: AppMessaging, private appAuth: AppAuth) { + constructor(private navCtrl: NavController, private appNotify: AppNotify, private appMessaging: AppMessaging, private appAuth: AppAuth) { //Set our nav controller this.location = navCtrl; + //Start Loading + this.appNotify.startLoading('Getting Messages...'); + + //Grab our user from localstorage + let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)) + //Make a request to get the messages - this.recentMessages = this.appMessaging.getConversations(this.appAuth.user.access_token); + let request = this.appMessaging.conversationRequest(user.access_token); + + //Get a reference to this + let self = this; + + request.subscribe(function(success) { + //Success! + + //Stop loading + self.appNotify.stopLoading().then(function() { + self.allConversations = success; + console.log(self.allConversations); + }); + }, function(error) { + //Error! + + //Stop Loading + self.appNotify.stopLoading().then(function() { + //Pass to Error Handler + self.appNotify.handleError(error); + }); + + }, function() { + //Completed + }) + + } //Get shortened text with elipses diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index 0b71683..f47b50d 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -3,9 +3,6 @@ import { Http } from '@angular/http'; import { App } from 'ionic-angular'; import 'rxjs/add/operator/map'; -//Import Pages we navigate to -import { Home } from '../../pages/home/home'; - //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; import { AppNotify } from '../../providers/app-notify/app-notify'; @@ -35,24 +32,19 @@ export class AppAuth { access_token: 'token' } */ - user: any; //Class constructor constructor(private app: App, private http: Http, private appNotify: AppNotify) { - //Initialize the user - //Grab our user from localstorage - if (localStorage.getItem(AppSettings.shushItemName)) { - this.user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)); - } else { - this.user = { - access_token: false - }; - } } //Return our Login Status authStatus() { - if (this.user.access_token) return true; + + //Grab our user from localstorage + let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)) + if (user && user.access_token) { + return true + } return false; } @@ -90,10 +82,36 @@ export class AppAuth { //Logout logout() { - let payload = { - access_token: this.user.access_token - } - this.serverLogout(payload); + + //Start Loading + this.appNotify.startLoading('Logging out...'); + + //No work is needed by the server, since the token will invalidate itself in OAuth + + //Get our stored user + //Grab our user from localstorage + let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)) + if (user && user.access_token) user.access_token = false;; + if (user && user.user) user.user = {}; + + //Set the user to false + localStorage.setItem(AppSettings.shushItemName, JSON.stringify(user)); + + //Store reference to this for timeout + let self = this; + + //Stop Loading + this.appNotify.stopLoading().then(function() { + //Toast What Happened + //In a timeout to avoid colliding with loading + setTimeout(function() { + self.appNotify.showToast('Logout Successful!'); + }, 250) + }); + + //Redirect to messages page + // let nav = this.app.getRootNav(); + // nav.setRoot(Home); } //Private functions for server requests @@ -113,14 +131,20 @@ export class AppAuth { response.subscribe(function(success) { //Success! + //Create our new user + let userJson = { + user: {}, + access_token: '', + keys: {} + }; //Get the neccesary info from the user object - self.user.user = success.user - self.user.access_token = payload.access_token; + userJson.user = success.user + userJson.access_token = payload.access_token; //TODO: Generate Encryption keys for the user if none - self.user.keys = {}; + userJson.keys = {}; //Save the user info - localStorage.setItem(AppSettings.shushItemName, JSON.stringify(self.user)); + localStorage.setItem(AppSettings.shushItemName, JSON.stringify(userJson)); //Stop Loading self.appNotify.stopLoading().then(function() { @@ -148,34 +172,5 @@ export class AppAuth { } - private serverLogout(payload) { - - //Start Loading - this.appNotify.startLoading('Logging out...'); - - //No work is needed by the server, since the token will invalidate itself in OAuth - - //Set the user to false - this.user.access_token = false; - this.user.user = {}; - localStorage.setItem(AppSettings.shushItemName, JSON.stringify(this.user)); - - //Store reference to this for timeout - let self = this; - - //Stop Loading - this.appNotify.stopLoading().then(function() { - //Toast What Happened - //In a timeout to avoid colliding with loading - setTimeout(function() { - self.appNotify.showToast('Logout Successful!'); - }, 250) - }); - - //Redirect to messages page - let nav = this.app.getRootNav(); - nav.setRoot(Home); - - } } diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts index 2678b55..13c12cc 100644 --- a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; +import { Http, RequestOptions, Headers } from '@angular/http'; import 'rxjs/add/operator/map'; //Import our providers import { AppSettings } from '../../providers/app-settings/app-settings'; -import { AppNotify } from '../../providers/app-notify/app-notify'; /* Generated class for the AppMessaging provider. @@ -15,45 +14,19 @@ import { AppNotify } from '../../providers/app-notify/app-notify'; @Injectable() export class AppMessaging { - constructor(private http: Http, private appSettings: AppSettings, private appNotify: AppNotify) { } + constructor(private http: Http, private appSettings: AppSettings) { } //Return all the conversations for a user - public getConversations(token) { + conversationRequest(token) { - //Start Loading - this.appNotify.startLoading('Getting Messages...'); - - //Our access_token header - let headers = { + //Our headers + let headers = new Headers({ access_token: token - }; + }); + let options = new RequestOptions({ headers: headers }); //Send the request with the payload to the server - var response = this.http.get(AppSettings.serverUrl + 'conversation', headers).map(res => res.json()); - - //Get a reference to this - let self = this; - - response.subscribe(function(success) { - //Success! - console.log(success); - - //Stop loading - return self.appNotify.stopLoading().then(function() { - return success; - }); - }, function(error) { - //Error! - - //Stop Loading - self.appNotify.stopLoading().then(function() { - //Pass to Error Handler - self.appNotify.handleError(error); - }); - - }, function() { - //Completed - }) + return this.http.get(AppSettings.serverUrl + 'conversation', options).map(res => res.json()); } From ba13b6cda7fef86b2d12d807c9f1b526b35655de Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 19:53:03 -0700 Subject: [PATCH 07/18] Started refactoring, and Created observables for Facebook Sdk As the title states, more refactoring needs to be done however --- client/secureChatIonic/app/app.ts | 6 +- .../all-conversations.html} | 2 +- .../all-conversations.scss} | 0 .../all-conversations.ts} | 7 +- .../app/pages/auth-login/auth-login.ts | 56 +++++++- .../app/providers/app-auth/app-auth.ts | 122 +++++------------- .../providers/app-messaging/app-messaging.ts | 6 - .../app/providers/app-notify/app-notify.ts | 8 -- .../providers/app-settings/app-settings.ts | 22 +++- .../secureChatIonic/app/theme/app.core.scss | 2 +- 10 files changed, 108 insertions(+), 123 deletions(-) rename client/secureChatIonic/app/pages/{all-messages/all-messages.html => all-conversations/all-conversations.html} (87%) rename client/secureChatIonic/app/pages/{all-messages/all-messages.scss => all-conversations/all-conversations.scss} (100%) rename client/secureChatIonic/app/pages/{all-messages/all-messages.ts => all-conversations/all-conversations.ts} (93%) diff --git a/client/secureChatIonic/app/app.ts b/client/secureChatIonic/app/app.ts index f8acc70..fca719e 100644 --- a/client/secureChatIonic/app/app.ts +++ b/client/secureChatIonic/app/app.ts @@ -10,7 +10,7 @@ import { AppMessaging } from './providers/app-messaging/app-messaging'; //Import our pages import { Home } from './pages/home/home'; -import { AllMessagesPage } from './pages/all-messages/all-messages'; +import { AllConversationsPage } from './pages/all-conversations/all-conversations'; import { AuthLoginPage } from './pages/auth-login/auth-login'; import { ConversationPage } from './pages/conversation/conversation'; @@ -40,11 +40,11 @@ class MyApp { { title: 'Login', component: AuthLoginPage } ]; this.authPages = [ - { title: 'Messages', component: AllMessagesPage } + { title: 'Messages', component: AllConversationsPage } ]; //Set our root page - if (this.isLoggedIn()) this.rootPage = AllMessagesPage; + if (this.isLoggedIn()) this.rootPage = AllConversationsPage; else this.rootPage = Home; } diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.html b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html similarity index 87% rename from client/secureChatIonic/app/pages/all-messages/all-messages.html rename to client/secureChatIonic/app/pages/all-conversations/all-conversations.html index 69e6156..1189790 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.html +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html @@ -23,7 +23,7 @@

{{conversation.message[conversation.message.length - 1].from}}

-
{{shortenText(conversation.message[conversation.message.length - 1].message)}}
+
{{shortenText(conversation.message[conversation.message.length - 1].from + ': ' + conversation.message[conversation.message.length - 1].message)}}
diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.scss b/client/secureChatIonic/app/pages/all-conversations/all-conversations.scss similarity index 100% rename from client/secureChatIonic/app/pages/all-messages/all-messages.scss rename to client/secureChatIonic/app/pages/all-conversations/all-conversations.scss diff --git a/client/secureChatIonic/app/pages/all-messages/all-messages.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts similarity index 93% rename from client/secureChatIonic/app/pages/all-messages/all-messages.ts rename to client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index b697147..76a8494 100644 --- a/client/secureChatIonic/app/pages/all-messages/all-messages.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -19,7 +19,7 @@ import { AppAuth } from '../../providers/app-auth/app-auth'; @Component({ templateUrl: 'build/pages/all-messages/all-messages.html', }) -export class AllMessagesPage { +export class AllConversationsPage { //Our NavController location: NavController; @@ -70,11 +70,12 @@ export class AllMessagesPage { //Get shortened text with elipses shortenText(text: string) { + let textMax = 35; //First check if the text is already short - if (text.length < 21) return text; + if (text.length < textMax) return text; else { //Get a substring of text - text = text.substring(0, 20); + text = text.substring(0, (textMax - 1)); text = text + '...'; return text; } diff --git a/client/secureChatIonic/app/pages/auth-login/auth-login.ts b/client/secureChatIonic/app/pages/auth-login/auth-login.ts index aa097e7..464f2c2 100644 --- a/client/secureChatIonic/app/pages/auth-login/auth-login.ts +++ b/client/secureChatIonic/app/pages/auth-login/auth-login.ts @@ -2,6 +2,8 @@ import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; //Import our providers (services) +import { AppSettings } from '../../providers/app-settings/app-settings'; +import { AppNotify } from '../../providers/app-notify/app-notify'; import { AppAuth } from '../../providers/app-auth/app-auth'; /* @@ -16,11 +18,61 @@ import { AppAuth } from '../../providers/app-auth/app-auth'; export class AuthLoginPage { - constructor(private navCtrl: NavController, private authProvider: AppAuth) { } + constructor(private navCtrl: NavController, private appNotify: AppNotify, private authProvider: AppAuth) { } //Call our log in function from our auth service login() { - this.authProvider.login(); + + //Start Loading + this.appNotify.startLoading('Logging in...'); + + //Save a reference to this + let self = this; + + let response = this.authProvider.login(); + + //Respond to the callback + response.subscribe(function(success: any) { + //Success! + + //Create our new user + let userJson = { + user: {}, + access_token: '', + keys: {} + }; + //Get the neccesary info from the user object + userJson.user = success.user; + userJson.access_token = success.access_token; + //TODO: Generate Encryption keys for the user if none + userJson.keys = {}; + + //Save the user info + localStorage.setItem(AppSettings.shushItemName, JSON.stringify(userJson)); + + //Stop Loading + self.appNotify.stopLoading().then(function() { + //Toast What Happened + //In a timeout to avoid colliding with loading + setTimeout(function() { + self.appNotify.showToast('Login Successful!'); + }, 250) + }); + + //Redirect to messages page + // let nav = self.app.getRootNav(); + // nav.setRoot(AllMessagesPage); + }, function(error) { + + //Error + //Stop Loading + self.appNotify.stopLoading().then(function() { + //Pass to Error Handler + self.appNotify.handleError(error); + }); + }, function() { + //Subscription has completed + }) } } diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index f47b50d..a3c0657 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -2,37 +2,15 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { App } from 'ionic-angular'; import 'rxjs/add/operator/map'; +import {Observable} from 'rxjs/Observable'; //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; import { AppNotify } from '../../providers/app-notify/app-notify'; -/* - Generated class for the AppAuth provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI -*/ @Injectable() export class AppAuth { - //Our user accesToken - /* - User schema - { - user: { - name:"" - email:"" - etc.... - } - keys: { - public: 'sdjlaksjda' - private: 'askjdklsjd' - }, - access_token: 'token' - } - */ - //Class constructor constructor(private app: App, private http: Http, private appNotify: AppNotify) { } @@ -60,24 +38,40 @@ export class AppAuth { //Login //Scope asks for permissions that we need to create/identify users + //How to make REST requests in Angular 2: http://stackoverflow.com/questions/34671715/angular2-http-get-map-subscribe-and-observable-pattern-basic-understan/34672550 login() { - //Make a reference to 'this' to avoid scoping this issue + //Get a reference to self let self = this; - FB.login(function(response) { - //Response from facebook on function call - let jsonResponse = response.authResponse; + //Create a new observable + //https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87#.g2xfbgf3h + //observer.next => success, observer.error => error, observer.complete => complete + return new Observable(function(observer) { + + FB.login(function(response) { + + //Response from facebook on function call + let jsonResponse = response.authResponse; + + //Pass the access token to our server login + let payload = { + access_token: jsonResponse.accessToken + } + + let request = self.http.post(AppSettings.serverUrl + 'login', payload).map(res => res.json()); + + + observer.next({ + request: request, + access_token: jsonResponse.accessToken + }); - //Pass the access token to our server login - let payload = { - access_token: jsonResponse.accessToken - } - self.serverLogin(payload); + }, { + scope: 'email' + }); - }, { - scope: 'email' - }); + }) } //Logout @@ -114,63 +108,5 @@ export class AppAuth { // nav.setRoot(Home); } - //Private functions for server requests - //How to make REST requests in Angular 2: http://stackoverflow.com/questions/34671715/angular2-http-get-map-subscribe-and-observable-pattern-basic-understan/34672550 - private serverLogin(payload) { - - //Start Loading - this.appNotify.startLoading('Logging in...'); - - //Save a reference to this - let self = this; - - //Send the request with the payload to the server - var response = this.http.post(AppSettings.serverUrl + 'login', payload).map(res => res.json()); - - //Respond to the callback - response.subscribe(function(success) { - //Success! - - //Create our new user - let userJson = { - user: {}, - access_token: '', - keys: {} - }; - //Get the neccesary info from the user object - userJson.user = success.user - userJson.access_token = payload.access_token; - //TODO: Generate Encryption keys for the user if none - userJson.keys = {}; - - //Save the user info - localStorage.setItem(AppSettings.shushItemName, JSON.stringify(userJson)); - - //Stop Loading - self.appNotify.stopLoading().then(function() { - //Toast What Happened - //In a timeout to avoid colliding with loading - setTimeout(function() { - self.appNotify.showToast('Login Successful!'); - }, 250) - }); - - //Redirect to messages page - // let nav = self.app.getRootNav(); - // nav.setRoot(AllMessagesPage); - }, function(error) { - - //Error - //Stop Loading - self.appNotify.stopLoading().then(function() { - //Pass to Error Handler - self.appNotify.handleError(error); - }); - }, function() { - //Subscription has completed - }) - - } - } diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts index 13c12cc..03dcaf5 100644 --- a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -5,12 +5,6 @@ import 'rxjs/add/operator/map'; //Import our providers import { AppSettings } from '../../providers/app-settings/app-settings'; -/* - Generated class for the AppMessaging provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ @Injectable() export class AppMessaging { diff --git a/client/secureChatIonic/app/providers/app-notify/app-notify.ts b/client/secureChatIonic/app/providers/app-notify/app-notify.ts index 97e45a8..b535e9a 100644 --- a/client/secureChatIonic/app/providers/app-notify/app-notify.ts +++ b/client/secureChatIonic/app/providers/app-notify/app-notify.ts @@ -4,14 +4,6 @@ import { App, LoadingController, ToastController } from 'ionic-angular'; //Our Providers import { AppSettings } from '../../providers/app-settings/app-settings'; - -/* - Generated class for the AppLoading provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ - //Handle Async requests, loading spinners, Toasts, and general errors @Injectable() export class AppNotify { diff --git a/client/secureChatIonic/app/providers/app-settings/app-settings.ts b/client/secureChatIonic/app/providers/app-settings/app-settings.ts index 116b087..7e36e4e 100644 --- a/client/secureChatIonic/app/providers/app-settings/app-settings.ts +++ b/client/secureChatIonic/app/providers/app-settings/app-settings.ts @@ -4,18 +4,28 @@ export class AppSettings { //How to ignore changes on this file: http://stackoverflow.com/a/17410119 //DO NOT UPLOAD ACTUAL KEYS TO GITHUB - //Declare our keys - static testing = 'testing test'; - //Fake key for now, to get the dialog working //Can be stored on the client: http://stackoverflow.com/questions/6709883/facebook-app-security-what-if-someone-uses-my-appid - static facebookAppId = '2365441780952680'; + static facebookAppId = '2345671234542689'; //The name of the json object stored on the device + /* + schema + { + user: { + name:"" + email:"" + etc.... + } + keys: { + public: 'sdjlaksjda' + private: 'askjdklsjd' + }, + access_token: 'token' + } + */ static shushItemName = 'shushUser'; - - //Add our server URL (Local testing not actual) //Must end with a slash static serverUrl = 'http://192.168.43.86:4780/api/v1/'; diff --git a/client/secureChatIonic/app/theme/app.core.scss b/client/secureChatIonic/app/theme/app.core.scss index f252325..825d28f 100644 --- a/client/secureChatIonic/app/theme/app.core.scss +++ b/client/secureChatIonic/app/theme/app.core.scss @@ -9,7 +9,7 @@ //Import our page scss @import "../pages/home/home"; -@import "../pages/all-messages/all-messages"; +@import "../pages/all-conversations/all-conversations"; @import "../pages/conversation/conversation"; @import "../pages/auth-login/auth-login"; From c52a93816491f879ae009c1525746ea697b20944 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 20:06:49 -0700 Subject: [PATCH 08/18] More Cleanup, and more observables Simply need to handle errors on FB login, Create Pages provider, and finish up messages --- .../app/pages/all-conversations/all-conversations.ts | 2 +- .../app/pages/auth-login/auth-login.ts | 11 +++++++---- .../app/providers/app-auth/app-auth.ts | 8 ++++++-- .../app/providers/app-notify/app-notify.ts | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index 76a8494..7e905f9 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -50,7 +50,7 @@ export class AllConversationsPage { //Stop loading self.appNotify.stopLoading().then(function() { self.allConversations = success; - console.log(self.allConversations); + //console.log(self.allConversations); }); }, function(error) { //Error! diff --git a/client/secureChatIonic/app/pages/auth-login/auth-login.ts b/client/secureChatIonic/app/pages/auth-login/auth-login.ts index 464f2c2..b27a3c4 100644 --- a/client/secureChatIonic/app/pages/auth-login/auth-login.ts +++ b/client/secureChatIonic/app/pages/auth-login/auth-login.ts @@ -1,6 +1,9 @@ import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; +//Pages +import { AllConversationsPage } from '../../pages/all-conversations/all-conversations'; + //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; import { AppNotify } from '../../providers/app-notify/app-notify'; @@ -55,13 +58,13 @@ export class AuthLoginPage { //Toast What Happened //In a timeout to avoid colliding with loading setTimeout(function() { + //Show Toast self.appNotify.showToast('Login Successful!'); + + //Redirect to messages page + self.navCtrl.setRoot(AllConversationsPage); }, 250) }); - - //Redirect to messages page - // let nav = self.app.getRootNav(); - // nav.setRoot(AllMessagesPage); }, function(error) { //Error diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index a3c0657..d3898bb 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -4,6 +4,9 @@ import { App } from 'ionic-angular'; import 'rxjs/add/operator/map'; import {Observable} from 'rxjs/Observable'; +//pages +import { Home } from '../../pages/home/home'; + //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; import { AppNotify } from '../../providers/app-notify/app-notify'; @@ -104,8 +107,9 @@ export class AppAuth { }); //Redirect to messages page - // let nav = this.app.getRootNav(); - // nav.setRoot(Home); + //Force the user to the login page + let nav = this.app.getRootNav(); + nav.setRoot(Home); } diff --git a/client/secureChatIonic/app/providers/app-notify/app-notify.ts b/client/secureChatIonic/app/providers/app-notify/app-notify.ts index b535e9a..30df1ba 100644 --- a/client/secureChatIonic/app/providers/app-notify/app-notify.ts +++ b/client/secureChatIonic/app/providers/app-notify/app-notify.ts @@ -70,6 +70,7 @@ export class AppNotify { localStorage.setItem(AppSettings.shushItemName, JSON.stringify(user)) //Force the user to the login page + //Will Create circular dependency, need to create pages provider // let nav = this.app.getRootNav(); // nav.setRoot(AuthLoginPage); From 281c37ad5beed094f0686ae21873c547364e54e5 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 20:10:21 -0700 Subject: [PATCH 09/18] Generated the pages provider --- .../all-conversations/all-conversations.ts | 6 ------ .../providers/app-nav-config/app-nav-config.ts | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index 7e905f9..788b02f 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -10,12 +10,6 @@ import { AppNotify } from '../../providers/app-notify/app-notify'; import { AppMessaging } from '../../providers/app-messaging/app-messaging'; import { AppAuth } from '../../providers/app-auth/app-auth'; -/* - Generated class for the AllMessagesPage page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ @Component({ templateUrl: 'build/pages/all-messages/all-messages.html', }) diff --git a/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts b/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts new file mode 100644 index 0000000..58cff62 --- /dev/null +++ b/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; + +/* + Generated class for the AppNavConfig provider. + + See https://angular.io/docs/ts/latest/guide/dependency-injection.html + for more info on providers and Angular 2 DI. +*/ +@Injectable() +export class AppNavConfig { + + constructor(private http: Http) {} + +} + From cefcf5cd668491639dd09f21ff5ba6be6e7ff0bb Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Thu, 20 Oct 2016 20:18:40 -0700 Subject: [PATCH 10/18] Couldnt make nav provider Pages are required to be imported into the app.ts --- .../providers/app-nav-config/app-nav-config.ts | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts diff --git a/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts b/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts deleted file mode 100644 index 58cff62..0000000 --- a/client/secureChatIonic/app/providers/app-nav-config/app-nav-config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; -import 'rxjs/add/operator/map'; - -/* - Generated class for the AppNavConfig provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ -@Injectable() -export class AppNavConfig { - - constructor(private http: Http) {} - -} - From 3a08a525a35dd84a52b2180782ee200b9c912e43 Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Fri, 21 Oct 2016 00:09:01 -0700 Subject: [PATCH 11/18] Fixed Miissing all conversations page, and added error handling for facebook login --- .../app/pages/all-conversations/all-conversations.scss | 4 ---- .../app/pages/all-conversations/all-conversations.ts | 2 +- client/secureChatIonic/app/pages/auth-login/auth-login.ts | 5 +++-- client/secureChatIonic/app/providers/app-auth/app-auth.ts | 6 ++++++ 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.scss b/client/secureChatIonic/app/pages/all-conversations/all-conversations.scss index a951b91..0a0d172 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.scss +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.scss @@ -1,7 +1,3 @@ -.all-messages { - -} - .recentMessagesList { width: 100%; } diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index 788b02f..d0617ec 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -11,7 +11,7 @@ import { AppMessaging } from '../../providers/app-messaging/app-messaging'; import { AppAuth } from '../../providers/app-auth/app-auth'; @Component({ - templateUrl: 'build/pages/all-messages/all-messages.html', + templateUrl: 'build/pages/all-conversations/all-conversations.html', }) export class AllConversationsPage { diff --git a/client/secureChatIonic/app/pages/auth-login/auth-login.ts b/client/secureChatIonic/app/pages/auth-login/auth-login.ts index b27a3c4..f365bed 100644 --- a/client/secureChatIonic/app/pages/auth-login/auth-login.ts +++ b/client/secureChatIonic/app/pages/auth-login/auth-login.ts @@ -70,8 +70,9 @@ export class AuthLoginPage { //Error //Stop Loading self.appNotify.stopLoading().then(function() { - //Pass to Error Handler - self.appNotify.handleError(error); + + //There was an error connecting to facebook + self.appNotify.showToast('Error, Facebook did not return your credentials.') }); }, function() { //Subscription has completed diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index d3898bb..35ecb28 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -57,6 +57,12 @@ export class AppAuth { //Response from facebook on function call let jsonResponse = response.authResponse; + //Check for an error + if (!jsonResponse) { + observer.error(response); + return; + } + //Pass the access token to our server login let payload = { access_token: jsonResponse.accessToken From 160bce3fce66d3e0115f614641f8ee5d094be1fa Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Fri, 21 Oct 2016 01:40:47 -0700 Subject: [PATCH 12/18] Finished the circular dependency of 401, and refactoring Code is looking very nice, and makes much sense now --- client/secureChatIonic/app/app.ts | 33 +++++++++++--- .../all-conversations/all-conversations.ts | 10 ++--- .../app/pages/auth-login/auth-login.ts | 7 ++- .../app/providers/app-auth/app-auth.ts | 44 ++++++------------- .../app/providers/app-notify/app-notify.ts | 29 +++++++----- 5 files changed, 68 insertions(+), 55 deletions(-) diff --git a/client/secureChatIonic/app/app.ts b/client/secureChatIonic/app/app.ts index fca719e..c40e410 100644 --- a/client/secureChatIonic/app/app.ts +++ b/client/secureChatIonic/app/app.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { ionicBootstrap, Platform, Nav } from 'ionic-angular'; import { StatusBar } from 'ionic-native'; @@ -10,13 +10,14 @@ import { AppMessaging } from './providers/app-messaging/app-messaging'; //Import our pages import { Home } from './pages/home/home'; -import { AllConversationsPage } from './pages/all-conversations/all-conversations'; import { AuthLoginPage } from './pages/auth-login/auth-login'; +import { AllConversationsPage } from './pages/all-conversations/all-conversations'; import { ConversationPage } from './pages/conversation/conversation'; @Component({ templateUrl: 'build/app.html', - providers: [AppSettings, AppAuth, AppMessaging, AppNotify] + providers: [AppSettings, AppAuth, AppMessaging, AppNotify], + changeDetection: ChangeDetectionStrategy.OnPush }) class MyApp { @ViewChild(Nav) nav: Nav; @@ -29,7 +30,7 @@ class MyApp { noAuthPages: Array<{ title: string, component: any }>; authPages: Array<{ title: string, component: any }>; - constructor(public platform: Platform, public authProvider: AppAuth) { + constructor(public platform: Platform, private authProvider: AppAuth, private appNotify: AppNotify) { this.initializeApp(); // used for an example of ngFor and navigation @@ -68,12 +69,34 @@ class MyApp { //Check if we are logged in isLoggedIn() { - return this.authProvider.authStatus(); + + //Get the auth Status + return this.authProvider.authStatus; } //Logout the user logout() { + //Start Loading + this.appNotify.startLoading('Logging out...'); + this.authProvider.logout(); + + //Store reference to this for timeout + let self = this; + + //Stop Loading + this.appNotify.stopLoading().then(function() { + //Toast What Happened + //In a timeout to avoid colliding with loading + setTimeout(function() { + + //Go back home + self.rootPage = Home; + self.nav.setRoot(Home); + + self.appNotify.showToast('Logout Successful!'); + }, 250) + }); } } diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index d0617ec..ea0b6dd 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -8,23 +8,19 @@ import { ConversationPage } from '../../pages/conversation/conversation'; import { AppSettings } from '../../providers/app-settings/app-settings'; import { AppNotify } from '../../providers/app-notify/app-notify'; import { AppMessaging } from '../../providers/app-messaging/app-messaging'; -import { AppAuth } from '../../providers/app-auth/app-auth'; @Component({ templateUrl: 'build/pages/all-conversations/all-conversations.html', }) export class AllConversationsPage { - //Our NavController - location: NavController; - //Our recent conversations allConversations: any; - constructor(private navCtrl: NavController, private appNotify: AppNotify, private appMessaging: AppMessaging, private appAuth: AppAuth) { + //If we have the conversations + hasConversations: boolean; - //Set our nav controller - this.location = navCtrl; + constructor(private navCtrl: NavController, private appNotify: AppNotify, private appMessaging: AppMessaging) { //Start Loading this.appNotify.startLoading('Getting Messages...'); diff --git a/client/secureChatIonic/app/pages/auth-login/auth-login.ts b/client/secureChatIonic/app/pages/auth-login/auth-login.ts index f365bed..32cd307 100644 --- a/client/secureChatIonic/app/pages/auth-login/auth-login.ts +++ b/client/secureChatIonic/app/pages/auth-login/auth-login.ts @@ -21,7 +21,7 @@ import { AppAuth } from '../../providers/app-auth/app-auth'; export class AuthLoginPage { - constructor(private navCtrl: NavController, private appNotify: AppNotify, private authProvider: AppAuth) { } + constructor(private navCtrl: NavController, private appNotify: AppNotify, private appAuth: AppAuth) { } //Call our log in function from our auth service login() { @@ -32,7 +32,7 @@ export class AuthLoginPage { //Save a reference to this let self = this; - let response = this.authProvider.login(); + let response = this.appAuth.login(); //Respond to the callback response.subscribe(function(success: any) { @@ -53,6 +53,9 @@ export class AuthLoginPage { //Save the user info localStorage.setItem(AppSettings.shushItemName, JSON.stringify(userJson)); + //Update the auth status + self.appAuth.updateAuthStatus(true); + //Stop Loading self.appNotify.stopLoading().then(function() { //Toast What Happened diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index 35ecb28..ee6ed7f 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; -import { App } from 'ionic-angular'; import 'rxjs/add/operator/map'; import {Observable} from 'rxjs/Observable'; @@ -9,24 +8,27 @@ import { Home } from '../../pages/home/home'; //Import our providers (services) import { AppSettings } from '../../providers/app-settings/app-settings'; -import { AppNotify } from '../../providers/app-notify/app-notify'; @Injectable() export class AppAuth { - //Class constructor - constructor(private app: App, private http: Http, private appNotify: AppNotify) { - } - - //Return our Login Status - authStatus() { + //Our auth status + authStatus: boolean; + //Class constructor + constructor(private http: Http) { //Grab our user from localstorage let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)) if (user && user.access_token) { - return true + this.updateAuthStatus(true); + } else { + this.updateAuthStatus(false); } - return false; + } + + //Return our Login Status + updateAuthStatus(status) { + this.authStatus = status; } //Initialize facebook @@ -85,10 +87,6 @@ export class AppAuth { //Logout logout() { - - //Start Loading - this.appNotify.startLoading('Logging out...'); - //No work is needed by the server, since the token will invalidate itself in OAuth //Get our stored user @@ -100,22 +98,8 @@ export class AppAuth { //Set the user to false localStorage.setItem(AppSettings.shushItemName, JSON.stringify(user)); - //Store reference to this for timeout - let self = this; - - //Stop Loading - this.appNotify.stopLoading().then(function() { - //Toast What Happened - //In a timeout to avoid colliding with loading - setTimeout(function() { - self.appNotify.showToast('Logout Successful!'); - }, 250) - }); - - //Redirect to messages page - //Force the user to the login page - let nav = this.app.getRootNav(); - nav.setRoot(Home); + //Update the auth status + this.updateAuthStatus(false); } diff --git a/client/secureChatIonic/app/providers/app-notify/app-notify.ts b/client/secureChatIonic/app/providers/app-notify/app-notify.ts index 30df1ba..39b9d18 100644 --- a/client/secureChatIonic/app/providers/app-notify/app-notify.ts +++ b/client/secureChatIonic/app/providers/app-notify/app-notify.ts @@ -1,20 +1,30 @@ -import { Injectable } from '@angular/core'; -import { App, LoadingController, ToastController } from 'ionic-angular'; +import { Injectable, ViewChild } from '@angular/core'; +import { App, Nav, LoadingController, ToastController } from 'ionic-angular'; //Our Providers import { AppSettings } from '../../providers/app-settings/app-settings'; +import { AppAuth } from '../../providers/app-auth/app-auth'; + +//Page to redirect to on 401 +import { Home } from '../../pages/home/home'; //Handle Async requests, loading spinners, Toasts, and general errors @Injectable() export class AppNotify { + //Our Nav + @ViewChild(Nav) nav: Nav; + + //Our login pages + loginPage: any; + //Our Loader loader: any; //Our default loading string defaultMessage: 'Loading, please wait...'; - constructor(private app: App, private loadingCtrl: LoadingController, private toastCtrl: ToastController) { + constructor(private app: App, private appAuth: AppAuth, private loadingCtrl: LoadingController, private toastCtrl: ToastController) { } //Show a Static toast @@ -64,15 +74,12 @@ export class AppNotify { } else if (status == 401) { //401 Unauthorized - //Set the access token to false - let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)); - user.access_token = false; - localStorage.setItem(AppSettings.shushItemName, JSON.stringify(user)) + //Logout + this.appAuth.logout(); - //Force the user to the login page - //Will Create circular dependency, need to create pages provider - // let nav = this.app.getRootNav(); - // nav.setRoot(AuthLoginPage); + //Redirect to home + let nav = this.app.getActiveNav(); + nav.setRoot(Home); //Toast the user this.showToast('Unauthorized. Please log back in.'); From f5021ab6c9ef0b8c3e35e2a86f4829b5da5af44a Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Fri, 21 Oct 2016 03:30:42 -0700 Subject: [PATCH 13/18] Tested Messaging Schema, and got message polling wokring All is looking good, simply need to finish up single conversationview to finish messaging --- client/secureChatIonic/app/app.ts | 1 + .../all-conversations/all-conversations.html | 23 ++++-- .../all-conversations/all-conversations.ts | 79 ++++++++++++++++--- .../app/providers/app-auth/app-auth.ts | 2 +- .../providers/app-messaging/app-messaging.ts | 14 +++- .../app/providers/app-notify/app-notify.ts | 15 +++- 6 files changed, 109 insertions(+), 25 deletions(-) diff --git a/client/secureChatIonic/app/app.ts b/client/secureChatIonic/app/app.ts index c40e410..9f914a8 100644 --- a/client/secureChatIonic/app/app.ts +++ b/client/secureChatIonic/app/app.ts @@ -14,6 +14,7 @@ import { AuthLoginPage } from './pages/auth-login/auth-login'; import { AllConversationsPage } from './pages/all-conversations/all-conversations'; import { ConversationPage } from './pages/conversation/conversation'; +//Change detection needed for updating "this" AKA $scope @Component({ templateUrl: 'build/app.html', providers: [AppSettings, AppAuth, AppMessaging, AppNotify], diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.html b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html index 1189790..f76b959 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.html +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html @@ -19,11 +19,22 @@ - + + +
+

No Conversations Found!

+
(Add some friends using the side menu)
+
+ + +
+ +
+
diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts index ea0b6dd..0a0e149 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; import { NavController } from 'ionic-angular'; //Import to conversation view @@ -10,17 +10,17 @@ import { AppNotify } from '../../providers/app-notify/app-notify'; import { AppMessaging } from '../../providers/app-messaging/app-messaging'; @Component({ - templateUrl: 'build/pages/all-conversations/all-conversations.html', + templateUrl: 'build/pages/all-conversations/all-conversations.html' }) export class AllConversationsPage { //Our recent conversations allConversations: any; - //If we have the conversations - hasConversations: boolean; + //Our message Polling + pollingRequest: any; - constructor(private navCtrl: NavController, private appNotify: AppNotify, private appMessaging: AppMessaging) { + constructor(private changeDetector: ChangeDetectorRef, private navCtrl: NavController, private appNotify: AppNotify, private appMessaging: AppMessaging) { //Start Loading this.appNotify.startLoading('Getting Messages...'); @@ -28,19 +28,23 @@ export class AllConversationsPage { //Grab our user from localstorage let user = JSON.parse(localStorage.getItem(AppSettings.shushItemName)) - //Make a request to get the messages - let request = this.appMessaging.conversationRequest(user.access_token); + //Start polling to get messages + let poll = this.appMessaging.conversationRequest(user.access_token); //Get a reference to this let self = this; - request.subscribe(function(success) { + this.pollingRequest = poll.subscribe(function(success) { //Success! //Stop loading self.appNotify.stopLoading().then(function() { + + //Add our messages self.allConversations = success; - //console.log(self.allConversations); + + //Update the UI + self.changeDetector.detectChanges(); }); }, function(error) { //Error! @@ -48,24 +52,66 @@ export class AllConversationsPage { //Stop Loading self.appNotify.stopLoading().then(function() { //Pass to Error Handler - self.appNotify.handleError(error); + self.appNotify.handleError(error, [{ + status: 404, + callback: function() { + //Simply set all conversations to an empty array + self.allConversations = []; + + //Update the UI + self.changeDetector.detectChanges(); + } + }]); }); }, function() { //Completed }) + } + + //Function to return if we have conversations + hasConversations() { + if (!this.allConversations || (this.allConversations && this.allConversations.length > 0)) return true; + else return false; + } + + //Function to reutn the users in a conversations + getConvoMembers(convo: any) { + + //Get the last message sender + console.log(convo); + + //Get the names of the members spilt by spaces + let members = ''; + for (let i = 0; i < convo.memberNames.length; ++i) { + members += convo.memberNames[i].split(' ')[0]; + if (i < convo.memberNames.length - 1) members += ', '; + } + return this.shortenText(members, 20); } + getConvoLatestText(convo: any) { + + //Get the last message sender + let lastMessage = convo.message[convo.message.length - 1]; + + let lastSender = lastMessage.from.split(' ')[0]; + let lastText = lastMessage.message; + + return this.shortenText(lastSender + ': ' + lastText, 35) + } + + //Function to return //Get shortened text with elipses - shortenText(text: string) { - let textMax = 35; + shortenText(text: string, textMax) { + //First check if the text is already short if (text.length < textMax) return text; else { //Get a substring of text - text = text.substring(0, (textMax - 1)); + text = text.substring(0, (textMax - 3)); text = text + '...'; return text; } @@ -79,4 +125,11 @@ export class AllConversationsPage { }); } + //Run on page leave + ionViewWillLeave() { + //Stop polling + console.log('hello!'); + this.pollingRequest.unsubscribe(); + } + } diff --git a/client/secureChatIonic/app/providers/app-auth/app-auth.ts b/client/secureChatIonic/app/providers/app-auth/app-auth.ts index ee6ed7f..a0364ca 100644 --- a/client/secureChatIonic/app/providers/app-auth/app-auth.ts +++ b/client/secureChatIonic/app/providers/app-auth/app-auth.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; -import {Observable} from 'rxjs/Observable'; //pages import { Home } from '../../pages/home/home'; diff --git a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts index 03dcaf5..44b888a 100644 --- a/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts +++ b/client/secureChatIonic/app/providers/app-messaging/app-messaging.ts @@ -1,7 +1,11 @@ import { Injectable } from '@angular/core'; import { Http, RequestOptions, Headers } from '@angular/http'; +import { Observable } from "rxjs/Observable"; +import 'rxjs/add/observable/interval'; +import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/map'; + //Import our providers import { AppSettings } from '../../providers/app-settings/app-settings'; @@ -19,10 +23,12 @@ export class AppMessaging { }); let options = new RequestOptions({ headers: headers }); - //Send the request with the payload to the server - return this.http.get(AppSettings.serverUrl + 'conversation', options).map(res => res.json()); - - + //Continually poll the server in an interval to get messages + //Poll Interval every 30 seconds + let pollInterval = 5000; + return Observable.interval(pollInterval) + .switchMap(() => this.http.get(AppSettings.serverUrl + 'conversation', options)) + .map(res => res.json()); } diff --git a/client/secureChatIonic/app/providers/app-notify/app-notify.ts b/client/secureChatIonic/app/providers/app-notify/app-notify.ts index 39b9d18..3378ce0 100644 --- a/client/secureChatIonic/app/providers/app-notify/app-notify.ts +++ b/client/secureChatIonic/app/providers/app-notify/app-notify.ts @@ -58,7 +58,7 @@ export class AppNotify { } //Function to handle Errors - handleError(error) { + handleError(error, expected?) { //TODO: Allow for overiding error codes, and using custom callbacks @@ -68,6 +68,19 @@ export class AppNotify { //Get our status let status = error.status; + //Check if we have any callbacks for specific error codes + if (expected) { + for (let i = 0; i < expected.length; ++i) { + if (expected[i].status == status) { + + //Launch the call abck and return + expected[i].callback(); + return; + } + + } + } + if (status == 400) { //400 Bad Request this.showToast('Bad Request. Please ensure your input is correct.'); From cc3e1d79ef04fa85cc53bf7ef52b5372939ef67a Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Fri, 21 Oct 2016 04:19:28 -0700 Subject: [PATCH 14/18] FInished Message polling Perfectly. All that remains is message posting (Conversation Create), and message putting (Sending new Message in a conversation) --- .../all-conversations/all-conversations.html | 2 +- .../all-conversations/all-conversations.ts | 25 ++- .../app/pages/conversation/conversation.html | 6 +- .../app/pages/conversation/conversation.ts | 198 +++++++++++------- .../providers/app-messaging/app-messaging.ts | 3 + 5 files changed, 142 insertions(+), 92 deletions(-) diff --git a/client/secureChatIonic/app/pages/all-conversations/all-conversations.html b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html index f76b959..d7db6f8 100644 --- a/client/secureChatIonic/app/pages/all-conversations/all-conversations.html +++ b/client/secureChatIonic/app/pages/all-conversations/all-conversations.html @@ -28,7 +28,7 @@
(Add some friends using the side menu)
-