Skip to content

Commit d526942

Browse files
author
tensor-programming
committed
add check for version dialog box
1 parent 086e91d commit d526942

File tree

7 files changed

+114
-31
lines changed

7 files changed

+114
-31
lines changed

lib/blocs/information_bloc.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@ import 'dart:async';
33
import 'package:rxdart/rxdart.dart';
44
import 'package:package_info/package_info.dart';
55

6+
import 'package:utopian_rocks/model/githubApi.dart';
7+
import 'package:utopian_rocks/model/model.dart';
8+
69
class InformationBloc {
710
Future<PackageInfo> packageInfo;
11+
GithubApi api;
812

913
// Package info stream
1014
Stream<PackageInfo> _infoStream = Stream.empty();
15+
Stream<GithubReleaseModel> _releases = Stream.empty();
1116

1217
Stream<PackageInfo> get infoStream => _infoStream;
18+
Stream<GithubReleaseModel> get releases => _releases;
1319

1420
// BLoc that serves connectivity information and package information to the information drawer.
15-
InformationBloc(this.packageInfo) {
21+
InformationBloc(this.packageInfo, this.api) {
1622
_infoStream = Observable.fromFuture(packageInfo).asBroadcastStream();
23+
24+
_releases = Observable.fromFuture(api.getReleases())
25+
.debounce(Duration(minutes: 5))
26+
.asBroadcastStream();
1727
}
1828
}

lib/components/list_page.dart

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import 'package:utopian_rocks/utils/utils.dart';
44
import 'package:timeago/timeago.dart' as timeago;
55
import 'package:url_launcher/url_launcher.dart';
66

7-
import 'package:intl/intl.dart';
8-
97
import 'package:utopian_rocks/model/htmlParser.dart';
8+
import 'package:utopian_rocks/providers/information_provider.dart';
109

1110
class ListPage extends StatelessWidget {
1211
final String tabname;
@@ -18,6 +17,7 @@ class ListPage extends StatelessWidget {
1817
// get block from [ContributionProvider] to add to [StreamBuilder]
1918
final bloc = ContributionProvider.of(context);
2019
final parseWebsite = ParseWebsite();
20+
final infoBloc = InformationProvider.of(context);
2121
// Pass in the [tabname] or string which represents the page name.
2222
// Based on the string passed in, the stream will get different contributions.
2323
bloc.tabname.add(tabname);
@@ -35,31 +35,33 @@ class ListPage extends StatelessWidget {
3535
);
3636
}
3737

38-
bloc.voteCount.listen((vc) => showBottomSheet(
39-
context: context,
40-
builder: (context) {
41-
return Container(
42-
color: Color(0xff26A69A),
43-
child: Row(
44-
children: [
45-
StreamBuilder(
46-
stream: bloc.timer,
47-
builder: (context, timerSnapshot) {
48-
return Text(
49-
'~ Next Vote Cycle: ${DateFormat.Hms().format(DateTime(0, 0, 0, 0, 0, timerSnapshot.data ?? 0))} ',
50-
style: TextStyle(fontWeight: FontWeight.w700),
51-
);
52-
}),
53-
Text(
54-
'Vote Power: ${double.parse(vc.replaceAll('\n', '')).toStringAsPrecision(4)}',
55-
style: TextStyle(fontWeight: FontWeight.w700),
56-
),
57-
],
58-
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
59-
crossAxisAlignment: CrossAxisAlignment.center,
60-
),
61-
);
62-
}));
38+
infoBloc.releases.listen((releases) {
39+
infoBloc.infoStream.listen((pkInfo) {
40+
print(pkInfo.version);
41+
print(releases.tagName);
42+
if (pkInfo.version.toString() != releases.tagName) {
43+
showDialog(
44+
context: context,
45+
builder: (BuildContext context) => AlertDialog(
46+
title: Text('${pkInfo.appName}'),
47+
content: Container(
48+
child: Text(
49+
'A new version of this application is available to download. The current version is ${pkInfo.version} and the new version is ${releases.tagName}'),
50+
),
51+
actions: <Widget>[
52+
FlatButton(
53+
child: Text('Download'),
54+
onPressed: () => _launchUrl(releases.htmlUrl),
55+
),
56+
FlatButton(
57+
child: Text('Close'),
58+
onPressed: () => Navigator.of(context).pop(),
59+
)
60+
],
61+
));
62+
}
63+
});
64+
});
6365

6466
// Generate [ListView] using the [AsyncSnapshot] from the [StreamBuilder]
6567
// [ListView] provides lazy loading and programmatically generates the Page.

lib/main.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22

33
import 'package:package_info/package_info.dart';
4+
import 'package:intl/intl.dart';
45

56
import 'package:utopian_rocks/components/list_page.dart';
67
import 'package:utopian_rocks/components/drawer.dart';
@@ -12,6 +13,7 @@ import 'package:utopian_rocks/blocs/contribution_bloc.dart';
1213
import 'package:utopian_rocks/blocs/information_bloc.dart';
1314
import 'package:utopian_rocks/providers/information_provider.dart';
1415
import 'package:utopian_rocks/model/htmlParser.dart';
16+
import 'package:utopian_rocks/model/githubApi.dart';
1517

1618
void main() => runApp(MyApp());
1719

@@ -23,6 +25,7 @@ class MyApp extends StatelessWidget {
2325
return InformationProvider(
2426
informationBloc: InformationBloc(
2527
PackageInfo.fromPlatform(),
28+
GithubApi(),
2629
),
2730
child: ContributionProvider(
2831
// Instantiate the API and the BLoC for the entire application.
@@ -95,10 +98,39 @@ class RootApp extends StatelessWidget {
9598
ListPage('pending'),
9699
],
97100
),
101+
bottomNavigationBar: _buildBottonSheet(context),
98102
endDrawer: InformationDrawer(snapshot),
99103
),
100104
),
101105
),
102106
);
103107
}
108+
109+
Widget _buildBottonSheet(BuildContext context) {
110+
final contributionBloc = ContributionProvider.of(context);
111+
112+
return StreamBuilder(
113+
stream: contributionBloc.voteCount,
114+
builder: (context, votecountSnapshot) => BottomAppBar(
115+
color: Color(0xff26A69A),
116+
child: Row(
117+
children: [
118+
StreamBuilder(
119+
stream: contributionBloc.timer,
120+
builder: (context, timerSnapshot) {
121+
return Text(
122+
'Next Vote Cycle: ${DateFormat.Hms().format(DateTime(0, 0, 0, 0, 0, timerSnapshot.data ?? 0))} ',
123+
style: TextStyle(fontWeight: FontWeight.w700),
124+
);
125+
}),
126+
Text(
127+
'Vote Power: ${double.parse(votecountSnapshot.data ?? '0.0').toStringAsPrecision(4)}',
128+
style: TextStyle(fontWeight: FontWeight.w700),
129+
),
130+
],
131+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
132+
crossAxisAlignment: CrossAxisAlignment.center,
133+
),
134+
));
135+
}
104136
}

