Skip to content

Commit

Permalink
fix: handling inconsistencies with API and better failure handling, a…
Browse files Browse the repository at this point in the history
…lso supporting Toph partially
  • Loading branch information
pavan-kalyan committed Jan 23, 2022
1 parent 4d91986 commit ac14fa0
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 160 deletions.
2 changes: 1 addition & 1 deletion .flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.5.1/","dependencies":[]},{"name":"shared_preferences","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.1+2/","dependencies":[]},{"name":"url_launcher","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-3.0.3/","dependencies":[]}],"android":[{"name":"path_provider","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.5.1/","dependencies":[]},{"name":"shared_preferences","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.1+2/","dependencies":[]},{"name":"url_launcher","path":"/home/pavan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-3.0.3/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":[]},{"name":"url_launcher","dependencies":[]}],"date_created":"2020-05-17 14:36:24.405398","version":"1.18.0-11.1.pre"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.28/","dependencies":[]},{"name":"shared_preferences","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.12+4/","dependencies":[]},{"name":"url_launcher","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.5/","dependencies":[]}],"android":[{"name":"path_provider","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.28/","dependencies":[]},{"name":"shared_preferences","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.12+4/","dependencies":[]},{"name":"url_launcher","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.5/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"shared_preferences_macos","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+11/","dependencies":[]},{"name":"url_launcher_macos","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-2.0.3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"shared_preferences_linux","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-0.0.2+4/","dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-2.0.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.5/","dependencies":[]},{"name":"shared_preferences_windows","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_windows-0.0.2+3/","dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-2.0.2/","dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]},{"name":"url_launcher_web","path":"/home/pavan/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.6/","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_linux","shared_preferences_macos","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2022-01-23 05:51:35.050130","version":"2.8.1"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*___Generated_by_IDEA___*/

package com.example.kontests;

/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
public final class BuildConfig {
public final static boolean DEBUG = Boolean.parseBoolean(null);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*___Generated_by_IDEA___*/

package com.example.kontests;

/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
public final class BuildConfig {
public final static boolean DEBUG = Boolean.parseBoolean(null);
}
19 changes: 14 additions & 5 deletions lib/Contest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class Contests {
factory Contests.fromJson(List<dynamic> parsedJson) {
List<Contest> contests = new List<Contest>();

contests = parsedJson.map((i) => Contest.fromJson(i)).toList();
if (parsedJson != null) {
contests = parsedJson.map((i) => Contest.fromJson(i)).toList();
}
return new Contests(
contests: contests,
);
Expand Down Expand Up @@ -46,17 +48,24 @@ class Contest {
return Contest(
name: json['name'],
url: json['url'],
start_time: new DateFormat("yyyy-MM-ddTHH:mm:ss.SSSZ")
.parseUtc(json['start_time']),
end_time:
new DateFormat("yyyy-MM-ddTHH:mm:ss.SSSZ").parseUtc(json['end_time']),
start_time: retrieveDateTime(json['site'], json['start_time']),
end_time: retrieveDateTime(json['site'], json['end_time']),
duration: json['duration'],
site: json['site'],
in_24_hours: within_24,
status: json['status'],
);
}

static DateTime retrieveDateTime(String site, String timeInputString) {
try {
return new DateFormat("yyyy-MM-ddTHH:mm:ss.SSSZ")
.parseUtc(timeInputString);
} on FormatException {
return new DateFormat("yyyy-MM-dd HH:mm:ss Z").parseUtc(timeInputString);
}
}

String getName() {
return name;
}
Expand Down
6 changes: 5 additions & 1 deletion lib/ContestServices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Future<Contest> loadContest() async {

Future<Contests> loadContests(String site, bool refreshing) async {
final path = (await getApplicationDocumentsDirectory()).path;
//exception for TOPH as the API for this currently does not exist.
if (site.toUpperCase() == 'TOPH') {
return Contests.fromJson(null);
}
final contests = HttpNetworkResource(
url: 'https://kontests.net/api/v1/' + site,
parser: (contents) => json.decode(contents),
Expand All @@ -29,4 +33,4 @@ Future<Contests> loadContests(String site, bool refreshing) async {
final myData = await contests.get(forceReload: refreshing);

return Contests.fromJson(myData);
}
}
228 changes: 105 additions & 123 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,6 @@ class MyApp extends StatelessWidget {
}
}

_launchURL(String url) async {
String launchURL = url;
if (await canLaunch(launchURL)) {
await launch(launchURL);
} else {
throw 'Could not launch $launchURL';
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
Expand Down Expand Up @@ -80,124 +71,111 @@ class _MyHomePageState extends State<MyHomePage> {

@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 10,
child: Scaffold(
drawer: Drawer(
child: Column(
children: [
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text("Kontests Unofficial App",
style: TextStyle(color: Colors.white, fontSize:24),),
),
ListTile(
leading: new Container(
padding: EdgeInsets.all(2),
child: new LayoutBuilder(builder: (context, constraint) {
return new Icon(FlutterIcons.mark_github_oct, size: constraint.biggest.height);
}),
),
title: Text("Developer"),
subtitle: Text("github/pavan-kalyan"),
onTap: () => launch("https://github.com/pavan-kalyan"),
return FutureBuilder<Sites>(
future: sites,
builder: (context, snapshot) {
var _numOfSites = 11;
if (snapshot.hasData) {
_numOfSites = snapshot.data.sites.length;
}

return DefaultTabController(
length: _numOfSites,
child: Scaffold(
drawer: Drawer(
child: Column(children: [
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text(
"Kontests Unofficial App",
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
ListTile(
leading: new Container(
padding: EdgeInsets.all(2),
child: new LayoutBuilder(
builder: (context, constraint) {
return new Icon(FlutterIcons.mark_github_oct,
size: constraint.biggest.height);
}),
),
title: Text("Developer"),
subtitle: Text("github/pavan-kalyan"),
onTap: () =>
launch("https://github.com/pavan-kalyan"),
),
],
),
),
],
),
),
Divider(),
Divider(),
Container(
child: Center(
child: ListTile(
title: Text("Made in Flutter",
style: TextStyle(fontWeight: FontWeight.w900))
),
)
)
]
)
),
appBar: AppBar(
title: Text("Kontests Unofficial"),
bottom: PreferredSize(
preferredSize: Size.fromHeight(50.0),
child: FutureBuilder<Sites>(
child: Center(
child: ListTile(
title: Text("Made in Flutter",
style: TextStyle(fontWeight: FontWeight.w900))),
))
])),
appBar: AppBar(
title: Text("Kontests Unofficial"),
bottom: PreferredSize(
preferredSize: Size.fromHeight(50.0),
child: FutureBuilder<Sites>(
future: sites,
builder: (context, snapshot) {
if (snapshot.hasData) {
return TabBar(
isScrollable: true,
tabs: List<Widget>.generate(
snapshot.data.sites.length, (int index) {
return new Tab(
text: snapshot.data.sites[index].name,
);
}));
}
return TabBar(
isScrollable: true,
tabs: <Widget>[
Text('Codeforces'),
Text('TopCoder'),
Text('AtCoder'),
Text('CS Academy'),
Text('CodeChef'),
Text('HackerEarth'),
Text('Kick Start'),
Text('LeetCode'),
Text('HackerRank'),
Text('Codeforces:gym'),
Text('Toph'),
],
);
},
))),
body: FutureBuilder<Sites>(
future: sites,
builder: (context, snapshot) {
if (snapshot.hasData) {
return TabBar(
isScrollable: true,
tabs: List<Widget>.generate(
return TabBarView(
children: List<Widget>.generate(
snapshot.data.sites.length, (int index) {
return new Tab(
text: snapshot.data.sites[index].name,
);
}));
return ContestList(
site: snapshot.data.sites[index].uname,
);
}));
}
return TabBar(
isScrollable: true,
tabs: <Widget>[
Text('Codeforces'),
Text('TopCoder'),
Text('AtCoder'),
Text('CS Academy'),
Text('CodeChef'),
Text('HackerEarth'),
Text('Kick Start'),
Text('LeetCode'),
Text('HackerRank'),
Text('Codeforces:gym'),
],
return TabBarView(
children:
List<Widget>.generate(_numOfSites, (int index) {
return Center(child: CircularProgressIndicator());
}),
);
},
))),
body: FutureBuilder<Sites>(
future: sites,
builder: (context, snapshot) {
if (snapshot.hasData) {
return TabBarView(
children: List<Widget>.generate(
snapshot.data.sites.length, (int index) {
return ContestList(
site: snapshot.data.sites[index].uname,
);
}));
}
return TabBarView(
children: List<Widget>.generate(10, (int index) {
return Center(child: CircularProgressIndicator());
}),
);
}
/*
TabBarView(
children: <Widget>[
ContestList(site: 'codeforces'),
ContestList(site: 'at_coder'),
ContestList(site: 'leet_code'),
ContestList(site: 'top_coder'),
ContestList(site: 'at_coder'),
ContestList(site: 'leet_code'),
ContestList(site: 'top_coder'),
ContestList(site: 'at_coder'),
ContestList(site: 'leet_code'),
ContestList(site: 'top_coder'),
ContestList(site: 'top_coder'),
],
)
*/
),
));
}

Future<Null> _handleRefresh() async {
setState(() => refreshing = true);
refreshing = false;
}),
));
});
}
}

Expand All @@ -207,6 +185,7 @@ class ContestList extends StatefulWidget {
ContestList({
this.site,
});

@override
createState() => _ContestListState();
}
Expand Down Expand Up @@ -259,9 +238,12 @@ class _ContestListState extends State<ContestList>
TimeOfDay timepicked =
TimeOfDay.fromDateTime(startDateTime);
String hour = timepicked.hourOfPeriod.toString();

String minute = timepicked.minute<10 ? '0'+timepicked.minute.toString():timepicked.minute.toString();
String meridiem = timepicked.period.index == 0 ? 'am': 'pm';

String minute = timepicked.minute < 10
? '0' + timepicked.minute.toString()
: timepicked.minute.toString();
String meridiem =
timepicked.period.index == 0 ? 'am' : 'pm';

return ListTile(
title: Text(snapshot.data.contests[index].name),
Expand All @@ -272,7 +254,7 @@ class _ContestListState extends State<ContestList>
' ' +
hour +
':' +
minute +
minute +
' ' +
meridiem),
);
Expand Down
Loading

0 comments on commit ac14fa0

Please sign in to comment.