Skip to content

Commit 5b043c4

Browse files
committed
fixed preview with link_preview_generator package
1 parent e5d7873 commit 5b043c4

File tree

3 files changed

+126
-34
lines changed

3 files changed

+126
-34
lines changed

lib/state/feedState.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import 'package:flutter_twitter_clone/helper/utility.dart';
1010
import 'package:flutter_twitter_clone/model/user.dart';
1111
import 'package:flutter_twitter_clone/state/appState.dart';
1212
import 'package:flutter_twitter_clone/ui/page/common/locator.dart';
13+
import 'package:link_preview_generator/link_preview_generator.dart'
14+
show WebInfo;
1315
import 'package:path/path.dart' as path;
1416
import 'package:translator/translator.dart';
15-
import 'package:flutter_chat_types/flutter_chat_types.dart' show PreviewData;
17+
// import 'package:flutter_chat_types/flutter_chat_types.dart' show PreviewData;
1618
// import 'authState.dart';
1719

1820
class FeedState extends AppState {
@@ -76,11 +78,10 @@ class FeedState extends AppState {
7678
return list;
7779
}
7880

79-
Map<String, PreviewData> _linkDataPreviews = {};
80-
Map<String, PreviewData> get linkDataPreviews => _linkDataPreviews;
81-
void addPreviewData(String url, PreviewData previewData) {
82-
_linkDataPreviews.addAll({url: previewData});
83-
notifyListeners();
81+
Map<String, WebInfo> _linkWebInfos = {};
82+
Map<String, WebInfo> get linkWebInfos => _linkWebInfos;
83+
void addWebInfo(String url, WebInfo webInfo) {
84+
_linkWebInfos.addAll({url: webInfo});
8485
}
8586

8687
Map<String, Translation?> _tweetsTranslations = {};
Lines changed: 118 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import 'package:cached_network_image/cached_network_image.dart';
22
import 'package:flutter/material.dart';
3-
import 'package:flutter_link_previewer/flutter_link_previewer.dart';
3+
import 'package:link_preview_generator/link_preview_generator.dart';
44

55
import 'package:flutter_twitter_clone/helper/utility.dart';
66
import 'package:flutter_twitter_clone/state/feedState.dart';
77
import 'package:flutter_twitter_clone/ui/theme/theme.dart';
8+
import 'package:link_preview_generator/src/utils/analyzer.dart'
9+
show
10+
LinkPreviewAnalyzer; //FIXME Don't import implementation files from another package.
811
import 'package:provider/provider.dart';
912

1013
class LinkPreviewer extends StatelessWidget {
@@ -31,42 +34,130 @@ class LinkPreviewer extends StatelessWidget {
3134
@override
3235
Widget build(BuildContext context) {
3336
var state = Provider.of<FeedState>(context, listen: false);
37+
3438
var uri = url ?? getUrl();
3539
if (uri == null) {
3640
return const SizedBox.shrink();
3741
} else if (uri.contains("page.link/")) {
3842
/// `flutter_link_preview` package is unable to fetch firebase dynamic link meta data
3943
return const SizedBox.shrink();
4044
}
41-
final style = TextStyle(
42-
fontSize: 0,
43-
);
44-
45-
try {
46-
return LinkPreview(
47-
enableAnimation: false,
48-
onPreviewDataFetched: (data) {
49-
state.addPreviewData(uri, data);
50-
},
51-
imageBuilder: (image) {
52-
return ClipRRect(
53-
borderRadius: BorderRadius.circular(10.0),
54-
child: CachedNetworkImage(
55-
imageUrl: image,
45+
if (state.linkWebInfos.containsKey(uri))
46+
return _buildLinkPreview(
47+
state.linkWebInfos[uri]!, uri, Theme.of(context));
48+
return FutureBuilder(
49+
builder: (BuildContext context, AsyncSnapshot<WebInfo> snapshot) {
50+
if (snapshot.hasData) {
51+
state.addWebInfo(uri, snapshot.data!);
52+
return _buildLinkPreview(snapshot.data!, uri, Theme.of(context));
53+
}
54+
if (snapshot.hasError) {
55+
return SizedBox.shrink();
56+
}
57+
return Container(
58+
width: MediaQuery.of(context).size.width,
59+
decoration: BoxDecoration(
60+
borderRadius: BorderRadius.circular(8),
61+
color: const Color.fromRGBO(248, 248, 248, 1.0),
5662
),
57-
).ripple(() {
58-
Utility.launchURL(uri);
59-
});
63+
alignment: Alignment.center,
64+
child: const Text('Fetching data...'),
65+
);
6066
},
61-
linkStyle: style,
62-
previewData:
63-
state.linkDataPreviews[uri], // Pass the preview data from the state
64-
text: uri,
65-
width: MediaQuery.of(context).size.width,
67+
future: LinkPreview.scrapeFromURL(uri));
68+
}
69+
70+
Widget _buildLinkPreview(WebInfo info, String uri, ThemeData theme) {
71+
var image = LinkPreviewAnalyzer.isNotEmpty(info.image)
72+
? info.image
73+
: LinkPreviewAnalyzer.isNotEmpty(info.icon)
74+
? info.icon
75+
: ""; //TODO Placeholder/error image
76+
if (!LinkPreviewAnalyzer.isNotEmpty(info.title) &&
77+
LinkPreviewAnalyzer.isNotEmpty(info.image)) {
78+
return CachedNetworkImage(
79+
imageUrl: image,
80+
fit: BoxFit.contain,
81+
).ripple(
82+
() {
83+
Utility.launchURL(uri);
84+
},
85+
borderRadius: BorderRadius.circular(10),
6686
);
67-
} catch (e) {
68-
cprint(e);
69-
return SizedBox.shrink();
7087
}
88+
if (!LinkPreviewAnalyzer.isNotEmpty(info.title)) return const SizedBox();
89+
90+
return Padding(
91+
padding: const EdgeInsets.only(top: 8),
92+
child: Container(
93+
decoration: BoxDecoration(
94+
borderRadius: BorderRadius.circular(10),
95+
border: Border.all(color: AppColor.extraLightGrey),
96+
color: theme.colorScheme.onPrimary),
97+
child: Column(
98+
crossAxisAlignment: CrossAxisAlignment.start,
99+
mainAxisAlignment: MainAxisAlignment.center,
100+
children: <Widget>[
101+
if (LinkPreviewAnalyzer.isNotEmpty(image))
102+
ClipRRect(
103+
borderRadius: BorderRadius.vertical(top: Radius.circular(10)),
104+
child: Container(
105+
height: 140,
106+
width: double.infinity,
107+
decoration: BoxDecoration(
108+
border: Border(
109+
bottom: BorderSide(color: theme.dividerColor, width: 1),
110+
),
111+
),
112+
child: CachedNetworkImage(
113+
imageUrl: image,
114+
fit: BoxFit.cover,
115+
),
116+
),
117+
),
118+
const SizedBox(height: 4),
119+
if (LinkPreviewAnalyzer.isNotEmpty(info.title))
120+
Padding(
121+
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
122+
child: Text(
123+
info.title.trim(),
124+
maxLines: 1,
125+
overflow: TextOverflow.ellipsis,
126+
style: TextStyles.titleStyle.copyWith(
127+
fontSize: 14,
128+
fontWeight: FontWeight.bold,
129+
color: Colors.black87),
130+
),
131+
),
132+
if (LinkPreviewAnalyzer.isNotEmpty(info.description))
133+
Padding(
134+
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
135+
child: Text(
136+
info.description.trim(),
137+
maxLines: 2,
138+
overflow: TextOverflow.ellipsis,
139+
style: TextStyles.subtitleStyle.copyWith(fontSize: 12),
140+
),
141+
),
142+
Padding(
143+
padding: EdgeInsets.only(bottom: 5, left: 8, right: 8),
144+
child: Text(
145+
Uri.tryParse(uri)!.authority,
146+
maxLines: 1,
147+
overflow: TextOverflow.ellipsis,
148+
style: TextStyles.subtitleStyle.copyWith(
149+
fontWeight: FontWeight.w400,
150+
fontSize: info.title.isNotEmpty ? 14 : 16),
151+
),
152+
),
153+
],
154+
),
155+
).ripple(
156+
() {
157+
Utility.launchURL(uri);
158+
},
159+
borderRadius: BorderRadius.circular(8),
160+
),
161+
);
71162
}
72163
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ dependencies:
5050
qr_code_scanner: ^0.5.2
5151
qr_flutter: ^4.0.0
5252
rxdart: ^0.27.2
53-
flutter_link_previewer: ^2.5.2
5453
translator: ^0.1.7
5554
flutter_chat_types: ^3.1.4
55+
link_preview_generator: ^1.2.0
5656

5757
dev_dependencies:
5858
test: ^1.17.10

0 commit comments

Comments
 (0)