diff --git a/demo-angular/app/app.component.html b/demo-angular/app/app.component.html index c4ea399..f7c106b 100644 --- a/demo-angular/app/app.component.html +++ b/demo-angular/app/app.component.html @@ -1,4 +1,6 @@ - - - + + + + + \ No newline at end of file diff --git a/demo-angular/app/app.component.ts b/demo-angular/app/app.component.ts index 3c0a389..bd3e6d4 100644 --- a/demo-angular/app/app.component.ts +++ b/demo-angular/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component } from "@angular/core"; +import { Component, ChangeDetectorRef } from "@angular/core"; import * as Facebook from "nativescript-facebook"; @Component({ @@ -6,13 +6,36 @@ import * as Facebook from "nativescript-facebook"; templateUrl: "app.component.html", }) export class AppComponent { - onLogin = function (error: string, loginResponse: Facebook.LoginResponse) { - console.log("TOKEN: " + loginResponse.token); + 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(); + }); }; - testAction = function () { - Facebook.login((error, data) => { - console.log("Success!"); + manualLogout = function () { + Facebook.logout(() => { + this.userId = "not logged in"; + this.ref.detectChanges(); }); }; + + public onLogout() { + this.userId = "not logged in"; + this.ref.detectChanges(); + } } diff --git a/demo/app/main-page.xml b/demo/app/main-page.xml index 2fddc4f..969171a 100644 --- a/demo/app/main-page.xml +++ b/demo/app/main-page.xml @@ -1,9 +1,9 @@ - - + diff --git a/demo/app/main-view-model.ts b/demo/app/main-view-model.ts index b1cb8c7..13d0a29 100644 --- a/demo/app/main-view-model.ts +++ b/demo/app/main-view-model.ts @@ -1,14 +1,22 @@ import { Observable } from 'data/observable'; -import { login } from "nativescript-facebook"; +import { LoginEventData, logout as fbLogout } from "nativescript-facebook"; -// Facebook Authentication CODE export class HelloWorldModel extends Observable { + public userId: string = "not logged in"; - public onLogin(error, data) { - console.log("Success!"); + public onLogin(eventData: LoginEventData) { + if (eventData.error) { + alert("Error during login: " + eventData.error.message); + } else { + this.set("userId", "UserId: " + eventData.loginResponse.userId); + } } - public testAction() { - login((error, data) => console.log("Success!")); + public onLogout() { + this.set("userId", "not logged in"); + } + + public logout() { + fbLogout(() => this.set("userId", "not logged in")); } } diff --git a/src/index.android.metadata.json b/src/index.android.metadata.json index 6f9ff5a..d8a493a 100644 --- a/src/index.android.metadata.json +++ b/src/index.android.metadata.json @@ -1 +1 @@ -[{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./login-manager"},{"from":"./login-button"}]},{"__symbolic":"module","version":1,"metadata":{},"exports":[{"from":"./login-manager"},{"from":"./login-button"}]}] \ No newline at end of file +[{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./login-manager"},{"from":"./login-button"},{"from":"./login-event-data"}]},{"__symbolic":"module","version":1,"metadata":{},"exports":[{"from":"./login-manager"},{"from":"./login-button"},{"from":"./login-event-data"}]}] \ No newline at end of file diff --git a/src/index.android.ts b/src/index.android.ts index 3320b2f..89ebabe 100644 --- a/src/index.android.ts +++ b/src/index.android.ts @@ -1,2 +1,3 @@ export * from "./login-manager"; -export * from "./login-button"; \ No newline at end of file +export * from "./login-button"; +export * from "./login-event-data"; \ No newline at end of file diff --git a/src/index.d.ts b/src/index.d.ts index f1c5d2e..1d9dfe0 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,3 +1,4 @@ export * from "./login-manager"; export * from "./login-button"; export * from "./login-response"; +export * from "./login-event-data"; diff --git a/src/index.ios.metadata.json b/src/index.ios.metadata.json index 6d119d6..4a8d6e6 100644 --- a/src/index.ios.metadata.json +++ b/src/index.ios.metadata.json @@ -1 +1 @@ -[{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./login-button"},{"from":"./login-manager"}]},{"__symbolic":"module","version":1,"metadata":{},"exports":[{"from":"./login-button"},{"from":"./login-manager"}]}] \ No newline at end of file +[{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./login-button"},{"from":"./login-manager"},{"from":"./login-event-data"}]},{"__symbolic":"module","version":1,"metadata":{},"exports":[{"from":"./login-button"},{"from":"./login-manager"},{"from":"./login-event-data"}]}] \ No newline at end of file diff --git a/src/index.ios.ts b/src/index.ios.ts index c2b4d0c..0c6e803 100644 --- a/src/index.ios.ts +++ b/src/index.ios.ts @@ -1,6 +1,7 @@ import * as applicationModule from "application"; export * from "./login-button"; export * from "./login-manager"; +export * from "./login-event-data"; declare class UIResponder { } declare class NSDictionary { } diff --git a/src/login-button.common.metadata.json b/src/login-button.common.metadata.json index ed28586..ed8a6e3 100644 --- a/src/login-button.common.metadata.json +++ b/src/login-button.common.metadata.json @@ -1 +1 @@ -[{"__symbolic":"module","version":3,"metadata":{"LoginButtonBase":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"ui/core/view","name":"View"},"members":{"onLoginPropertyChanged":[{"__symbolic":"method"}]}},"onLoginProperty":{"__symbolic":"error","message":"Function call not supported","line":10,"character":31}}},{"__symbolic":"module","version":1,"metadata":{"LoginButtonBase":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"ui/core/view","name":"View"},"members":{"onLoginPropertyChanged":[{"__symbolic":"method"}]}},"onLoginProperty":{"__symbolic":"error","message":"Function call not supported","line":10,"character":31}}}] \ No newline at end of file +[{"__symbolic":"module","version":3,"metadata":{"LoginButtonBase":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"ui/core/view","name":"View"},"members":{"initNativeView":[{"__symbolic":"method"}]},"statics":{"loginEvent":"login","logoutEvent":"logout"}}}},{"__symbolic":"module","version":1,"metadata":{"LoginButtonBase":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"ui/core/view","name":"View"},"members":{"initNativeView":[{"__symbolic":"method"}]},"statics":{"loginEvent":"login","logoutEvent":"logout"}}}}] \ No newline at end of file diff --git a/src/login-button.common.ts b/src/login-button.common.ts index 548dc9b..638701f 100644 --- a/src/login-button.common.ts +++ b/src/login-button.common.ts @@ -1,15 +1,19 @@ import { View, Property } from "ui/core/view"; import * as loginManager from './login-manager'; +import { LoginResponse } from './login-response'; +import { LoginEventData } from './login-event-data'; +import { EventData } from "data/observable"; export abstract class LoginButtonBase extends View { - onLoginPropertyChanged(callback: any) { - loginManager._registerLoginCallback(callback); - } -} + public static loginEvent: string = "login"; + public static logoutEvent: string = "logout"; -export const onLoginProperty = new Property({ - name: "login", valueChanged: (btn, oldV, newV) => { - btn.onLoginPropertyChanged(newV); + initNativeView() { + loginManager._registerLoginCallback((error: Error, loginResponse: LoginResponse) => { + this.notify({ eventName: LoginButtonBase.loginEvent, object: this, error: error, loginResponse: loginResponse }); + }); + loginManager._registerLogoutCallback(() => { + this.notify({ eventName: LoginButtonBase.logoutEvent, object: this }); + }); } -}); -onLoginProperty.register(LoginButtonBase); +} diff --git a/src/login-button.d.ts b/src/login-button.d.ts index 0fc6bb1..d5b7aab 100644 --- a/src/login-button.d.ts +++ b/src/login-button.d.ts @@ -1 +1,8 @@ -export declare class LoginButton {} +import { LoginEventData } from './login-event-data'; +import { EventData } from "data/observable"; +import { View } from "ui/core/view"; + +export declare class LoginButton extends View { + on(event: "login", callback: (data: LoginEventData) => void, thisArg?: any); + on(eventNames: string, callback: (data: EventData) => void, thisArg?: any); +} diff --git a/src/login-button.ios.ts b/src/login-button.ios.ts index 89b6da2..165e6eb 100644 --- a/src/login-button.ios.ts +++ b/src/login-button.ios.ts @@ -31,13 +31,15 @@ class LoginButtonDelegate extends NSObject implements FBSDKLoginButtonDelegate { public static ObjCProtocols = [FBSDKLoginButtonDelegate]; loginButtonDidCompleteWithResultError(loginButton: any, result: any, error: NSError) { - if (loginManager._onLoginCallback) { - loginManager._onLoginCallback(result, error); + if (loginManager.onLoginCallback) { + loginManager.onLoginCallback(result, error); } } loginButtonDidLogOut(loginButton: any) { - // TODO: Provide logout callback + if (loginManager.onLogoutCallback) { + loginManager.onLogoutCallback(); + } } loginButtonWillLogin(loginButton: any) { diff --git a/src/login-event-data.d.ts b/src/login-event-data.d.ts new file mode 100644 index 0000000..45843ba --- /dev/null +++ b/src/login-event-data.d.ts @@ -0,0 +1,7 @@ +import { EventData } from "data/observable"; +import { LoginResponse } from "./login-response"; + +export declare interface LoginEventData extends EventData { + error: Error; + loginResponse: LoginResponse; +} \ No newline at end of file diff --git a/src/login-event-data.metadata.json b/src/login-event-data.metadata.json new file mode 100644 index 0000000..e9a6063 --- /dev/null +++ b/src/login-event-data.metadata.json @@ -0,0 +1 @@ +[{"__symbolic":"module","version":3,"metadata":{"LoginEventData":{"__symbolic":"interface"}}},{"__symbolic":"module","version":1,"metadata":{"LoginEventData":{"__symbolic":"interface"}}}] \ No newline at end of file diff --git a/src/login-event-data.ts b/src/login-event-data.ts new file mode 100644 index 0000000..ad2f732 --- /dev/null +++ b/src/login-event-data.ts @@ -0,0 +1,7 @@ +import { EventData } from "data/observable"; +import { LoginResponse } from "./login-response"; + +export interface LoginEventData extends EventData { + error: Error; + loginResponse: LoginResponse; +} \ No newline at end of file diff --git a/src/login-manager.android.metadata.json b/src/login-manager.android.metadata.json index 94aa44b..a68bd93 100644 --- a/src/login-manager.android.metadata.json +++ b/src/login-manager.android.metadata.json @@ -1 +1 @@ -[{"__symbolic":"module","version":3,"metadata":{"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"}}},{"__symbolic":"module","version":1,"metadata":{"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"}}}] \ No newline at end of file +[{"__symbolic":"module","version":3,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":7,"character":11},"onLogoutCallback":{"__symbolic":"error","message":"Variable not initialized","line":8,"character":11},"_registerLogoutCallback":{"__symbolic":"function"},"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"},"logout":{"__symbolic":"function"}}},{"__symbolic":"module","version":1,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":7,"character":11},"onLogoutCallback":{"__symbolic":"error","message":"Variable not initialized","line":8,"character":11},"_registerLogoutCallback":{"__symbolic":"function"},"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"},"logout":{"__symbolic":"function"}}}] \ No newline at end of file diff --git a/src/login-manager.android.ts b/src/login-manager.android.ts index 111f704..4379581 100644 --- a/src/login-manager.android.ts +++ b/src/login-manager.android.ts @@ -5,11 +5,16 @@ declare let com: any; const LOGIN_PERMISSIONS = ["public_profile", "email"]; // TODO: add getter and setter -let onLoginCallback; +export let onLoginCallback; +export let onLogoutCallback; let androidApplication; let _act: android.app.Activity; let loginManager; +export function _registerLogoutCallback(callback: Function) { + onLogoutCallback = callback; +} + export function init(fbId: string) { setAppId(fbId); androidApplication = application.android; @@ -23,6 +28,18 @@ export function init(fbId: string) { onLoginCallback = com.facebook.CallbackManager.Factory.create(); loginManager = com.facebook.login.LoginManager.getInstance(); loginManager.logOut(); + + // Workaround for firing the logout event in android: + // https://stackoverflow.com/questions/30233284/how-to-add-a-logout-callback-for-facebook-sdk-in-android + let LogoutAccessTokenTracker = com.facebook.AccessTokenTracker.extend({ + onCurrentAccessTokenChanged: function (oldToken, newToken) { + if (oldToken != null && newToken == null && onLogoutCallback) { + onLogoutCallback(); + } + } + }); + let accessTokenTracker = new LogoutAccessTokenTracker(); + accessTokenTracker.startTracking(); } export function _registerLoginCallback(callback: Function) { @@ -38,7 +55,7 @@ export function _registerLoginCallback(callback: Function) { callback(null, loginResponse); }, onCancel: function () { - callback('canceled'); + callback(new Error('canceled')); }, onError: function (e) { @@ -52,7 +69,7 @@ export function _registerLoginCallback(callback: Function) { else { errorMessage += ": " + e; } - callback(errorMessage); + callback(new Error(errorMessage)); } })); @@ -89,7 +106,13 @@ export function requestReadPermissions(permissions: string[], callback: Function } export function login(callback: Function) { - console.log("requesting read permissions .... ."); requestReadPermissions(LOGIN_PERMISSIONS, callback); } +export function logout(callback: Function) { + loginManager.logOut(); + if (callback) { + callback(); + } +} + diff --git a/src/login-manager.d.ts b/src/login-manager.d.ts index 9983021..a2ef5d9 100644 --- a/src/login-manager.d.ts +++ b/src/login-manager.d.ts @@ -1,5 +1,7 @@ export declare function _registerLoginCallback(callback: Function): void; -export declare let _onLoginCallback: Function; +export declare function _registerLogoutCallback(callback: Function): void; +export declare let onLoginCallback: Function; +export declare let onLogoutCallback: Function; /** * Sets the Facebook application Id for the current app and init the native facebook sdk. @@ -22,4 +24,9 @@ export declare function requestReadPermissions(permissions: string[], callback: * Trigger a login procedure by requesting the "public_profile" and "email" read permissions. * @param {Function} callback Function reference to be executed when the requested permissions are granted or denied. */ -export declare function login(callback: Function): void; \ No newline at end of file +export declare function login(callback: Function): void; +/** +* Trigger a logout procedure. +* @param {Function} callback Function reference to be executed when the logout is executed. +*/ +export declare function logout(callback: Function): void; \ No newline at end of file diff --git a/src/login-manager.ios.metadata.json b/src/login-manager.ios.metadata.json index c17bbf0..f46753c 100644 --- a/src/login-manager.ios.metadata.json +++ b/src/login-manager.ios.metadata.json @@ -1 +1 @@ -[{"__symbolic":"module","version":3,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":15,"character":11},"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"}}},{"__symbolic":"module","version":1,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":15,"character":11},"init":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"}}}] \ No newline at end of file +[{"__symbolic":"module","version":3,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":15,"character":11},"onLogoutCallback":{"__symbolic":"error","message":"Variable not initialized","line":16,"character":11},"init":{"__symbolic":"function"},"_registerLogoutCallback":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"},"logout":{"__symbolic":"function"}}},{"__symbolic":"module","version":1,"metadata":{"onLoginCallback":{"__symbolic":"error","message":"Variable not initialized","line":15,"character":11},"onLogoutCallback":{"__symbolic":"error","message":"Variable not initialized","line":16,"character":11},"init":{"__symbolic":"function"},"_registerLogoutCallback":{"__symbolic":"function"},"_registerLoginCallback":{"__symbolic":"function"},"requestPublishPermissions":{"__symbolic":"function"},"requestReadPermissions":{"__symbolic":"function"},"login":{"__symbolic":"function"},"logout":{"__symbolic":"function"}}}] \ No newline at end of file diff --git a/src/login-manager.ios.ts b/src/login-manager.ios.ts index dfe9d33..4b1bd1a 100644 --- a/src/login-manager.ios.ts +++ b/src/login-manager.ios.ts @@ -14,6 +14,8 @@ const LOGIN_PERMISSIONS = ["public_profile", "email"]; // TODO: add getter and setter export let onLoginCallback; +export let onLogoutCallback; + let loginManager; export function init(fbId: string) { @@ -23,23 +25,26 @@ export function init(fbId: string) { loginManager.logOut(); } +export function _registerLogoutCallback(callback: Function) { + onLogoutCallback = callback; +} + export function _registerLoginCallback(callback: Function) { onLoginCallback = function (result: FBSDKLoginManagerLoginResult, error: NSError) { if (error) { - callback(error); + callback(new Error(error.localizedDescription)); return; } - // something went really wrong no error and no result if (!result) { - callback("Fatal error"); + callback(new Error("Fatal error")); return; } if (result.isCancelled) { - callback('canceled'); + callback(new Error('canceled')); return; } @@ -50,7 +55,7 @@ export function _registerLoginCallback(callback: Function) { callback(null, loginResponse); } else { - callback("Could not acquire an access token"); + callback(new Error("Could not acquire an access token")); return; } }; @@ -74,3 +79,9 @@ export function login(callback: Function) { requestReadPermissions(LOGIN_PERMISSIONS, callback); } +export function logout(callback: Function) { + loginManager.logOut(); + if (callback) { + callback(); + } +}