diff --git a/README.md b/README.md index 3fbd83e..48f3d35 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,20 @@ NativeScript : Facebook SDK ![apple](https://cdn3.iconfinder.com/data/icons/pico - [Login](#login) - [Facebook Login Button](#facebook-login-button) - [Custom Login Button](#custom-login-button) + - [Log out](#log-out) + - [Facebook Logout Button](#facebook-logout-button) + - [Custom Logout Button](#custom-logout-button) - [NativeScript Angular](#nativescript-angular) - [Initialization](#initialization-1) - [Login](#login-1) - [Facebook Login Button](#facebook-login-button-1) - [Custom Login Button](#custom-login-button-1) + - [Logout](#logout) + - [Facebook Logout Button](#facebook-logout-button-1) + - [Custom Logout Button](#custom-logout-button-1) - [Login Response](#login-response) +- [Graph API Example](#graph-api-example) +- [Release notes](#release-notes) - [License](#license) @@ -73,21 +81,23 @@ Update Info.plist file (app/App_Resources/iOS/Info.plist) to contains `CFBundleU ### Initialization Call init of nativescript-facebook module on application launch. -app.ts +[app.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/app.ts) ```TypeScript import * as application from 'application'; -var nsFacebook = require('nativescript-facebook'); +import { init } from "nativescript-facebook"; application.on(application.launchEvent, function (args) { - nsFacebook.init("{facebook_app_id}"); + init("{facebook_app_id}"); }); -application.start({ moduleName: "main-page" }); +application.start({ moduleName: "login-page" }); ``` ### Login #### Facebook Login Button -main-page.xml +Add Facebook login button as simple as adding a Facebook:LoginButton tag in your view. Then you can define `login` event handler name. In the example below - `onLogin`. + +[login-page.xml](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/login-page.xml) ```xml ``` -main-view-model.ts +Implement `onLogin` event handler in your view-model. It receives an argument from type `LoginEventData`. Currently `LoginEventData` object has 2 properties: error and loginResponse. loginResponse is an object that consists of 1 property - token that keeps the facebook access token which will be used for further authentications. Ideally we can add some other properties here in the future such as Facebook user id. + +[login-view-model.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/login-view-model.ts) ```TypeScript import { Observable } from 'data/observable'; +import { Facebook:LoginButton } from "nativescript-facebook"; -export class HelloWorldModel extends Observable { +export class LoginViewModel extends Observable { - public onLogin(error, data) { - console.log("Success!"); + onLogin(eventData: LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error.message); + } else { + console.log(eventData.loginResponse.token); + } } - } ``` #### Custom Login Button -main-page.xml +Add a button and define a `tap` event handler in your login view. + +[login-page.xml](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/login-page.xml) +```xml + + + ... + + + + ... + + +``` + +In the view model implement the tap event handler in this case `login` method. It just has to call the login method that comes from the plugin. In the example below the login method from the plugin is imported as fbLogin. + +> **BEST PRACTICE**: +Import only the methods that you need instead of the entire file. It is crucial when you bundle your app with webpack. + +[login-view-model.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/login-view-model.ts) +```TypeScript +import { Observable } from 'data/observable'; +import { login as fbLogin } from "nativescript-facebook"; + +export class LoginViewModel extends Observable { + + login() { + fbLogin((err, fbData) => { + if (err) { + alert("Error during login: " + err.message); + } else { + console.log(fbData.token); + } + }); + } + +} +``` + +### Log out +#### Facebook Logout Button + +Add Facebook logout button as simple as adding a Facebook:LoginButton tag in your view. Then you can define `logout` event handler name. In the example below - `onLogout`. + +[home-page.xml](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/home-page.xml) ```xml + ... ``` -main-view-model.ts +Implement `onLogout` event handler in your view-model. + +[home-view-model.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/home-view-model.ts) ```TypeScript import { Observable } from 'data/observable'; -import { login } from "nativescript-facebook"; -export class HelloWorldModel extends Observable { +export class HomeViewModel extends Observable { - public testAction() { - login((error, data) => console.log("Success!")); + onLogout() { + console.log("logged out"); } } ``` +#### Custom Logout Button + +Add a button and define a `tap` event handler in your view. In this case - `logout` + +[home-page.xml](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/home-page.xml) +```xml + + + ... + + + + ... + + +``` + +In the view model implement the tap event handler in this case `logout` method. It just has to call the logout method that comes from the plugin. In the example below the logout method from the plugin is imported as fbLogout. + +[home-view-model.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/home-view-model.ts) +```TypeScript +import { Observable } from 'data/observable'; +import { logout as fbLogout } from "nativescript-facebook"; + +export class LoginViewModel extends Observable { + + logout() { + fbLogout(() => { + console.log("logged out"); + }); + } + +} +``` + + ## NativeScript Angular ### Initialization Call init of nativescript-facebook module on application launch. -app.module.ts +[app.module.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/app.module.ts) ```TypeScript ... import * as application from 'application'; -var nsFacebook = require('nativescript-facebook'); +import { NativeScriptModule } from "nativescript-angular/nativescript.module"; -import { AppModule } from "./app.module"; +let nsFacebook = require('nativescript-facebook'); application.on(application.launchEvent, function (args) { nsFacebook.init("{facebook_app_id}"); @@ -165,63 +267,203 @@ application.on(application.launchEvent, function (args) { ### Login #### Facebook Login Button -app.component.html + +Add Facebook login button as simple as adding a Facebook:LoginButton tag in your component html file. Then you can define `login` event handler name. In the example below - `onLogin`. Bare in mind the $event argument. + +[pages/login/login.component.html](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/login/login.component.html) ```html - + ``` -app.component.ts +Implement `onLogin` event handler in your component. It receives an argument from type `LoginEventData`. Currently `LoginEventData` object has 2 properties: error and loginResponse. loginResponse is an object that consists of 1 property - token that keeps the facebook access token which will be used for further authentications. Ideally we can add some other properties here in the future such as Facebook user id. + +[pages/login/login.component.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/login/login.component.ts) ```TypeScript import { Component } from "@angular/core"; -import { LoginResponse } from "nativescript-facebook"; +import * as Facebook from "nativescript-facebook"; @Component({ - selector: "ns-app", - templateUrl: "app.component.html", + selector: "login", + templateUrl: "login.component.html", }) -export class AppComponent { - onLogin = function (error: string, loginResponse : LoginResponse) { - console.log("TOKEN: " + loginResponse.token); +export class LoginComponent { + onLogin(eventData: Facebook.LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error); + } else { + console.log(eventData.loginResponse.token); + } } } ``` #### Custom Login Button -app.component.html + +Add a button and define a `tap` event handler in your login component html. + +[pages/login/login.component.html](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/login/login.component.html) ```html - + ``` -app.component.ts +In the component implement the tap event handler in this case `login` method. It just has to call the login method that comes from the plugin. + +[pages/login/login.component.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/login/login.component.ts) ```TypeScript import { Component } from "@angular/core"; import * as Facebook from "nativescript-facebook"; @Component({ - selector: "ns-app", - templateUrl: "app.component.html", + selector: "login", + templateUrl: "login.component.html", }) -export class AppComponent { - testAction = function () { - Facebook.login((error, data) => { - console.log("Success!"); +export class LoginComponent { + login() { + Facebook.login((error, fbData) => { + if (error) { + alert("Error during login: " + error.message); + } else { + console.log(fbData.token); + } }); } } ``` + +### Logout +#### Facebook Logout Button + +Add Facebook logout button as simple as adding a Facebook:LoginButton tag in your component html file. Then you can define `logout` event handler name. In the example below - `onLogout`. Bare in mind the $event argument. + +[pages/home/home.component.html](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/home/home.component.html) +```html + + + +``` + +Implement `onLogout` event handler. + +[pages/home/home.component.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/home/home.component.ts) +```TypeScript +import { Component } from "@angular/core"; +import * as Facebook from "nativescript-facebook"; + +@Component({ + selector: "home", + templateUrl: "home.component.html", +}) +export class HomeComponent { + onLogout(eventData: Facebook.LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error); + } else { + console.log("logged out"); + } + } +} +``` + +#### Custom Logout Button + +Add a button and define a `tap` event handler in your view. In this case - `logout` + +[pages/home/home.component.html](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/home/home.component.html) +```html + + + +``` + +In the component implement the tap event handler in this case `logout` method. It just has to call the logout method that comes from the plugin. In the example below the logout method from the plugin is imported as fbLogout. + +[pages/home/home.component.ts](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/home/home.component.ts) +```TypeScript +import { Component } from "@angular/core"; +import { logout as fbLogout } from "nativescript-facebook"; + +@Component({ + selector: "home", + templateUrl: "home.component.html", +}) +export class AppComponent { + logout() { + fbLogout(() => { + console.log("logged out"); + }); + } +} +``` + + ## Login Response The callback that have to be provided to Facebook.login method receives 2 arguments: error and login response object. Login response object has the following structure: | Property | Description | ------------- |:-------------| -| userId | user Id of the logged in user | | token | access token which will be used for further authentications | +## Graph API Example +Once the Facebook access token is retrieved you can execute Graph API requests. In the example below after successful login, the access token is stored in application settings. And then on the home view it is retrieved and 2 Graph API calls are executed. +1. Get Facebook id of the logged in user +2. Get the logged in user avatar (this is kind of workaround of this NativeScript issue. [#2176](https://github.com/NativeScript/NativeScript/issues/2176)) + +```TypeScript +export class HomeComponent { + accessToken: string = appSettings.getString("access_token"); + userId: string; + username: string; + avatarUrl: string; + + constructor(private ref: ChangeDetectorRef, private navigationService: NavigationService) { + // Get logged in user's info + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/me?access_token=" + this.accessToken).then((res) => { + this.username = res.name; + this.userId = res.id; + + // Get logged in user's avatar + // ref: https://github.com/NativeScript/NativeScript/issues/2176 + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/" + this.userId + "/picture?type=large&redirect=false&access_token=" + this.accessToken).then((res) => { + this.avatarUrl = res.data.url; + this.ref.detectChanges(); + }, function (err) { + alert("Error getting user info: " + err); + }); + }, function (err) { + alert("Error getting user info: " + err); + }); + } +``` + +This sample is part of the demo apps and can be observed [here](https://github.com/NativeScript/nativescript-facebook/blob/master/demo/app/home-view-model.ts) for Nativescript Code and [here](https://github.com/NativeScript/nativescript-facebook/blob/master/demo-angular/app/pages/home/home.component.ts) for NativeScript + Angular. + + +## Release notes + +2.0.0 +------------- +* Login event instead of login callback +* Log out +* Breaking Changes + * Core + * [Updated callback arguments](https://github.com/NativeScript/nativescript-facebook/pull/27/commits/5b862cdff5b86265f2c8626650f64823894fceee#diff-d1caaad1e0e272eb17c0a532f49657fdR7) + * Angular + * [Define Facebook login event handler](https://github.com/NativeScript/nativescript-facebook/pull/27/commits/5b862cdff5b86265f2c8626650f64823894fceee#diff-7cb31853fb9985534873f170bdc9df34R3) + * [Updated callback arguments](https://github.com/NativeScript/nativescript-facebook/pull/27/commits/5b862cdff5b86265f2c8626650f64823894fceee#diff-05f7e0f50b1b755ef9122a67a9561abcR16) + +1.0.1 +------------- +* Native Facebook login button +* Custom Facebook login button +* Angular ready +* NativeScript 3.0 ready +* Webpack ready + ## License -Apache 2.0 +[Apache 2.0](https://github.com/NativeScript/nativescript-facebook/blob/master/LICENSE) diff --git a/demo-angular/app/app.component.html b/demo-angular/app/app.component.html index f7c106b..41b82cc 100644 --- a/demo-angular/app/app.component.html +++ b/demo-angular/app/app.component.html @@ -1,6 +1 @@ - - - - - - \ No newline at end of file + diff --git a/demo-angular/app/app.component.ts b/demo-angular/app/app.component.ts index bd3e6d4..7ded227 100644 --- a/demo-angular/app/app.component.ts +++ b/demo-angular/app/app.component.ts @@ -5,37 +5,4 @@ import * as Facebook from "nativescript-facebook"; selector: "ns-app", templateUrl: "app.component.html", }) -export class AppComponent { - userId: string = "not logged in"; - - constructor(private ref: ChangeDetectorRef) { - } - - onLogin = function (eventData: Facebook.LoginEventData) { - if (eventData.error) { - alert("Error during login: " + eventData.error); - } else { - this.userId = "UserId: " + eventData.loginResponse.userId; - this.ref.detectChanges(); - } - }; - - manualLogin = function () { - Facebook.login((error, loginResponse) => { - this.userId = "UserId: " + loginResponse.userId; - this.ref.detectChanges(); - }); - }; - - manualLogout = function () { - Facebook.logout(() => { - this.userId = "not logged in"; - this.ref.detectChanges(); - }); - }; - - public onLogout() { - this.userId = "not logged in"; - this.ref.detectChanges(); - } -} +export class AppComponent {} diff --git a/demo-angular/app/app.config.ts b/demo-angular/app/app.config.ts new file mode 100644 index 0000000..94cb8f4 --- /dev/null +++ b/demo-angular/app/app.config.ts @@ -0,0 +1,3 @@ +export const config = { + FACEBOOK_GRAPH_API_URL: "https://graph.facebook.com/v2.9" +}; \ No newline at end of file diff --git a/demo-angular/app/app.css b/demo-angular/app/app.css index b0629b5..e8f7432 100644 --- a/demo-angular/app/app.css +++ b/demo-angular/app/app.css @@ -10,3 +10,4 @@ of writing your own CSS rules. For a full list of class names in the theme refer to http://docs.nativescript.org/ui/theme. */ @import 'nativescript-theme-core/css/core.light.css'; + diff --git a/demo-angular/app/app.module.ts b/demo-angular/app/app.module.ts index 5e5485f..59e43bb 100644 --- a/demo-angular/app/app.module.ts +++ b/demo-angular/app/app.module.ts @@ -1,10 +1,14 @@ -import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; +import { NgModule, NO_ERRORS_SCHEMA, NgModuleFactoryLoader } from "@angular/core"; import { NativeScriptModule } from "nativescript-angular/nativescript.module"; +import { NativeScriptRouterModule, NSModuleFactoryLoader } from "nativescript-angular/router"; import { AppComponent } from "./app.component"; - +import { LoginModule } from "./pages/login/login.module"; +import { HomeModule } from "./pages/home/home.module"; import { NativeScriptFacebookModule } from "nativescript-facebook/angular"; - import * as application from 'application'; +import { routes } from "./app.routing"; +import { NavigationService } from "./services/navigation.service"; + let nsFacebook = require('nativescript-facebook'); application.on(application.launchEvent, function (args) { @@ -12,12 +16,18 @@ application.on(application.launchEvent, function (args) { }); @NgModule({ - bootstrap: [ AppComponent ], + bootstrap: [AppComponent], imports: [ NativeScriptModule, - NativeScriptFacebookModule + NativeScriptFacebookModule, + NativeScriptRouterModule, + NativeScriptRouterModule.forRoot(routes) + ], + providers: [ + NavigationService, + { provide: NgModuleFactoryLoader, useClass: NSModuleFactoryLoader } ], - declarations: [ AppComponent ], - schemas: [ NO_ERRORS_SCHEMA ] + declarations: [AppComponent], + schemas: [NO_ERRORS_SCHEMA] }) export class AppModule { } diff --git a/demo-angular/app/app.routing.ts b/demo-angular/app/app.routing.ts new file mode 100644 index 0000000..877dea2 --- /dev/null +++ b/demo-angular/app/app.routing.ts @@ -0,0 +1,16 @@ +export const routes = [ + { + path: "home", + loadChildren: "./pages/home/home.module#HomeModule" + }, + { + path: "login", + loadChildren: "./pages/login/login.module#LoginModule" + }, + { + path: "", + redirectTo: "login", + pathMatch: "full" + } + +]; \ No newline at end of file diff --git a/demo-angular/app/pages/home/home.component.css b/demo-angular/app/pages/home/home.component.css new file mode 100644 index 0000000..abe3fb1 --- /dev/null +++ b/demo-angular/app/pages/home/home.component.css @@ -0,0 +1,26 @@ +.label { + font-size: 10; + font-weight: bold; + padding-top: 10; +} + +.home { + margin-left: 30; + margin-right: 30; + margin-top: 20%; +} + +.home .buttons { + margin-top: 30%; +} + +.home .info { + margin-top: 20; + horizontal-align: center; +} + +.avatar { + border-radius: 100; + width: 150; + height: auto; +} \ No newline at end of file diff --git a/demo-angular/app/pages/home/home.component.html b/demo-angular/app/pages/home/home.component.html new file mode 100644 index 0000000..8f3b55f --- /dev/null +++ b/demo-angular/app/pages/home/home.component.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/demo-angular/app/pages/home/home.component.ts b/demo-angular/app/pages/home/home.component.ts new file mode 100644 index 0000000..84e9155 --- /dev/null +++ b/demo-angular/app/pages/home/home.component.ts @@ -0,0 +1,55 @@ +import { Component, ChangeDetectorRef } from "@angular/core"; +import * as Facebook from "nativescript-facebook"; +import { NavigationService } from "../../services/navigation.service"; +import { config } from "../../app.config"; +let http = require("http"); +let appSettings = require("application-settings"); + +@Component({ + selector: "home", + moduleId: module.id, + templateUrl: "home.component.html", + styleUrls: ["home.component.css"] +}) +export class HomeComponent { + accessToken: string = appSettings.getString("access_token"); + userId: string; + username: string; + avatarUrl: string; + + constructor(private ref: ChangeDetectorRef, private navigationService: NavigationService) { + // Get logged in user's info + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/me?access_token=" + this.accessToken).then((res) => { + this.username = res.name; + this.userId = res.id; + + // Get logged in user's avatar + // ref: https://github.com/NativeScript/NativeScript/issues/2176 + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/" + this.userId + "/picture?type=large&redirect=false&access_token=" + this.accessToken).then((res) => { + this.avatarUrl = res.data.url; + this.ref.detectChanges(); + }, function (err) { + alert("Error getting user info: " + err); + }); + }, function (err) { + alert("Error getting user info: " + err); + }); + } + + onLogout(eventData: Facebook.LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error); + } else { + appSettings.clear(); + this.navigationService.go(['login'], "slideRight"); + } + + } + + logout() { + Facebook.logout(() => { + appSettings.clear(); + this.navigationService.go(['login'], "slideRight"); + }); + } +} diff --git a/demo-angular/app/pages/home/home.module.ts b/demo-angular/app/pages/home/home.module.ts new file mode 100644 index 0000000..2b1f084 --- /dev/null +++ b/demo-angular/app/pages/home/home.module.ts @@ -0,0 +1,24 @@ +import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; +import { NativeScriptModule } from "nativescript-angular/nativescript.module"; +import { NativeScriptRouterModule } from "nativescript-angular/router"; +import { HomeComponent } from "./home.component"; + +import { NativeScriptFacebookModule } from "nativescript-facebook/angular"; + +export const routerConfig = [ + { + path: "", + component: HomeComponent + } +]; + +@NgModule({ + imports: [ + NativeScriptModule, + NativeScriptRouterModule, + NativeScriptRouterModule.forChild(routerConfig) + ], + declarations: [ HomeComponent ], + schemas: [ NO_ERRORS_SCHEMA ] +}) +export class HomeModule { } diff --git a/demo-angular/app/pages/login/login.component.css b/demo-angular/app/pages/login/login.component.css new file mode 100644 index 0000000..1937b3c --- /dev/null +++ b/demo-angular/app/pages/login/login.component.css @@ -0,0 +1,5 @@ +.login-buttons { + margin-left: 30; + margin-right: 30; + margin-top: 80%; +} \ No newline at end of file diff --git a/demo-angular/app/pages/login/login.component.html b/demo-angular/app/pages/login/login.component.html new file mode 100644 index 0000000..87f0268 --- /dev/null +++ b/demo-angular/app/pages/login/login.component.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/demo-angular/app/pages/login/login.component.ts b/demo-angular/app/pages/login/login.component.ts new file mode 100644 index 0000000..cb4b0d9 --- /dev/null +++ b/demo-angular/app/pages/login/login.component.ts @@ -0,0 +1,36 @@ +import { Component, ChangeDetectorRef } from "@angular/core"; +import * as Facebook from "nativescript-facebook"; +import { NavigationService } from "../../services/navigation.service"; +let appSettings = require("application-settings"); + +@Component({ + selector: "login", + moduleId: module.id, + templateUrl: "login.component.html", + styleUrls: ["login.component.css"] +}) +export class LoginComponent { + + constructor(private ref: ChangeDetectorRef, private navigationService: NavigationService) { + } + + onLogin(eventData: Facebook.LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error); + } else { + appSettings.setString("access_token", eventData.loginResponse.token); + this.navigationService.go(['home']); + } + } + + login() { + Facebook.login((error, fbData) => { + if (error) { + alert("Error during login: " + error.message); + } else { + appSettings.setString("access_token", fbData.token); + this.navigationService.go(['home']); + } + }); + } +} diff --git a/demo-angular/app/pages/login/login.module.ts b/demo-angular/app/pages/login/login.module.ts new file mode 100644 index 0000000..b4058eb --- /dev/null +++ b/demo-angular/app/pages/login/login.module.ts @@ -0,0 +1,24 @@ +import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; +import { NativeScriptModule } from "nativescript-angular/nativescript.module"; +import { NativeScriptRouterModule } from "nativescript-angular/router"; +import { LoginComponent } from "./login.component"; + +import { NativeScriptFacebookModule } from "nativescript-facebook/angular"; + +export const routerConfig = [ + { + path: "", + component: LoginComponent + } +]; + +@NgModule({ + imports: [ + NativeScriptModule, + NativeScriptRouterModule, + NativeScriptRouterModule.forChild(routerConfig) + ], + declarations: [ LoginComponent ], + schemas: [ NO_ERRORS_SCHEMA ] +}) +export class LoginModule { } diff --git a/demo-angular/app/services/navigation.service.ts b/demo-angular/app/services/navigation.service.ts new file mode 100644 index 0000000..a73a88c --- /dev/null +++ b/demo-angular/app/services/navigation.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from "@angular/core"; +import { RouterExtensions } from "nativescript-angular/router"; + +@Injectable() +export class NavigationService { + + constructor(private routerExtensions: RouterExtensions) { } + + go(route: Array, name?: string) { + + this + .routerExtensions + .navigate(route, { + clearHistory: true, + animated: true, + transition: { + name: name ? name : "slide", + duration: 200, + curve: "linear" + } + }); + + } +} \ No newline at end of file diff --git a/demo-angular/package.json b/demo-angular/package.json index 3f0795f..c218c1d 100644 --- a/demo-angular/package.json +++ b/demo-angular/package.json @@ -1,15 +1,13 @@ { - "description": "NativeScript Application", - "license": "SEE LICENSE IN ", - "readme": "NativeScript Application", - "repository": "", + "description": "NativeScript Facebook Sample Application With Angular", + "license": "MIT", "nativescript": { "id": "org.nativescript.demoangular", "tns-android": { "version": "3.0.0" }, "tns-ios": { - "version": "3.0.0" + "version": "3.0.1" } }, "dependencies": { diff --git a/demo/.nsbuildinfo b/demo/.nsbuildinfo new file mode 100644 index 0000000..1c8981b --- /dev/null +++ b/demo/.nsbuildinfo @@ -0,0 +1,4 @@ +{ + "prepareTime": "Thu May 25 2017 15:02:35 GMT+0300 (EEST)", + "buildTime": "Thu May 25 2017 15:02:58 GMT+0300 (EEST)" +} \ No newline at end of file diff --git a/demo/.nslivesyncinfo b/demo/.nslivesyncinfo new file mode 100644 index 0000000..c5e316d --- /dev/null +++ b/demo/.nslivesyncinfo @@ -0,0 +1,7 @@ +{ + "time": "Thu May 25 2017 15:02:35 GMT+0300 (EEST)", + "bundle": false, + "release": false, + "changesRequireBuild": true, + "changesRequireBuildTime": "Thu May 25 2017 15:02:35 GMT+0300 (EEST)" +} \ No newline at end of file diff --git a/demo/app/app.config.ts b/demo/app/app.config.ts new file mode 100644 index 0000000..94cb8f4 --- /dev/null +++ b/demo/app/app.config.ts @@ -0,0 +1,3 @@ +export const config = { + FACEBOOK_GRAPH_API_URL: "https://graph.facebook.com/v2.9" +}; \ No newline at end of file diff --git a/demo/app/app.css b/demo/app/app.css index 634f26a..e99945a 100644 --- a/demo/app/app.css +++ b/demo/app/app.css @@ -1 +1,33 @@ @import 'nativescript-theme-core/css/core.light.css'; +.login-buttons { + margin-left: 30; + margin-right: 30; + margin-top: 80%; +} + +.label { + font-size: 10; + font-weight: bold; + padding-top: 10; +} + +.home { + margin-left: 30; + margin-right: 30; + margin-top: 20%; +} + +.home .buttons { + margin-top: 30%; +} + +.home .info { + margin-top: 20; + horizontal-align: center; +} + +.avatar { + border-radius: 100; + width: 150; + height: auto; +} \ No newline at end of file diff --git a/demo/app/app.ts b/demo/app/app.ts index 50313e5..44c61e7 100644 --- a/demo/app/app.ts +++ b/demo/app/app.ts @@ -7,5 +7,5 @@ application.on(application.launchEvent, function (args) { init("1771472059772879"); }); -application.start({ moduleName: "main-page" }); +application.start({ moduleName: "login-page" }); diff --git a/demo/app/bundle-config.ts b/demo/app/bundle-config.ts index a88fa89..74f6298 100644 --- a/demo/app/bundle-config.ts +++ b/demo/app/bundle-config.ts @@ -1,7 +1,8 @@ if ((global).TNS_WEBPACK) { require("bundle-entry-points"); - global.registerModule("main-page", () => require("./main-page")); + global.registerModule("login-page", () => require("./login-page")); + global.registerModule("home-page", () => require("./home-page")); // register application modules global.registerModule("nativescript-facebook", () => require("nativescript-facebook")); diff --git a/demo/app/main-page.ts b/demo/app/home-page.ts similarity index 71% rename from demo/app/main-page.ts rename to demo/app/home-page.ts index dca878e..00c2cef 100644 --- a/demo/app/main-page.ts +++ b/demo/app/home-page.ts @@ -1,10 +1,10 @@ import { EventData } from 'data/observable'; import { Page } from 'ui/page'; -import { HelloWorldModel } from './main-view-model'; +import { HomeViewModel } from './home-view-model'; // Event handler for Page 'loaded' event attached in main-page.xml export function pageLoaded(args: EventData) { // Get the event sender let page = args.object; - page.bindingContext = new HelloWorldModel(); + page.bindingContext = new HomeViewModel(); } diff --git a/demo/app/home-page.xml b/demo/app/home-page.xml new file mode 100644 index 0000000..00cb66e --- /dev/null +++ b/demo/app/home-page.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/demo/app/home-view-model.ts b/demo/app/home-view-model.ts new file mode 100644 index 0000000..8081185 --- /dev/null +++ b/demo/app/home-view-model.ts @@ -0,0 +1,53 @@ +import { Observable } from 'data/observable'; +import { LoginEventData, logout as fbLogout } from "nativescript-facebook"; + +let frameModule = require("ui/frame"); +let appSettings = require("application-settings"); +let imageSource = require("image-source"); +let http = require("http"); +let config = require("./app.config").config; + +export class HomeViewModel extends Observable { + userId: string; + accessToken: string = appSettings.getString("access_token"); + + constructor() { + super(); + // Get logged in user's info + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/me?access_token=" + this.accessToken).then((res) => { + this.set("username", res.name); + this.set("userId", res.id); + + // Get logged in user's avatar + // ref: https://github.com/NativeScript/NativeScript/issues/2176 + console.log(config.FACEBOOK_GRAPH_API_URL + "/" + this.get("userId") + "/picture?type=large&redirect=false&access_token=" + this.accessToken); + http.getJSON(config.FACEBOOK_GRAPH_API_URL + "/" + this.get("userId") + "/picture?type=large&redirect=false&access_token=" + this.accessToken).then((res) => { + this.set("avatarUrl", res.data.url); + }, function (err) { + alert("Error getting user info: " + err); + }); + }, function (err) { + alert("Error getting user info: " + err); + }); + } + + private _navigate(path: string) { + let topmost = frameModule.topmost(); + topmost.navigate({ + moduleName: path, + clearHistory: true + }); + } + + public onLogout() { + appSettings.clear(); + this._navigate("login-page"); + } + + public logout() { + fbLogout(() => { + appSettings.clear(); + this._navigate("login-page"); + }); + } +} diff --git a/demo/app/login-page.ts b/demo/app/login-page.ts new file mode 100644 index 0000000..d85e534 --- /dev/null +++ b/demo/app/login-page.ts @@ -0,0 +1,10 @@ +import { EventData } from 'data/observable'; +import { Page } from 'ui/page'; +import { LoginViewModel } from './login-view-model'; + +// Event handler for Page 'loaded' event attached in main-page.xml +export function pageLoaded(args: EventData) { + // Get the event sender + let page = args.object; + page.bindingContext = new LoginViewModel(); +} diff --git a/demo/app/login-page.xml b/demo/app/login-page.xml new file mode 100644 index 0000000..8787a44 --- /dev/null +++ b/demo/app/login-page.xml @@ -0,0 +1,8 @@ + + + diff --git a/demo/app/login-view-model.ts b/demo/app/login-view-model.ts new file mode 100644 index 0000000..dfd0428 --- /dev/null +++ b/demo/app/login-view-model.ts @@ -0,0 +1,35 @@ +import { Observable } from 'data/observable'; +import { LoginEventData, login as fbLogin } from "nativescript-facebook"; +let frameModule = require("ui/frame"); +let appSettings = require("application-settings"); + +export class LoginViewModel extends Observable { + + private _navigate(path: string) { + let topmost = frameModule.topmost(); + topmost.navigate({ + moduleName: path, + clearHistory: true + }); + } + + public onLogin(eventData: LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error.message); + } else { + appSettings.setString("access_token", eventData.loginResponse.token); + this._navigate("home-page"); + } + } + + public login() { + fbLogin((err, fbData) => { + if (err) { + alert("Error during login: " + err.message); + } else { + appSettings.setString("access_token", fbData.token); + this._navigate("home-page"); + } + }); + } +} diff --git a/demo/app/main-page.xml b/demo/app/main-page.xml deleted file mode 100644 index 969171a..0000000 --- a/demo/app/main-page.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/demo/app/main-view-model.ts b/demo/app/main-view-model.ts deleted file mode 100644 index 13d0a29..0000000 --- a/demo/app/main-view-model.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Observable } from 'data/observable'; -import { LoginEventData, logout as fbLogout } from "nativescript-facebook"; - -export class HelloWorldModel extends Observable { - public userId: string = "not logged in"; - - public onLogin(eventData: LoginEventData) { - if (eventData.error) { - alert("Error during login: " + eventData.error.message); - } else { - this.set("userId", "UserId: " + eventData.loginResponse.userId); - } - } - - public onLogout() { - this.set("userId", "not logged in"); - } - - public logout() { - fbLogout(() => this.set("userId", "not logged in")); - } -} diff --git a/demo/app/vendor-platform.ts b/demo/app/vendor-platform.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/login-manager.android.ts b/src/login-manager.android.ts index 4379581..6d6de39 100644 --- a/src/login-manager.android.ts +++ b/src/login-manager.android.ts @@ -50,8 +50,7 @@ export function _registerLoginCallback(callback: Function) { onSuccess: function (result) { let token = result.getAccessToken().getToken(); - let userId = result.getAccessToken().getUserId(); - let loginResponse = new LoginResponse(userId, token); + let loginResponse = new LoginResponse(token); callback(null, loginResponse); }, onCancel: function () { diff --git a/src/login-manager.ios.ts b/src/login-manager.ios.ts index 4b1bd1a..c70f1e9 100644 --- a/src/login-manager.ios.ts +++ b/src/login-manager.ios.ts @@ -2,7 +2,7 @@ import * as applicationModule from "application"; import { LoginResponse } from './login-response'; declare let FBSDKLoginManager: any; declare let FBSDKSettings: any; -declare class FBSDKLoginManagerLoginResult { isCancelled: boolean; token: any; userId: any; } +declare class FBSDKLoginManagerLoginResult { isCancelled: boolean; token: any; } declare class UIResponder { } declare var UIApplicationDelegate: any; declare class UIApplication { } @@ -50,8 +50,7 @@ export function _registerLoginCallback(callback: Function) { if (result.token) { let token = result.token.tokenString; - let userId = result.token.userID; - let loginResponse = new LoginResponse(userId, token); + let loginResponse = new LoginResponse(token); callback(null, loginResponse); } else { diff --git a/src/login-response.d.ts b/src/login-response.d.ts index 744f692..08610d3 100644 --- a/src/login-response.d.ts +++ b/src/login-response.d.ts @@ -1,5 +1,4 @@ export declare class LoginResponse { - userId: string; token: string; - constructor(userId: string, token: string); + constructor(token: string); } diff --git a/src/login-response.ts b/src/login-response.ts index 37358f9..73c62e3 100644 --- a/src/login-response.ts +++ b/src/login-response.ts @@ -1,9 +1,7 @@ export class LoginResponse { - userId: string; token: string; - constructor(userId: string, token: string) { - this.userId = userId; + constructor(token: string) { this.token = token; } } \ No newline at end of file diff --git a/src/package.json b/src/package.json index d678b77..f2cc88e 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-facebook", - "version": "1.0.1", + "version": "2.0.0", "description": "NativeScript plugin, wrapper of native Facebook SDK for Adroid and iOS.", "nativescript": { "platforms": {