From 9444bfcbb66aadadc28e397d7fb77bf02f02d3a3 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Sat, 11 Nov 2023 22:55:16 +0800 Subject: [PATCH 01/16] add: tab for audit review (undone) --- ios/Runner.xcodeproj/project.pbxproj | 21 ++-- ios/Runner/Info.plist | 2 +- lib/main.dart | 2 +- lib/page/opentreehole/hole_reports.dart | 128 +++++++++++++++--------- macos/Runner.xcodeproj/project.pbxproj | 12 ++- 5 files changed, 107 insertions(+), 58 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4d42abc9f..87bf49bd6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -514,7 +514,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 469; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -524,11 +524,14 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -662,7 +665,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 469; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; @@ -673,11 +676,14 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -699,7 +705,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 469; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -709,11 +715,14 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 8fe1c1e12..5a1937a62 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.11 + 1.4.0 CFBundleSignature ???? CFBundleURLTypes diff --git a/lib/main.dart b/lib/main.dart index 2ba047eef..428a1d66c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,4 @@ -/* + /* * Copyright (C) 2021 DanXi-Dev * * This program is free software: you can redistribute it and/or modify diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index f5dae780b..18ae70867 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -36,6 +36,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_progress_dialog/flutter_progress_dialog.dart'; +import 'package:lazy_load_indexed_stack/lazy_load_indexed_stack.dart'; /// A list page showing the reports for administrators. class BBSReportDetail extends StatefulWidget { @@ -51,6 +52,8 @@ class BBSReportDetailState extends State { final PagedListViewController _listViewController = PagedListViewController(); + int _tabIndex = 0; + /// Reload/load the (new) content and set the [_content] future. Future?> _loadContent(int page) => OpenTreeHoleRepository.getInstance().adminGetReports(page * 10, 10); @@ -58,55 +61,86 @@ class BBSReportDetailState extends State { @override Widget build(BuildContext context) { return PlatformScaffold( - material: (_, __) => - MaterialScaffoldData(resizeToAvoidBottomInset: false), - cupertino: (_, __) => - CupertinoPageScaffoldData(resizeToAvoidBottomInset: false), - iosContentPadding: false, - iosContentBottomPadding: false, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PlatformAppBarX( - title: TopController( - controller: PrimaryScrollController.of(context), - child: Text(S.of(context).reports), - )), - body: StatefulBuilder( - // The builder widget updates context so that MediaQuery below can use the correct context (that is, Scaffold considered) - builder: (context, setState) { - return RefreshIndicator( - edgeOffset: MediaQuery.of(context).padding.top, - color: Theme.of(context).colorScheme.secondary, - backgroundColor: Theme.of(context).dialogBackgroundColor, - onRefresh: () async { - HapticFeedback.mediumImpact(); - await refreshSelf(); - await _listViewController.notifyUpdate( - useInitialData: false, queueDataClear: false); - }, - child: PagedListView( - startPage: 0, - pagedController: _listViewController, - withScrollbar: true, - scrollController: PrimaryScrollController.of(context), - dataReceiver: _loadContent, - builder: _getListItems, - loadingBuilder: (BuildContext context) => Container( - padding: const EdgeInsets.all(8), - child: Center(child: PlatformCircularProgressIndicator()), - ), - endBuilder: (context) => Center( - child: Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(S.of(context).end_reached), - ), - ), - ), - ); - }, - ), - ); + material: (_, __) => + MaterialScaffoldData(resizeToAvoidBottomInset: false), + cupertino: (_, __) => + CupertinoPageScaffoldData(resizeToAvoidBottomInset: false), + iosContentPadding: false, + iosContentBottomPadding: false, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: PlatformAppBarX( + title: TopController( + controller: PrimaryScrollController.of(context), + child: Text(S.of(context).reports), + )), + body: SafeArea( + bottom: false, + child: StatefulBuilder( + // The builder widget updates context so that MediaQuery below can use the correct context (that is, Scaffold considered) + builder: (context, setState) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: CupertinoSlidingSegmentedControl( + onValueChanged: (int? value) { + setState(() { + _tabIndex = value!; + }); + }, + groupValue: _tabIndex, + children: ["Report", "Audit"] + .map((t) => Text(t)) + .toList() + .asMap(), + // todo reformat the code + ), + ), + Expanded( + child: LazyLoadIndexedStack(index: _tabIndex, children: [ + _buildReportPage(), + ]), + ), + ], + ); + }, + ))); } + Widget _buildReportPage() => RefreshIndicator( + edgeOffset: MediaQuery.of(context).padding.top, + color: Theme.of(context).colorScheme.secondary, + backgroundColor: Theme.of(context).dialogBackgroundColor, + onRefresh: () async { + HapticFeedback.mediumImpact(); + await refreshSelf(); + await _listViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); + }, + child: PagedListView( + startPage: 0, + pagedController: _listViewController, + withScrollbar: true, + scrollController: PrimaryScrollController.of(context), + dataReceiver: _loadContent, + builder: _getListItems, + loadingBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(8), + child: Center(child: PlatformCircularProgressIndicator()), + ), + endBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(S.of(context).end_reached), + ), + ), + ), + ); + + // Widget _buildAuditPage() { + // return + // } + List _buildContextMenu( BuildContext pageContext, BuildContext menuContext, OTReport e) => [ diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index b3e4a179c..78763d835 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -435,16 +435,18 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 26; + CURRENT_PROJECT_VERSION = 29; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_COPYRIGHT = "Copyright © 2021 DanXi-Dev. All rights reserved."; PRODUCT_MODULE_NAME = dan_xi; @@ -581,16 +583,18 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 26; + CURRENT_PROJECT_VERSION = 29; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_COPYRIGHT = "Copyright © 2021 DanXi-Dev. All rights reserved."; PRODUCT_MODULE_NAME = dan_xi; @@ -614,16 +618,18 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 26; + CURRENT_PROJECT_VERSION = 29; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_COPYRIGHT = "Copyright © 2021 DanXi-Dev. All rights reserved."; PRODUCT_MODULE_NAME = dan_xi; From 3c5cf2fb65a5fd4821938dc835c43b66ddabaef0 Mon Sep 17 00:00:00 2001 From: w568w <1278297578@qq.com> Date: Sun, 12 Nov 2023 12:20:05 +0800 Subject: [PATCH 02/16] feat: impl audit models and APIs --- lib/common/pubspec.yaml.g.dart | 5 ++- lib/model/opentreehole/audit.dart | 37 +++++++++++++++++++ lib/model/opentreehole/audit.g.dart | 23 ++++++++++++ .../opentreehole/opentreehole_repository.dart | 22 +++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 lib/model/opentreehole/audit.dart create mode 100644 lib/model/opentreehole/audit.g.dart diff --git a/lib/common/pubspec.yaml.g.dart b/lib/common/pubspec.yaml.g.dart index e718031cf..4dee261c3 100644 --- a/lib/common/pubspec.yaml.g.dart +++ b/lib/common/pubspec.yaml.g.dart @@ -58,13 +58,14 @@ const List pre = []; const List build = [r'336']; /// Build date in Unix Time (in seconds) -const int timestamp = 1695302774; +const int timestamp = 1699762316; /// Name [name] const String name = r'dan_xi'; /// Description [description] -const String description = r'Maybe the best all-rounded service app for Fudan University students.'; +const String description = + r'Maybe the best all-rounded service app for Fudan University students.'; /// Repository [repository] const String repository = r''; diff --git a/lib/model/opentreehole/audit.dart b/lib/model/opentreehole/audit.dart new file mode 100644 index 000000000..293320cf5 --- /dev/null +++ b/lib/model/opentreehole/audit.dart @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 DanXi-Dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import 'package:json_annotation/json_annotation.dart'; + +part 'audit.g.dart'; + +@JsonSerializable() +class OTAudit { + final String content; + final int hole_id; + final int id; + final bool? is_actual_sensitive; + final int modified; + + OTAudit(this.content, this.hole_id, this.id, this.is_actual_sensitive, + this.modified); + + factory OTAudit.fromJson(Map json) => + _$OTAuditFromJson(json); + + Map toJson() => _$OTAuditToJson(this); +} diff --git a/lib/model/opentreehole/audit.g.dart b/lib/model/opentreehole/audit.g.dart new file mode 100644 index 000000000..1a6d5c9c6 --- /dev/null +++ b/lib/model/opentreehole/audit.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'audit.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +OTAudit _$OTAuditFromJson(Map json) => OTAudit( + json['content'] as String, + json['hole_id'] as int, + json['id'] as int, + json['is_actual_sensitive'] as bool?, + json['modified'] as int, + ); + +Map _$OTAuditToJson(OTAudit instance) => { + 'content': instance.content, + 'hole_id': instance.hole_id, + 'id': instance.id, + 'is_actual_sensitive': instance.is_actual_sensitive, + 'modified': instance.modified, + }; diff --git a/lib/repository/opentreehole/opentreehole_repository.dart b/lib/repository/opentreehole/opentreehole_repository.dart index f3268b120..9d5e8dda9 100644 --- a/lib/repository/opentreehole/opentreehole_repository.dart +++ b/lib/repository/opentreehole/opentreehole_repository.dart @@ -19,6 +19,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:dan_xi/common/constant.dart'; +import 'package:dan_xi/model/opentreehole/audit.dart'; import 'package:dan_xi/model/opentreehole/division.dart'; import 'package:dan_xi/model/opentreehole/floor.dart'; import 'package:dan_xi/model/opentreehole/hole.dart'; @@ -655,6 +656,27 @@ class OpenTreeHoleRepository extends BaseRepositoryWithDio { return result.map((e) => OTReport.fromJson(e)).toList(); } + Future?> adminGetAuditFloors(DateTime startTime, + [int length = 10]) async { + final response = await dio.get("$_BASE_URL/floors/_sensitive", + queryParameters: { + "offset": startTime.toUtc().toIso8601String(), + "size": length, + "all": false, + "open": true + }, + options: Options(headers: _tokenHeader)); + final result = response.data; + return result.map((e) => OTAudit.fromJson(e)).toList(); + } + + Future adminSetAuditFloor(int floorId, bool isActualSensitive) async { + return (await dio.put("$_BASE_URL/floors/$floorId/_sensitive", + data: {"is_actual_sensitive": isActualSensitive}, + options: Options(headers: _tokenHeader))) + .statusCode; + } + Future adminDeleteFloor(int? floorId, String? deleteReason) async { return (await dio.delete("$_BASE_URL/floors/$floorId", data: { From 1bd3965cda04a5a41058b959d5595719dc73c1ef Mon Sep 17 00:00:00 2001 From: w568w <1278297578@qq.com> Date: Sun, 12 Nov 2023 12:21:08 +0800 Subject: [PATCH 03/16] feat: impl audit tab in hole_reports (unfinished) --- lib/page/opentreehole/hole_reports.dart | 91 ++++++++++++++++--------- 1 file changed, 59 insertions(+), 32 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 18ae70867..6b23add2b 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -49,8 +49,11 @@ class BBSReportDetail extends StatefulWidget { } class BBSReportDetailState extends State { - final PagedListViewController _listViewController = + final PagedListViewController _reportListViewController = PagedListViewController(); + final PagedListViewController _auditListViewController = + PagedListViewController(); + final ScrollController _auditScrollController = ScrollController(); int _tabIndex = 0; @@ -77,33 +80,31 @@ class BBSReportDetailState extends State { bottom: false, child: StatefulBuilder( // The builder widget updates context so that MediaQuery below can use the correct context (that is, Scaffold considered) - builder: (context, setState) { - return Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: CupertinoSlidingSegmentedControl( - onValueChanged: (int? value) { - setState(() { - _tabIndex = value!; - }); - }, - groupValue: _tabIndex, - children: ["Report", "Audit"] - .map((t) => Text(t)) - .toList() - .asMap(), - // todo reformat the code - ), - ), - Expanded( - child: LazyLoadIndexedStack(index: _tabIndex, children: [ - _buildReportPage(), - ]), + builder: (context, setState) => Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: CupertinoSlidingSegmentedControl( + onValueChanged: (int? value) { + setState(() { + _tabIndex = value!; + }); + }, + groupValue: _tabIndex, + children: ["Report", "Audit"] + .map((t) => Text(t)) + .toList() + .asMap(), + // todo reformat the code ), - ], - ); - }, + ), + Expanded( + child: LazyLoadIndexedStack( + index: _tabIndex, + children: [_buildReportPage(), _buildAuditPage()]), + ), + ], + ), ))); } @@ -114,12 +115,12 @@ class BBSReportDetailState extends State { onRefresh: () async { HapticFeedback.mediumImpact(); await refreshSelf(); - await _listViewController.notifyUpdate( + await _reportListViewController.notifyUpdate( useInitialData: false, queueDataClear: false); }, child: PagedListView( startPage: 0, - pagedController: _listViewController, + pagedController: _reportListViewController, withScrollbar: true, scrollController: PrimaryScrollController.of(context), dataReceiver: _loadContent, @@ -137,9 +138,35 @@ class BBSReportDetailState extends State { ), ); - // Widget _buildAuditPage() { - // return - // } + Widget _buildAuditPage() => RefreshIndicator( + edgeOffset: MediaQuery.of(context).padding.top, + color: Theme.of(context).colorScheme.secondary, + backgroundColor: Theme.of(context).dialogBackgroundColor, + onRefresh: () async { + HapticFeedback.mediumImpact(); + await refreshSelf(); + await _auditListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); + }, + child: PagedListView( + startPage: 0, + pagedController: _auditListViewController, + withScrollbar: true, + scrollController: _auditScrollController, + dataReceiver: _loadContent, + builder: _getListItems, + loadingBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(8), + child: Center(child: PlatformCircularProgressIndicator()), + ), + endBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(S.of(context).end_reached), + ), + ), + ), + ); List _buildContextMenu( BuildContext pageContext, BuildContext menuContext, OTReport e) => From 2b3e81f869c940322e82525e30f8745d9ec8d75a Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Sun, 12 Nov 2023 16:38:06 +0800 Subject: [PATCH 04/16] add: tab for audit review --- lib/common/pubspec.yaml.g.dart | 31 +++-- lib/model/opentreehole/audit.dart | 10 +- lib/model/opentreehole/audit.g.dart | 4 + lib/page/opentreehole/hole_reports.dart | 158 ++++++++++++++++++++++-- 4 files changed, 175 insertions(+), 28 deletions(-) diff --git a/lib/common/pubspec.yaml.g.dart b/lib/common/pubspec.yaml.g.dart index 4dee261c3..3054e5103 100644 --- a/lib/common/pubspec.yaml.g.dart +++ b/lib/common/pubspec.yaml.g.dart @@ -29,16 +29,16 @@ SOFTWARE. */ - -// The pubspec file: -// https://dart.dev/tools/pub/pubspec - + +// The pubspec file: +// https://dart.dev/tools/pub/pubspec + // ignore_for_file: lines_longer_than_80_chars // ignore_for_file: unnecessary_raw_strings // ignore_for_file: use_raw_strings // ignore_for_file: avoid_escaping_inner_quotes // ignore_for_file: prefer_single_quotes - + /// Current app version const String version = r'1.4.0+336'; @@ -56,16 +56,15 @@ const List pre = []; /// The build identifier: "foo" in "1.2.3+foo". const List build = [r'336']; - + /// Build date in Unix Time (in seconds) -const int timestamp = 1699762316; - +const int timestamp = 1699774538; + /// Name [name] const String name = r'dan_xi'; /// Description [description] -const String description = - r'Maybe the best all-rounded service app for Fudan University students.'; +const String description = r'Maybe the best all-rounded service app for Fudan University students.'; /// Repository [repository] const String repository = r''; @@ -81,12 +80,12 @@ const String documentation = r''; /// Publish to [publish_to] const String publishTo = r'none'; - + /// Environment const Map environment = { 'sdk': '>=3.0.0', }; - + /// Dependencies const Map dependencies = { 'flutter': { @@ -202,7 +201,7 @@ const Map dependencies = { 'device_identity': r'^1.0.0', 'tutorial_coach_mark': r'^1.2.9', }; - + /// Developer dependencies const Map devDependencies = { 'build_runner': r'^2.1.2', @@ -213,7 +212,7 @@ const Map devDependencies = { 'flutter_lints': r'^2.0.1', 'intl_utils': r'^2.8.3', }; - + /// Dependency overrides const Map dependencyOverrides = { 'intl': r'^0.18.1', @@ -258,10 +257,10 @@ const Map dependencyOverrides = { }, }, }; - + /// Executables const Map executables = {}; - + /// Source data from pubspec.yaml const Map source = { 'name': name, diff --git a/lib/model/opentreehole/audit.dart b/lib/model/opentreehole/audit.dart index 293320cf5..1a3fb1cb4 100644 --- a/lib/model/opentreehole/audit.dart +++ b/lib/model/opentreehole/audit.dart @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +// ignore_for_file: non_constant_identifier_names import 'package:json_annotation/json_annotation.dart'; @@ -26,12 +27,19 @@ class OTAudit { final int id; final bool? is_actual_sensitive; final int modified; + final String? time_created; + final String? time_updated; OTAudit(this.content, this.hole_id, this.id, this.is_actual_sensitive, - this.modified); + this.modified, this.time_created, this.time_updated); factory OTAudit.fromJson(Map json) => _$OTAuditFromJson(json); Map toJson() => _$OTAuditToJson(this); + + @override + String toString() { + return 'OTAudit{content: $content, hole_id: $hole_id, id: $id, is_actual_sensitive: $is_actual_sensitive, modified: $modified, time_created: $time_created, time_updated: $time_updated}'; + } } diff --git a/lib/model/opentreehole/audit.g.dart b/lib/model/opentreehole/audit.g.dart index 1a6d5c9c6..01b90c194 100644 --- a/lib/model/opentreehole/audit.g.dart +++ b/lib/model/opentreehole/audit.g.dart @@ -12,6 +12,8 @@ OTAudit _$OTAuditFromJson(Map json) => OTAudit( json['id'] as int, json['is_actual_sensitive'] as bool?, json['modified'] as int, + json['time_created'] as String?, + json['time_updated'] as String?, ); Map _$OTAuditToJson(OTAudit instance) => { @@ -20,4 +22,6 @@ Map _$OTAuditToJson(OTAudit instance) => { 'id': instance.id, 'is_actual_sensitive': instance.is_actual_sensitive, 'modified': instance.modified, + 'time_created': instance.time_created, + 'time_updated': instance.time_updated, }; diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 6b23add2b..5082dcd5a 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -38,6 +38,11 @@ import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_progress_dialog/flutter_progress_dialog.dart'; import 'package:lazy_load_indexed_stack/lazy_load_indexed_stack.dart'; +import '../../common/constant.dart'; +import '../../model/opentreehole/audit.dart'; +import '../../model/opentreehole/floor.dart'; +import '../subpage_treehole.dart'; + /// A list page showing the reports for administrators. class BBSReportDetail extends StatefulWidget { final Map? arguments; @@ -51,16 +56,38 @@ class BBSReportDetail extends StatefulWidget { class BBSReportDetailState extends State { final PagedListViewController _reportListViewController = PagedListViewController(); - final PagedListViewController _auditListViewController = + final PagedListViewController _auditListViewController = PagedListViewController(); + final ScrollController _auditScrollController = ScrollController(); + final TimeBasedLoadAdaptLayer adaptLayer = + TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 1); - int _tabIndex = 0; + int _tabIndex = 1; /// Reload/load the (new) content and set the [_content] future. - Future?> _loadContent(int page) => + Future?> _loadReportContent(int page) => OpenTreeHoleRepository.getInstance().adminGetReports(page * 10, 10); + Future?> _loadAuditContent(int page) async { + List? loadedAuditFloors = await adaptLayer + .generateReceiver(_auditListViewController, (lastElement) async { + DateTime time = DateTime.now(); + if (lastElement != null) { + time = DateTime.parse(lastElement.time_updated!); + } + // var answer = (await OpenTreeHoleRepository.getInstance() + // .adminGetAuditFloors(time, 10)) + // .toString(); + return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, 10); + }).call(page); + + // If not more posts, notify ListView that we reached the end. + if (loadedAuditFloors?.isEmpty ?? false) return []; + + return loadedAuditFloors; + } + @override Widget build(BuildContext context) { return PlatformScaffold( @@ -123,8 +150,8 @@ class BBSReportDetailState extends State { pagedController: _reportListViewController, withScrollbar: true, scrollController: PrimaryScrollController.of(context), - dataReceiver: _loadContent, - builder: _getListItems, + dataReceiver: _loadReportContent, + builder: _getReportListItems, loadingBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(8), child: Center(child: PlatformCircularProgressIndicator()), @@ -148,13 +175,13 @@ class BBSReportDetailState extends State { await _auditListViewController.notifyUpdate( useInitialData: false, queueDataClear: false); }, - child: PagedListView( + child: PagedListView( startPage: 0, pagedController: _auditListViewController, withScrollbar: true, scrollController: _auditScrollController, - dataReceiver: _loadContent, - builder: _getListItems, + dataReceiver: _loadAuditContent, + builder: _getAuditFloorsListItems, loadingBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(8), child: Center(child: PlatformCircularProgressIndicator()), @@ -168,7 +195,7 @@ class BBSReportDetailState extends State { ), ); - List _buildContextMenu( + List _buildReportContextMenu( BuildContext pageContext, BuildContext menuContext, OTReport e) => [ PlatformContextMenuItem( @@ -185,7 +212,36 @@ class BBSReportDetailState extends State { ) ]; - Widget _getListItems(BuildContext context, + List _buildAuditContextMenu( + BuildContext pageContext, BuildContext menuContext, OTAudit e) => + [ + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, true); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + } + }, + ), + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as not sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, false); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + } + }, + ) + ]; + + Widget _getReportListItems(BuildContext context, ListProvider dataProvider, int index, OTReport e) { void onLinkTap(String? url) { BrowserUtil.openUrl(url!, context); @@ -205,7 +261,7 @@ class BBSReportDetailState extends State { showPlatformModalSheet( context: context, builder: (BuildContext cxt) => PlatformContextMenu( - actions: _buildContextMenu(context, cxt, e), + actions: _buildReportContextMenu(context, cxt, e), cancelButton: CupertinoActionSheetAction( child: Text(S.of(cxt).cancel), onPressed: () => Navigator.of(cxt).pop(), @@ -277,4 +333,84 @@ class BBSReportDetailState extends State { ), ); } + + Widget _getAuditFloorsListItems(BuildContext context, + ListProvider dataProvider, int index, OTAudit e) { + void onLinkTap(String? url) { + BrowserUtil.openUrl(url!, context); + } + + void onImageTap(String? url, Object heroTag) { + smartNavigatorPush(context, '/image/detail', arguments: { + 'preview_url': url, + 'hd_url': OpenTreeHoleRepository.getInstance() + .extractHighDefinitionImageUrl(url!), + 'hero_tag': heroTag + }); + } + + return GestureDetector( + onLongPress: () { + showPlatformModalSheet( + context: context, + builder: (BuildContext cxt) => PlatformContextMenu( + actions: _buildAuditContextMenu(context, cxt, e), + cancelButton: CupertinoActionSheetAction( + child: Text(S.of(cxt).cancel), + onPressed: () => Navigator.of(cxt).pop(), + ), + )); + }, + child: Card( + child: ListTile( + dense: true, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.topLeft, + child: smartRender( + context, e.content, onLinkTap, onImageTap, false)), + const Divider(), + ], + ), + subtitle: Column(children: [ + const SizedBox( + height: 8, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "#${e.hole_id} (##${e.id})", + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ), + Text( + HumanDuration.tryFormat( + context, DateTime.parse(e.time_created!)), + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ), + ]), + ]), + onTap: () async { + ProgressFuture progressDialog = showProgressDialog( + loadingText: S.of(context).loading, context: context); + try { + final OTHole? post = + await OpenTreeHoleRepository.getInstance() + .loadSpecificHole(e.hole_id); + final OTFloor? floor = await OpenTreeHoleRepository.getInstance().loadSpecificFloor(e.id); + if (!mounted) return; + smartNavigatorPush(context, "/bbs/postDetail", + arguments: {"post": post!, "locate": floor!}); + } catch (error, st) { + Noticing.showErrorDialog(context, error, trace: st); + } finally { + progressDialog.dismiss(showAnim: false); + } + })), + ); + } } From 46b7f937c7208f36112eb2557223ef6c79e0d7db Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Sun, 12 Nov 2023 16:38:06 +0800 Subject: [PATCH 05/16] add: tab for audit review --- lib/common/pubspec.yaml.g.dart | 31 +++-- lib/model/opentreehole/audit.dart | 10 +- lib/model/opentreehole/audit.g.dart | 4 + lib/page/opentreehole/hole_reports.dart | 164 ++++++++++++++++++++++-- 4 files changed, 181 insertions(+), 28 deletions(-) diff --git a/lib/common/pubspec.yaml.g.dart b/lib/common/pubspec.yaml.g.dart index 4dee261c3..3054e5103 100644 --- a/lib/common/pubspec.yaml.g.dart +++ b/lib/common/pubspec.yaml.g.dart @@ -29,16 +29,16 @@ SOFTWARE. */ - -// The pubspec file: -// https://dart.dev/tools/pub/pubspec - + +// The pubspec file: +// https://dart.dev/tools/pub/pubspec + // ignore_for_file: lines_longer_than_80_chars // ignore_for_file: unnecessary_raw_strings // ignore_for_file: use_raw_strings // ignore_for_file: avoid_escaping_inner_quotes // ignore_for_file: prefer_single_quotes - + /// Current app version const String version = r'1.4.0+336'; @@ -56,16 +56,15 @@ const List pre = []; /// The build identifier: "foo" in "1.2.3+foo". const List build = [r'336']; - + /// Build date in Unix Time (in seconds) -const int timestamp = 1699762316; - +const int timestamp = 1699774538; + /// Name [name] const String name = r'dan_xi'; /// Description [description] -const String description = - r'Maybe the best all-rounded service app for Fudan University students.'; +const String description = r'Maybe the best all-rounded service app for Fudan University students.'; /// Repository [repository] const String repository = r''; @@ -81,12 +80,12 @@ const String documentation = r''; /// Publish to [publish_to] const String publishTo = r'none'; - + /// Environment const Map environment = { 'sdk': '>=3.0.0', }; - + /// Dependencies const Map dependencies = { 'flutter': { @@ -202,7 +201,7 @@ const Map dependencies = { 'device_identity': r'^1.0.0', 'tutorial_coach_mark': r'^1.2.9', }; - + /// Developer dependencies const Map devDependencies = { 'build_runner': r'^2.1.2', @@ -213,7 +212,7 @@ const Map devDependencies = { 'flutter_lints': r'^2.0.1', 'intl_utils': r'^2.8.3', }; - + /// Dependency overrides const Map dependencyOverrides = { 'intl': r'^0.18.1', @@ -258,10 +257,10 @@ const Map dependencyOverrides = { }, }, }; - + /// Executables const Map executables = {}; - + /// Source data from pubspec.yaml const Map source = { 'name': name, diff --git a/lib/model/opentreehole/audit.dart b/lib/model/opentreehole/audit.dart index 293320cf5..1a3fb1cb4 100644 --- a/lib/model/opentreehole/audit.dart +++ b/lib/model/opentreehole/audit.dart @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +// ignore_for_file: non_constant_identifier_names import 'package:json_annotation/json_annotation.dart'; @@ -26,12 +27,19 @@ class OTAudit { final int id; final bool? is_actual_sensitive; final int modified; + final String? time_created; + final String? time_updated; OTAudit(this.content, this.hole_id, this.id, this.is_actual_sensitive, - this.modified); + this.modified, this.time_created, this.time_updated); factory OTAudit.fromJson(Map json) => _$OTAuditFromJson(json); Map toJson() => _$OTAuditToJson(this); + + @override + String toString() { + return 'OTAudit{content: $content, hole_id: $hole_id, id: $id, is_actual_sensitive: $is_actual_sensitive, modified: $modified, time_created: $time_created, time_updated: $time_updated}'; + } } diff --git a/lib/model/opentreehole/audit.g.dart b/lib/model/opentreehole/audit.g.dart index 1a6d5c9c6..01b90c194 100644 --- a/lib/model/opentreehole/audit.g.dart +++ b/lib/model/opentreehole/audit.g.dart @@ -12,6 +12,8 @@ OTAudit _$OTAuditFromJson(Map json) => OTAudit( json['id'] as int, json['is_actual_sensitive'] as bool?, json['modified'] as int, + json['time_created'] as String?, + json['time_updated'] as String?, ); Map _$OTAuditToJson(OTAudit instance) => { @@ -20,4 +22,6 @@ Map _$OTAuditToJson(OTAudit instance) => { 'id': instance.id, 'is_actual_sensitive': instance.is_actual_sensitive, 'modified': instance.modified, + 'time_created': instance.time_created, + 'time_updated': instance.time_updated, }; diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 6b23add2b..d6fb3293f 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -38,6 +38,11 @@ import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_progress_dialog/flutter_progress_dialog.dart'; import 'package:lazy_load_indexed_stack/lazy_load_indexed_stack.dart'; +import '../../common/constant.dart'; +import '../../model/opentreehole/audit.dart'; +import '../../model/opentreehole/floor.dart'; +import '../subpage_treehole.dart'; + /// A list page showing the reports for administrators. class BBSReportDetail extends StatefulWidget { final Map? arguments; @@ -51,16 +56,38 @@ class BBSReportDetail extends StatefulWidget { class BBSReportDetailState extends State { final PagedListViewController _reportListViewController = PagedListViewController(); - final PagedListViewController _auditListViewController = + final PagedListViewController _auditListViewController = PagedListViewController(); + final ScrollController _auditScrollController = ScrollController(); + final TimeBasedLoadAdaptLayer adaptLayer = + TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 1); - int _tabIndex = 0; + int _tabIndex = 1; /// Reload/load the (new) content and set the [_content] future. - Future?> _loadContent(int page) => + Future?> _loadReportContent(int page) => OpenTreeHoleRepository.getInstance().adminGetReports(page * 10, 10); + Future?> _loadAuditContent(int page) async { + List? loadedAuditFloors = await adaptLayer + .generateReceiver(_auditListViewController, (lastElement) async { + DateTime time = DateTime.now(); + if (lastElement != null) { + time = DateTime.parse(lastElement.time_updated!); + } + // var answer = (await OpenTreeHoleRepository.getInstance() + // .adminGetAuditFloors(time, 10)) + // .toString(); + return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, 10); + }).call(page); + + // If not more posts, notify ListView that we reached the end. + if (loadedAuditFloors?.isEmpty ?? false) return []; + + return loadedAuditFloors; + } + @override Widget build(BuildContext context) { return PlatformScaffold( @@ -123,8 +150,8 @@ class BBSReportDetailState extends State { pagedController: _reportListViewController, withScrollbar: true, scrollController: PrimaryScrollController.of(context), - dataReceiver: _loadContent, - builder: _getListItems, + dataReceiver: _loadReportContent, + builder: _getReportListItems, loadingBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(8), child: Center(child: PlatformCircularProgressIndicator()), @@ -148,17 +175,23 @@ class BBSReportDetailState extends State { await _auditListViewController.notifyUpdate( useInitialData: false, queueDataClear: false); }, - child: PagedListView( + child: PagedListView( startPage: 0, pagedController: _auditListViewController, withScrollbar: true, scrollController: _auditScrollController, - dataReceiver: _loadContent, - builder: _getListItems, + dataReceiver: _loadAuditContent, + builder: _getAuditFloorsListItems, loadingBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(8), child: Center(child: PlatformCircularProgressIndicator()), ), + emptyBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text(S.of(context).no_data), + ), + ), endBuilder: (context) => Center( child: Padding( padding: const EdgeInsets.only(bottom: 16), @@ -168,7 +201,7 @@ class BBSReportDetailState extends State { ), ); - List _buildContextMenu( + List _buildReportContextMenu( BuildContext pageContext, BuildContext menuContext, OTReport e) => [ PlatformContextMenuItem( @@ -185,7 +218,36 @@ class BBSReportDetailState extends State { ) ]; - Widget _getListItems(BuildContext context, + List _buildAuditContextMenu( + BuildContext pageContext, BuildContext menuContext, OTAudit e) => + [ + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, true); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + } + }, + ), + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as not sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, false); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + } + }, + ) + ]; + + Widget _getReportListItems(BuildContext context, ListProvider dataProvider, int index, OTReport e) { void onLinkTap(String? url) { BrowserUtil.openUrl(url!, context); @@ -205,7 +267,7 @@ class BBSReportDetailState extends State { showPlatformModalSheet( context: context, builder: (BuildContext cxt) => PlatformContextMenu( - actions: _buildContextMenu(context, cxt, e), + actions: _buildReportContextMenu(context, cxt, e), cancelButton: CupertinoActionSheetAction( child: Text(S.of(cxt).cancel), onPressed: () => Navigator.of(cxt).pop(), @@ -277,4 +339,84 @@ class BBSReportDetailState extends State { ), ); } + + Widget _getAuditFloorsListItems(BuildContext context, + ListProvider dataProvider, int index, OTAudit e) { + void onLinkTap(String? url) { + BrowserUtil.openUrl(url!, context); + } + + void onImageTap(String? url, Object heroTag) { + smartNavigatorPush(context, '/image/detail', arguments: { + 'preview_url': url, + 'hd_url': OpenTreeHoleRepository.getInstance() + .extractHighDefinitionImageUrl(url!), + 'hero_tag': heroTag + }); + } + + return GestureDetector( + onLongPress: () { + showPlatformModalSheet( + context: context, + builder: (BuildContext cxt) => PlatformContextMenu( + actions: _buildAuditContextMenu(context, cxt, e), + cancelButton: CupertinoActionSheetAction( + child: Text(S.of(cxt).cancel), + onPressed: () => Navigator.of(cxt).pop(), + ), + )); + }, + child: Card( + child: ListTile( + dense: true, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.topLeft, + child: smartRender( + context, e.content, onLinkTap, onImageTap, false)), + const Divider(), + ], + ), + subtitle: Column(children: [ + const SizedBox( + height: 8, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "#${e.hole_id} (##${e.id})", + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ), + Text( + HumanDuration.tryFormat( + context, DateTime.parse(e.time_created!)), + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ), + ]), + ]), + onTap: () async { + ProgressFuture progressDialog = showProgressDialog( + loadingText: S.of(context).loading, context: context); + try { + final OTHole? post = + await OpenTreeHoleRepository.getInstance() + .loadSpecificHole(e.hole_id); + final OTFloor? floor = await OpenTreeHoleRepository.getInstance().loadSpecificFloor(e.id); + if (!mounted) return; + smartNavigatorPush(context, "/bbs/postDetail", + arguments: {"post": post!, "locate": floor!}); + } catch (error, st) { + Noticing.showErrorDialog(context, error, trace: st); + } finally { + progressDialog.dismiss(showAnim: false); + } + })), + ); + } } From 40b5f18a84bcaea403388a33a86f941259a755e6 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Sun, 12 Nov 2023 16:41:28 +0800 Subject: [PATCH 06/16] add: empty builder for reports --- lib/page/opentreehole/hole_reports.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index d6fb3293f..1fff5ae93 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -156,6 +156,12 @@ class BBSReportDetailState extends State { padding: const EdgeInsets.all(8), child: Center(child: PlatformCircularProgressIndicator()), ), + emptyBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text(S.of(context).no_data), + ), + ), endBuilder: (context) => Center( child: Padding( padding: const EdgeInsets.only(bottom: 16), From 9b7af6f0d94a05de3f63477bf635c34c023dc95e Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Sun, 12 Nov 2023 16:53:59 +0800 Subject: [PATCH 07/16] add: audit (dealt) tab --- lib/page/opentreehole/hole_reports.dart | 15 ++++++--------- .../opentreehole/opentreehole_repository.dart | 6 +++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 1fff5ae93..eac51fd5c 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -69,17 +69,14 @@ class BBSReportDetailState extends State { Future?> _loadReportContent(int page) => OpenTreeHoleRepository.getInstance().adminGetReports(page * 10, 10); - Future?> _loadAuditContent(int page) async { + Future?> _loadAuditContent(int page, bool open) async { List? loadedAuditFloors = await adaptLayer .generateReceiver(_auditListViewController, (lastElement) async { DateTime time = DateTime.now(); if (lastElement != null) { time = DateTime.parse(lastElement.time_updated!); } - // var answer = (await OpenTreeHoleRepository.getInstance() - // .adminGetAuditFloors(time, 10)) - // .toString(); - return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, 10); + return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, open, 10); }).call(page); // If not more posts, notify ListView that we reached the end. @@ -118,7 +115,7 @@ class BBSReportDetailState extends State { }); }, groupValue: _tabIndex, - children: ["Report", "Audit"] + children: ["Report", "Audit", "Audit (dealt)"] .map((t) => Text(t)) .toList() .asMap(), @@ -128,7 +125,7 @@ class BBSReportDetailState extends State { Expanded( child: LazyLoadIndexedStack( index: _tabIndex, - children: [_buildReportPage(), _buildAuditPage()]), + children: [_buildReportPage(), _buildAuditPage(true), _buildAuditPage(false)]), ), ], ), @@ -171,7 +168,7 @@ class BBSReportDetailState extends State { ), ); - Widget _buildAuditPage() => RefreshIndicator( + Widget _buildAuditPage(bool open) => RefreshIndicator( edgeOffset: MediaQuery.of(context).padding.top, color: Theme.of(context).colorScheme.secondary, backgroundColor: Theme.of(context).dialogBackgroundColor, @@ -186,7 +183,7 @@ class BBSReportDetailState extends State { pagedController: _auditListViewController, withScrollbar: true, scrollController: _auditScrollController, - dataReceiver: _loadAuditContent, + dataReceiver: (page) => _loadAuditContent(page, open), builder: _getAuditFloorsListItems, loadingBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(8), diff --git a/lib/repository/opentreehole/opentreehole_repository.dart b/lib/repository/opentreehole/opentreehole_repository.dart index 9d5e8dda9..8790b97df 100644 --- a/lib/repository/opentreehole/opentreehole_repository.dart +++ b/lib/repository/opentreehole/opentreehole_repository.dart @@ -40,7 +40,7 @@ import 'package:dan_xi/util/platform_universal.dart'; import 'package:dan_xi/widget/libraries/paged_listview.dart'; import 'package:dio/dio.dart'; -import '../../model/opentreehole/history.dart'; +import 'package:dan_xi/model/opentreehole/history.dart'; /// The repository for OpenTreeHole. /// @@ -656,14 +656,14 @@ class OpenTreeHoleRepository extends BaseRepositoryWithDio { return result.map((e) => OTReport.fromJson(e)).toList(); } - Future?> adminGetAuditFloors(DateTime startTime, + Future?> adminGetAuditFloors(DateTime startTime, bool open, [int length = 10]) async { final response = await dio.get("$_BASE_URL/floors/_sensitive", queryParameters: { "offset": startTime.toUtc().toIso8601String(), "size": length, "all": false, - "open": true + "open": open }, options: Options(headers: _tokenHeader)); final result = response.data; From 95f2b51787a9b96b2e10f0ae7b2d0d4a62e8a208 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 14:09:46 +0800 Subject: [PATCH 08/16] add: audit status text --- lib/page/opentreehole/hole_reports.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index eac51fd5c..94b701a1c 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -72,13 +72,14 @@ class BBSReportDetailState extends State { Future?> _loadAuditContent(int page, bool open) async { List? loadedAuditFloors = await adaptLayer .generateReceiver(_auditListViewController, (lastElement) async { + // print(lastElement); DateTime time = DateTime.now(); if (lastElement != null) { time = DateTime.parse(lastElement.time_updated!); } return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, open, 10); }).call(page); - + // print('loaded:${loadedAuditFloors}'); // If not more posts, notify ListView that we reached the end. if (loadedAuditFloors?.isEmpty ?? false) return []; @@ -119,7 +120,6 @@ class BBSReportDetailState extends State { .map((t) => Text(t)) .toList() .asMap(), - // todo reformat the code ), ), Expanded( @@ -401,6 +401,16 @@ class BBSReportDetailState extends State { style: TextStyle( color: Theme.of(context).hintColor, fontSize: 12), ), + // if (e.is_actual_sensitive == null) do not display + Text( + e.is_actual_sensitive == null + ? "" + : e.is_actual_sensitive! + ? "Sensitive" + : "Not sensitive", + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ), ]), ]), onTap: () async { From ea912a306c3fc2b047caed29c5ad72c1ef994b86 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 14:16:37 +0800 Subject: [PATCH 09/16] change: ref style --- lib/page/opentreehole/hole_reports.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 94b701a1c..62ed881de 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -37,11 +37,10 @@ import 'package:flutter/services.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_progress_dialog/flutter_progress_dialog.dart'; import 'package:lazy_load_indexed_stack/lazy_load_indexed_stack.dart'; - -import '../../common/constant.dart'; -import '../../model/opentreehole/audit.dart'; -import '../../model/opentreehole/floor.dart'; -import '../subpage_treehole.dart'; +import 'package:dan_xi/common/constant.dart'; +import 'package:dan_xi/model/opentreehole/audit.dart'; +import 'package:dan_xi/model/opentreehole/floor.dart'; +import 'package:dan_xi/page/subpage_treehole.dart'; /// A list page showing the reports for administrators. class BBSReportDetail extends StatefulWidget { From 1633cd8604332440f60443413534924729935346 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 14:47:12 +0800 Subject: [PATCH 10/16] change: information display style --- lib/page/opentreehole/hole_reports.dart | 33 ++++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 62ed881de..a678cb8a4 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -76,7 +76,8 @@ class BBSReportDetailState extends State { if (lastElement != null) { time = DateTime.parse(lastElement.time_updated!); } - return OpenTreeHoleRepository.getInstance().adminGetAuditFloors(time, open, 10); + return OpenTreeHoleRepository.getInstance() + .adminGetAuditFloors(time, open, 10); }).call(page); // print('loaded:${loadedAuditFloors}'); // If not more posts, notify ListView that we reached the end. @@ -122,9 +123,11 @@ class BBSReportDetailState extends State { ), ), Expanded( - child: LazyLoadIndexedStack( - index: _tabIndex, - children: [_buildReportPage(), _buildAuditPage(true), _buildAuditPage(false)]), + child: LazyLoadIndexedStack(index: _tabIndex, children: [ + _buildReportPage(), + _buildAuditPage(true), + _buildAuditPage(false) + ]), ), ], ), @@ -400,16 +403,14 @@ class BBSReportDetailState extends State { style: TextStyle( color: Theme.of(context).hintColor, fontSize: 12), ), - // if (e.is_actual_sensitive == null) do not display - Text( - e.is_actual_sensitive == null - ? "" - : e.is_actual_sensitive! - ? "Sensitive" - : "Not sensitive", - style: TextStyle( - color: Theme.of(context).hintColor, fontSize: 12), - ), + if (e.is_actual_sensitive != null) + Text( + e.is_actual_sensitive! + ? "Sensitive" + : "Not Sensitive", + style: TextStyle( + color: Theme.of(context).hintColor, fontSize: 12), + ) ]), ]), onTap: () async { @@ -419,7 +420,9 @@ class BBSReportDetailState extends State { final OTHole? post = await OpenTreeHoleRepository.getInstance() .loadSpecificHole(e.hole_id); - final OTFloor? floor = await OpenTreeHoleRepository.getInstance().loadSpecificFloor(e.id); + final OTFloor? floor = + await OpenTreeHoleRepository.getInstance() + .loadSpecificFloor(e.id); if (!mounted) return; smartNavigatorPush(context, "/bbs/postDetail", arguments: {"post": post!, "locate": floor!}); From 4b136eb90266ce182328d63a7c334ea0dacf0442 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 15:38:56 +0800 Subject: [PATCH 11/16] fix: consistency of page number --- lib/page/opentreehole/hole_reports.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index a678cb8a4..a2ce74898 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -60,7 +60,7 @@ class BBSReportDetailState extends State { final ScrollController _auditScrollController = ScrollController(); final TimeBasedLoadAdaptLayer adaptLayer = - TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 1); + TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 0); int _tabIndex = 1; @@ -77,7 +77,7 @@ class BBSReportDetailState extends State { time = DateTime.parse(lastElement.time_updated!); } return OpenTreeHoleRepository.getInstance() - .adminGetAuditFloors(time, open, 10); + .adminGetAuditFloors(time, open, Constant.POST_COUNT_PER_PAGE); }).call(page); // print('loaded:${loadedAuditFloors}'); // If not more posts, notify ListView that we reached the end. From 71f601452fef515bd5de5893082defe4160d814e Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 17:01:00 +0800 Subject: [PATCH 12/16] fix: scroll controller issue --- lib/page/opentreehole/hole_reports.dart | 199 +++++++++++++----------- 1 file changed, 108 insertions(+), 91 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index a2ce74898..b313b1d48 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -55,12 +55,6 @@ class BBSReportDetail extends StatefulWidget { class BBSReportDetailState extends State { final PagedListViewController _reportListViewController = PagedListViewController(); - final PagedListViewController _auditListViewController = - PagedListViewController(); - - final ScrollController _auditScrollController = ScrollController(); - final TimeBasedLoadAdaptLayer adaptLayer = - TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 0); int _tabIndex = 1; @@ -68,24 +62,6 @@ class BBSReportDetailState extends State { Future?> _loadReportContent(int page) => OpenTreeHoleRepository.getInstance().adminGetReports(page * 10, 10); - Future?> _loadAuditContent(int page, bool open) async { - List? loadedAuditFloors = await adaptLayer - .generateReceiver(_auditListViewController, (lastElement) async { - // print(lastElement); - DateTime time = DateTime.now(); - if (lastElement != null) { - time = DateTime.parse(lastElement.time_updated!); - } - return OpenTreeHoleRepository.getInstance() - .adminGetAuditFloors(time, open, Constant.POST_COUNT_PER_PAGE); - }).call(page); - // print('loaded:${loadedAuditFloors}'); - // If not more posts, notify ListView that we reached the end. - if (loadedAuditFloors?.isEmpty ?? false) return []; - - return loadedAuditFloors; - } - @override Widget build(BuildContext context) { return PlatformScaffold( @@ -125,8 +101,8 @@ class BBSReportDetailState extends State { Expanded( child: LazyLoadIndexedStack(index: _tabIndex, children: [ _buildReportPage(), - _buildAuditPage(true), - _buildAuditPage(false) + AuditList(true), + AuditList(false) ]), ), ], @@ -170,42 +146,6 @@ class BBSReportDetailState extends State { ), ); - Widget _buildAuditPage(bool open) => RefreshIndicator( - edgeOffset: MediaQuery.of(context).padding.top, - color: Theme.of(context).colorScheme.secondary, - backgroundColor: Theme.of(context).dialogBackgroundColor, - onRefresh: () async { - HapticFeedback.mediumImpact(); - await refreshSelf(); - await _auditListViewController.notifyUpdate( - useInitialData: false, queueDataClear: false); - }, - child: PagedListView( - startPage: 0, - pagedController: _auditListViewController, - withScrollbar: true, - scrollController: _auditScrollController, - dataReceiver: (page) => _loadAuditContent(page, open), - builder: _getAuditFloorsListItems, - loadingBuilder: (BuildContext context) => Container( - padding: const EdgeInsets.all(8), - child: Center(child: PlatformCircularProgressIndicator()), - ), - emptyBuilder: (context) => Center( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: Text(S.of(context).no_data), - ), - ), - endBuilder: (context) => Center( - child: Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(S.of(context).end_reached), - ), - ), - ), - ); - List _buildReportContextMenu( BuildContext pageContext, BuildContext menuContext, OTReport e) => [ @@ -223,35 +163,6 @@ class BBSReportDetailState extends State { ) ]; - List _buildAuditContextMenu( - BuildContext pageContext, BuildContext menuContext, OTAudit e) => - [ - PlatformContextMenuItem( - menuContext: menuContext, - child: const Text("Mark as sensitive"), - onPressed: () async { - int? result = await OpenTreeHoleRepository.getInstance() - .adminSetAuditFloor(e.id, true); - if (result != null && result < 300 && mounted) { - Noticing.showModalNotice(pageContext, - message: S.of(pageContext).operation_successful); - } - }, - ), - PlatformContextMenuItem( - menuContext: menuContext, - child: const Text("Mark as not sensitive"), - onPressed: () async { - int? result = await OpenTreeHoleRepository.getInstance() - .adminSetAuditFloor(e.id, false); - if (result != null && result < 300 && mounted) { - Noticing.showModalNotice(pageContext, - message: S.of(pageContext).operation_successful); - } - }, - ) - ]; - Widget _getReportListItems(BuildContext context, ListProvider dataProvider, int index, OTReport e) { void onLinkTap(String? url) { @@ -344,6 +255,73 @@ class BBSReportDetailState extends State { ), ); } +} + +class AuditList extends StatefulWidget { + final bool open; + + AuditList(this.open, {super.key}); + + @override + AuditListState createState() => AuditListState(); +} + +class AuditListState extends State { + final PagedListViewController _auditListViewController = + PagedListViewController(); + final ScrollController _auditScrollController = ScrollController(); + final TimeBasedLoadAdaptLayer auditAdaptLayer = + TimeBasedLoadAdaptLayer(Constant.POST_COUNT_PER_PAGE, 0); + + Future?> _loadAuditContent(int page, bool open) async { + List? loadedAuditFloors = await auditAdaptLayer + .generateReceiver(_auditListViewController, (lastElement) async { + // print(lastElement); + DateTime time = DateTime.now(); + if (lastElement != null) { + time = DateTime.parse(lastElement.time_updated!); + } + return OpenTreeHoleRepository.getInstance() + .adminGetAuditFloors(time, open, Constant.POST_COUNT_PER_PAGE); + }).call(page); + // print('loaded:${loadedAuditFloors}'); + // If not more posts, notify ListView that we reached the end. + if (loadedAuditFloors?.isEmpty ?? false) return []; + return loadedAuditFloors; + } + + List _buildAuditContextMenu( + BuildContext pageContext, BuildContext menuContext, OTAudit e) => + [ + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, true); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + await _auditListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); + } + }, + ), + PlatformContextMenuItem( + menuContext: menuContext, + child: const Text("Mark as not sensitive"), + onPressed: () async { + int? result = await OpenTreeHoleRepository.getInstance() + .adminSetAuditFloor(e.id, false); + if (result != null && result < 300 && mounted) { + Noticing.showModalNotice(pageContext, + message: S.of(pageContext).operation_successful); + await _auditListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); + } + }, + ) + ]; Widget _getAuditFloorsListItems(BuildContext context, ListProvider dataProvider, int index, OTAudit e) { @@ -434,4 +412,43 @@ class BBSReportDetailState extends State { })), ); } + + @override + Widget build(BuildContext context) { + return RefreshIndicator( + edgeOffset: MediaQuery.of(context).padding.top, + color: Theme.of(context).colorScheme.secondary, + backgroundColor: Theme.of(context).dialogBackgroundColor, + onRefresh: () async { + HapticFeedback.mediumImpact(); + await refreshSelf(); + await _auditListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); + }, + child: PagedListView( + startPage: 0, + pagedController: _auditListViewController, + withScrollbar: true, + scrollController: _auditScrollController, + dataReceiver: (page) => _loadAuditContent(page, widget.open), + builder: _getAuditFloorsListItems, + loadingBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(8), + child: Center(child: PlatformCircularProgressIndicator()), + ), + emptyBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text(S.of(context).no_data), + ), + ), + endBuilder: (context) => Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(S.of(context).end_reached), + ), + ), + ), + ); + } } From 80b511e16a84260fbb64d181ea12b5bc55a6e276 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 17:04:00 +0800 Subject: [PATCH 13/16] reformat: add const modifier --- lib/page/opentreehole/hole_reports.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index b313b1d48..116e53e63 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -260,7 +260,7 @@ class BBSReportDetailState extends State { class AuditList extends StatefulWidget { final bool open; - AuditList(this.open, {super.key}); + const AuditList(this.open, {super.key}); @override AuditListState createState() => AuditListState(); From 56f4f3ce86861693e222f39800d636ce11d36686 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Mon, 13 Nov 2023 17:04:59 +0800 Subject: [PATCH 14/16] remove: useless comments --- lib/page/opentreehole/hole_reports.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 116e53e63..8c8be1b56 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -276,7 +276,6 @@ class AuditListState extends State { Future?> _loadAuditContent(int page, bool open) async { List? loadedAuditFloors = await auditAdaptLayer .generateReceiver(_auditListViewController, (lastElement) async { - // print(lastElement); DateTime time = DateTime.now(); if (lastElement != null) { time = DateTime.parse(lastElement.time_updated!); @@ -284,7 +283,6 @@ class AuditListState extends State { return OpenTreeHoleRepository.getInstance() .adminGetAuditFloors(time, open, Constant.POST_COUNT_PER_PAGE); }).call(page); - // print('loaded:${loadedAuditFloors}'); // If not more posts, notify ListView that we reached the end. if (loadedAuditFloors?.isEmpty ?? false) return []; return loadedAuditFloors; From 860fe62c308b3aa5c4bffe5e3d7bbea1c27b758c Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Wed, 15 Nov 2023 20:15:44 +0800 Subject: [PATCH 15/16] change: remove useless refresh and refresh after reports being dealt --- lib/page/opentreehole/hole_reports.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/page/opentreehole/hole_reports.dart b/lib/page/opentreehole/hole_reports.dart index 8c8be1b56..a9bbad336 100644 --- a/lib/page/opentreehole/hole_reports.dart +++ b/lib/page/opentreehole/hole_reports.dart @@ -26,7 +26,6 @@ import 'package:dan_xi/util/browser_util.dart'; import 'package:dan_xi/util/master_detail_view.dart'; import 'package:dan_xi/util/noticing.dart'; import 'package:dan_xi/util/opentreehole/human_duration.dart'; -import 'package:dan_xi/util/public_extension_methods.dart'; import 'package:dan_xi/widget/libraries/paged_listview.dart'; import 'package:dan_xi/widget/libraries/platform_app_bar_ex.dart'; import 'package:dan_xi/widget/libraries/platform_context_menu.dart'; @@ -116,7 +115,6 @@ class BBSReportDetailState extends State { backgroundColor: Theme.of(context).dialogBackgroundColor, onRefresh: () async { HapticFeedback.mediumImpact(); - await refreshSelf(); await _reportListViewController.notifyUpdate( useInitialData: false, queueDataClear: false); }, @@ -158,6 +156,8 @@ class BBSReportDetailState extends State { if (result != null && result < 300 && mounted) { Noticing.showModalNotice(pageContext, message: S.of(pageContext).operation_successful); + await _reportListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); } }, ) @@ -232,6 +232,8 @@ class BBSReportDetailState extends State { if (result != null && result < 300 && mounted) { Noticing.showModalNotice(context, message: S.of(context).operation_successful); + await _reportListViewController.notifyUpdate( + useInitialData: false, queueDataClear: false); } }, ), @@ -419,7 +421,6 @@ class AuditListState extends State { backgroundColor: Theme.of(context).dialogBackgroundColor, onRefresh: () async { HapticFeedback.mediumImpact(); - await refreshSelf(); await _auditListViewController.notifyUpdate( useInitialData: false, queueDataClear: false); }, From f35f726fda1627db97ade7c8267fe4c1e62eda43 Mon Sep 17 00:00:00 2001 From: Ivanfei Date: Thu, 16 Nov 2023 01:33:28 +0800 Subject: [PATCH 16/16] change: ios runner version follows the version in pubspec.yaml --- ios/Runner.xcodeproj/project.pbxproj | 18 ++++++------------ lib/common/pubspec.yaml.g.dart | 8 ++++---- pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 87bf49bd6..320e7215c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -514,7 +514,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 469; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -524,7 +524,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -665,7 +665,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 469; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; @@ -676,14 +676,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = xros; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -705,7 +702,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 469; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = QZ9KCS2T78; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -715,14 +712,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; PRODUCT_BUNDLE_IDENTIFIER = "io.github.danxi-dev.dan-xi"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = xros; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/lib/common/pubspec.yaml.g.dart b/lib/common/pubspec.yaml.g.dart index 3054e5103..a98374a8a 100644 --- a/lib/common/pubspec.yaml.g.dart +++ b/lib/common/pubspec.yaml.g.dart @@ -40,7 +40,7 @@ // ignore_for_file: prefer_single_quotes /// Current app version -const String version = r'1.4.0+336'; +const String version = r'1.4.2+338'; /// The major version number: "1" in "1.2.3". const int major = 1; @@ -49,16 +49,16 @@ const int major = 1; const int minor = 4; /// The patch version number: "3" in "1.2.3". -const int patch = 0; +const int patch = 2; /// The pre-release identifier: "foo" in "1.2.3-foo". const List pre = []; /// The build identifier: "foo" in "1.2.3+foo". -const List build = [r'336']; +const List build = [r'338']; /// Build date in Unix Time (in seconds) -const int timestamp = 1699774538; +const int timestamp = 1700069432; /// Name [name] const String name = r'dan_xi'; diff --git a/pubspec.yaml b/pubspec.yaml index 40c707d31..3e1d61fe6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: dan_xi description: Maybe the best all-rounded service app for Fudan University students. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.4.0+336 +version: 1.4.2+338 environment: sdk: '>=3.0.0'