Skip to content

Commit 556cca0

Browse files
committed
✨ Add module to share tweet link and user profile link to other social media app.
1 parent 3c55c69 commit 556cca0

File tree

6 files changed

+133
-19
lines changed

6 files changed

+133
-19
lines changed

lib/helper/utility.dart

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22

33
import 'package:firebase_analytics/firebase_analytics.dart';
44
import 'package:firebase_database/firebase_database.dart';
5+
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
56
import 'package:flutter/foundation.dart';
67
import 'package:flutter/material.dart';
78
import 'package:flutter_twitter_clone/widgets/customWidgets.dart';
@@ -126,11 +127,14 @@ void cprint(dynamic data, {String errorIn, String event}) {
126127
if (errorIn != null) {
127128
print(
128129
'****************************** error ******************************');
129-
developer.log('[Error]', time: DateTime.now(), error:data, name:errorIn);
130+
developer.log('[Error]', time: DateTime.now(), error: data, name: errorIn);
130131
print(
131132
'****************************** error ******************************');
132133
} else if (data != null) {
133-
developer.log(data, time: DateTime.now(), );
134+
developer.log(
135+
data,
136+
time: DateTime.now(),
137+
);
134138
}
135139
if (event != null) {
136140
// logEvent(event);
@@ -166,10 +170,13 @@ List<String> getHashTags(String text) {
166170
return resultMatches;
167171
}
168172

169-
String getUserName({ String id,String name,}) {
173+
String getUserName({
174+
String id,
175+
String name,
176+
}) {
170177
String userName = '';
171-
if(name.length > 15){
172-
name = name.substring(0,6);
178+
if (name.length > 15) {
179+
name = name.substring(0, 6);
173180
}
174181
name = name.split(' ')[0];
175182
id = id.substring(0, 4).toLowerCase();
@@ -207,3 +214,27 @@ bool validateEmal(String email) {
207214
var status = regExp.hasMatch(email);
208215
return status;
209216
}
217+
218+
createLinkAndShare(BuildContext context, String id,
219+
{SocialMetaTagParameters socialMetaTagParameters}) async {
220+
final DynamicLinkParameters parameters = DynamicLinkParameters(
221+
uriPrefix: 'https://fwitterdev.page.link',
222+
link: Uri.parse('https://twitter.com/$id'),
223+
androidParameters: AndroidParameters(
224+
packageName: 'com.thealphamerc.flutter_twitter_clone_dev',
225+
minimumVersion: 0,
226+
),
227+
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
228+
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
229+
),
230+
socialMetaTagParameters: socialMetaTagParameters);
231+
Uri url;
232+
if (true) {
233+
final ShortDynamicLink shortLink = await parameters.buildShortLink();
234+
url = shortLink.shortUrl;
235+
} else {
236+
url = await parameters.buildUrl();
237+
}
238+
239+
share(url.toString(), subject: "Tweet");
240+
}

lib/page/common/splash.dart

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:convert';
22
import 'dart:io';
3+
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
34
import 'package:firebase_remote_config/firebase_remote_config.dart';
45
import 'package:flutter/cupertino.dart';
56
import 'package:flutter/foundation.dart';
@@ -9,8 +10,10 @@ import 'package:flutter_twitter_clone/helper/theme.dart';
910
import 'package:flutter_twitter_clone/helper/utility.dart';
1011
import 'package:flutter_twitter_clone/page/Auth/selectAuthMethod.dart';
1112
import 'package:flutter_twitter_clone/page/common/updateApp.dart';
13+
import 'package:flutter_twitter_clone/page/feed/feedPostDetail.dart';
1214
import 'package:flutter_twitter_clone/page/homePage.dart';
1315
import 'package:flutter_twitter_clone/state/authState.dart';
16+
import 'package:flutter_twitter_clone/state/feedState.dart';
1417
import 'package:flutter_twitter_clone/widgets/customWidgets.dart';
1518
import 'package:package_info/package_info.dart';
1619
import 'package:provider/provider.dart';
@@ -27,10 +30,46 @@ class _SplashPageState extends State<SplashPage> {
2730
void initState() {
2831
WidgetsBinding.instance.addPostFrameCallback((_) {
2932
timer();
33+
initDynamicLinks();
3034
});
3135
super.initState();
3236
}
3337

38+
void initDynamicLinks() async {
39+
FirebaseDynamicLinks.instance.onLink(
40+
onSuccess: (PendingDynamicLinkData dynamicLink) async {
41+
final Uri deepLink = dynamicLink?.link;
42+
43+
if (deepLink != null) {
44+
redirectFromDeepLink(deepLink);
45+
}
46+
}, onError: (OnLinkErrorException e) async {
47+
print('onLinkError');
48+
print(e.message);
49+
});
50+
51+
final PendingDynamicLinkData data =
52+
await FirebaseDynamicLinks.instance.getInitialLink();
53+
final Uri deepLink = data?.link;
54+
55+
if (deepLink != null) {
56+
redirectFromDeepLink(deepLink);
57+
}
58+
}
59+
60+
void redirectFromDeepLink(Uri deepLink) {
61+
print("Found Url from share: ${deepLink.path}");
62+
var type = deepLink.path.split("/")[1];
63+
var id = deepLink.path.split("/")[2];
64+
if (type == "profilePage") {
65+
Navigator.of(context).pushNamed('/ProfilePage/' + id);
66+
} else if (type == "tweet") {
67+
var feedstate = Provider.of<FeedState>(context, listen: false);
68+
feedstate.getpostDetailFromDatabase(id);
69+
Navigator.of(context).pushNamed('/FeedPostDetail/' + id);
70+
}
71+
}
72+
3473
void timer() async {
3574
final isAppUpdated = await _checkAppVersion();
3675
if (isAppUpdated) {
@@ -42,21 +81,24 @@ class _SplashPageState extends State<SplashPage> {
4281
});
4382
}
4483
}
45-
/// Return installed app version
84+
85+
/// Return installed app version
4686
/// For testing purpose in debug mode update screen will not be open up
47-
/// In an old version of realease app is installed on user's device then
48-
/// User will not be able to see home screen
87+
/// In an old version of realease app is installed on user's device then
88+
/// User will not be able to see home screen
4989
/// User will redirected to update app screen.
5090
/// Once user update app with latest verson and back to app then user automatically redirected to welcome / Home page
5191
Future<bool> _checkAppVersion() async {
5292
PackageInfo packageInfo = await PackageInfo.fromPlatform();
5393
final currentAppVersion = "${packageInfo.version}";
5494
final appVersion = await _getAppVersionFromFirebaseConfig();
5595
if (appVersion != currentAppVersion) {
56-
if(kDebugMode){
96+
if (kDebugMode) {
5797
cprint("Latest version of app is not installed on your system");
58-
cprint("In debug mode we are not restrict devlopers to redirect to update screen");
59-
cprint("Redirect devs to update screen can put other devs in confusion");
98+
cprint(
99+
"In debug mode we are not restrict devlopers to redirect to update screen");
100+
cprint(
101+
"Redirect devs to update screen can put other devs in confusion");
60102
return true;
61103
}
62104
Navigator.pushReplacement(

lib/page/profile/profilePage.dart

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter_twitter_clone/helper/constant.dart';
34
import 'package:flutter_twitter_clone/helper/enum.dart';
@@ -62,7 +63,11 @@ class _ProfilePageState extends State<ProfilePage>
6263
authstate.isbusy
6364
? SizedBox.shrink()
6465
: PopupMenuButton<Choice>(
65-
onSelected: (d) {},
66+
onSelected: (d) {
67+
if (d.title == "Share") {
68+
shareProfile(context);
69+
}
70+
},
6671
itemBuilder: (BuildContext context) {
6772
return choices.map((Choice choice) {
6873
return PopupMenuItem<Choice>(
@@ -97,8 +102,9 @@ class _ProfilePageState extends State<ProfilePage>
97102
height: 180,
98103
padding: EdgeInsets.only(top: 28),
99104
child: customNetworkImage(
100-
authstate.userModel.bannerImage ??
101-
'https://pbs.twimg.com/profile_banners/457684585/1510495215/1500x500',
105+
authstate.profileUserModel.bannerImage != null
106+
? authstate.profileUserModel.bannerImage
107+
: 'https://pbs.twimg.com/profile_banners/457684585/1510495215/1500x500',
102108
fit: BoxFit.fill,
103109
),
104110
),
@@ -285,6 +291,19 @@ class _ProfilePageState extends State<ProfilePage>
285291

286292
TabController _tabController;
287293

294+
void shareProfile(BuildContext context) async {
295+
var authstate = context.read<AuthState>();
296+
var user = authstate.profileUserModel;
297+
createLinkAndShare(
298+
context,
299+
"profilePage/${widget.profileId}/",
300+
socialMetaTagParameters: SocialMetaTagParameters(
301+
description: user.bio ?? "Checkout ${user.displayName}'s profile",
302+
title: "${user.displayName} is on Fwitter app",
303+
imageUrl: Uri.parse(user.profilePic)),
304+
);
305+
}
306+
288307
@override
289308
build(BuildContext context) {
290309
var state = Provider.of<FeedState>(context);

lib/widgets/tweet/widgets/tweetIconsRow.dart

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter_twitter_clone/helper/constant.dart';
34
import 'package:flutter_twitter_clone/helper/customRoute.dart';
@@ -77,8 +78,7 @@ class TweetIconsRow extends StatelessWidget {
7778
),
7879
_iconWidget(context, text: '', icon: null, sysIcon: Icons.share,
7980
onPressed: () {
80-
share('${model.description}',
81-
subject: '${model.user.displayName}\'s post');
81+
shareTweet(context);
8282
}, iconColor: iconColor, size: size ?? 20),
8383
],
8484
),
@@ -144,7 +144,8 @@ class TweetIconsRow extends StatelessWidget {
144144
}
145145

146146
Widget _likeCommentWidget(BuildContext context) {
147-
bool isLikeAvailable = model.likeCount != null ? model.likeCount > 0 : false;
147+
bool isLikeAvailable =
148+
model.likeCount != null ? model.likeCount > 0 : false;
148149
bool isRetweetAvailable = model.retweetCount > 0;
149150
bool isLikeRetweetAvailable = isRetweetAvailable || isLikeAvailable;
150151
return Column(
@@ -231,12 +232,26 @@ class TweetIconsRow extends StatelessWidget {
231232
pageTitle: "Liked by",
232233
userIdsList: model.likeList.map((userId) => userId).toList(),
233234
emptyScreenText: "This tweet has no like yet",
234-
emptyScreenSubTileText: "Once a user likes this tweet, user list will be shown here",
235+
emptyScreenSubTileText:
236+
"Once a user likes this tweet, user list will be shown here",
235237
),
236238
),
237239
);
238240
}
239241

242+
void shareTweet(BuildContext context) async {
243+
createLinkAndShare(
244+
context,
245+
"tweet/${model.key}",
246+
socialMetaTagParameters: SocialMetaTagParameters(
247+
description: model.description ??
248+
"${model.user.displayName} posted a tweet on Fwitter.",
249+
title: "Tweet on Fwitter app",
250+
imageUrl: Uri.parse(
251+
"https://play-lh.googleusercontent.com/e66XMuvW5hZ7HnFf8R_lcA3TFgkxm0SuyaMsBs3KENijNHZlogUAjxeu9COqsejV5w=s180-rw")),
252+
);
253+
}
254+
240255
@override
241256
Widget build(BuildContext context) {
242257
return Container(

pubspec.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@ packages:
232232
url: "https://pub.dartlang.org"
233233
source: hosted
234234
version: "6.0.0"
235+
firebase_dynamic_links:
236+
dependency: "direct main"
237+
description:
238+
name: firebase_dynamic_links
239+
url: "https://pub.dartlang.org"
240+
source: hosted
241+
version: "0.7.0+1"
235242
firebase_messaging:
236243
dependency: "direct main"
237244
description:

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ dependencies:
4545
share: ^0.6.3
4646
google_fonts: ^0.3.9
4747
firebase_remote_config: ^0.6.0
48-
# firebase_dynamic_links: ^0.7.0+1
48+
firebase_dynamic_links: ^0.7.0+1
4949
# simple_url_preview: ^1.1.0
5050

5151
# camera:

0 commit comments

Comments
 (0)