diff --git a/assets/translations/en.json b/assets/translations/en.json index 876cf46d..98263701 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -5,7 +5,8 @@ "cancel": "Cancel", "delete": "Delete", "add": "Add", - "reset": "Reset", + "reset": "Clear", + "reset_all": "Clear All", "search": "Search", "upload": "Upload", "edit": "Edit", @@ -14,7 +15,9 @@ "no_result": "No result.", "select_all": "Select All", "unselect_all": "Unselect All", - "no_info": "No information" + "no_info": "No information", + "all_selected": "All Selected", + "num_selected": " Selected" }, "semester": { "spring": "Spring", diff --git a/assets/translations/ko.json b/assets/translations/ko.json index e5ecf7b7..6fa9f1b6 100644 --- a/assets/translations/ko.json +++ b/assets/translations/ko.json @@ -6,6 +6,7 @@ "delete": "삭제", "add": "추가하기", "reset": "초기화", + "reset_all": "전체 초기화", "search": "검색", "upload": "업로드", "edit": "수정", @@ -14,7 +15,9 @@ "no_result": "검색 결과가 없습니다.", "select_all": "모두 선택", "unselect_all": "모두 해제", - "no_info": "정보 없음" + "no_info": "정보 없음", + "all_selected": "전체 선택됨", + "num_selected": "개 선택됨" }, "semester": { "spring": "봄", diff --git a/lib/main.dart b/lib/main.dart index c1cf01ba..3bd9f187 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -103,6 +103,12 @@ class OTLFirebaseApp extends StatelessWidget { SystemUiOverlayStyle(statusBarColor: Colors.transparent)); return MaterialApp( + builder: (context, child) { + return ScrollConfiguration( + behavior: NoEndOfScrollBehavior(), + child: child ?? Container(), + ); + }, localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, @@ -160,3 +166,11 @@ class OTLFirebaseApp extends StatelessWidget { ); } } + +class NoEndOfScrollBehavior extends ScrollBehavior { + @override + Widget buildOverscrollIndicator( + BuildContext context, Widget child, ScrollableDetails details) { + return child; + } +} diff --git a/lib/models/filter.dart b/lib/models/filter.dart index 16430700..dc66f33b 100644 --- a/lib/models/filter.dart +++ b/lib/models/filter.dart @@ -14,5 +14,5 @@ class CodeLabelPair { final String code; final String label; bool selected; - CodeLabelPair({required this.code, this.label = "", this.selected = true}); + CodeLabelPair({required this.code, this.label = "", this.selected = false}); } diff --git a/lib/pages/course_search_page.dart b/lib/pages/course_search_page.dart index 7d98db53..ceb7373c 100644 --- a/lib/pages/course_search_page.dart +++ b/lib/pages/course_search_page.dart @@ -108,7 +108,7 @@ class _CourseSearchPageState extends State { context.read().resetCourseFilter(); }, child: Text( - "common.reset".tr(), + "common.reset_all".tr(), style: bodyBold.copyWith(color: OTLColor.pinksMain), ), style: ButtonStyle( diff --git a/lib/pages/lecture_search_page.dart b/lib/pages/lecture_search_page.dart index 82608d03..8713d6c5 100644 --- a/lib/pages/lecture_search_page.dart +++ b/lib/pages/lecture_search_page.dart @@ -108,7 +108,7 @@ class _LectureSearchPageState extends State { context.read().resetLectureFilter(); }, child: Text( - "common.reset".tr(), + "common.reset_all".tr(), style: bodyBold.copyWith(color: OTLColor.pinksMain), ), style: ButtonStyle( diff --git a/lib/pages/timetable_page.dart b/lib/pages/timetable_page.dart index 95fcd4fb..26fa50b0 100644 --- a/lib/pages/timetable_page.dart +++ b/lib/pages/timetable_page.dart @@ -74,9 +74,6 @@ class _TimetablePageState extends State { GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { - context - .read() - .resetLectureFilter(); Navigator.push( context, buildLectureSearchPageRoute()); }, diff --git a/lib/providers/course_search_model.dart b/lib/providers/course_search_model.dart index 7e98d9bd..46f9c52a 100644 --- a/lib/providers/course_search_model.dart +++ b/lib/providers/course_search_model.dart @@ -121,7 +121,7 @@ class CourseSearchModel extends ChangeNotifier { _courseSearchText = ''; _courseFilter.values.forEach((e) { if (e.isMultiSelect) - e.options.forEach((b) => b.forEach((c) => c.selected = true)); + e.options.forEach((b) => b.forEach((c) => c.selected = false)); else { e.options.forEach((b) => b.forEach((c) => c.selected = false)); e.options.first.first.selected = true; @@ -191,7 +191,7 @@ class CourseSearchModel extends ChangeNotifier { if (v.options.expand((i) => i).every((i) => i.selected == false)) { if (v.isMultiSelect == true) v.options.expand((i) => i).forEach((j) { - j.selected = true; + // j.selected = true; }); else v.options.first.first.selected = true; @@ -200,7 +200,7 @@ class CourseSearchModel extends ChangeNotifier { List dep = _courseFilter['departments']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _courseFilter['departments']! .options @@ -210,7 +210,7 @@ class CourseSearchModel extends ChangeNotifier { List typ = _courseFilter['types']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _courseFilter['types']! .options @@ -220,7 +220,7 @@ class CourseSearchModel extends ChangeNotifier { List lev = _courseFilter['levels']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _courseFilter['levels']! .options diff --git a/lib/providers/lecture_search_model.dart b/lib/providers/lecture_search_model.dart index 22c03c6c..6f72b76b 100644 --- a/lib/providers/lecture_search_model.dart +++ b/lib/providers/lecture_search_model.dart @@ -105,7 +105,7 @@ class LectureSearchModel extends ChangeNotifier { _lectureSearchText = ''; _lectureFilter.values.forEach((e) { if (e.isMultiSelect) - e.options.forEach((b) => b.forEach((c) => c.selected = true)); + e.options.forEach((b) => b.forEach((c) => c.selected = false)); else { e.options.forEach((b) => b.forEach((c) => c.selected = false)); e.options.first.first.selected = true; @@ -212,7 +212,7 @@ class LectureSearchModel extends ChangeNotifier { if (v.options.expand((i) => i).every((i) => i.selected == false)) { if (v.isMultiSelect == true) v.options.expand((i) => i).forEach((j) { - j.selected = true; + // j.selected = true; }); else v.options.first.first.selected = true; @@ -221,7 +221,7 @@ class LectureSearchModel extends ChangeNotifier { List dep = _lectureFilter['departments']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _lectureFilter['departments']! .options @@ -231,7 +231,7 @@ class LectureSearchModel extends ChangeNotifier { List typ = _lectureFilter['types']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _lectureFilter['types']! .options @@ -241,7 +241,7 @@ class LectureSearchModel extends ChangeNotifier { List lev = _lectureFilter['levels']! .options .expand((i) => i) - .every((i) => i.selected == true) + .every((i) => i.selected == false) ? [] : _lectureFilter['levels']! .options diff --git a/lib/widgets/search_filter_panel.dart b/lib/widgets/search_filter_panel.dart index c4be8a56..48ecfb10 100644 --- a/lib/widgets/search_filter_panel.dart +++ b/lib/widgets/search_filter_panel.dart @@ -1,5 +1,4 @@ import 'dart:math' as math; - import 'package:easy_localization/easy_localization.dart' as _; import 'package:flutter/material.dart'; import 'package:otlplus/constants/color.dart'; @@ -95,40 +94,60 @@ class _SelectorState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - widget.title, - style: titleBold, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + widget.title, + style: titleBold, + ), + SizedBox(width: 8), + Visibility( + visible: widget.isMultiSelect, + child: Text.rich( + TextSpan( + children: widget.selectList + .expand((i) => i) + .where((i) => i.selected) + .length == + 0 + ? [TextSpan(text: "common.all_selected".tr())] + : [ + TextSpan( + text: widget.selectList + .expand((i) => i) + .where((i) => i.selected) + .length + .toString(), + ), + TextSpan(text: "common.num_selected".tr()), + ], + style: bodyRegular, + ), + ), + ) + ], ), Visibility( - visible: widget.isMultiSelect, + visible: widget.isMultiSelect && + !widget.selectList.every( + (v) => v.every((w) => w.selected == false), + ), child: IconTextButton( onTap: () { - if (widget.selectList - .every((v) => v.every((w) => w.selected == true))) { - widget.selectList.forEach((v) { - v.forEach((w) { - widget.setFilter(w.code, false); - }); - }); - } else { - widget.selectList.forEach((v) { - v.forEach((w) { - widget.setFilter(w.code, true); - }); + widget.selectList.forEach((v) { + v.forEach((w) { + widget.setFilter(w.code, false); }); - } + }); }, - text: widget.selectList.every( - (v) => v.every((w) => w.selected == true), - ) - ? "common.unselect_all".tr() - : "common.select_all".tr(), + text: "common.reset".tr(), textStyle: bodyRegular.copyWith( color: OTLColor.pinksMain, decoration: TextDecoration.underline, ), ), - ) + ), ], ), ),