diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh index 6f319d3d..1b5e8f22 100755 --- a/ios/Flutter/flutter_export_environment.sh +++ b/ios/Flutter/flutter_export_environment.sh @@ -2,10 +2,9 @@ # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=/Users/rainvisitor/development/flutter" export "FLUTTER_APPLICATION_PATH=/Users/rainvisitor/Documents/GitHub-NKUST-ITC/NKUST-AP-Flutter" -export "FLUTTER_TARGET=/Users/rainvisitor/Documents/GitHub-NKUST-ITC/NKUST-AP-Flutter/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build/ios" -export "FLUTTER_FRAMEWORK_DIR=/Users/rainvisitor/development/flutter/bin/cache/artifacts/engine/ios" -export "FLUTTER_BUILD_NAME=3.2.6" -export "FLUTTER_BUILD_NUMBER=30206" -export "TRACK_WIDGET_CREATION=true" +export "FLUTTER_FRAMEWORK_DIR=/Users/rainvisitor/development/flutter/bin/cache/artifacts/engine/ios-release" +export "FLUTTER_BUILD_NAME=3.2.8" +export "FLUTTER_BUILD_NUMBER=30208" diff --git a/lib/api/helper.dart b/lib/api/helper.dart index 77214f32..dc42476f 100644 --- a/lib/api/helper.dart +++ b/lib/api/helper.dart @@ -56,7 +56,7 @@ class Helper { Helper() { options = new BaseOptions( - baseUrl: 'https://$HOST:$PORT', + baseUrl: 'https://$HOST:$PORT/$VERSION', connectTimeout: 10000, receiveTimeout: 10000, ); @@ -441,7 +441,8 @@ class Helper { 'leavesData': data.toJson(), 'leavesProof': image == null ? null - : UploadFileInfo(image, image.path.split('/').last), + : MultipartFile.fromFile(image.path, + filename: image.path.split('/').last), }, cancelToken: cancelToken, ); diff --git a/lib/config/constants.dart b/lib/config/constants.dart index f19b53f6..b0cdb86c 100644 --- a/lib/config/constants.dart +++ b/lib/config/constants.dart @@ -73,4 +73,7 @@ class Constants { static const DONATE_URL = 'https://payment.ecpay.com.tw/QuickCollect/PayData?mLM7iy8RpUGk%2fyBotSDMdvI0qGI5ToToqBW%2bOQbOE80%3d'; + + static const MAX_IMAGE_SIZE = 4.0; + static const IMAGE_RESIZE_RATE = 2.5; } diff --git a/lib/models/leaves_campus_data.dart b/lib/models/leaves_campus_data.dart index e6430c31..9afbd260 100644 --- a/lib/models/leaves_campus_data.dart +++ b/lib/models/leaves_campus_data.dart @@ -73,12 +73,12 @@ class LeavesDepartment { } class LeavesTeacher { - String teacherName; - String teacherId; + String name; + String id; LeavesTeacher({ - this.teacherName, - this.teacherId, + this.name, + this.id, }); factory LeavesTeacher.fromRawJson(String str) => LeavesTeacher.fromJson(json.decode(str)); @@ -86,12 +86,12 @@ class LeavesTeacher { String toRawJson() => json.encode(toJson()); factory LeavesTeacher.fromJson(Map json) => LeavesTeacher( - teacherName: json["teacherName"] == null ? null : json["teacherName"], - teacherId: json["teacherId"] == null ? null : json["teacherId"], + name: json["teacherName"] == null ? null : json["teacherName"], + id: json["teacherId"] == null ? null : json["teacherId"], ); Map toJson() => { - "teacherName": teacherName == null ? null : teacherName, - "teacherId": teacherId == null ? null : teacherId, + "teacherName": name == null ? null : name, + "teacherId": id == null ? null : id, }; } diff --git a/lib/models/leaves_submit_data.dart b/lib/models/leaves_submit_data.dart index 85dcb839..78ec5dc5 100644 --- a/lib/models/leaves_submit_data.dart +++ b/lib/models/leaves_submit_data.dart @@ -30,7 +30,7 @@ class LeavesSubmitData { leaveTypeId: json["leaveType"], teacherId: json["teacherId"], reasonText: json["reasonText"], - delayReasonText: json["delayReason"], + delayReasonText: json["delayReasonText"], ); Map toJson() => { @@ -38,7 +38,7 @@ class LeavesSubmitData { "leaveType": leaveTypeId, "teacherId": teacherId, "reasonText": reasonText, - "delayReason": delayReasonText, + "delayReasonText": delayReasonText, }; } @@ -64,4 +64,17 @@ class Day { "day": day, "class": new List.from(dayClass.map((x) => x)), }; + + @override + String toString() { + if (day == null && dayClass == null) + return 'empty'; + else { + String text = day; + dayClass.forEach((item) { + text = '$text ($item)'; + }); + return text; + } + } } diff --git a/lib/pages/home/about/about_us_page.dart b/lib/pages/home/about/about_us_page.dart index 2fdfbd08..4a5424aa 100644 --- a/lib/pages/home/about/about_us_page.dart +++ b/lib/pages/home/about/about_us_page.dart @@ -30,7 +30,7 @@ class AboutUsPageState extends State { } String get sectionImage { - final department = ShareDataWidget.of(context).data.userInfo.department; + final department = ShareDataWidget.of(context).data.userInfo?.department ?? ''; Random random = Random(); bool halfSnapFingerChance = random.nextInt(2000) % 2 == 0; if (department.contains('建工') || department.contains('燕巢')) diff --git a/lib/pages/home/about/open_source_page.dart b/lib/pages/home/about/open_source_page.dart index a51a37cb..c32f1e2e 100644 --- a/lib/pages/home/about/open_source_page.dart +++ b/lib/pages/home/about/open_source_page.dart @@ -310,7 +310,77 @@ class OpenSourcePageState extends State { "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + "See the License for the specific language governing permissions and\n" + "limitations under the License.", - ) + ), + _Item( + 'photo_view', + "Copyright 2018 Renan C. Araújo\n" + + "\n" + + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n" + + "\n" + + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n" + + "\n" + + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", + ), + _Item( + 'date_range_picker', + "The MIT License (MIT)\n" + + "\n" + + "Copyright (c) 2018 anicdh\n" + + "\n" + + "Permission is hereby granted, free of charge, to any person obtaining a copy\n" + + "of this software and associated documentation files (the \"Software\"), to deal\n" + + "in the Software without restriction, including without limitation the rights\n" + + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" + + "copies of the Software, and to permit persons to whom the Software is\n" + + "furnished to do so, subject to the following conditions:\n" + + "\n" + + "The above copyright notice and this permission notice shall be included in all\n" + + "copies or substantial portions of the Software.\n" + + "\n" + + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" + + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" + + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" + + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" + + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" + + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n" + + "SOFTWARE.", + ), + _Item( + 'flutter_autofill', + "Copyright 2019-present Applaud Software Inc.\n" + + "\n" + + "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n" + + "\n" + + "1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n" + + "\n" + + "2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n" + + "\n" + + "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + ), + _Item( + 'flutter_native_image', + "MIT License\n" + + "\n" + + "Copyright (c) 2018 Ben Konsemüller\n" + + "\n" + + "Permission is hereby granted, free of charge, to any person obtaining a copy\n" + + "of this software and associated documentation files (the \"Software\"), to deal\n" + + "in the Software without restriction, including without limitation the rights\n" + + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" + + "copies of the Software, and to permit persons to whom the Software is\n" + + "furnished to do so, subject to the following conditions:\n" + + "\n" + + "The above copyright notice and this permission notice shall be included in all\n" + + "copies or substantial portions of the Software.\n" + + "\n" + + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" + + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" + + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" + + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" + + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" + + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n" + + "SOFTWARE.", + ), ]; AppLocalizations app; diff --git a/lib/pages/home/leaves/leave_apply_page.dart b/lib/pages/home/leaves/leave_apply_page.dart index 0e79a334..69480fb7 100644 --- a/lib/pages/home/leaves/leave_apply_page.dart +++ b/lib/pages/home/leaves/leave_apply_page.dart @@ -16,6 +16,8 @@ import 'package:nkust_ap/widgets/default_dialog.dart'; import 'package:nkust_ap/widgets/hint_content.dart'; import 'package:date_range_picker/date_range_picker.dart' as DateRagePicker; import 'package:nkust_ap/widgets/progress_dialog.dart'; +import 'package:nkust_ap/widgets/yes_no_dialog.dart'; +import 'package:sprintf/sprintf.dart'; enum _State { loading, finish, error, empty } enum Leave { normal, sick, official, funeral, maternity } @@ -138,40 +140,53 @@ class LeaveApplyPageState extends State SizedBox(height: 16), Divider(color: Resource.Colors.grey, height: 1), SizedBox(height: 16), - MaterialButton( - onPressed: () async { - final List picked = - await DateRagePicker.showDatePicker( - context: context, - initialFirstDate: DateTime.now(), - initialLastDate: (DateTime.now()).add(Duration(days: 7)), - firstDate: DateTime(2015), - lastDate: DateTime(2020), - ); - if (picked != null && picked.length == 2) { - DateTime dateTime = picked[0], - end = picked[1].add(Duration(days: 1)); - while (dateTime.isBefore(end)) { - bool hasRepeat = false; - for (var i = 0; i < leavesModels.length; i++) { - if (leavesModels[i].isSameDay(dateTime)) - hasRepeat = true; - } - if (!hasRepeat) { - leavesModels.add( - LeavesModel( - dateTime, - leavesSubmitInfo.timeCodes.length, - ), - ); + FractionallySizedBox( + widthFactor: 0.3, + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(30.0), + ), + ), + padding: EdgeInsets.all(4.0), + color: Resource.Colors.blueAccent, + onPressed: () async { + final List picked = + await DateRagePicker.showDatePicker( + context: context, + initialFirstDate: DateTime.now(), + initialLastDate: (DateTime.now()).add(Duration(days: 7)), + firstDate: DateTime(2015), + lastDate: DateTime(2020), + ); + if (picked != null && picked.length == 2) { + DateTime dateTime = picked[0], + end = picked[1].add(Duration(days: 1)); + while (dateTime.isBefore(end)) { + bool hasRepeat = false; + for (var i = 0; i < leavesModels.length; i++) { + if (leavesModels[i].isSameDay(dateTime)) + hasRepeat = true; + } + if (!hasRepeat) { + leavesModels.add( + LeavesModel( + dateTime, + leavesSubmitInfo.timeCodes.length, + ), + ); + } + dateTime = dateTime.add(Duration(days: 1)); } - dateTime = dateTime.add(Duration(days: 1)); + checkIsDelay(); + setState(() {}); } - checkIsDelay(); - setState(() {}); - } - }, - child: Text(app.addDate), + }, + child: Text( + app.addDate, + style: TextStyle(color: Colors.white), + ), + ), ), SizedBox(height: 16), Container( @@ -310,20 +325,29 @@ class LeaveApplyPageState extends State ), subtitle: Text( leavesSubmitInfo.tutor == null - ? (teacher?.teacherName ?? app.pleasePick) + ? (teacher?.name ?? app.pleasePick) : (leavesSubmitInfo.tutor?.name ?? ''), style: TextStyle(fontSize: 20), ), ), Divider(color: Resource.Colors.grey, height: 1), ListTile( - onTap: () async { - image = - await ImagePicker.pickImage(source: ImageSource.gallery); - if (image != null) { - print(image.lengthSync() / 1024 / 1024); - setState(() {}); - } + onTap: () { + ImagePicker.pickImage(source: ImageSource.gallery).then( + (image) async { + if (image != null) { + FA.logLeavesImageSize(image); + if ((image.lengthSync() / 1024 / 1024) >= + Constants.MAX_IMAGE_SIZE) { + resizeImage(image); + } else { + setState(() { + this.image = image; + }); + } + } + }, + ); }, contentPadding: EdgeInsets.symmetric( horizontal: 24, @@ -344,7 +368,7 @@ class LeaveApplyPageState extends State style: TextStyle(fontSize: 20), ), subtitle: Text( - image?.path?.split('/')?.last ?? '', + image?.path?.split('/')?.last ?? app.leavesProofHint, style: TextStyle(fontSize: 20), ), ), @@ -409,11 +433,11 @@ class LeaveApplyPageState extends State padding: EdgeInsets.all(14.0), onPressed: () { _leaveSubmit(); -// FA.logAction('leaves_submit', 'click'); + FA.logAction('leaves_submit', 'click'); }, color: Resource.Colors.blueAccent, child: Text( - app.submit, + app.confirm, style: TextStyle( color: Colors.white, fontSize: 18.0, @@ -471,102 +495,213 @@ class LeaveApplyPageState extends State ); } }); - LeavesSubmitData data = LeavesSubmitData( - days: days, - leaveTypeId: leavesSubmitInfo.type[typeIndex].id, - teacherId: leavesSubmitInfo.tutor?.id, - reasonText: _reason.text ?? '', - delayReasonText: isDelay ? (_delayReason.text ?? '') : '', - ); - print(data.toJson()); - print(teacher?.teacherName); if (days.length == 0) { Utils.showToast(context, app.pleasePickDateAndSection); } else if (leavesSubmitInfo.tutor == null && teacher == null) { Utils.showToast(context, app.pickTeacher); } else if (_formKey.currentState.validate()) { //TODO submit summary - Utils.showToast(context, '上傳中,測試功能'); + String tutorId, tutorName; + if (leavesSubmitInfo.tutor == null) { + tutorId = teacher.id; + tutorName = teacher.name; + } else { + tutorId = leavesSubmitInfo.tutor.id; + tutorName = leavesSubmitInfo.tutor.name; + } + LeavesSubmitData data = LeavesSubmitData( + days: days, + leaveTypeId: leavesSubmitInfo.type[typeIndex].id, + teacherId: tutorId, + reasonText: _reason.text ?? '', + delayReasonText: isDelay ? (_delayReason.text ?? '') : '', + ); + print(data.toJson()); showDialog( context: context, - builder: (BuildContext context) => WillPopScope( - child: ProgressDialog(app.leavesSubmitUploadHint), - onWillPop: () async { - return false; + builder: (BuildContext context) => YesNoDialog( + title: app.leavesSubmit, + contentWidgetPadding: EdgeInsets.all(0.0), + contentWidget: SizedBox( + height: MediaQuery.of(context).size.height * + ((image == null) ? 0.3 : 0.5), + width: MediaQuery.of(context).size.width * 0.7, + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.only( + top: 16.0, + left: 30.0, + right: 30.0, + ), + child: RichText( + textAlign: TextAlign.left, + text: TextSpan( + style: TextStyle( + color: Resource.Colors.grey, + height: 1.5, + fontSize: 16.0), + children: [ + TextSpan( + text: '${app.leavesType}:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: + '${leavesSubmitInfo.type[typeIndex].title}\n'), + TextSpan( + text: '${app.tutor}:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: '$tutorName\n'), + TextSpan( + text: '${app.reason}:\n', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: '${_reason.text}'), + if (isDelay) ...[ + TextSpan( + text: '${app.delayReason}:\n', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: '${_delayReason.text}\n'), + ], + TextSpan( + text: '${app.leavesDateAndSection}:\n', + style: TextStyle(fontWeight: FontWeight.bold), + ), + for (var day in days) + TextSpan(text: '${day.toString()}\n'), + TextSpan( + text: + '${app.leavesProof}:${(image == null ? app.none : '')}\n', + style: TextStyle(fontWeight: FontWeight.bold), + ), + ], + ), + ), + ), + if (image != null) + Padding( + padding: const EdgeInsets.only( + bottom: 16.0, + left: 30.0, + right: 30.0, + ), + child: Image.file(image), + ), + ], + ), + ), + leftActionText: app.cancel, + rightActionText: app.submit, + leftActionFunction: null, + rightActionFunction: () { + _leaveUpload(data); + Utils.showToast(context, '上傳中,測試功能'); }, ), - barrierDismissible: false, ); - //TODO image crop or resize - Helper.instance.sendLeavesSubmit(data, image).then((Response response) { - Navigator.of(context, rootNavigator: true).pop(); - showDialog( - context: context, - builder: (BuildContext context) => DefaultDialog( - title: response.statusCode == 200 - ? app.leavesSubmitSuccess - : '${response.statusCode}', - contentWidget: RichText( - textAlign: TextAlign.left, - text: TextSpan( - style: TextStyle( - color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), - children: [ - TextSpan( - text: response.statusCode == 200 - ? app.leavesSubmitSuccess - : '${response.data}', - style: TextStyle(fontWeight: FontWeight.bold), - ), - ], - ), + } + } + + void _leaveUpload(LeavesSubmitData data) { + showDialog( + context: context, + builder: (BuildContext context) => WillPopScope( + child: ProgressDialog(app.leavesSubmitUploadHint), + onWillPop: () async { + return false; + }, + ), + barrierDismissible: false, + ); + Helper.instance.sendLeavesSubmit(data, image).then((Response response) { + Navigator.of(context, rootNavigator: true).pop(); + showDialog( + context: context, + builder: (BuildContext context) => DefaultDialog( + title: response.statusCode == 200 + ? app.leavesSubmitSuccess + : '${response.statusCode}', + contentWidget: RichText( + textAlign: TextAlign.left, + text: TextSpan( + style: TextStyle( + color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), + children: [ + TextSpan( + text: response.statusCode == 200 + ? app.leavesSubmitSuccess + : '${response.data}', + style: TextStyle(fontWeight: FontWeight.bold), + ), + ], ), - actionText: app.iKnow, - actionFunction: () => - Navigator.of(context, rootNavigator: true).pop(), ), - ); - }).catchError((e) { - Navigator.of(context, rootNavigator: true).pop(); - if (e is DioError) { - switch (e.type) { - case DioErrorType.RESPONSE: - ErrorResponse errorResponse = - ErrorResponse.fromJson(e.response.data); - showDialog( - context: context, - builder: (BuildContext context) => DefaultDialog( - title: app.busReserveFailTitle, - contentWidget: Text( - errorResponse.description, - style: TextStyle( - color: Resource.Colors.grey, - height: 1.3, - fontSize: 16.0), - ), - actionText: app.iKnow, - actionFunction: () { - Navigator.of(context, rootNavigator: true).pop(); - }, + actionText: app.iKnow, + actionFunction: () => + Navigator.of(context, rootNavigator: true).pop(), + ), + ); + }).catchError((e) { + Navigator.of(context, rootNavigator: true).pop(); + if (e is DioError) { + switch (e.type) { + case DioErrorType.RESPONSE: + ErrorResponse errorResponse = + ErrorResponse.fromJson(e.response.data); + showDialog( + context: context, + builder: (BuildContext context) => DefaultDialog( + title: app.busReserveFailTitle, + contentWidget: Text( + errorResponse.description, + style: TextStyle( + color: Resource.Colors.grey, height: 1.3, fontSize: 16.0), ), - ); - break; - case DioErrorType.DEFAULT: - setState(() { - state = _State.error; - }); - Utils.showToast(context, app.somethingError); - break; - case DioErrorType.CANCEL: - break; - default: - Utils.handleDioError(context, e); - break; - } - } else { - throw e; + actionText: app.iKnow, + actionFunction: () { + Navigator.of(context, rootNavigator: true).pop(); + }, + ), + ); + break; + case DioErrorType.DEFAULT: + setState(() { + state = _State.error; + }); + Utils.showToast(context, app.somethingError); + break; + case DioErrorType.CANCEL: + break; + default: + Utils.handleDioError(context, e); + break; } + } else { + throw e; + } + }); + } + + Future resizeImage(File image) async { + File result = await Utils.resizeImageByNative(image); + FA.logLeavesImageCompressSize(image, result); + if ((result.lengthSync() / 1024 / 1024) <= Constants.MAX_IMAGE_SIZE) { + Utils.showToast( + context, + sprintf( + app.imageCompressHint, + [(result.lengthSync() / 1024 / 1024)], + ), + ); + setState(() { + this.image = result; }); + } else { + Utils.showToast(context, app.imageTooBigHint); + FA.logEvent('leaves_pick_fail'); } } } diff --git a/lib/pages/home/leaves/pick_tutor_page.dart b/lib/pages/home/leaves/pick_tutor_page.dart index 0d8db1e9..d1347646 100644 --- a/lib/pages/home/leaves/pick_tutor_page.dart +++ b/lib/pages/home/leaves/pick_tutor_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart' show rootBundle; import 'package:nkust_ap/models/leaves_campus_data.dart'; import 'package:nkust_ap/res/app_icon.dart'; +import 'package:nkust_ap/res/assets.dart'; import 'package:nkust_ap/utils/app_localizations.dart'; import 'package:nkust_ap/widgets/dialog_option.dart'; import 'package:nkust_ap/widgets/hint_content.dart'; @@ -115,14 +116,14 @@ class _PickTutorPageState extends State { ListTile( leading: Icon(Icons.person), title: Text(app.teacher), - subtitle: Text('${teacher.teacherName}'), + subtitle: Text('${teacher.name}'), onTap: () { pickItem( _Type.teacher, teacherIndex, department.teacherList.map( (item) { - return item.teacherName; + return item.name; }, ).toList(), ); @@ -163,7 +164,7 @@ class _PickTutorPageState extends State { Future getFileData() async { var start = DateTime.now(); - String text = await rootBundle.loadString('assets/leaves_campus_data.json'); + String text = await rootBundle.loadString(FileAssets.leavesCampusData); setState(() { leavesCampusData = LeavesCampusData.fromRawJson(text); if (leavesCampusData != null) { diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index b58b9b1d..29a37762 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -74,10 +74,14 @@ class HomePageState extends State { ], ), drawer: DrawerBody( - userInfo: ShareDataWidget.of(context).data.userInfo, - onClickLogout: () { - checkLogin(); - }), + userInfo: ShareDataWidget.of(context).data.userInfo, + onClickLogin: () { + openLoginPage(); + }, + onClickLogout: () { + checkLogin(); + }, + ), body: OrientationBuilder( builder: (_, orientation) { return Container( @@ -452,33 +456,36 @@ class HomePageState extends State { }); } + Future openLoginPage() async { + var result = await Navigator.of(context).push( + CupertinoPageRoute( + builder: (_) => LoginPage(), + ), + ); + print((result)); + checkLogin(); + if (result ?? false) { + _getUserInfo(); + setState(() { + ShareDataWidget.of(context).data.isLogin = true; + }); + } + } + void checkLogin() async { await Future.delayed(Duration(microseconds: 30)); print(ShareDataWidget.of(context).data.isLogin); if (ShareDataWidget.of(context).data.isLogin) { - // _scaffoldKey.currentState.hideCurrentSnackBar(); + _scaffoldKey.currentState.hideCurrentSnackBar(); } else { _scaffoldKey.currentState.showSnackBar( SnackBar( content: Text(app.notLogin), duration: Duration(days: 1), action: SnackBarAction( - onPressed: () async { - var result = await Navigator.of(context).push( - CupertinoPageRoute( - builder: (_) => LoginPage(), - ), - ); - if (result ?? false) { - _getUserInfo(); - setState(() { - ShareDataWidget.of(context).data.isLogin = true; - }); - } else { - checkLogin(); - } - }, + onPressed: openLoginPage, label: app.login, + textColor: Resource.Colors.snackBarActionTextColor, ), ), ); diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 9790e825..a4c067d6 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -104,60 +104,68 @@ class LoginPageState extends State { ), SizedBox(height: orientation == Orientation.portrait ? 30.0 : 0.0), ]; - List sectionInput = [ - Autofill( - onAutofilled: (val) { - // set value in controller & cursor position after auto-filled value - _username.value = TextEditingValue( - text: val, - selection: - TextSelection.fromPosition(TextPosition(offset: val.length))); - }, - autofillHints: [FlutterAutofill.AUTOFILL_HINT_USERNAME], - autofillType: FlutterAutofill.AUTOFILL_TYPE_TEXT, - textController: _username, - child: TextField( - maxLines: 1, - controller: _username, - textInputAction: TextInputAction.next, - focusNode: usernameFocusNode, - onSubmitted: (text) { - usernameFocusNode.unfocus(); - FocusScope.of(context).requestFocus(passwordFocusNode); - }, - decoration: InputDecoration( - labelText: app.username, - ), - style: _editTextStyle, - ), + Widget usernameTextField = TextField( + maxLines: 1, + controller: _username, + textInputAction: TextInputAction.next, + focusNode: usernameFocusNode, + onSubmitted: (text) { + usernameFocusNode.unfocus(); + FocusScope.of(context).requestFocus(passwordFocusNode); + }, + decoration: InputDecoration( + labelText: app.username, ), - Autofill( - onAutofilled: (val) { - // set value in controller & cursor position after auto-filled value - _password.value = TextEditingValue( - text: val, - selection: - TextSelection.fromPosition(TextPosition(offset: val.length))); - }, - autofillHints: [FlutterAutofill.AUTOFILL_HINT_PASSWORD], - autofillType: FlutterAutofill.AUTOFILL_TYPE_TEXT, - textController: _password, - child: TextField( - obscureText: true, - maxLines: 1, - textInputAction: TextInputAction.send, - controller: _password, - focusNode: passwordFocusNode, - onSubmitted: (text) { - passwordFocusNode.unfocus(); - _login(); - }, - decoration: InputDecoration( - labelText: app.password, - ), - style: _editTextStyle, - ), + style: _editTextStyle, + ); + Widget passwordTextField = TextField( + obscureText: true, + maxLines: 1, + textInputAction: TextInputAction.send, + controller: _password, + focusNode: passwordFocusNode, + onSubmitted: (text) { + passwordFocusNode.unfocus(); + _login(); + }, + decoration: InputDecoration( + labelText: app.password, ), + style: _editTextStyle, + ); + List sectionInput = [ + (Platform.isAndroid) + ? Autofill( + onAutofilled: (val) { + // set value in controller & cursor position after auto-filled value + _username.value = TextEditingValue( + text: val, + selection: TextSelection.fromPosition( + TextPosition(offset: val.length), + ), + ); + }, + autofillHints: [FlutterAutofill.AUTOFILL_HINT_USERNAME], + autofillType: FlutterAutofill.AUTOFILL_TYPE_TEXT, + textController: _username, + child: usernameTextField, + ) + : usernameTextField, + (Platform.isAndroid) + ? Autofill( + onAutofilled: (val) { + // set value in controller & cursor position after auto-filled value + _password.value = TextEditingValue( + text: val, + selection: TextSelection.fromPosition( + TextPosition(offset: val.length))); + }, + autofillHints: [FlutterAutofill.AUTOFILL_HINT_PASSWORD], + autofillType: FlutterAutofill.AUTOFILL_TYPE_TEXT, + textController: _password, + child: passwordTextField, + ) + : passwordTextField, SizedBox(height: 8.0), Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/res/assets.dart b/lib/res/assets.dart index 82483614..039bc37e 100644 --- a/lib/res/assets.dart +++ b/lib/res/assets.dart @@ -57,3 +57,9 @@ class ImageAssets { } } } + +class FileAssets { + static const String basePath = 'assets/'; + + static String leavesCampusData = '$basePath/leaves_campus_data.json'; +} \ No newline at end of file diff --git a/lib/res/colors.dart b/lib/res/colors.dart index 4f93037a..67f20fd4 100644 --- a/lib/res/colors.dart +++ b/lib/res/colors.dart @@ -125,6 +125,16 @@ class Colors { } } + static get snackBarActionTextColor { + switch (AppTheme.code) { + case AppTheme.DARK: + return yellow500; + case AppTheme.LIGHT: + default: + return yellow500; + } + } + static const Color blueDark = const Color(0xff141e2f); static const Color onyx = const Color(0xff121212); static const Color grayChateau = const Color(0xffa5a5a5); diff --git a/lib/utils/app_localizations.dart b/lib/utils/app_localizations.dart index 20c30913..6e04bad1 100644 --- a/lib/utils/app_localizations.dart +++ b/lib/utils/app_localizations.dart @@ -236,7 +236,7 @@ class AppLocalizations { 'The best KUAS Campus App\nKUAS AP\n\nAre you afreshman?\nDon\'t know about school info, telephone numbers, or up coming events?\nBeenhere a few years?\nHave checking class schedule, report card and reserving bus seatsdrove you crazy?\n\nNo more, no more worries, anymore!\n\nKUAS AP lets no matter old or newfellow\nhave control over your life in KUAS!\n\nFrom checking class schedule, report card toyour absence records!\nPlus reserving/canceling bus seats with newest school feeds!\n\n\n\nMuch Simple, Many Convenient, Very instinct, wow!\n\n☆FABULOUS☆', 'about_author_title': 'Made by', 'about_author_content': - 'v1 & v2\n呂紹榕(Louie Lu), 姜尚德(JohnThunder), \nregisterAutumn, 詹濬鍵(Evans), \n陳建霖(HearSilent), 陳冠蓁, 徐羽柔\nv3\n房志剛(Rainvisitor),林義翔(takidog)', + 'v1 & v2\n呂紹榕(Louie Lu), 姜尚德(JohnThunder), \nregisterAutumn, 詹濬鍵(Evans), \n陳建霖(HearSilent), 陳冠蓁, 徐羽柔\nv3\n房志剛(Rainvisitor),林義翔(takidog)\n周鈺禮(CHOU YU-LI)', 'about_us': '“Ask not why nobody is doing this. You are \'nobody\'.”\n\nWe did this cause no one did it.\nWe created KUAS Wifi Login, KUASAP and KUAS Gourmet, Course Selection Sim, etc…\nTo bring convenience to everyone\'s on campus!', 'about_recruit_title': 'We Need You !', @@ -394,6 +394,13 @@ class AppLocalizations { 'pleasePickDateAndSection': 'Please pick date and section.', 'leavesSubmitSuccess': 'Leaves submit successful.', 'leavesDelayHint': 'Because over time, need to fill delay reason.', + 'leavesProofHint': 'Please pick image', + 'imageCompressHint': 'Because file big than 4MB, so compress to %.2f MB', + 'imageTooBigHint': + 'Image size is too big, can\'t compress in except. Plese pick another one.', + 'leavesDateAndSection': 'Date & Section', + 'none': 'None', + 'leavesSubmit': 'Leaves Submit', }, 'zh': { 'app_name': '高科校務通', @@ -549,7 +556,7 @@ class AppLocalizations { 'app_version': 'App 版本', 'about_author_title': '作者群', 'about_author_content': - 'v1 & v2\n呂紹榕(Louie Lu), 姜尚德(JohnThunder), \nregisterAutumn, 詹濬鍵(Evans), \n陳建霖(HearSilent), 陳冠蓁, 徐羽柔 \nv3\n房志剛(Rainvisitor),林義翔(takidog)', + 'v1 & v2\n呂紹榕(Louie Lu), 姜尚德(JohnThunder), \nregisterAutumn, 詹濬鍵(Evans), \n陳建霖(HearSilent), 陳冠蓁, 徐羽柔 \nv3\n房志剛(Rainvisitor),林義翔(takidog)\n周鈺禮(CHOU YU-LI)', 'about_us': '「不要問為何沒有人做這個,\n先承認你就是『沒有人』」。\n因為,「沒有人」是萬能的。\n\n因為沒有人做這些,所以我們跳下來做。\n先後完成了高應無線通、高應校務通,到後來的高應美食通、模擬選課等等.......\n無非是希望帶給大家更便利的校園生活!', 'about_recruit_title': 'We Need You !', @@ -704,6 +711,12 @@ class AppLocalizations { 'pleasePickDateAndSection': '請選擇日期及節次', 'leavesSubmitSuccess': '請假送出成功', 'leavesDelayHint': '因為超出請假時間 請填寫延遲原因', + 'leavesProofHint': '請選擇照片', + 'imageCompressHint': '因檔案超出 4MB 自動將其壓縮至 %.2f MB', + 'imageTooBigHint': '圖片大小過大 無法預期壓縮 請重新挑選', + 'leavesDateAndSection': '日期與節次', + 'none': '無', + 'leavesSubmit': '假單送出', }, }; @@ -1259,6 +1272,18 @@ class AppLocalizations { String get leavesSubmitSuccess => _vocabularies['leavesSubmitSuccess']; String get leavesDelayHint => _vocabularies['leavesDelayHint']; + + String get leavesProofHint => _vocabularies['leavesProofHint']; + + String get imageCompressHint => _vocabularies['imageCompressHint']; + + String get imageTooBigHint => _vocabularies['imageTooBigHint']; + + String get leavesDateAndSection => _vocabularies['leavesDateAndSection']; + + String get none => _vocabularies['none']; + + String get leavesSubmit => _vocabularies['leavesSubmit']; } class AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/utils/firebase_analytics_utils.dart b/lib/utils/firebase_analytics_utils.dart index 946cddf7..6821372f 100644 --- a/lib/utils/firebase_analytics_utils.dart +++ b/lib/utils/firebase_analytics_utils.dart @@ -41,6 +41,14 @@ class FA { ); } + static Future logEvent(String name) async { + if (Platform.isIOS || Platform.isAndroid) { + await analytics?.logEvent( + name: name ?? '', + ); + } + } + static Future logApiEvent(String type, int status, {String message = ''}) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); @@ -101,4 +109,26 @@ class FA { ); } } + + static Future logLeavesImageSize(File source) async { + if (Platform.isIOS || Platform.isAndroid) + await analytics?.logEvent( + name: 'leaves_image_pick', + parameters: { + 'image_size': source.lengthSync() / 1024 / 1024, + }, + ); + } + + static Future logLeavesImageCompressSize( + File source, File result) async { + if (Platform.isIOS || Platform.isAndroid) + await analytics?.logEvent( + name: 'leaves_image_compress', + parameters: { + 'image_original_size': source.lengthSync() / 1024 / 1024, + 'image_compress_size': result.lengthSync() / 1024 / 1024, + }, + ); + } } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 25961117..975daa33 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -6,6 +6,8 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/cupertino.dart' show CupertinoPageRoute; import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:flutter_native_image/flutter_native_image.dart'; +import 'package:image/image.dart' as ImageUtils; import 'package:nkust_ap/config/constants.dart'; import 'package:nkust_ap/models/bus_reservations_data.dart'; import 'package:nkust_ap/models/course_data.dart'; @@ -24,6 +26,7 @@ import 'package:nkust_ap/widgets/default_dialog.dart'; import 'package:nkust_ap/widgets/share_data_widget.dart'; import 'package:nkust_ap/widgets/yes_no_dialog.dart'; import 'package:package_info/package_info.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:share/share.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sprintf/sprintf.dart'; @@ -519,4 +522,32 @@ class Utils { }), ); } + + static Future resizeImageByDart(File source) async { + ImageUtils.Image image = ImageUtils.decodeImage(source.readAsBytesSync()); + double sourceSize = source.lengthSync() / 1024 / 1024; + double rate = sourceSize / Constants.IMAGE_RESIZE_RATE; + ImageUtils.Image thumbnail = ImageUtils.copyResize( + image, + width: (image.width / rate).ceil(), + height: (image.height / rate).ceil(), + ); + Directory appDocDir = await getApplicationDocumentsDirectory(); + File result = File('${appDocDir.path}/proof.jpg') + ..writeAsBytesSync(ImageUtils.encodeJpg(thumbnail)); + return result; + } + + static Future resizeImageByNative(File source) async { + ImageProperties properties = + await FlutterNativeImage.getImageProperties(source.path); + Directory appDocDir = await getApplicationDocumentsDirectory(); + File result = await FlutterNativeImage.compressImage( + '${appDocDir.path}/proof.jpg', + quality: 80, + targetWidth: properties.width, + targetHeight: properties.height, + ); + return result; + } } diff --git a/lib/widgets/drawer_body.dart b/lib/widgets/drawer_body.dart index 829bde4f..37c3de7e 100644 --- a/lib/widgets/drawer_body.dart +++ b/lib/widgets/drawer_body.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:nkust_ap/config/constants.dart'; @@ -19,11 +20,13 @@ import 'package:nkust_ap/widgets/share_data_widget.dart'; class DrawerBody extends StatefulWidget { final UserInfo userInfo; + final Function onClickLogin; final Function onClickLogout; const DrawerBody({ Key key, @required this.userInfo, + @required this.onClickLogin, @required this.onClickLogout, }) : super(key: key); @@ -61,14 +64,19 @@ class DrawerBodyState extends State { child: Column( children: [ GestureDetector( - onTap: () { - if (widget.userInfo != null && - ShareDataWidget.of(context).data.isLogin) - Utils.pushCupertinoStyle( - context, - UserInfoPage(userInfo: widget.userInfo), - ); - }, + onTap: ShareDataWidget.of(context).data.isLogin + ? () { + if (widget.userInfo != null && + ShareDataWidget.of(context).data.isLogin) + Utils.pushCupertinoStyle( + context, + UserInfoPage(userInfo: widget.userInfo), + ); + } + : () async { + Navigator.of(context).pop(); + widget.onClickLogin(); + }, child: Stack( children: [ UserAccountsDrawerHeader( @@ -247,19 +255,20 @@ class DrawerBodyState extends State { title: app.settings, page: SettingPage(), ), - ListTile( - leading: Icon( - AppIcon.powerSettingsNew, - color: Resource.Colors.grey, + if (ShareDataWidget.of(context).data.isLogin) + ListTile( + leading: Icon( + AppIcon.powerSettingsNew, + color: Resource.Colors.grey, + ), + onTap: () async { + await Preferences.setBool(Constants.PREF_AUTO_LOGIN, false); + ShareDataWidget.of(context).data.logout(); + Navigator.of(context).pop(); + widget.onClickLogout(); + }, + title: Text(app.logout, style: _defaultStyle), ), - onTap: () async { - await Preferences.setBool(Constants.PREF_AUTO_LOGIN, false); - ShareDataWidget.of(context).data.logout(); - Navigator.of(context).pop(); - widget.onClickLogout(); - }, - title: Text(app.logout, style: _defaultStyle), - ), ], ), ), diff --git a/lib/widgets/semester_picker.dart b/lib/widgets/semester_picker.dart index 0d7704c7..cd051c81 100644 --- a/lib/widgets/semester_picker.dart +++ b/lib/widgets/semester_picker.dart @@ -125,21 +125,21 @@ class SemesterPickerState extends State { content: SizedBox( width: MediaQuery.of(context).size.width * 0.7, height: MediaQuery.of(context).size.height * 0.8, - child: ListView( + child: ListView.separated( controller: ScrollController(initialScrollOffset: index * 48.0), - children: [ - for (var i = 0; i < semesterData.data.length; i++) ...[ - DialogOption( - text: semesterData.data[i].text, - check: semesterData.data[i].text == selectSemester.text, - onPressed: () { - Navigator.pop(context, i); - }), - Divider( - height: 6.0, - ) - ] - ], + itemCount: semesterData.data.length, + separatorBuilder: (BuildContext context, int index) { + return Divider(height: 6.0); + }, + itemBuilder: (BuildContext context, int index) { + return DialogOption( + text: semesterData.data[index].text, + check: semesterData.data[index].text == selectSemester.text, + onPressed: () { + Navigator.pop(context, index); + }, + ); + }, ), ), ), diff --git a/lib/widgets/yes_no_dialog.dart b/lib/widgets/yes_no_dialog.dart index 8197eb5e..1202a3c6 100644 --- a/lib/widgets/yes_no_dialog.dart +++ b/lib/widgets/yes_no_dialog.dart @@ -4,6 +4,7 @@ import 'package:nkust_ap/res/resource.dart' as Resource; class YesNoDialog extends StatelessWidget { final String title; final Widget contentWidget; + final EdgeInsetsGeometry contentWidgetPadding; final String leftActionText; final String rightActionText; final Function leftActionFunction; @@ -13,6 +14,7 @@ class YesNoDialog extends StatelessWidget { {Key key, this.title, this.contentWidget, + this.contentWidgetPadding, this.leftActionText, this.rightActionText, this.leftActionFunction, @@ -66,7 +68,8 @@ class YesNoDialog extends StatelessWidget { bottom: BorderSide(color: Colors.grey, width: 0.5), ), ), - padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 24.0), + padding: contentWidgetPadding ?? + EdgeInsets.symmetric(horizontal: 30.0, vertical: 24.0), child: contentWidget, ), Row( diff --git a/macos/.gitignore b/macos/.gitignore index 7c8c39de..d2fd3772 100644 --- a/macos/.gitignore +++ b/macos/.gitignore @@ -1,6 +1,6 @@ -xcuserdata +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ -# Generated by flutter tooling as needed. -Flutter/ephemeral/ -# Created by CocoaPods for plugins. -Pods/ +# Xcode-related +**/xcuserdata/ diff --git a/macos/AppDelegate.swift b/macos/AppDelegate.swift deleted file mode 100644 index bdcc151b..00000000 --- a/macos/AppDelegate.swift +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Cocoa - -@NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate { - @IBOutlet weak var window: NSWindow! - - func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} - diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9d0ecc78..00000000 --- a/macos/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,199 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "57x57", - "idiom" : "iphone", - "filename" : "Icon-App-57x57@1x.png", - "scale" : "1x" - }, - { - "size" : "57x57", - "idiom" : "iphone", - "filename" : "Icon-App-57x57@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "ItunesArtwork@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-72x72@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-76x76@3x.png", - "scale" : "3x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-20x20@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-40x40@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-60x60@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-72x72@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-76x76@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-Small-50x50@1x.png", - "unassigned" : true, - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-76x76@2x.png", - "unassigned" : true, - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Icon-App-83.5x83.5@2x.png", - "unassigned" : true, - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Icon-Small-50x50@2x.png", - "unassigned" : true, - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index e9a1b63e..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 397afa26..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 5b1baf51..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index bfe03fc9..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 9f5e8bf2..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index 8ecfbc8f..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index 2b1859f0..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 5b1baf51..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index f95396df..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index 46e2ab4c..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png deleted file mode 100644 index 3d588678..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png deleted file mode 100644 index f5513778..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@1x.png deleted file mode 100644 index bfe03fc9..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 46e2ab4c..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index cd1842e0..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png deleted file mode 100644 index 635da1ac..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png deleted file mode 100644 index 1dddbe1f..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index 59f42cc2..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 58b2c263..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png deleted file mode 100644 index fc6b1212..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index cba19f6d..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@1x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@1x.png deleted file mode 100644 index 019d52d6..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@1x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@2x.png deleted file mode 100644 index 0d911133..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/Icon-Small-50x50@2x.png and /dev/null differ diff --git a/macos/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/macos/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png deleted file mode 100644 index e9a1b63e..00000000 Binary files a/macos/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png and /dev/null differ diff --git a/macos/Configs/Debug.xcconfig b/macos/Configs/Debug.xcconfig deleted file mode 100644 index 41b74956..00000000 --- a/macos/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/macos/Configs/Release.xcconfig b/macos/Configs/Release.xcconfig deleted file mode 100644 index 2a7dc01d..00000000 --- a/macos/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/macos/ExampleWindow.swift b/macos/ExampleWindow.swift deleted file mode 100644 index 633dfc1d..00000000 --- a/macos/ExampleWindow.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Cocoa -import FlutterMacOS - -class ExampleWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FLEViewController.init() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} - diff --git a/macos/Flutter/Generated.xcconfig b/macos/Flutter/Generated.xcconfig deleted file mode 100644 index b59a4a68..00000000 --- a/macos/Flutter/Generated.xcconfig +++ /dev/null @@ -1,6 +0,0 @@ -// This is a generated file; do not edit or check into version control. -FLUTTER_ROOT=/Users/rainvisitor/development/flutter -FLUTTER_APPLICATION_PATH=/Users/rainvisitor/development/flutter-desktop-embedding/example -FLUTTER_BUILD_DIR=build -SYMROOT=/Users/rainvisitor/development/flutter-desktop-embedding/example/build/macos/Build/Products -FLUTTER_FRAMEWORK_DIR=/Users/rainvisitor/development/flutter/bin/cache/artifacts/engine/darwin-x64 diff --git a/macos/Flutter/flutter_export_environment.sh b/macos/Flutter/flutter_export_environment.sh deleted file mode 100755 index 9e21f37e..00000000 --- a/macos/Flutter/flutter_export_environment.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/rainvisitor/development/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/rainvisitor/Documents/GitHub/NKUST-AP-Flutter" -export "FLUTTER_TARGET=/Users/rainvisitor/Documents/GitHub/NKUST-AP-Flutter/lib/main.dart" -export "FLUTTER_BUILD_DIR=/Users/rainvisitor/Documents/GitHub/NKUST-AP-Flutter/.dart_tool/flutter_build/25c1fbd5ee33c3b4cf3abf2baeaddc44" -export "FLUTTER_FRAMEWORK_DIR=/Users/rainvisitor/development/flutter/bin/cache/artifacts/engine/darwin-x64" -export "FLUTTER_BUILD_NAME=3.2.0" -export "FLUTTER_BUILD_NUMBER=30200" diff --git a/macos/Podfile b/macos/Podfile index 45f32620..dc90941d 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.13' +platform :osx, '10.11' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -38,9 +38,7 @@ def pubspec_supports_macos(file) return false; end File.foreach(file_abs_path) { |line| - # TODO(stuartmorgan): Use formal platform declaration once it exists, - # see https://github.com/flutter/flutter/issues/33597. - return true if line =~ /^\s*macosPrefix:/ + return true if line =~ /^\s*macos:/ } return false end diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 8e1e6a60..1461a3ea 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -3,19 +3,19 @@ archiveVersion = 1; classes = { }; - objectVersion = 48; + objectVersion = 51; objects = { /* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */ = { + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Build Flutter Bundle" */; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; buildPhases = ( 33CC111E2044C6BF0003C045 /* ShellScript */, ); dependencies = ( ); - name = "Build Flutter Bundle"; + name = "Flutter Assemble"; productName = FLX; }; /* End PBXAggregateTarget section */ @@ -25,11 +25,12 @@ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* ExampleWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* ExampleWindow.swift */; }; - 33CC112F204626C80003C045 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC112C20461AD40003C045 /* flutter_assets */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 3B2398DFB6ED470D0AE9ACC5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E976979D3EC1F83E826671AA /* Pods_Runner.framework */; }; + 86BA163A718330527B473ADE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A83419312CCB6B92CDD43FDB /* Pods_Runner.framework */; }; + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,6 +50,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; @@ -57,24 +59,28 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Warnings.xcconfig; path = Configs/Warnings.xcconfig; sourceTree = ""; }; + 31F65FB1350475BFF4AFD43A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* NKUST AP.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NKUST AP.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* nkust_ap_flutter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = nkust_ap_flutter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* ExampleWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleWindow.swift; sourceTree = ""; }; - 33CC112C20461AD40003C045 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = ../build/flutter_assets; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; - 3791C254B5D15F61597672EC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Configs/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Configs/Debug.xcconfig; sourceTree = ""; }; - E976979D3EC1F83E826671AA /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F6D1C7225F9B1694A8A75E31 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 576B66FB82929633562AEAFF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9358FA716C58C01BDF277EBE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + A83419312CCB6B92CDD43FDB /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,50 +88,41 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, - 3B2398DFB6ED470D0AE9ACC5 /* Pods_Runner.framework in Frameworks */, + 86BA163A718330527B473ADE /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 121BD0F826E3339928FD5815 /* Frameworks */ = { - isa = PBXGroup; - children = ( - E976979D3EC1F83E826671AA /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 33BA886A226E78AF003329D5 /* Configs */ = { isa = PBXGroup; children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, ); - name = Configs; + path = Configs; sourceTree = ""; }; 33CC10E42044A3C60003C045 = { isa = PBXGroup; children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* ExampleWindow.swift */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, + 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, 33CC10EE2044A3C60003C045 /* Products */, - 3C590732CA5578AFB3561924 /* Pods */, - 121BD0F826E3339928FD5815 /* Frameworks */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + FBF9466862C252453B961220 /* Pods */, ); sourceTree = ""; }; 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* NKUST AP.app */, + 33CC10ED2044A3C60003C045 /* nkust_ap_flutter.app */, ); name = Products; sourceTree = ""; @@ -136,9 +133,9 @@ 33CC10F22044A3C60003C045 /* Assets.xcassets */, 33CC10F42044A3C60003C045 /* MainMenu.xib */, 33CC10F72044A3C60003C045 /* Info.plist */, - 33CC112C20461AD40003C045 /* flutter_assets */, ); name = Resources; + path = ..; sourceTree = ""; }; 33CEB47122A05771004F2AC0 /* Flutter */ = { @@ -148,17 +145,41 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + D73912EF22F37F9E000D13A0 /* App.framework */, 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; }; - 3C590732CA5578AFB3561924 /* Pods */ = { + 33FAB671232836740065AC1E /* Runner */ = { isa = PBXGroup; children = ( - 3791C254B5D15F61597672EC /* Pods-Runner.debug.xcconfig */, - F6D1C7225F9B1694A8A75E31 /* Pods-Runner.release.xcconfig */, + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A83419312CCB6B92CDD43FDB /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + FBF9466862C252453B961220 /* Pods */ = { + isa = PBXGroup; + children = ( + 576B66FB82929633562AEAFF /* Pods-Runner.debug.xcconfig */, + 31F65FB1350475BFF4AFD43A /* Pods-Runner.release.xcconfig */, + 9358FA716C58C01BDF277EBE /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; path = Pods; sourceTree = ""; }; @@ -169,13 +190,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - F8478360E5B25ECFF8849625 /* [CP] Check Pods Manifest.lock */, + 4DC141AC22531BBE979D98C9 /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, - 45584FC44CA4E8AE5653DDB4 /* [CP] Embed Pods Frameworks */, + 7B7F643CD9CF5931C23CF49B /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -183,8 +204,8 @@ 33CC11202044C79F0003C045 /* PBXTargetDependency */, ); name = Runner; - productName = "NKUST AP"; - productReference = 33CC10ED2044A3C60003C045 /* NKUST AP.app */; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* nkust_ap_flutter.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -201,10 +222,15 @@ CreatedOnToolsVersion = 9.2; LastSwiftMigration = 0920; ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; }; 33CC111A2044C6BA0003C045 = { CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; }; }; }; @@ -222,7 +248,7 @@ projectRoot = ""; targets = ( 33CC10EC2044A3C60003C045 /* Runner */, - 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, ); }; /* End PBXProject section */ @@ -234,7 +260,6 @@ files = ( 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - 33CC112F204626C80003C045 /* flutter_assets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -263,49 +288,56 @@ buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_build_flutter_assets.sh\n"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; }; - 45584FC44CA4E8AE5653DDB4 /* [CP] Embed Pods Frameworks */ = { + 4DC141AC22531BBE979D98C9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F8478360E5B25ECFF8849625 /* [CP] Check Pods Manifest.lock */ = { + 7B7F643CD9CF5931C23CF49B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -315,7 +347,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 33CC11132044BFA00003C045 /* ExampleWindow.swift in Sources */, + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, ); @@ -326,7 +358,7 @@ /* Begin PBXTargetDependency section */ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Build Flutter Bundle */; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -338,11 +370,89 @@ 33CC10F52044A3C60003C045 /* Base */, ); name = MainMenu.xib; + path = Runner; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 4.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; 33CC10F92044A3C60003C045 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; @@ -369,7 +479,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -387,7 +497,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -422,7 +532,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -434,31 +544,32 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; 33CC10FC2044A3C60003C045 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3791C254B5D15F61597672EC /* Pods-Runner.debug.xcconfig */; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = R7BC26UNC9; FRAMEWORK_SEARCH_PATHS = ( - "$PROJECT_DIR/Flutter/ephemeral", "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", ); - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.nkust.ap.flutter; - PRODUCT_NAME = "NKUST AP"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 4.0; @@ -467,22 +578,22 @@ }; 33CC10FD2044A3C60003C045 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F6D1C7225F9B1694A8A75E31 /* Pods-Runner.release.xcconfig */; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = R7BC26UNC9; FRAMEWORK_SEARCH_PATHS = ( - "$PROJECT_DIR/Flutter/ephemeral", "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", ); - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.nkust.ap.flutter; - PRODUCT_NAME = "NKUST AP"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.0; }; @@ -491,7 +602,7 @@ 33CC111C2044C6BA0003C045 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -512,6 +623,7 @@ buildConfigurations = ( 33CC10F92044A3C60003C045 /* Debug */, 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -521,15 +633,17 @@ buildConfigurations = ( 33CC10FC2044A3C60003C045 /* Debug */, 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Build Flutter Bundle" */ = { + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { isa = XCConfigurationList; buildConfigurations = ( 33CC111C2044C6BA0003C045 /* Debug */, 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index f75281fc..3c48efb6 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -43,7 +43,7 @@ @@ -66,7 +66,7 @@ @@ -85,7 +85,7 @@ diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift new file mode 100644 index 00000000..d53ef643 --- /dev/null +++ b/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..a2ec33f1 --- /dev/null +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 00000000..3c4935a7 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 00000000..ed4cc164 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 00000000..483be613 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 00000000..bcbf36df Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 00000000..9c0a6528 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 00000000..e71a7261 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 00000000..8a31fe2d Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/macos/Base.lproj/MainMenu.xib b/macos/Runner/Base.lproj/MainMenu.xib similarity index 97% rename from macos/Base.lproj/MainMenu.xib rename to macos/Runner/Base.lproj/MainMenu.xib index 8a14279a..537341ab 100644 --- a/macos/Base.lproj/MainMenu.xib +++ b/macos/Runner/Base.lproj/MainMenu.xib @@ -13,19 +13,20 @@ - + - + + - + - + - + @@ -39,7 +40,7 @@ - + @@ -57,7 +58,7 @@ - + @@ -325,7 +326,7 @@ - + diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 00000000..70cb9602 --- /dev/null +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = nkust_ap_flutter + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.nkust.nkustApFlutter + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2019 com.nkust. All rights reserved. diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 00000000..36b0fd94 --- /dev/null +++ b/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 00000000..dff4f495 --- /dev/null +++ b/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from macos/Configs/Warnings.xcconfig rename to macos/Runner/Configs/Warnings.xcconfig diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements new file mode 100644 index 00000000..38bf141d --- /dev/null +++ b/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + com.apple.security.network.client + + + diff --git a/macos/Info.plist b/macos/Runner/Info.plist similarity index 88% rename from macos/Info.plist rename to macos/Runner/Info.plist index 20ee72c5..4789daa6 100644 --- a/macos/Info.plist +++ b/macos/Runner/Info.plist @@ -17,13 +17,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.0.1 + $(FLUTTER_BUILD_NAME) CFBundleVersion - 1 + $(FLUTTER_BUILD_NUMBER) LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright - Copyright © 2018 Google LLC. All rights reserved. + $(PRODUCT_COPYRIGHT) NSMainNibFile MainMenu NSPrincipalClass diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 00000000..2722837e --- /dev/null +++ b/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements new file mode 100644 index 00000000..852fa1a4 --- /dev/null +++ b/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/pubspec.yaml b/pubspec.yaml index 26c88ce0..7b96b594 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: nkust_ap description: A new Flutter application. -version: 3.2.7+30207 +version: 3.2.8+30208 environment: sdk: ">=2.2.2 <3.0.0" @@ -18,6 +18,7 @@ dependencies: url_launcher: 5.1.2 share: 0.6.2+1 image_picker: 0.6.1+4 + path_provider: 1.3.0 firebase_core: 0.4.0+9 firebase_analytics: 5.0.2 firebase_remote_config: 0.2.0+7 @@ -26,7 +27,7 @@ dependencies: http: 0.12.0+2 html: 0.14.0+2 #third party plugin - dio: 2.1.13 + dio: 3.0.3 toast: 0.1.4 tuple: 1.0.2 encrypt: 2.0.0 @@ -39,6 +40,8 @@ dependencies: photo_view: 0.5.0 date_range_picker: 1.0.6 flutter_autofill: 0.4.1 + image: 2.1.4 + flutter_native_image: 0.0.4 dev_dependencies: flutter_test: sdk: flutter