diff --git a/POLICY.md b/POLICY.md new file mode 100644 index 00000000..c8003971 --- /dev/null +++ b/POLICY.md @@ -0,0 +1,44 @@ +高科校務通由國立高雄科技大學資訊研習社團隊(以下稱「團隊」)所提供。我們十分重視您的隱私權保護, +將依個人資料保護法及本隱私權政策蒐集、處理及利用您的個人資料,並且提供您對個人資料權利之行使與保護。 +若您不同意本隱私權政策之全部或部份者,請您停止使用本APP服務。 + +1. 本隱私權政策適用範圍 +=== +請您在於使用高科校務通服務前,確認您已審閱並同意本隱私權政策所列全部條款,若您不同意全部或部分者,則請勿使用本高科校務通服務。 + +本隱私權政策僅適用於本高科校務通對您個人資料所為蒐集、處理與利用,不及於其他非本團隊所有或控制之其他團隊或個人。您可能經由本高科校務通連結至第三人所經營之活動,各該活動為之個人資料蒐集係依其活動之隱私權政策規定處理,與本團隊無涉。 + +2.個人資料保護法應告知事項 +=== +1. 蒐集機關名稱:高科校務通團隊。 +2. 蒐集之目的:提供相關校務查詢服務,校車訂閱服務,缺曠課服務等。 +3. 個人資料類別: + * 識別類 (學號) + * 其他類 (使用偏好,系統自動紀錄之軌跡資訊等) + + +依據個人資料保護法第三條,您就您的個人資料享有以下權力: + * 查詢或請求閱覽。 + * 請求制給副本。 + * 請求補正或更正。 + * 請求停止蒐集、處理或利用。 + * 請求刪除。 + + + +3. 個人資料蒐集、處理及利用說明 +=== +高科校務通服務將利用您的國立高雄科技大學學號與密碼,登入校務系統、請假系統、與校車系統。 + +資料的處理將不會儲存在我們伺服器上,將直接轉發到使用者客戶端上。 + + +4. 隱私權政策之修改 +=== + +隱私權政策如經修改,將於本文公告。若您不同意該等變更或修改,請停止繼續使用本服務,並依本隱私權政策規定通知本團隊停止蒐集、處理及利用您的個人資料。 + +問題和建議 +=== + +如果您有任何問題或建議,請與我們聯繫。 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 7e65b279..6524077d 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -194,7 +194,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = 75S866VSMR; + DevelopmentTeam = R7BC26UNC9; LastSwiftMigration = 0910; ProvisioningStyle = Automatic; SystemCapabilities = { @@ -513,7 +513,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 75S866VSMR; + DEVELOPMENT_TEAM = R7BC26UNC9; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -547,7 +547,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 75S866VSMR; + DEVELOPMENT_TEAM = R7BC26UNC9; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 21a3cc14..6a624c49 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -7,4 +7,7 @@ + + diff --git a/lib/models/user_info.dart b/lib/models/user_info.dart index 2c0ebcd4..e296b294 100644 --- a/lib/models/user_info.dart +++ b/lib/models/user_info.dart @@ -9,14 +9,14 @@ class UserInfo { String message; UserInfo( - {this.educationSystem, - this.department, - this.className, - this.studentId, - this.studentNameCht, - this.studentNameEng, + {this.educationSystem = "", + this.department = "", + this.className = "", + this.studentId = "", + this.studentNameCht = "", + this.studentNameEng = "", this.status, - this.message}); + this.message = ""}); UserInfo.fromJson(Map json) { educationSystem = json['education_system']; @@ -41,4 +41,15 @@ class UserInfo { data['message'] = this.message; return data; } + + void setData(UserInfo userInfo) { + educationSystem = userInfo.educationSystem; + department = userInfo.department; + className = userInfo.className; + studentId = userInfo.studentId; + studentNameCht = userInfo.studentNameCht; + studentNameEng = userInfo.studentNameEng; + status = userInfo.status; + message = userInfo.message; + } } diff --git a/lib/pages/home/bus/bus_reservations_page.dart b/lib/pages/home/bus/bus_reservations_page.dart index 90b944fa..b3d5e9e2 100644 --- a/lib/pages/home/bus/bus_reservations_page.dart +++ b/lib/pages/home/bus/bus_reservations_page.dart @@ -76,8 +76,11 @@ class BusReservationsPageState extends State ), ); default: - return ListView( - children: busReservationWeights, + return RefreshIndicator( + onRefresh: () => _getBusReservations(), + child: ListView( + children: busReservationWeights, + ), ); } } diff --git a/lib/pages/home/bus/bus_reserve_page.dart b/lib/pages/home/bus/bus_reserve_page.dart index 2a43f625..70a8aa62 100644 --- a/lib/pages/home/bus/bus_reserve_page.dart +++ b/lib/pages/home/bus/bus_reserve_page.dart @@ -78,9 +78,12 @@ class BusReservePageState extends State ), ); default: - return ListView( - physics: const NeverScrollableScrollPhysics(), - children: _renderBusTimeWidgets(), + return RefreshIndicator( + onRefresh: () => _getBusTimeTables(), + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: _renderBusTimeWidgets(), + ), ); } } @@ -225,7 +228,7 @@ class BusReservePageState extends State SliverAppBar( leading: Container(), expandedHeight: orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.19 + ? MediaQuery.of(context).size.height * 0.20 : MediaQuery.of(context).size.width * 0.19, floating: true, backgroundColor: Colors.transparent, diff --git a/lib/pages/home/info/schedule_page.dart b/lib/pages/home/info/schedule_page.dart index 986d4dd5..ade8f7aa 100644 --- a/lib/pages/home/info/schedule_page.dart +++ b/lib/pages/home/info/schedule_page.dart @@ -114,12 +114,14 @@ class SchedulePageState extends State scheduleList = ScheduleData.toList(jsonArray); scheduleWeights.clear(); for (var i in scheduleList) scheduleWeights.addAll(_scheduleItem(i)); - setState(() { - if (scheduleList.length == 0) - state = _State.empty; - else - state = _State.finish; - }); + if (mounted) { + setState(() { + if (scheduleList.length == 0) + state = _State.empty; + else + state = _State.finish; + }); + } } } diff --git a/lib/pages/home/user_info_page.dart b/lib/pages/home/user_info_page.dart index 484a0617..093c25a3 100644 --- a/lib/pages/home/user_info_page.dart +++ b/lib/pages/home/user_info_page.dart @@ -1,6 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; +import 'package:nkust_ap/models/user_info.dart'; import 'package:nkust_ap/res/colors.dart' as Resource; import 'package:nkust_ap/utils/global.dart'; import 'package:nkust_ap/widgets/drawer_body.dart'; @@ -8,18 +9,26 @@ import 'package:nkust_ap/widgets/drawer_body.dart'; enum _Status { loading, finish, error, empty } class UserInfoPageRoute extends MaterialPageRoute { - UserInfoPageRoute() - : super(builder: (BuildContext context) => new UserInfoPage()); + final UserInfo userInfo; + + UserInfoPageRoute(this.userInfo) + : super( + builder: (BuildContext context) => + new UserInfoPage(userInfo: userInfo)); @override Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { - return new FadeTransition(opacity: animation, child: new UserInfoPage()); + return new FadeTransition( + opacity: animation, child: new UserInfoPage(userInfo: userInfo)); } } class UserInfoPage extends StatefulWidget { - static const String routerName = "/userInfo"; + static const String routerName = "/widget.userInfo"; + final UserInfo userInfo; + + const UserInfoPage({Key key, this.userInfo}) : super(key: key); @override UserInfoPageState createState() => new UserInfoPageState(); @@ -34,7 +43,7 @@ class UserInfoPageState extends State void initState() { super.initState(); FA.setCurrentScreen("UserInfoPage", "user_info_page.dart"); - if (userInfo == null) _getUserInfo(); + if (pictureUrl == null || pictureUrl.isEmpty) _getUserPicture(); } @override @@ -79,27 +88,27 @@ class UserInfoPageState extends State children: [ ListTile( title: Text(app.studentNameCht), - subtitle: Text(userInfo.studentNameCht), + subtitle: Text(widget.userInfo.studentNameCht), ), Divider(height: 1.0), ListTile( title: Text(app.educationSystem), - subtitle: Text(userInfo.educationSystem), + subtitle: Text(widget.userInfo.educationSystem), ), Divider(height: 1.0), ListTile( title: Text(app.department), - subtitle: Text(userInfo.department), + subtitle: Text(widget.userInfo.department), ), Divider(height: 1.0), ListTile( title: Text(app.studentClass), - subtitle: Text(userInfo.className), + subtitle: Text(widget.userInfo.className), ), Divider(height: 1.0), ListTile( title: Text(app.studentId), - subtitle: Text(userInfo.studentId), + subtitle: Text(widget.userInfo.studentId), ), ], ), @@ -145,29 +154,4 @@ class UserInfoPageState extends State } }); } - - _getUserInfo() { - setState(() { - state = _Status.loading; - }); - Helper.instance.getUsersInfo().then((response) { - if (this.mounted) { - setState(() { - userInfo = response; - _getUserPicture(); - state = _Status.finish; - }); - } - }).catchError((e) { - assert(e is DioError); - DioError dioError = e as DioError; - switch (dioError.type) { - case DioErrorType.RESPONSE: - Utils.handleResponseError(context, 'getUserInfo', mounted, e); - break; - default: - break; - } - }); - } } diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index e336f6d0..900261a7 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -36,6 +36,7 @@ class HomePageState extends State { int _currentTabIndex = 0; int _currentNewsIndex = 0; + UserInfo userInfo = UserInfo(); List newsWidgets = []; List newsList = []; @@ -47,6 +48,7 @@ class HomePageState extends State { super.initState(); FA.setCurrentScreen("HomePage", "home_page.dart"); _getAllNews(); + _getUserInfo(); } @override @@ -156,7 +158,7 @@ class HomePageState extends State { ) ], ), - drawer: DrawerBody(), + drawer: DrawerBody(userInfo: userInfo), body: OrientationBuilder(builder: (_, orientation) { return Container( padding: EdgeInsets.symmetric( @@ -272,6 +274,30 @@ class HomePageState extends State { }); } + _getUserInfo() { + Helper.instance.getUsersInfo().then((response) { + if (this.mounted) { + setState(() { + userInfo = response; + }); + FA.setUserProperty('department', userInfo.department); + FA.setUserId(userInfo.studentId); + } + }).catchError((e) { + if (e is DioError) { + switch (e.type) { + case DioErrorType.RESPONSE: + Utils.handleResponseError(context, 'getUserInfo', mounted, e); + break; + default: + break; + } + } else { + throw e; + } + }); + } + void _showLogoutDialog() { showDialog( context: context, diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index af6f60e3..ead17e18 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -436,7 +436,6 @@ class LoginPageState extends State setState(() { isAutoLogin = false; pictureUrl = ""; - userInfo = null; }); } } diff --git a/lib/utils/firebase_analytics_utils.dart b/lib/utils/firebase_analytics_utils.dart index 8c43e27e..0a8d66f9 100644 --- a/lib/utils/firebase_analytics_utils.dart +++ b/lib/utils/firebase_analytics_utils.dart @@ -31,7 +31,7 @@ class FA { static Future logApiEvent(String type, int status) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); await analytics.logEvent( - name: 'ap-api', + name: 'ap_api', parameters: { 'type': type, 'status': status, @@ -45,7 +45,7 @@ class FA { static Future logAESErrorEvent(String encryptPassword) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); await analytics.logEvent( - name: 'aes-error', + name: 'aes_error', parameters: { 'type': encryptPassword, 'version': packageInfo.version, diff --git a/lib/widgets/default_dialog.dart b/lib/widgets/default_dialog.dart index 26e7e3c1..a1d52b8e 100644 --- a/lib/widgets/default_dialog.dart +++ b/lib/widgets/default_dialog.dart @@ -12,7 +12,7 @@ class DefaultDialog extends StatelessWidget { this.title, this.contentWidget, this.actionText, - this.actionFunction}) + @required this.actionFunction}) : super(key: key); static showSample(BuildContext context) => showDialog( diff --git a/lib/widgets/drawer_body.dart b/lib/widgets/drawer_body.dart index fb101682..271f4c6d 100644 --- a/lib/widgets/drawer_body.dart +++ b/lib/widgets/drawer_body.dart @@ -7,14 +7,16 @@ import 'package:nkust_ap/models/models.dart'; import 'package:nkust_ap/pages/page.dart'; import 'package:nkust_ap/res/resource.dart' as Resource; import 'package:nkust_ap/utils/app_localizations.dart'; -import 'package:nkust_ap/utils/firebase_analytics_utils.dart'; import 'package:nkust_ap/utils/utils.dart'; import 'package:shared_preferences/shared_preferences.dart'; var pictureUrl = ""; -UserInfo userInfo; class DrawerBody extends StatefulWidget { + final UserInfo userInfo; + + const DrawerBody({Key key, this.userInfo}) : super(key: key); + @override DrawerBodyState createState() => new DrawerBodyState(); } @@ -34,7 +36,6 @@ class DrawerBodyState extends State { super.initState(); _getPreference(); _getUserPicture(); - _getUserInfo(); } @override @@ -56,11 +57,15 @@ class DrawerBodyState extends State { width: double.infinity, child: GestureDetector( onTap: () { - if (userInfo == null) return; - if ((userInfo.status == null ? 200 : userInfo.status) == 200) - Navigator.of(context).push(UserInfoPageRoute()); + if (widget.userInfo == null) return; + if ((widget.userInfo.status == null + ? 200 + : widget.userInfo.status) == + 200) + Navigator.of(context) + .push(UserInfoPageRoute(widget.userInfo)); else - Utils.showToast(userInfo.message); + Utils.showToast(widget.userInfo.message); }, child: Stack( children: [ @@ -111,10 +116,10 @@ class DrawerBodyState extends State { SizedBox( height: 32.0, child: Text( - userInfo == null + widget.userInfo == null ? " \n " - : "${userInfo.studentNameCht}\n" - "${userInfo.studentId}", + : "${widget.userInfo.studentNameCht}\n" + "${widget.userInfo.studentId}", style: TextStyle(color: Colors.white), ), ), @@ -270,30 +275,6 @@ class DrawerBodyState extends State { }); } - _getUserInfo() { - Helper.instance.getUsersInfo().then((response) { - if (this.mounted) { - setState(() { - userInfo = response; - FA.setUserProperty('department', userInfo.department); - FA.setUserId(userInfo.studentId); - }); - } - }).catchError((e) { - if (e is DioError) { - switch (e.type) { - case DioErrorType.RESPONSE: - Utils.handleResponseError(context, 'getUserInfo', mounted, e); - break; - default: - break; - } - } else { - throw e; - } - }); - } - _getPreference() async { prefs = await SharedPreferences.getInstance(); setState(() { diff --git a/lib/widgets/yes_no_dialog.dart b/lib/widgets/yes_no_dialog.dart index 94761baf..5fbb6cc9 100644 --- a/lib/widgets/yes_no_dialog.dart +++ b/lib/widgets/yes_no_dialog.dart @@ -95,7 +95,7 @@ class YesNoDialog extends StatelessWidget { ), onTap: () { Navigator.of(context, rootNavigator: true).pop('dialog'); - leftActionFunction(); + if (leftActionFunction != null) leftActionFunction(); }, ), ), @@ -117,7 +117,7 @@ class YesNoDialog extends StatelessWidget { ), onTap: () { Navigator.of(context, rootNavigator: true).pop('dialog'); - rightActionFunction(); + if (rightActionFunction != null) rightActionFunction(); }, ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 6cb4f7a4..d107be22 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: nkust_ap description: A new Flutter application. -version: 3.1.1+30101 +version: 3.1.2+30102 environment: sdk: ">=2.1.0 <3.0.0" @@ -24,8 +24,7 @@ dependencies: dio: 2.0.11 fluttertoast: ^2.2.11 tuple: ^1.0.1 - carousel_slider: - path: ../flutter_carousel_slider + carousel_slider: ^1.2.0 flutter_crashlytics: 0.1.1 encrypt: ^2.0.0 flutter_local_notifications: ^0.4.5