Skip to content

Commit

Permalink
대회탭 디자인 변경 및 개선 (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
w8385 authored Sep 6, 2023
1 parent e3123a2 commit dc2b77a
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 581 deletions.
Binary file added my_solved/lib/assets/venues/ac arena.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions my_solved/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class PageRouterState extends State<PageRouter> {
),
theme: const CupertinoThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: Color(0xFFF9F9F9),
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(
fontFamily: 'Pretendard',
Expand Down
44 changes: 44 additions & 0 deletions my_solved/lib/models/contest.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:html/dom.dart';

class Contest {
final String venue;
final String name;
Expand All @@ -12,4 +14,46 @@ class Contest {
required this.startTime,
required this.endTime,
});

factory Contest.fromElement(Element element) {
String? url;
try {
url = element
.getElementsByTagName('td')[1]
.getElementsByTagName('a')[0]
.attributes['href'];
} catch (e) {
url = null;
}
List<String> startTimeList = element
.getElementsByTagName('td')[2]
.text
.toString()
.replaceAll('년', '')
.replaceAll('월', '')
.replaceAll('일', '')
.split(' ');
DateTime startTime = DateTime.parse(
"${startTimeList[0].padLeft(4, "0")}-${startTimeList[1].padLeft(2, "0")}-${startTimeList[2].padLeft(2, "0")}T${startTimeList[3].padLeft(2, "0")}:00+09:00")
.toLocal();
List<String> endTimeList = element
.getElementsByTagName('td')[3]
.text
.toString()
.replaceAll('년', '')
.replaceAll('월', '')
.replaceAll('일', '')
.split(' ');
DateTime endTime = DateTime.parse(
"${endTimeList[0].padLeft(4, "0")}-${endTimeList[1].padLeft(2, "0")}-${endTimeList[2].padLeft(2, "0")}T${endTimeList[3].padLeft(2, "0")}:00+09:00")
.toLocal();

return Contest(
venue: element.getElementsByTagName('td')[0].text,
name: element.getElementsByTagName('td')[1].text,
url: url,
startTime: startTime,
endTime: endTime,
);
}
}
8 changes: 7 additions & 1 deletion my_solved/lib/services/contest_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ContestService extends ChangeNotifier {

bool _disposed = false;

Map showVenues = {
Map<String, bool> showVenues = {
'AtCoder': false,
'BOJ Open': false,
'Codeforces': false,
Expand All @@ -37,10 +37,12 @@ class ContestService extends ChangeNotifier {

Future<void> init() async {
await _initializeContest();
notifyListeners();
}

Future<void> _initializeContest() async {
initContestShow();
notifyListeners();
}

Future<void> initContestShow() async {
Expand All @@ -52,6 +54,10 @@ class ContestService extends ChangeNotifier {
notifyListeners();
}

Future<Map<String, bool>> getContestShow() async {
return showVenues;
}

Future<void> toggleContestShow(String venue) async {
final prefs = await SharedPreferences.getInstance();
final show = prefs.getBool('show$venue') ?? false;
Expand Down
120 changes: 116 additions & 4 deletions my_solved/lib/services/network_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import 'package:my_solved/models/user/organizations.dart';
import 'package:my_solved/models/user/tag_ratings.dart';
import 'package:my_solved/models/user/top_100.dart';

import '../models/contest.dart';

class NetworkService {
static final NetworkService _instance = NetworkService._privateConstructor();

Expand Down Expand Up @@ -210,14 +212,124 @@ class NetworkService {
}
}

Future<dom.Document> requestContests() async {
final response =
Future<List<List<Contest>>> requestContests() async {
List<Contest> upcomingContests(dom.Element element) {
if (element.getElementsByClassName('col-md-12').length < 5) {
return element
.getElementsByClassName('col-md-12')[2]
.getElementsByTagName('tbody')
.first
.getElementsByTagName('tr')
.toList()
.map((e) {
return Contest.fromElement(e);
}).toList();
} else {
return element
.getElementsByClassName('col-md-12')[4]
.getElementsByTagName('tbody')
.first
.getElementsByTagName('tr')
.toList()
.map<Contest>((e) {
return Contest.fromElement(e);
}).toList();
}
}

List<Contest> ongoingContests(dom.Element element) {
if (element.getElementsByClassName('col-md-12').length < 5) {
return element
.getElementsByClassName('col-md-12')[2]
.getElementsByTagName('tbody')
.first
.getElementsByTagName('tr')
.toList()
.map((e) {
return Contest.fromElement(e);
}).toList();
} else {
return [];
}
}

List<Contest> endedContests(dom.Element element) {
final endedContestList = element
.getElementsByClassName('col-md-12')[1]
.getElementsByTagName('tbody')
.first
.getElementsByTagName('tr')
.where(
(element) => element.getElementsByTagName('td')[5].text == '종료')
.toList();

return endedContestList.map((e) {
List<String> startTimeList = element
.getElementsByTagName('td')[3]
.text
.toString()
.replaceAll('년', '')
.replaceAll('월', '')
.replaceAll('일', '')
.split(' ');
DateTime startTime = DateTime.parse(
"${startTimeList[0].padLeft(4, "0")}-${startTimeList[1].padLeft(2, "0")}-${startTimeList[2].padLeft(2, "0")}T${startTimeList[3].padLeft(2, "0")}:00+09:00")
.toLocal();
List<String> endTimeList = element
.getElementsByTagName('td')[4]
.text
.toString()
.replaceAll('년', '')
.replaceAll('월', '')
.replaceAll('일', '')
.split(' ');
DateTime endTime = DateTime.parse(
"${endTimeList[0].padLeft(4, "0")}-${endTimeList[1].padLeft(2, "0")}-${endTimeList[2].padLeft(2, "0")}T${endTimeList[3].padLeft(2, "0")}:00+09:00")
.toLocal();

return Contest(
venue: 'BOJ Open',
name: e.getElementsByTagName('td')[0].text.trim(),
url:
'https://www.acmicpc.net${e.getElementsByTagName('td')[0].getElementsByTagName('a')[0].attributes['href']}',
startTime: startTime,
endTime: endTime,
);
}).toList();
}

final others =
await http.get(Uri.parse("https://www.acmicpc.net/contest/other/list"));
dom.Document docOthers = parser.parse(others.body);

final ended = await http
.get(Uri.parse("https://www.acmicpc.net/contest/official/list"));
dom.Document docEnded = parser.parse(ended.body);

return [
ongoingContests(docOthers.body!),
upcomingContests(docOthers.body!),
endedContests(docEnded.body!),
];
}

Future<Set<int>> requestArenaContests() async {
final response =
await http.get(Uri.parse("https://solved.ac/api/v3/arena/contests"));
final statusCode = response.statusCode;

if (statusCode == 200) {
dom.Document document = parser.parse(response.body);
return document;
Map<String, dynamic> contestMap = jsonDecode(response.body);
Set<int> contestIds = {};

for (var contests in contestMap.values) {
for (var contest in contests) {
if (contest['arenaBojContestId'] != null) {
contestIds.add(contest['arenaBojContestId']);
}
}
}
return contestIds;
} else {
throw Exception('Fail to load');
}
Expand Down
Loading

0 comments on commit dc2b77a

Please sign in to comment.