Skip to content
This repository was archived by the owner on Jan 5, 2021. It is now read-only.

Commit 0fdec6e

Browse files
author
Luis Antonio Correa Leyva
authored
Merge pull request #10 from leynier/master
Implement JSON configuration fetch from GitHub
2 parents d75d281 + e5af73d commit 0fdec6e

File tree

5 files changed

+267
-16
lines changed

5 files changed

+267
-16
lines changed

lib/components/settings.dart

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:provider/provider.dart';
33
import 'package:shared_preferences/shared_preferences.dart';
4+
import 'package:todo/pages/download_ussd_page.dart';
45
import 'package:todo/services/AppStateNotifier.dart';
56
import 'package:todo/themes/colors.dart';
67
import 'package:todo/components/disclaim.dart';
@@ -52,11 +53,13 @@ class _SettingsState extends State<SettingsWidget> {
5253
Row(
5354
mainAxisAlignment: MainAxisAlignment.spaceBetween,
5455
children: <Widget>[
55-
Text(
56-
'Activar modo oscuro',
57-
style: TextStyle(
58-
color: Colors.white,
59-
fontWeight: FontWeight.bold,
56+
Expanded(
57+
child: Text(
58+
'Activar modo oscuro',
59+
style: TextStyle(
60+
color: Colors.white,
61+
fontWeight: FontWeight.bold,
62+
),
6063
),
6164
),
6265
Switch(
@@ -74,12 +77,46 @@ class _SettingsState extends State<SettingsWidget> {
7477
prefs.setBool('darkmode', darkMode);
7578
});
7679
},
77-
)
80+
),
7881
],
7982
),
8083
SizedBox(
8184
height: 48,
8285
),
86+
GestureDetector(
87+
child: Row(
88+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
89+
children: <Widget>[
90+
Expanded(
91+
child: Text(
92+
'Descargar códigos USSD',
93+
style: TextStyle(
94+
color: Colors.white,
95+
fontWeight: FontWeight.bold,
96+
),
97+
),
98+
),
99+
Container(
100+
margin: EdgeInsets.symmetric(horizontal: 15),
101+
child: Icon(
102+
Icons.file_download,
103+
color: GFColors.SUCCESS,
104+
),
105+
),
106+
],
107+
),
108+
onTap: () {
109+
Navigator.pushReplacement(
110+
context,
111+
MaterialPageRoute(
112+
builder: (context) => DownloadUssdPage(),
113+
),
114+
);
115+
},
116+
),
117+
SizedBox(
118+
height: 48,
119+
),
83120
MaterialButton(
84121
onPressed: () {
85122
Navigator.of(context).push(

lib/components/ussd_widget.dart

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'dart:convert';
2+
import 'dart:developer';
23

34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart' show rootBundle;
6+
import 'package:http/http.dart';
7+
import 'package:shared_preferences/shared_preferences.dart';
58

69
import 'package:todo/services/contacts.dart';
710
import 'package:todo/services/phone.dart';
@@ -22,10 +25,52 @@ class _UssdRootState extends State<UssdRootWidget> {
2225
}
2326

2427
Future<void> _loadData() async {
25-
final data = await rootBundle.loadString('config/ussd_codes.json');
26-
27-
final parsedJson = jsonDecode(data);
28-
28+
String data;
29+
Map<String, dynamic> parsedJson;
30+
try {
31+
var prefs = await SharedPreferences.getInstance();
32+
var lastHash = prefs.getString('hash');
33+
var lastDay = prefs.getInt('day');
34+
var actualDay = DateTime.now().day;
35+
if (lastDay == null || lastDay != actualDay) {
36+
try {
37+
var resp = await get(
38+
'https://todo-devs.github.io/todo-json/hash.json',
39+
headers: {
40+
'Accept-Encoding': 'gzip, deflate, br',
41+
},
42+
);
43+
if (resp.statusCode == 200) {
44+
var json = jsonDecode(utf8.decode(resp.bodyBytes));
45+
var actualHash = json['hash'];
46+
if (actualHash != lastHash) {
47+
var resp = await get(
48+
'https://todo-devs.github.io/todo-json/config.json',
49+
headers: {
50+
'Accept-Encoding': 'gzip, deflate, br',
51+
},
52+
);
53+
if (resp.statusCode == 200) {
54+
var body = utf8.decode(resp.bodyBytes);
55+
data = body;
56+
prefs.setString('hash', actualHash);
57+
prefs.setString('config', body);
58+
}
59+
}
60+
prefs.setInt('day', actualDay);
61+
}
62+
} catch (e) {
63+
log(e.toString());
64+
}
65+
}
66+
data ??= prefs.getString('config');
67+
data ??= await rootBundle.loadString('config/ussd_codes.json');
68+
parsedJson = jsonDecode(data);
69+
} catch (e) {
70+
log(e.toString());
71+
data = await rootBundle.loadString('config/ussd_codes.json');
72+
parsedJson = jsonDecode(data);
73+
}
2974
setState(() {
3075
items = UssdRoot.fromJson(parsedJson).items;
3176
});
@@ -41,14 +86,22 @@ class _UssdRootState extends State<UssdRootWidget> {
4186

4287
if (item.type == 'code')
4388
return Padding(
44-
padding: EdgeInsets.only(left: 14.0, right: 14.0),
89+
padding: EdgeInsets.only(
90+
left: 14.0,
91+
right: 14.0,
92+
top: index == 0 ? 10 : 0,
93+
),
4594
child: UssdWidget(
4695
ussdCode: item,
4796
),
4897
);
4998
else
5099
return Padding(
51-
padding: EdgeInsets.only(left: 14.0, right: 14.0),
100+
padding: EdgeInsets.only(
101+
left: 14.0,
102+
right: 14.0,
103+
top: index == 0 ? 10 : 0,
104+
),
52105
child: UssdCategoryWidget(
53106
category: item,
54107
),
@@ -145,14 +198,22 @@ class UssdWidgets extends StatelessWidget {
145198

146199
if (item.type == 'code')
147200
return Padding(
148-
padding: EdgeInsets.only(left: 14.0, right: 14.0),
201+
padding: EdgeInsets.only(
202+
left: 14.0,
203+
right: 14.0,
204+
top: index == 0 ? 10 : 0,
205+
),
149206
child: UssdWidget(
150207
ussdCode: item,
151208
),
152209
);
153210
else
154211
return Padding(
155-
padding: EdgeInsets.only(left: 14.0, right: 14.0),
212+
padding: EdgeInsets.only(
213+
left: 14.0,
214+
right: 14.0,
215+
top: index == 0 ? 10 : 0,
216+
),
156217
child: UssdCategoryWidget(
157218
category: item,
158219
),
@@ -330,7 +391,7 @@ class _CodeFormState extends State<CodeForm> {
330391
key: _formKey,
331392
child: ListView.builder(
332393
itemCount: widget.fields.length + 1,
333-
itemBuilder: (contex, index) {
394+
itemBuilder: (_, index) {
334395
if (index == widget.fields.length) {
335396
return Padding(
336397
padding: EdgeInsets.all(10.0),

lib/pages/download_ussd_page.dart

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import 'dart:convert';
2+
import 'dart:developer';
3+
4+
import 'package:flutter/cupertino.dart';
5+
import 'package:flutter/material.dart';
6+
import 'package:http/http.dart';
7+
import 'package:shared_preferences/shared_preferences.dart';
8+
import 'package:todo/models/ussd_codes.dart';
9+
import 'package:todo/pages/home_page.dart';
10+
import 'package:todo/themes/colors.dart';
11+
12+
class DownloadUssdPage extends StatefulWidget {
13+
@override
14+
_DownloadUssdPageState createState() => _DownloadUssdPageState();
15+
}
16+
17+
class _DownloadUssdPageState extends State<DownloadUssdPage> {
18+
var loading = true;
19+
var message = '';
20+
var buttonText = 'CANCELAR DESCARGA';
21+
22+
@override
23+
void initState() {
24+
super.initState();
25+
26+
_loadData();
27+
}
28+
29+
Future<void> _loadData() async {
30+
await Future.delayed(Duration(milliseconds: 1500));
31+
try {
32+
var prefs = await SharedPreferences.getInstance();
33+
var lastHash = prefs.getString('hash');
34+
var lastDay = prefs.getInt('day');
35+
var actualDay = DateTime.now().day;
36+
if (lastDay == null || lastDay != actualDay) {
37+
var resp = await get(
38+
'https://todo-devs.github.io/todo-json/hash.json',
39+
headers: {
40+
'Accept-Encoding': 'gzip, deflate, br',
41+
},
42+
);
43+
if (resp.statusCode == 200) {
44+
var json = jsonDecode(utf8.decode(resp.bodyBytes));
45+
var actualHash = json['hash'];
46+
if (actualHash != lastHash) {
47+
var resp = await get(
48+
'https://todo-devs.github.io/todo-json/config.json',
49+
headers: {
50+
'Accept-Encoding': 'gzip, deflate, br',
51+
},
52+
);
53+
if (resp.statusCode == 200) {
54+
var body = utf8.decode(resp.bodyBytes);
55+
var parsedJson = jsonDecode(body);
56+
UssdRoot.fromJson(parsedJson);
57+
prefs.setString('hash', actualHash);
58+
prefs.setString('config', body);
59+
} else {
60+
throw Exception(
61+
'Request failed: ${resp.request.url}\n'
62+
'StatusCode: ${resp.statusCode}\n'
63+
'Body: ${resp.body}',
64+
);
65+
}
66+
}
67+
prefs.setInt('day', actualDay);
68+
} else {
69+
throw Exception(
70+
'Request failed: ${resp.request.url}\n'
71+
'StatusCode: ${resp.statusCode}\n'
72+
'Body: ${resp.body}',
73+
);
74+
}
75+
}
76+
Navigator.pushReplacement(
77+
context,
78+
MaterialPageRoute(builder: (context) => HomePage(title: 'TODO')),
79+
);
80+
} catch (e) {
81+
log(e.toString());
82+
setState(() {
83+
loading = false;
84+
message = 'Ha ocurrido un error en la descarga de los códigos USSD.\n\n'
85+
'Revise su conexión e intentelo nuevamente.\n\n'
86+
'Si el error continúa póngase en contacto con el soporte para '
87+
'clientes.';
88+
buttonText = 'CERRAR';
89+
});
90+
}
91+
}
92+
93+
@override
94+
Widget build(BuildContext context) {
95+
return Scaffold(
96+
appBar: AppBar(
97+
title: Text(
98+
'Descarga',
99+
style: TextStyle(
100+
fontWeight: FontWeight.bold,
101+
),
102+
),
103+
centerTitle: true,
104+
),
105+
body: Center(
106+
child: Column(
107+
children: <Widget>[
108+
Expanded(
109+
child: Center(
110+
child: loading
111+
? CircularProgressIndicator()
112+
: Container(
113+
margin: EdgeInsets.all(30),
114+
child: Text(
115+
message,
116+
textAlign: TextAlign.center,
117+
style: TextStyle(
118+
fontWeight: FontWeight.bold,
119+
),
120+
),
121+
),
122+
),
123+
),
124+
Container(
125+
margin: EdgeInsets.all(30),
126+
child: MaterialButton(
127+
onPressed: () {
128+
Navigator.pushReplacement(
129+
context,
130+
MaterialPageRoute(
131+
builder: (context) => HomePage(title: 'TODO'),
132+
),
133+
);
134+
},
135+
color: GFColors.SUCCESS,
136+
minWidth: MediaQuery.of(context).size.width,
137+
elevation: 0.5,
138+
child: Text(
139+
buttonText,
140+
style: TextStyle(
141+
color: Colors.white,
142+
fontWeight: FontWeight.bold,
143+
),
144+
),
145+
),
146+
),
147+
],
148+
),
149+
),
150+
);
151+
}
152+
}

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ packages:
129129
source: hosted
130130
version: "0.13.4+2"
131131
http:
132-
dependency: transitive
132+
dependency: "direct main"
133133
description:
134134
name: http
135135
url: "https://pub.dartlang.org"

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies:
3838
webview_flutter: ^0.3.22+1
3939
get_ip: ^0.4.0
4040
provider: ^4.1.3
41+
http: ^0.12.0+4
4142

4243
# The following adds the Cupertino Icons font to your application.
4344
# Use with the CupertinoIcons class for iOS style icons.

0 commit comments

Comments
 (0)