Skip to content

Commit 9f8ba74

Browse files
authored
Replaces infinite scrolling & fetching of feeds with a button (#12)
Reason - better UX
1 parent 297e6ef commit 9f8ba74

File tree

1 file changed

+110
-32
lines changed

1 file changed

+110
-32
lines changed

lib/hn-state.dart

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -131,45 +131,108 @@ class HackerNewsState extends State<HackerNews> {
131131

132132
@override
133133
Widget build(BuildContext context) {
134-
if (this.loading) {
135-
return Loader(text: "Fetching stories...");
134+
if (this.loading && data.length == 0) {
135+
return Stack(
136+
children: <Widget>[
137+
Loader(text: "Fetching stories...")
138+
],
139+
);
136140
}
137141

138-
return ListView.builder(
139-
itemCount: data == null ? 0 : data.length,
140-
itemBuilder: (BuildContext context, int index) {
141-
var urlChecked = openedLinks.contains(data[index].url);
142+
var listView = ListView.builder(
143+
itemCount: data == null ? 0 : data.length + 1,
144+
itemBuilder: (BuildContext context, int index) {
145+
if (index >= data.length) {
142146
if (currentPage < maxPages) {
143-
if (index > 0 && index % 29 == 0 && loadedIndices.contains(index) == false) {
144-
_incrementPageNum();
145-
_getJSONData();
146-
loadedIndices.add(index);
147-
}
147+
return GestureDetector(
148+
onTap: () async {
149+
_incrementPageNum();
150+
_getJSONData();
151+
},
152+
child: Container(
153+
child: Card(
154+
color: Colors.deepOrangeAccent,
155+
child: Container(
156+
child: Align(
157+
alignment: Alignment.center,
158+
child: Text(
159+
this.loading ? "Loading more stories" : "Load more stories",
160+
style: TextStyle(
161+
fontSize: 16.0,
162+
fontWeight: FontWeight.w300,
163+
color: Colors.white,
164+
)
165+
)
166+
),
167+
padding: EdgeInsets.all(16.0)
168+
),
169+
elevation: 2.0,
170+
margin: EdgeInsets.only(
171+
top: 16.0,
172+
bottom: 16.0,
173+
left: 10.0,
174+
right: 10.0,
175+
)
176+
),
177+
),
178+
);
148179
}
149180
return GestureDetector(
181+
onTap: () async {
182+
Scaffold.of(context).showSnackBar(SnackBar(content: Text("You have reached the end of the feed")));
183+
},
184+
child: Container(
185+
child: Card(
186+
color: Colors.deepOrangeAccent,
187+
child: Container(
188+
child: Align(
189+
alignment: Alignment.center,
190+
child: Text(
191+
"Load more stories",
192+
style: TextStyle(
193+
fontSize: 16.0,
194+
fontWeight: FontWeight.w300,
195+
color: Colors.white,
196+
)
197+
)
198+
),
199+
padding: EdgeInsets.all(16.0)
200+
),
201+
elevation: 2.0,
202+
margin: EdgeInsets.only(
203+
bottom: 16.0,
204+
left: 10.0,
205+
right: 10.0,
206+
)
207+
),
208+
),
209+
);
210+
}
211+
var urlChecked = openedLinks.contains(data[index].url);
212+
return GestureDetector(
150213
onTap: () async {
151214
String __url = data[index].url.startsWith("item?") ? "https://news.ycombinator.com/" + data[index].url : data[index].url;
152215
DateTime start = DateTime.now();
153216

154217
final result = await Navigator.push(
155-
context,
156-
MaterialPageRoute(
157-
builder: (context) => HNWebView(
158-
url: __url,
159-
title: data[index].title,
160-
analytics: this.analytics,
161-
observer: this.observer,
218+
context,
219+
MaterialPageRoute(
220+
builder: (context) => HNWebView(
221+
url: __url,
222+
title: data[index].title,
223+
analytics: this.analytics,
224+
observer: this.observer,
225+
)
162226
)
163-
)
164227
);
165228

166229
this._sendAnalyticsEvent(
167-
"story_read",
168-
{
169-
"url": __url,
170-
"title": data[index].title,
171-
"time_spent": DateTime.now().difference(start).inSeconds,
172-
}
230+
"story_read",
231+
{
232+
"url": __url,
233+
"title": data[index].title,
234+
"time_spent": DateTime.now().difference(start).inSeconds,
235+
}
173236
);
174237

175238
_updateOpenedLinks(data[index].url, "onTap");
@@ -178,12 +241,12 @@ class HackerNewsState extends State<HackerNews> {
178241
var flag = openedLinks.contains(data[index].url) ? "not read" : "read";
179242
String __url = data[index].url.startsWith("item?") ? "https://news.ycombinator.com/" + data[index].url : data[index].url;
180243
this._sendAnalyticsEvent(
181-
"story_bookmarked",
182-
{
183-
"url": __url,
184-
"title": data[index].title,
185-
"bookmarked": !openedLinks.contains(data[index].url)
186-
}
244+
"story_bookmarked",
245+
{
246+
"url": __url,
247+
"title": data[index].title,
248+
"bookmarked": !openedLinks.contains(data[index].url)
249+
}
187250
);
188251
final snackBar = SnackBar(content: Text("Marking as " + flag.toString() + ": " + data[index].url), duration: Duration(milliseconds: 500));
189252
Scaffold.of(context).showSnackBar(snackBar);
@@ -218,7 +281,7 @@ class HackerNewsState extends State<HackerNews> {
218281
elevation: 2.0,
219282
margin: EdgeInsets.only(
220283
top: 16.0,
221-
bottom: index == data.length - 1 ? 16.0 : 0.0,
284+
bottom: index == data.length - 1 && currentPage >= maxPages ? 16.0 : 0.0,
222285
left: 10.0,
223286
right: 10.0,
224287
),
@@ -227,5 +290,20 @@ class HackerNewsState extends State<HackerNews> {
227290
);
228291
}
229292
);
293+
294+
if (this.loading) {
295+
return Stack(
296+
children: <Widget>[
297+
listView,
298+
Loader(text: "Fetching stories...")
299+
],
300+
);
301+
}
302+
303+
return Stack(
304+
children: <Widget>[
305+
listView,
306+
],
307+
);
230308
}
231309
}

0 commit comments

Comments
 (0)