lib/model/githubApi.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'dart:async';
2+
import 'dart:convert';
3+
4+
import 'package:utopian_rocks/model/model.dart';
5+
6+
import 'package:http/http.dart' show Client, Response;
7+
8+
class GithubApi {
9+
final Client _client = Client();
10+
static const String _url =
11+
'https://api.github.com/repos/tensor-programming/utopian-rocks-mobile/releases';
12+
13+
Future<GithubReleaseModel> getReleases() async {
14+
List<GithubReleaseModel> items = [];
15+
16+
await _client
17+
.get(Uri.parse(_url))
18+
.then((Response res) => res.body)
19+
.then(json.decode)
20+
.then((j) => j.forEach((Map<String, dynamic> contribution) =>
21+
items.add(GithubReleaseModel.fromJson(contribution))));
22+
23+
return items.first;
24+
}
25+
}

lib/model/model.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,14 @@ class Date {
5050

5151
Date.fromJson(Map json) : date = json['\$date'];
5252
}
53+
54+
class GithubReleaseModel {
55+
final String tagName;
56+
final String htmlUrl;
57+
58+
GithubReleaseModel(this.tagName, this.htmlUrl);
59+
60+
GithubReleaseModel.fromJson(Map<String, dynamic> json)
61+
: this.tagName = json['tag_name'],
62+
this.htmlUrl = json['html_url'];
63+
}

lib/model/repository.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import 'dart:convert';
33

44
import 'package:utopian_rocks/model/model.dart';
55

6-
import 'package:http/http.dart' as http;
6+
import 'package:http/http.dart' show Client;
77

88
class Api {
9-
final http.Client _client = http.Client();
9+
final Client _client = Client();
1010
// static url for the API endpoint
1111
static const String _url = 'https://utopian.rocks/api/posts?status={0}';
1212

lib/providers/information_provider.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import 'package:flutter/widgets.dart';
22

3-
import 'package:utopian_rocks/blocs/information_bloc.dart';
43
import 'package:package_info/package_info.dart';
54

5+
import 'package:utopian_rocks/blocs/information_bloc.dart';
6+
import 'package:utopian_rocks/model/githubApi.dart';
7+
68
// Provider for the [InformationBloc]
79
class InformationProvider extends InheritedWidget {
810
final InformationBloc informationBloc;
@@ -22,6 +24,7 @@ class InformationProvider extends InheritedWidget {
2224
}) : this.informationBloc = informationBloc ??
2325
InformationBloc(
2426
PackageInfo.fromPlatform(),
27+
GithubApi(),
2528
),
2629
super(
2730
key: key,

0 commit comments

Comments
 (0)