Skip to content

Commit e405ddd

Browse files
authored
Merge pull request #139 from NativeScript/gogoout-master
feat: share to facebook
2 parents 504270d + bce5254 commit e405ddd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+12653
-76
lines changed

README.md

Lines changed: 158 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ NativeScript : Facebook SDK ![apple](https://cdn3.iconfinder.com/data/icons/pico
2424
- [Log out](#log-out)
2525
- [Facebook Logout Button](#facebook-logout-button)
2626
- [Custom Logout Button](#custom-logout-button)
27+
- [Share](#share)
28+
- [Create Sharing Content](#create-sharing-content)
29+
- [Facebook Share Button](#facebook-share-button)
30+
- [Facebook Send Button](#facebook-send-button)
31+
- [Show Share Dialog Programmatically](#show-dialog-programmatically)
32+
- [Hide Custom Button If Can't share](#hide-custom-button)
2733
- [NativeScript Angular](#nativescript-angular)
2834
- [Initialization](#initialization-1)
2935
- [Login](#login-1)
@@ -32,6 +38,12 @@ NativeScript : Facebook SDK ![apple](https://cdn3.iconfinder.com/data/icons/pico
3238
- [Logout](#logout)
3339
- [Facebook Logout Button](#facebook-logout-button-1)
3440
- [Custom Logout Button](#custom-logout-button-1)
41+
- [Share](#share-1)
42+
- [Create Sharing Content](#create-sharing-content-1)
43+
- [Facebook Share Button](#facebook-share-button-1)
44+
- [Facebook Send Button](#facebook-send-button-1)
45+
- [Show Share Dialog Programmatically](#show-dialog-programmatically-1)
46+
- [Hide Custom Button If Can't share](#hide-custom-button-1)
3547
- [Login Response](#login-response)
3648
- [Get Current Access Token](#get-current-access-token)
3749
- [Graph API Example](#graph-api-example)
@@ -44,7 +56,7 @@ NativeScript : Facebook SDK ![apple](https://cdn3.iconfinder.com/data/icons/pico
4456

4557
## Features
4658
- [x] Login & Logout
47-
- [ ] Share
59+
- [x] Share
4860
- [ ] Graph API
4961

5062

@@ -55,9 +67,16 @@ tns plugin add nativescript-facebook
5567

5668
## Configuration
5769
### Android
58-
No additional configuration required!
70+
Update AndroidManifest.xml (app/App_Resources/Android/AndroidManifest.xml) to put `provider` under `<application>`
71+
`{facebook_app_id}` is your app id
72+
73+
```xml
74+
<provider android:authorities="com.facebook.app.FacebookContentProvider{facebook_app_id}"
75+
android:name="com.facebook.FacebookContentProvider"
76+
android:exported="true"/>
77+
```
5978
### iOS
60-
Update Info.plist file (app/App_Resources/iOS/Info.plist) to contains `CFBundleURLTypes` like below:
79+
Update Info.plist file (app/App_Resources/iOS/Info.plist) to contains `CFBundleURLTypes` and `LSApplicationQueriesSchemes` like below:
6180
```xml
6281
<?xml version="1.0" encoding="UTF-8"?>
6382
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -74,7 +93,13 @@ Update Info.plist file (app/App_Resources/iOS/Info.plist) to contains `CFBundleU
7493
</array>
7594
</dict>
7695
</array>
77-
96+
<key>LSApplicationQueriesSchemes</key>
97+
<array>
98+
<string>fbapi</string>
99+
<string>fb-messenger-share-api</string>
100+
<string>fbauth2</string>
101+
<string>fbshareextension</string>
102+
</array>
78103
</dict>
79104
</plist>
80105
```
@@ -250,6 +275,96 @@ export class LoginViewModel extends Observable {
250275
}
251276
```
252277

278+
### Share
279+
### Create Sharing Content
280+
For sharing, you have to create sharing content first.
281+
Currently the available content types are:
282+
- **createShareLinksContent(link: string, quote?: string, addition?: ShareAdditionContent)** available for every condition
283+
- **createSharePhotosContent(images: ImageSource[] | string[], userGenerated: boolean, addition?: ShareAdditionContent)** available for ShareButton and `showShareDialog` ( only when user have native Facebook installed, version 7.0 or higher )
284+
- **createShareMessageGenericTemplateContent(contentConfig: MessageGenericTemplateContent)** available for SendButton and `showMessageDialog`
285+
- **createShareMessageMediaTemplateContent(contentConfig: MessageMediaTemplateContent)** available for SendButton and `showMessageDialog`
286+
287+
You can see more information from [https://developers.facebook.com/docs/sharing/overview#content](https://developers.facebook.com/docs/sharing/overview#content) and [https://developers.facebook.com/docs/sharing/messenger#share-types](https://developers.facebook.com/docs/sharing/messenger#share-types)
288+
```TypeScript
289+
import {
290+
LoginEventData,
291+
getCurrentAccessToken,
292+
createShareLinksContent,
293+
createSharePhotosContent,
294+
createShareMessageGenericTemplateContent,
295+
MessageGenericTemplateImageAspectRatio,
296+
showShareDialog,
297+
showMessageDialog,
298+
canShareDialogShow,
299+
canMessageDialogShow
300+
} from 'nativescript-facebook';
301+
302+
const linkContent = createShareLinksContent('https://www.nativescript.org',
303+
'Create Native iOS and Android Apps With JavaScript',
304+
{
305+
hashtag: '#Nativescript'
306+
});
307+
308+
// you can also pass in imageUrls as string[] in here
309+
const logoImage = fromResource('logo');
310+
const photosContent = createSharePhotosContent([logoImage], false, {
311+
hashtag: '#Nativescript'
312+
});
313+
const GenericTemplate = createShareMessageGenericTemplateContent({
314+
element: {
315+
title: 'Nativescript',
316+
subtitle: 'Create Native iOS and Android Apps With JavaScript',
317+
imageUrl: 'https://d2odgkulk9w7if.cloudfront.net/images/default-source/home/how-it-works-min.png',
318+
button: {
319+
title: 'Check Doc',
320+
url: 'https://docs.nativescript.org'
321+
},
322+
defaultAction: {
323+
title: 'Go HomePage',
324+
url: 'https://www.nativescript.org'
325+
}
326+
},
327+
// it seems android have to provide a pageId, otherwise the MessageDialog just wont show
328+
pageID: 'testestsett',
329+
imageAspectRatio: MessageGenericTemplateImageAspectRatio.Horizontal
330+
});
331+
332+
```
333+
334+
### Facebook Share Button
335+
```xml
336+
<Facebook:ShareButton content="{{ linkContent }}"></Facebook:ShareButton>
337+
```
338+
339+
### Facebook Send Button
340+
341+
If the Messenger app is not installed, the Send button will be hidden. Be sure that your app layout is appropriate when this button is hidden.
342+
343+
```xml
344+
<Facebook:SendButton content="{{ genericContent }}"></Facebook:SendButton>
345+
```
346+
347+
### Show Share Dialog Programmatically
348+
349+
**Note** The share dialog will try fallback to browse page sharing if user doesn't have Facebook installed (only for linkContent)
350+
351+
```TypeScript
352+
showShareDialog(this.linkContent);
353+
showMessageDialog(this.linkContent);
354+
```
355+
356+
### Hide Custom Button If Can't share
357+
358+
You can use this method to check if the content can be shared and hide the custom button if can't
359+
360+
```TypeScript
361+
public canShowPhotosShareDialog = canShareDialogShow(this.photosContent);
362+
public canShowGenericMessageDialog = canMessageDialogShow(this.genericContent);
363+
```
364+
```xml
365+
<Button tap="{{ onShareDialogPhotos }}" text="Open Share dialog (photos)" visibility="{{ canShowPhotosShareDialog ? 'visible' : 'collapsed' }}"></Button>
366+
<Button tap="{{ onSendGenericDialog }}" text="Share Message Generic Template" visibility="{{ canShowGenericMessageDialog ? 'visible' : 'collapsed' }}"></Button>
367+
```
253368

254369
## NativeScript Angular
255370
### Initialization
@@ -417,6 +532,45 @@ export class AppComponent {
417532
```
418533

419534

535+
### Share
536+
### Create Sharing Content
537+
Read Nativescript [chapter](#create-sharing-content) for this
538+
539+
### Facebook Share Button
540+
```html
541+
<FacebookShareButton [content] = "linkContent"></FacebookShareButton>
542+
```
543+
544+
### Facebook Send Button
545+
546+
If the Messenger app is not installed, the Send button will be hidden. Be sure that your app layout is appropriate when this button is hidden.
547+
548+
```html
549+
<FacebookSendButton [content] = "genericContent"></FacebookSendButton>
550+
```
551+
552+
### Show Share Dialog Programmatically
553+
554+
**Note** The share dialog will try fallback to browse page sharing if user doesn't have Facebook installed (only for linkContent)
555+
556+
```TypeScript
557+
showShareDialog(this.linkContent);
558+
showMessageDialog(this.linkContent);
559+
```
560+
561+
### Hide Custom Button If Can't share
562+
563+
You can use this method to check if the content can be shared and hide the custom button if can't
564+
565+
```TypeScript
566+
public canShowPhotosShareDialog = canShareDialogShow(this.photosContent);
567+
public canShowGenericMessageDialog = canMessageDialogShow(this.genericContent);
568+
```
569+
```html
570+
<Button (tap) = "onShareDialogPhotos()" text = "Open Share dialog (photos)" *ngIf = "canShowPhotosShareDialog"></Button>
571+
<Button (tap) = "onSendGenericDialog()" text = "Share Message Generic Template" *ngIf = "canShowGenericMessageDialog"></Button>
572+
```
573+
420574
## Login Response
421575
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:
422576

demo-angular/app/App_Resources/Android/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,9 @@
3939
</intent-filter>
4040
</activity>
4141
<activity android:name="com.tns.ErrorReportActivity"/>
42+
43+
<provider android:authorities="com.facebook.app.FacebookContentProvider1771472059772879"
44+
android:name="com.facebook.FacebookContentProvider"
45+
android:exported="true"/>
4246
</application>
4347
</manifest>

demo-angular/app/App_Resources/iOS/Info.plist

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,12 @@
5252
</array>
5353
</dict>
5454
</array>
55+
<key>LSApplicationQueriesSchemes</key>
56+
<array>
57+
<string>fbapi</string>
58+
<string>fb-messenger-share-api</string>
59+
<string>fbauth2</string>
60+
<string>fbshareextension</string>
61+
</array>
5562
</dict>
5663
</plist>
193 KB
Loading

demo-angular/app/app.module.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { NgModule, NO_ERRORS_SCHEMA, NgModuleFactoryLoader } from "@angular/core";
1+
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
22
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
3-
import { NativeScriptRouterModule, NSModuleFactoryLoader } from "nativescript-angular/router";
3+
import { NativeScriptRouterModule } from "nativescript-angular/router";
44
import { AppComponent } from "./app.component";
55
import { LoginModule } from "./pages/login/login.module";
66
import { HomeModule } from "./pages/home/home.module";
@@ -23,8 +23,7 @@ application.on(application.launchEvent, function (args) {
2323
NativeScriptRouterModule.forRoot(routes)
2424
],
2525
providers: [
26-
NavigationService,
27-
{ provide: NgModuleFactoryLoader, useClass: NSModuleFactoryLoader }
26+
NavigationService
2827
],
2928
declarations: [AppComponent],
3029
schemas: [NO_ERRORS_SCHEMA]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.login-buttons {
22
margin-left: 30;
33
margin-right: 30;
4-
margin-top: 70%;
4+
margin-top: 10;
55
}

demo-angular/app/pages/login/login.component.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,15 @@
22
<FacebookLoginButton (login)="onLogin($event)"></FacebookLoginButton>
33
<Button text="Continue with Facebook (custom)" (tap)="login()"></Button>
44
<Button text="Get current access token" (tap)="getCurrentAccessToken()"></Button>
5+
6+
<FacebookShareButton [content] = "linkContent"></FacebookShareButton>
7+
<FacebookSendButton [content] = "genericContent"></FacebookSendButton>
8+
<Button (tap) = "onShareDialog()" text = "Open Share dialog (link)"
9+
*ngIf = "canShowLinksShareDialog"></Button>
10+
<Button (tap) = "onShareDialogPhotos()" text = "Open Share dialog (photos)"
11+
*ngIf = "canShowPhotosShareDialog"></Button>
12+
<Button (tap) = "onSendDialog()" text = "Open Message Share dialog"
13+
*ngIf = "canShowLinksMessageDialog"></Button>
14+
<Button (tap) = "onSendGenericDialog()" text = "Share Message Generic Template"
15+
*ngIf = "canShowGenericMessageDialog"></Button>
516
</StackLayout>

demo-angular/app/pages/login/login.component.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Component, ChangeDetectorRef } from "@angular/core";
22
import * as Facebook from "nativescript-facebook";
33
import { NavigationService } from "../../services/navigation.service";
44
import * as appSettings from "tns-core-modules/application-settings";
5+
import {fromResource} from 'tns-core-modules/image-source';
56

67
@Component({
78
selector: "login",
@@ -10,8 +11,29 @@ import * as appSettings from "tns-core-modules/application-settings";
1011
styleUrls: ["login.component.css"]
1112
})
1213
export class LoginComponent {
14+
linkContent = null;
15+
photosContent = null;
16+
genericContent = null;
17+
canShowLinksShareDialog = false;
18+
canShowPhotosShareDialog = false;
19+
canShowLinksMessageDialog = false;
20+
canShowGenericMessageDialog = false;
1321

1422
constructor(private ref: ChangeDetectorRef, private navigationService: NavigationService) {
23+
// have to init after facebook sdk inited
24+
setTimeout(() => {
25+
this.init();
26+
}, 100);
27+
}
28+
29+
init() {
30+
this.linkContent = this.generateLinksShareContent();
31+
this.photosContent = this.generatePhotosShareContent();
32+
this.genericContent = this.generateGenericTemplateContent();
33+
this.canShowLinksShareDialog = Facebook.canShareDialogShow(this.linkContent);
34+
this.canShowPhotosShareDialog = Facebook.canShareDialogShow(this.photosContent);
35+
this.canShowLinksMessageDialog = Facebook.canMessageDialogShow(this.linkContent);
36+
this.canShowGenericMessageDialog = Facebook.canMessageDialogShow(this.genericContent);
1537
}
1638

1739
onLogin(eventData: Facebook.LoginEventData) {
@@ -34,9 +56,61 @@ export class LoginComponent {
3456
});
3557
}
3658

37-
public getCurrentAccessToken() {
59+
getCurrentAccessToken() {
3860
let accessToken = Facebook.getCurrentAccessToken();
3961

4062
alert("Current access token: " + JSON.stringify(accessToken, null, '\t'));
4163
}
64+
65+
generateLinksShareContent() {
66+
return Facebook.createShareLinksContent('https://www.nativescript.org',
67+
'Create Native iOS and Android Apps With JavaScript',
68+
{
69+
hashtag: '#Nativescript'
70+
});
71+
}
72+
73+
generatePhotosShareContent() {
74+
const logoImage = fromResource('logo');
75+
return Facebook.createSharePhotosContent([logoImage], false, {
76+
hashtag: '#Nativescript'
77+
});
78+
}
79+
80+
generateGenericTemplateContent() {
81+
return Facebook.createShareMessageGenericTemplateContent({
82+
element: {
83+
title: 'Nativescript',
84+
subtitle: 'Create Native iOS and Android Apps With JavaScript',
85+
imageUrl: 'https://d2odgkulk9w7if.cloudfront.net/images/default-source/home/how-it-works-min.png',
86+
button: {
87+
title: 'Check Doc',
88+
url: 'https://docs.nativescript.org'
89+
},
90+
defaultAction: {
91+
title: 'Go HomePage',
92+
url: 'https://www.nativescript.org'
93+
}
94+
},
95+
// it seems android have to provide a pageId, otherwise the MessageDialog just wont show
96+
pageID: 'testestsett',
97+
imageAspectRatio: Facebook.MessageGenericTemplateImageAspectRatio.Horizontal
98+
});
99+
}
100+
101+
onShareDialog() {
102+
Facebook.showShareDialog(this.linkContent);
103+
}
104+
105+
onShareDialogPhotos() {
106+
Facebook.showShareDialog(this.photosContent);
107+
}
108+
109+
onSendDialog() {
110+
Facebook.showMessageDialog(this.linkContent);
111+
}
112+
113+
onSendGenericDialog() {
114+
Facebook.showMessageDialog(this.genericContent);
115+
}
42116
}

demo-angular/app/pages/login/login.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
2+
import { NativeScriptCommonModule } from "nativescript-angular/common";
23
import { NativeScriptRouterModule } from "nativescript-angular/router";
34
import { LoginComponent } from "./login.component";
45

@@ -13,6 +14,7 @@ export const routerConfig = [
1314

1415
@NgModule({
1516
imports: [
17+
NativeScriptCommonModule,
1618
NativeScriptRouterModule,
1719
NativeScriptRouterModule.forChild(routerConfig)
1820
],

0 commit comments

Comments
 (0)