完成 作业首页更改和作业笔迹还原默认两倍速 和查看原稿功能
This commit is contained in:
parent
8287518fc1
commit
1f2e5dbb56
|
|
@ -41,3 +41,11 @@ class GestureHandwritingRecording {
|
||||||
required this.intervalTime,
|
required this.intervalTime,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记还原页面 查看原稿
|
||||||
|
*/
|
||||||
|
class ShowStudentMmanuscript {
|
||||||
|
bool showManuscript; // 查看原稿
|
||||||
|
ShowStudentMmanuscript(this.showManuscript);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
|
||||||
|
|
||||||
var zhixinCall = () async {
|
var zhixinCall = () async {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
print('执行添加笔画${i},${j}');
|
// print('执行添加笔画${i},${j}');
|
||||||
trajectorys = List.from(trajectorys)..add(theRecording);
|
trajectorys = List.from(trajectorys)..add(theRecording);
|
||||||
ref.read(jobDrawingTrajectoryProvider.notifier).setVal(trajectorys);
|
ref.read(jobDrawingTrajectoryProvider.notifier).setVal(trajectorys);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,568 @@
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:flutter/services.dart';
|
||||||
|
// import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
// import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
// import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
|
// import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
// import 'package:marking_app/common/model/event_bus/job_home_refresh_bus.dart';
|
||||||
|
// import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
||||||
|
// import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
|
// import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
// import 'package:marking_app/utils/index.dart';
|
||||||
|
// import 'package:marking_app/utils/my_text.dart';
|
||||||
|
// import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
|
|
||||||
|
// import 'package:badges/badges.dart' as badges;
|
||||||
|
|
||||||
|
// part 'job_home.g.dart';
|
||||||
|
|
||||||
|
// class JobHome extends StatefulWidget {
|
||||||
|
// const JobHome({super.key});
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// State<JobHome> createState() => _JobHomeState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, AutomaticKeepAliveClientMixin {
|
||||||
|
// @override
|
||||||
|
// bool get wantKeepAlive => true;
|
||||||
|
|
||||||
|
// late LinkHeaderNotifier _linkNotifier;
|
||||||
|
// late ValueNotifier<bool> _secondFloorOpen;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// getData();
|
||||||
|
// eventOn(callback: (JobHomeRefreshBus item) => getData());
|
||||||
|
// _linkNotifier = LinkHeaderNotifier();
|
||||||
|
// _secondFloorOpen = ValueNotifier<bool>(false);
|
||||||
|
// super.initState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void dispose() {
|
||||||
|
// eventCancel();
|
||||||
|
// _linkNotifier.dispose();
|
||||||
|
// _secondFloorOpen.dispose();
|
||||||
|
// super.dispose();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Future<int> getData() async {
|
||||||
|
// try {
|
||||||
|
// var _client = await getClient();
|
||||||
|
// var _result = await _client.getJobsByPage(MarkingListParams(
|
||||||
|
// isFinish: false,
|
||||||
|
// page: 1,
|
||||||
|
// limit: 1,
|
||||||
|
// pageType: 0,
|
||||||
|
// ));
|
||||||
|
// var data = _result.data?.total ?? 0;
|
||||||
|
// eventFire(model: QuantityToBeReviewedData(data));
|
||||||
|
// return data;
|
||||||
|
// } catch (e) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// super.build(context);
|
||||||
|
|
||||||
|
// return AnnotatedRegion(
|
||||||
|
// value: const SystemUiOverlayStyle(
|
||||||
|
// systemNavigationBarColor: Color(0xFF000000),
|
||||||
|
// systemNavigationBarDividerColor: null,
|
||||||
|
// statusBarColor: Colors.white,
|
||||||
|
// systemNavigationBarIconBrightness: Brightness.light,
|
||||||
|
// statusBarIconBrightness: Brightness.dark,
|
||||||
|
// statusBarBrightness: Brightness.light,
|
||||||
|
// ),
|
||||||
|
// child: SizedBox(
|
||||||
|
// height: ScreenUtil().screenHeight,
|
||||||
|
// width: ScreenUtil().screenWidth,
|
||||||
|
// child: Column(
|
||||||
|
// children: [
|
||||||
|
// // 二楼
|
||||||
|
// SecondFloorWidget(_linkNotifier, _secondFloorOpen, refreshCall: () => eventFire(model: JobHomeRefreshBus())),
|
||||||
|
// Expanded(
|
||||||
|
// child: EasyRefresh.custom(
|
||||||
|
// header: LinkHeader(
|
||||||
|
// _linkNotifier,
|
||||||
|
// extent: 70.0,
|
||||||
|
// triggerDistance: 70.0,
|
||||||
|
// completeDuration: Duration(milliseconds: 500),
|
||||||
|
// ),
|
||||||
|
// onRefresh: () async {
|
||||||
|
// if (_secondFloorOpen.value) return;
|
||||||
|
// // await Future.delayed(Duration(seconds: 2), () {
|
||||||
|
// // if (mounted) {
|
||||||
|
// // setState(() {
|
||||||
|
// // _count = 20;
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// // });
|
||||||
|
// },
|
||||||
|
// onLoad: () async {
|
||||||
|
// // await Future.delayed(Duration(seconds: 2), () {
|
||||||
|
// // if (mounted) {
|
||||||
|
// // setState(() {
|
||||||
|
// // _count += 20;
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// // });
|
||||||
|
// },
|
||||||
|
// slivers: <Widget>[
|
||||||
|
// SliverAppBar(
|
||||||
|
// expandedHeight: 300.h,
|
||||||
|
// pinned: true,
|
||||||
|
// floating: true,
|
||||||
|
// backgroundColor: Colors.red,
|
||||||
|
// flexibleSpace: FlexibleSpaceBar(
|
||||||
|
// centerTitle: false,
|
||||||
|
// title: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// children: [
|
||||||
|
// SlidingData([
|
||||||
|
// EntranceModel(
|
||||||
|
// title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: RouterManager.jobMainListPagePath),
|
||||||
|
// EntranceModel(
|
||||||
|
// title: '学生历史作业',
|
||||||
|
// image: 'assets/images/job_home_history.png',
|
||||||
|
// navigationUrl: '${RouterManager.jobStudentGroupPath}?page=history',
|
||||||
|
// ),
|
||||||
|
// EntranceModel(
|
||||||
|
// title: '知识点点掌握',
|
||||||
|
// image: 'assets/images/job_home_knowledge.png',
|
||||||
|
// navigationUrl: RouterManager.jobKnowledgePointsPath)
|
||||||
|
// ]),
|
||||||
|
// $TermRow([
|
||||||
|
// EntranceModel(
|
||||||
|
// title: '答题轨迹',
|
||||||
|
// image: 'assets/images/job_home_answer_record.png',
|
||||||
|
// navigationUrl: RouterManager.answerTrajectoryPath),
|
||||||
|
// EntranceModel(
|
||||||
|
// title: '优先批阅设定',
|
||||||
|
// image: 'assets/images/job_home_youxian.png',
|
||||||
|
// navigationUrl: '${RouterManager.jobStudentGroupPath}?page=set',
|
||||||
|
// )
|
||||||
|
// ], 0),
|
||||||
|
// ],
|
||||||
|
// )),
|
||||||
|
// ),
|
||||||
|
// SliverList(
|
||||||
|
// delegate: SliverChildBuilderDelegate(
|
||||||
|
// (context, index) {
|
||||||
|
// return Container(
|
||||||
|
// height: 40.h,
|
||||||
|
// color: Colors.amber,
|
||||||
|
// width: ScreenUtil().screenWidth,
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// childCount: 10,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class EntranceModel extends Object {
|
||||||
|
// String title;
|
||||||
|
// String image;
|
||||||
|
// String navigationUrl;
|
||||||
|
// EntranceModel({required this.title, required this.image, required this.navigationUrl});
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class QuantityToBeReviewedData extends Object {
|
||||||
|
// int num;
|
||||||
|
// QuantityToBeReviewedData(this.num);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @swidget
|
||||||
|
// Widget $termRow(BuildContext context, List<EntranceModel> items, int data) {
|
||||||
|
// var leng = items.length;
|
||||||
|
// Widget childWidget;
|
||||||
|
// switch (leng) {
|
||||||
|
// case 1:
|
||||||
|
// childWidget = Row(children: [Expanded(child: $TermItem(items[0], data))]);
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// childWidget = Row(children: [
|
||||||
|
// Expanded(flex: 9, child: $TermItem(items[0], data)),
|
||||||
|
// Expanded(flex: 1, child: SizedBox()),
|
||||||
|
// Expanded(flex: 9, child: $TermItem(items[1], data)),
|
||||||
|
// ]);
|
||||||
|
// break;
|
||||||
|
// case 3:
|
||||||
|
// double _theHeight = ScreenUtil().screenWidth / 19 + 54.h * 2;
|
||||||
|
// childWidget = Row(
|
||||||
|
// children: [
|
||||||
|
// Expanded(child: $TermItem(items[0], data, theHeight: _theHeight)),
|
||||||
|
// SizedBox(width: ScreenUtil().screenWidth / 19),
|
||||||
|
// Expanded(
|
||||||
|
// child: SizedBox(
|
||||||
|
// height: _theHeight,
|
||||||
|
// child: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// $TermItem(items[1], data),
|
||||||
|
// $TermItem(items[2], data),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// childWidget = Container();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return Container(padding: EdgeInsets.symmetric(horizontal: 14.w), child: childWidget);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @swidget
|
||||||
|
// Widget $termItem(BuildContext context, EntranceModel e, int data, {double? theHeight}) {
|
||||||
|
// bool isJob = e.title == '作业批阅';
|
||||||
|
|
||||||
|
// return Material(
|
||||||
|
// color: Colors.white,
|
||||||
|
// elevation: 3.r,
|
||||||
|
// shadowColor: const Color.fromRGBO(231, 231, 231, 1),
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
||||||
|
// child: InkWell(
|
||||||
|
// onTap: () => easyThrottle('GO_TO_JOB_HOME_NAVIGATION', () {
|
||||||
|
// RouterManager.router.navigateTo(context, e.navigationUrl, transition: getTransition());
|
||||||
|
// }),
|
||||||
|
|
||||||
|
// // splashColor: splashColor,
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
||||||
|
// child: badges.Badge(
|
||||||
|
// showBadge: isJob && data > 0,
|
||||||
|
// ignorePointer: false,
|
||||||
|
// badgeContent: quickText(data, color: Colors.white, size: 10.sp),
|
||||||
|
// badgeAnimation: badges.BadgeAnimation.rotation(
|
||||||
|
// animationDuration: Duration(seconds: 1),
|
||||||
|
// colorChangeAnimationDuration: Duration(seconds: 1),
|
||||||
|
// loopAnimation: false,
|
||||||
|
// curve: Curves.fastOutSlowIn,
|
||||||
|
// colorChangeAnimationCurve: Curves.easeInCubic,
|
||||||
|
// ),
|
||||||
|
// badgeStyle: badges.BadgeStyle(
|
||||||
|
// badgeColor: Color.fromRGBO(255, 105, 105, 1),
|
||||||
|
// shape: badges.BadgeShape.square,
|
||||||
|
// borderRadius: BorderRadius.only(topLeft: Radius.circular(10.r), topRight: Radius.circular(8.5.r), bottomRight: Radius.circular(8.5.r)),
|
||||||
|
// // borderSide: BorderSide(color: Colors.white, width: 2),
|
||||||
|
// elevation: 1,
|
||||||
|
// padding: EdgeInsets.symmetric(horizontal: isPad() ? 11.w : 16.w, vertical: 2.h),
|
||||||
|
// ),
|
||||||
|
// position: badges.BadgePosition.topEnd(top: 10.r, end: 10.r),
|
||||||
|
// child: Container(
|
||||||
|
// height: theHeight,
|
||||||
|
// padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(8.r)),
|
||||||
|
// // boxShadow: [
|
||||||
|
// // BoxShadow(
|
||||||
|
// // color: const Color.fromRGBO(231, 231, 231, 1),
|
||||||
|
// // offset: Offset(4.w, 6.h), //阴影y轴偏移量
|
||||||
|
// // blurRadius: 8, //阴影模糊程度
|
||||||
|
// // spreadRadius: 0.2, //阴影扩散程度
|
||||||
|
// // )
|
||||||
|
// // ],
|
||||||
|
// // border: Border.all(width: 0.5.w, color: Color.fromARGB(255, 219, 226, 250)),
|
||||||
|
// ),
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// child: isJob
|
||||||
|
// ? Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Image.asset(e.image, height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||||
|
// SizedBox(height: 6.r),
|
||||||
|
// quickText(e.title, size: 12.sp, color: Color.fromRGBO(79, 79, 79, 1), fontWeight: FontWeight.w500),
|
||||||
|
// ],
|
||||||
|
// )
|
||||||
|
// : Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Image.asset(e.image, height: 32.r, width: 32.r, fit: BoxFit.cover),
|
||||||
|
// SizedBox(width: 6.r),
|
||||||
|
// quickText(e.title, size: 12.sp, color: Color.fromRGBO(79, 79, 79, 1), fontWeight: FontWeight.w500),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// )),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class SlidingData extends HookWidget with EventBusMixin {
|
||||||
|
// final List<EntranceModel> items;
|
||||||
|
// SlidingData(this.items);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// var dataNumber = useState<QuantityToBeReviewedData?>(null);
|
||||||
|
|
||||||
|
// useEffect(() {
|
||||||
|
// eventOn(callback: (QuantityToBeReviewedData data) => (dataNumber.value = data));
|
||||||
|
// return () {
|
||||||
|
// eventCancel();
|
||||||
|
// };
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
// return $TermRow(items, dataNumber.value?.num ?? 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// 二楼视图
|
||||||
|
// class SecondFloorWidget extends StatefulWidget {
|
||||||
|
// // Header连接通知器
|
||||||
|
// final LinkHeaderNotifier linkNotifier;
|
||||||
|
// // 二楼开启状态
|
||||||
|
// final ValueNotifier<bool> secondFloorOpen;
|
||||||
|
// final Function refreshCall;
|
||||||
|
|
||||||
|
// const SecondFloorWidget(this.linkNotifier, this.secondFloorOpen, {required this.refreshCall, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// State<StatefulWidget> createState() => SecondFloorWidgetState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class SecondFloorWidgetState extends State<SecondFloorWidget> {
|
||||||
|
// // 触发二楼高度
|
||||||
|
// final double _openSecondFloorExtent = 100.0;
|
||||||
|
// // 指示器值
|
||||||
|
// double? _indicatorValue = 0.0;
|
||||||
|
|
||||||
|
// // 二楼高度
|
||||||
|
// double _secondFloor = 0.0;
|
||||||
|
// // 显示展开收起动画
|
||||||
|
// bool _toggleAnimation = false;
|
||||||
|
// Duration _toggleAnimationDuration = Duration(milliseconds: 300);
|
||||||
|
// // 二楼是否打开
|
||||||
|
// bool _isOpen = false;
|
||||||
|
|
||||||
|
// RefreshMode get _refreshState => widget.linkNotifier.refreshState;
|
||||||
|
// double get _pulledExtent => widget.linkNotifier.pulledExtent;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// widget.linkNotifier.addListener(onLinkNotify);
|
||||||
|
// super.initState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void onLinkNotify() {
|
||||||
|
// setState(() {
|
||||||
|
// if (_refreshState == RefreshMode.armed || _refreshState == RefreshMode.refresh) {
|
||||||
|
// _indicatorValue = null;
|
||||||
|
// // 判断是否到展开二楼
|
||||||
|
// if (widget.secondFloorOpen.value && !_toggleAnimation) {
|
||||||
|
// _isOpen = true;
|
||||||
|
// _secondFloor = MediaQuery.of(context).size.height - 60.h;
|
||||||
|
// _toggleAnimation = true;
|
||||||
|
// Future.delayed(_toggleAnimationDuration, () {
|
||||||
|
// if (mounted) {
|
||||||
|
// setState(() {
|
||||||
|
// _toggleAnimation = false;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// } else if (_refreshState == RefreshMode.refreshed || _refreshState == RefreshMode.done) {
|
||||||
|
// _indicatorValue = 1.0;
|
||||||
|
// } else {
|
||||||
|
// if (_refreshState == RefreshMode.inactive) {
|
||||||
|
// _indicatorValue = 0.0;
|
||||||
|
// _toggleAnimation = true;
|
||||||
|
// Future.delayed(_toggleAnimationDuration, () {
|
||||||
|
// if (mounted) {
|
||||||
|
// setState(() {
|
||||||
|
// _toggleAnimation = false;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// double indicatorValue = _pulledExtent / 70.0 * 0.8;
|
||||||
|
// _indicatorValue = indicatorValue < 0.8 ? indicatorValue : 0.8;
|
||||||
|
// // 判断是否到达打开二楼高度
|
||||||
|
// if (_refreshState == RefreshMode.drag) {
|
||||||
|
// if (_pulledExtent >= _openSecondFloorExtent) {
|
||||||
|
// widget.secondFloorOpen.value = true;
|
||||||
|
// } else {
|
||||||
|
// widget.secondFloorOpen.value = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// // var spaceWidth = SizedBox(height: ScreenUtil().screenWidth / 19);
|
||||||
|
// // return RefreshIndicator(
|
||||||
|
// // onRefresh: () async => widget.refreshCall(),
|
||||||
|
// // child: ListView(
|
||||||
|
// // children: [
|
||||||
|
// // Container(
|
||||||
|
// // constraints: BoxConstraints(
|
||||||
|
// // minHeight: 200.h,
|
||||||
|
// // maxWidth: double.infinity,
|
||||||
|
// // ),
|
||||||
|
// // child: Image.asset('assets/images/job_home_top_bgm.png', fit: BoxFit.fitWidth),
|
||||||
|
// // ),
|
||||||
|
// // SizedBox(height: 30.h),
|
||||||
|
// // SlidingData([
|
||||||
|
// // EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: RouterManager.jobMainListPagePath),
|
||||||
|
// // EntranceModel(
|
||||||
|
// // title: '学生历史作业',
|
||||||
|
// // image: 'assets/images/job_home_history.png',
|
||||||
|
// // navigationUrl: '${RouterManager.jobStudentGroupPath}?page=history',
|
||||||
|
// // ),
|
||||||
|
// // EntranceModel(title: '知识点点掌握', image: 'assets/images/job_home_knowledge.png', navigationUrl: RouterManager.jobKnowledgePointsPath)
|
||||||
|
// // ]),
|
||||||
|
// // spaceWidth,
|
||||||
|
// // $TermRow([
|
||||||
|
// // EntranceModel(title: '答题轨迹', image: 'assets/images/job_home_answer_record.png', navigationUrl: RouterManager.answerTrajectoryPath),
|
||||||
|
// // EntranceModel(
|
||||||
|
// // title: '优先批阅设定',
|
||||||
|
// // image: 'assets/images/job_home_youxian.png',
|
||||||
|
// // navigationUrl: '${RouterManager.jobStudentGroupPath}?page=set',
|
||||||
|
// // )
|
||||||
|
// // ], 0),
|
||||||
|
// // // spaceWidth,
|
||||||
|
// // // $TermRow([EntranceModel(title: '批阅设置', image: 'assets/images/job_home_marking_set.png', navigationUrl: '')], 0),
|
||||||
|
// // ],
|
||||||
|
// // ),
|
||||||
|
// // );
|
||||||
|
// var heightVal = _isOpen
|
||||||
|
// ? _secondFloor
|
||||||
|
// : _refreshState == RefreshMode.inactive
|
||||||
|
// ? 0.0
|
||||||
|
// : _pulledExtent;
|
||||||
|
// return AnnotatedRegion(
|
||||||
|
// value: const SystemUiOverlayStyle(
|
||||||
|
// systemNavigationBarColor: Color(0xFF000000),
|
||||||
|
// systemNavigationBarDividerColor: null,
|
||||||
|
// statusBarColor: Colors.white,
|
||||||
|
// systemNavigationBarIconBrightness: Brightness.light,
|
||||||
|
// statusBarIconBrightness: Brightness.dark,
|
||||||
|
// statusBarBrightness: Brightness.light,
|
||||||
|
// ),
|
||||||
|
// child: InkWell(
|
||||||
|
// onTap: () {
|
||||||
|
// if (_isOpen) {
|
||||||
|
// setState(() {
|
||||||
|
// _isOpen = false;
|
||||||
|
// _toggleAnimation = true;
|
||||||
|
// Future.delayed(_toggleAnimationDuration, () {
|
||||||
|
// if (mounted) {
|
||||||
|
// setState(() {
|
||||||
|
// _toggleAnimation = false;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// child: AnimatedContainer(
|
||||||
|
// padding: EdgeInsets.zero,
|
||||||
|
// height: heightVal,
|
||||||
|
// color: Colors.white,
|
||||||
|
// duration: _toggleAnimation ? _toggleAnimationDuration : Duration(milliseconds: 1),
|
||||||
|
// child: Stack(
|
||||||
|
// children: <Widget>[
|
||||||
|
// Positioned(
|
||||||
|
// bottom: 0.0,
|
||||||
|
// left: 0.0,
|
||||||
|
// right: 0.0,
|
||||||
|
// child: Container(
|
||||||
|
// height: MediaQuery.of(context).size.height,
|
||||||
|
// width: double.infinity,
|
||||||
|
// child: Image.asset(
|
||||||
|
// 'assets/images/job_home_top_bgm.png',
|
||||||
|
// fit: BoxFit.fitHeight,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Positioned(
|
||||||
|
// bottom: 0.0,
|
||||||
|
// left: 0.0,
|
||||||
|
// right: 0.0,
|
||||||
|
// child: AnimatedCrossFade(
|
||||||
|
// firstChild: Center(
|
||||||
|
// child: Container(
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// margin: EdgeInsets.only(
|
||||||
|
// bottom: 20.0,
|
||||||
|
// top: 10.0,
|
||||||
|
// ),
|
||||||
|
// width: 24.0,
|
||||||
|
// height: 24.0,
|
||||||
|
// child: Offstage(
|
||||||
|
// offstage: widget.secondFloorOpen.value,
|
||||||
|
// child: CircularProgressIndicator(
|
||||||
|
// value: _indicatorValue,
|
||||||
|
// valueColor: AlwaysStoppedAnimation(Colors.white),
|
||||||
|
// strokeWidth: 2.4,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// secondChild: Center(
|
||||||
|
// child: Container(
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// margin: EdgeInsets.only(
|
||||||
|
// bottom: 20.0,
|
||||||
|
// top: 10.0,
|
||||||
|
// ),
|
||||||
|
// child: Offstage(
|
||||||
|
// offstage: !widget.secondFloorOpen.value,
|
||||||
|
// child: Text(
|
||||||
|
// '欢迎来到二楼',
|
||||||
|
// style: TextStyle(fontSize: 18.0, color: Colors.white),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// crossFadeState: widget.secondFloorOpen.value ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||||
|
// duration: Duration(milliseconds: 300),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
|
||||||
import 'package:marking_app/common/mixin/common.dart';
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
|
import 'package:marking_app/common/model/common/base_page_data.dart';
|
||||||
import 'package:marking_app/common/model/event_bus/job_home_refresh_bus.dart';
|
import 'package:marking_app/common/model/event_bus/job_home_refresh_bus.dart';
|
||||||
|
import 'package:marking_app/common/model/job/job_task_item.dart';
|
||||||
import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
import 'package:marking_app/common/model/marking/marking_list_params.dart';
|
||||||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
import 'package:marking_app/routes/RouterManager.dart';
|
import 'package:marking_app/routes/RouterManager.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
||||||
|
import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart';
|
||||||
import 'package:marking_app/utils/index.dart';
|
import 'package:marking_app/utils/index.dart';
|
||||||
import 'package:marking_app/utils/my_text.dart';
|
import 'package:marking_app/utils/my_text.dart';
|
||||||
|
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
|
import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
|
|
||||||
import '../../utils/my_future_builder.dart';
|
import 'components/new_version_of_homework/homework_tasks_view_item.dart';
|
||||||
|
|
||||||
part 'job_home.g.dart';
|
part 'job_home.g.dart';
|
||||||
|
|
||||||
|
|
@ -24,37 +573,51 @@ class JobHome extends StatefulWidget {
|
||||||
State<JobHome> createState() => _JobHomeState();
|
State<JobHome> createState() => _JobHomeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, AutomaticKeepAliveClientMixin {
|
class _JobHomeState extends State<JobHome>
|
||||||
|
with CommonMixin, EventBusMixin, RefreshDataHandle<JobTaskItem, MarkingListParams>, AutomaticKeepAliveClientMixin {
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
|
var param = MarkingListParams(isFinish: false, page: 1, limit: 1, pageType: 0);
|
||||||
|
|
||||||
|
int totalJobNumber = 0;
|
||||||
|
List<JobTaskItem> jobDatas = [];
|
||||||
|
late final EasyRefreshController _refreshController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
getData();
|
_refreshController = EasyRefreshController();
|
||||||
eventOn(callback: (JobHomeRefreshBus item) => getData());
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_refreshController.dispose();
|
||||||
eventCancel();
|
eventCancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getData() async {
|
/* 发起请求 => 作业 */
|
||||||
try {
|
Future<void> toGetPageData({bool isReFresh = false}) async {
|
||||||
var _client = await getClient();
|
if (!isReFresh) {
|
||||||
var _result = await _client.getJobsByPage(MarkingListParams(
|
param.page++;
|
||||||
isFinish: false,
|
}
|
||||||
page: 1,
|
RestClient client = await getClient();
|
||||||
limit: 1,
|
BasePageData<JobTaskItem>? results = await toRefreshData(
|
||||||
pageType: 0,
|
_refreshController,
|
||||||
));
|
api: client.getJobsByPage,
|
||||||
var data = _result.data?.total ?? 0;
|
params: param,
|
||||||
eventFire(model: QuantityToBeReviewedData(data));
|
isReFresh: isReFresh,
|
||||||
return data;
|
context: context,
|
||||||
} catch (e) {
|
);
|
||||||
return 0;
|
if (results != null) {
|
||||||
|
Future.delayed(Duration(seconds: 1), () => eventFire(model: QuantityToBeReviewedData(results.total)));
|
||||||
|
if (isReFresh) {
|
||||||
|
jobDatas.clear();
|
||||||
|
jobDatas = results.items;
|
||||||
|
} else
|
||||||
|
jobDatas.addAll(results.items);
|
||||||
|
setState(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,24 +634,31 @@ class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, Auto
|
||||||
statusBarIconBrightness: Brightness.dark,
|
statusBarIconBrightness: Brightness.dark,
|
||||||
statusBarBrightness: Brightness.light,
|
statusBarBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: RefreshIndicator(
|
child: EasyRefresh(
|
||||||
onRefresh: () async => eventFire(model: JobHomeRefreshBus()),
|
firstRefresh: true,
|
||||||
|
taskIndependence: true,
|
||||||
|
enableControlFinishLoad: true,
|
||||||
|
enableControlFinishRefresh: true,
|
||||||
|
emptyWidget: jobDatas.isEmpty ? const MyEmptyWidget() : null,
|
||||||
|
controller: _refreshController,
|
||||||
|
header: MaterialHeader(),
|
||||||
|
footer: TaurusFooter(),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
// Container(
|
||||||
constraints: BoxConstraints(
|
// constraints: BoxConstraints(
|
||||||
minHeight: 200.h,
|
// minHeight: 200.h,
|
||||||
maxWidth: double.infinity,
|
// maxWidth: double.infinity,
|
||||||
),
|
// ),
|
||||||
// decoration: BoxDecoration(
|
// // decoration: BoxDecoration(
|
||||||
// image: DecorationImage(
|
// // image: DecorationImage(
|
||||||
// image: AssetImage('assets/images/job_home_top_bgm.png'),
|
// // image: AssetImage('assets/images/job_home_top_bgm.png'),
|
||||||
// fit: BoxFit.fitWidth, // 完全填充
|
// // fit: BoxFit.fitWidth, // 完全填充
|
||||||
// ),
|
// // ),
|
||||||
// ),
|
// // ),
|
||||||
child: Image.asset('assets/images/job_home_top_bgm.png', fit: BoxFit.fitWidth),
|
// child: Image.asset('assets/images/job_home_top_bgm.png', fit: BoxFit.fitWidth),
|
||||||
),
|
// ),
|
||||||
SizedBox(height: 30.h),
|
SizedBox(height: MediaQuery.of(context).padding.top + 20.h),
|
||||||
SlidingData([
|
SlidingData([
|
||||||
EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: RouterManager.jobMainListPagePath),
|
EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: RouterManager.jobMainListPagePath),
|
||||||
EntranceModel(
|
EntranceModel(
|
||||||
|
|
@ -109,8 +679,19 @@ class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, Auto
|
||||||
], 0),
|
], 0),
|
||||||
// spaceWidth,
|
// spaceWidth,
|
||||||
// $TermRow([EntranceModel(title: '批阅设置', image: 'assets/images/job_home_marking_set.png', navigationUrl: '')], 0),
|
// $TermRow([EntranceModel(title: '批阅设置', image: 'assets/images/job_home_marking_set.png', navigationUrl: '')], 0),
|
||||||
|
spaceWidth,
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12.w),
|
||||||
|
child: Column(
|
||||||
|
children: jobDatas
|
||||||
|
.map((e) => HomeworkTasksViewItem(completed: false, jobTaskItem: e, call: () => _refreshController.callRefresh()))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
onRefresh: () => toGetPageData(isReFresh: true),
|
||||||
|
onLoad: () => toGetPageData(isReFresh: false),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,15 @@ class JobHandwritingDrawingTrajectoryProviderHandle extends StateNotifier<List<G
|
||||||
state = val;
|
state = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查看原稿
|
||||||
|
final jobHandwritingStudentManuscriptProvider = StateNotifierProvider<JobHandwritingStudentManuscriptHandle, ShowStudentMmanuscript>(
|
||||||
|
(ref) => JobHandwritingStudentManuscriptHandle(ShowStudentMmanuscript(false)));
|
||||||
|
|
||||||
|
class JobHandwritingStudentManuscriptHandle extends StateNotifier<ShowStudentMmanuscript> {
|
||||||
|
JobHandwritingStudentManuscriptHandle(ShowStudentMmanuscript progress) : super(progress);
|
||||||
|
|
||||||
|
setVal(ShowStudentMmanuscript val) {
|
||||||
|
state = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -375,19 +375,35 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
||||||
late ImageStreamListener theImageStreamListener;
|
late ImageStreamListener theImageStreamListener;
|
||||||
|
|
||||||
late ValueNotifier<List<GestureHandwritingRecording>> _vnHandWritings;
|
late ValueNotifier<List<GestureHandwritingRecording>> _vnHandWritings;
|
||||||
|
late ValueNotifier<List<GestureHandwritingRecording>> _vnPrimaryHandWritings;
|
||||||
|
|
||||||
late RemoveListener _jobHandwritingDrawingTrajectoryListener; // 批注关闭监听
|
late RemoveListener _jobHandwritingDrawingTrajectoryListener; // 批注关闭监听
|
||||||
|
late RemoveListener _jobHandwritingDrawingTrajectoryListener1; // 查看原稿
|
||||||
List<List<GestureHandwritingRecording>> _packagedHandwritingDatas = [];
|
List<List<GestureHandwritingRecording>> _packagedHandwritingDatas = [];
|
||||||
List<GestureHandwritingRecording> _packagedHandwritingDataAll = [];
|
List<GestureHandwritingRecording> _packagedHandwritingDataAll = []; // 总数据
|
||||||
List<GestureHandwritingRecording> pendingData = []; // 待执行数据
|
List<GestureHandwritingRecording> pendingData = []; // 待执行数据
|
||||||
List<Timer> timers = [];
|
List<Timer> timers = [];
|
||||||
int handwritingTime = 0;
|
int handwritingTime = 0;
|
||||||
int handwritingDuration = 0;
|
int handwritingDuration = 0;
|
||||||
double speed = 1; // 播放速度
|
double speed = 2.0; // 播放速度
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_vnHandWritings = ValueNotifier<List<GestureHandwritingRecording>>([]);
|
_vnHandWritings = ValueNotifier<List<GestureHandwritingRecording>>([]);
|
||||||
|
_vnPrimaryHandWritings = ValueNotifier<List<GestureHandwritingRecording>>([]);
|
||||||
|
_jobHandwritingDrawingTrajectoryListener1 = ref.read(jobHandwritingStudentManuscriptProvider.notifier).addListener((state) {
|
||||||
|
print('点击进入了');
|
||||||
|
// 查看原稿控制
|
||||||
|
if (state.showManuscript) {
|
||||||
|
// 查看原稿
|
||||||
|
eventFire(model: JobHandwritingPlaybarBus(false)); // 暂停
|
||||||
|
_vnPrimaryHandWritings.value = [..._packagedHandwritingDataAll];
|
||||||
|
} else {
|
||||||
|
// 清空原稿数据
|
||||||
|
_vnPrimaryHandWritings.value = [];
|
||||||
|
}
|
||||||
|
}, fireImmediately: false);
|
||||||
_jobHandwritingDrawingTrajectoryListener = ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).addListener((state) {
|
_jobHandwritingDrawingTrajectoryListener = ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).addListener((state) {
|
||||||
_vnHandWritings.value = state;
|
_vnHandWritings.value = state;
|
||||||
}, fireImmediately: false);
|
}, fireImmediately: false);
|
||||||
|
|
@ -447,7 +463,9 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
||||||
if (e.isActive) e.cancel();
|
if (e.isActive) e.cancel();
|
||||||
});
|
});
|
||||||
_jobHandwritingDrawingTrajectoryListener();
|
_jobHandwritingDrawingTrajectoryListener();
|
||||||
|
_jobHandwritingDrawingTrajectoryListener1();
|
||||||
_vnHandWritings.dispose();
|
_vnHandWritings.dispose();
|
||||||
|
_vnPrimaryHandWritings.dispose();
|
||||||
try {
|
try {
|
||||||
imageStream?.removeListener(theImageStreamListener);
|
imageStream?.removeListener(theImageStreamListener);
|
||||||
eventCancel();
|
eventCancel();
|
||||||
|
|
@ -537,7 +555,7 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
||||||
pendingData.addAll(_packagedHandwritingDataAll);
|
pendingData.addAll(_packagedHandwritingDataAll);
|
||||||
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
|
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
|
||||||
}
|
}
|
||||||
|
ref.read(jobHandwritingStudentManuscriptProvider.notifier).setVal(ShowStudentMmanuscript(false));
|
||||||
executableData.forEach((e) {
|
executableData.forEach((e) {
|
||||||
var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e));
|
var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e));
|
||||||
timers.add(ter);
|
timers.add(ter);
|
||||||
|
|
@ -579,14 +597,12 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
var showManuscript = ref.watch(jobHandwritingStudentManuscriptProvider).showManuscript;
|
||||||
return Container(
|
return Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: RepaintBoundary(
|
child: RepaintBoundary(
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
willChange: true,
|
foregroundPainter: HandWritingDrawingPainter(ctrl: showManuscript ? _vnPrimaryHandWritings : _vnHandWritings),
|
||||||
isComplex: true,
|
|
||||||
foregroundPainter: HandWritingDrawingPainter(ctrl: _vnHandWritings),
|
|
||||||
// size: Size(ScreenUtil().screenWidth - 60.r, widget.boxHeight),
|
|
||||||
child: RepaintBoundary(
|
child: RepaintBoundary(
|
||||||
child: $TheCachedNetworkImage(
|
child: $TheCachedNetworkImage(
|
||||||
imageUrl: widget.image,
|
imageUrl: widget.image,
|
||||||
|
|
@ -609,6 +625,47 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HandWritingDrawingPainter1 extends CustomPainter {
|
||||||
|
final ValueNotifier<List<GestureHandwritingRecording>> ctrl;
|
||||||
|
HandWritingDrawingPainter1({required this.ctrl}) : super(repaint: ctrl);
|
||||||
|
//[定义画笔]
|
||||||
|
final Paint paintBrush = Paint()
|
||||||
|
//画笔颜色
|
||||||
|
..color = Colors.black
|
||||||
|
//画笔笔触类型
|
||||||
|
..strokeCap = StrokeCap.round
|
||||||
|
//是否启动抗锯齿
|
||||||
|
..isAntiAlias = true
|
||||||
|
//绘画风格,默认为填充
|
||||||
|
// ..style = PaintingStyle.fill
|
||||||
|
//画笔的宽度
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 0.5.r;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
// canvas.drawPoints(PointMode.points, thePoints, paintBrush);
|
||||||
|
|
||||||
|
var points = ctrl.value;
|
||||||
|
var _length = points.length;
|
||||||
|
for (int i = 0; i < _length; i++) {
|
||||||
|
GestureHandwritingRecording item = points[i];
|
||||||
|
GestureHandwritingRecording? nextItem = i + 1 < _length ? points[i + 1] : null;
|
||||||
|
|
||||||
|
Offset offsetData = item.data;
|
||||||
|
Offset? nextOffsetData = nextItem?.data;
|
||||||
|
if (nextOffsetData != null && item.stroke == nextItem?.stroke) {
|
||||||
|
canvas.drawLine(offsetData, nextOffsetData, paintBrush);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||||
|
return false; // 如果 oldDelegate 不是 MyCustomPainter 的实例,则总是重绘
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class HandWritingDrawingPainter extends CustomPainter {
|
class HandWritingDrawingPainter extends CustomPainter {
|
||||||
final ValueNotifier<List<GestureHandwritingRecording>> ctrl;
|
final ValueNotifier<List<GestureHandwritingRecording>> ctrl;
|
||||||
HandWritingDrawingPainter({required this.ctrl}) : super(repaint: ctrl);
|
HandWritingDrawingPainter({required this.ctrl}) : super(repaint: ctrl);
|
||||||
|
|
@ -746,148 +803,174 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount, L
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
height: 60.h,
|
height: 62.h,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
color: Color.fromRGBO(0, 0, 0, 0.4),
|
color: Color.fromRGBO(0, 0, 0, 0.4),
|
||||||
child: Row(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (usePlaybar.handWritingReady.value)
|
Container(alignment: Alignment.centerRight, child: StudentManuscriptBtn()), // 查看原稿按钮
|
||||||
InkWell(
|
Row(
|
||||||
onTap: () => easyThrottle('job_handwriting_play_pause', () {
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
if (usePlaybar.handwritingDuration.value == 0) return ToastUtils.showInfo('没有笔迹');
|
children: [
|
||||||
|
if (usePlaybar.handWritingReady.value)
|
||||||
|
InkWell(
|
||||||
|
onTap: () => easyThrottle('job_handwriting_play_pause', () {
|
||||||
|
if (usePlaybar.handwritingDuration.value == 0) return ToastUtils.showInfo('没有笔迹');
|
||||||
|
|
||||||
usePlaybar.playPause.value = !usePlaybar.playPause.value;
|
usePlaybar.playPause.value = !usePlaybar.playPause.value;
|
||||||
usePlaybar.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
usePlaybar.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
||||||
}),
|
}),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
!usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
!usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 28.r,
|
size: 28.r,
|
||||||
),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
SpinKitPouringHourGlassRefined(size: 40.sp, color: Colors.white),
|
|
||||||
SizedBox(width: 6.w),
|
|
||||||
Expanded(
|
|
||||||
child: LayoutBuilder(builder: (context, constraints) {
|
|
||||||
final double containerWidth = constraints.maxWidth; // 展示区域总宽度
|
|
||||||
var unitScale = containerWidth / timeConsuming; // 单位刻度
|
|
||||||
var pauseIntervalsLength = pauseIntervals.length;
|
|
||||||
|
|
||||||
List<Widget> pauseTickMarks = pauseIntervals.asMap().keys.map((e) {
|
|
||||||
bool isLast = e == pauseIntervalsLength - 1;
|
|
||||||
bool isFirst = e == 0;
|
|
||||||
var item = pauseIntervals[e];
|
|
||||||
return Positioned(
|
|
||||||
top: 0,
|
|
||||||
left: unitScale * item.startTime,
|
|
||||||
child: Container(
|
|
||||||
width: unitScale * (item.apart ?? 0),
|
|
||||||
height: 8.h,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color.fromRGBO(202, 201, 201, 1),
|
|
||||||
borderRadius: isFirst
|
|
||||||
? BorderRadius.only(topLeft: Radius.circular(8.r), bottomLeft: Radius.circular(10.r))
|
|
||||||
: (isLast ? BorderRadius.only(topRight: Radius.circular(8.r), bottomRight: Radius.circular(10.r)) : null),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
)
|
||||||
}).toList();
|
else
|
||||||
|
SpinKitPouringHourGlassRefined(size: 40.sp, color: Colors.white),
|
||||||
|
SizedBox(width: 6.w),
|
||||||
|
Expanded(
|
||||||
|
child: LayoutBuilder(builder: (context, constraints) {
|
||||||
|
final double containerWidth = constraints.maxWidth; // 展示区域总宽度
|
||||||
|
var unitScale = containerWidth / timeConsuming; // 单位刻度
|
||||||
|
var pauseIntervalsLength = pauseIntervals.length;
|
||||||
|
|
||||||
return Column(
|
List<Widget> pauseTickMarks = pauseIntervals.asMap().keys.map((e) {
|
||||||
mainAxisSize: MainAxisSize.min,
|
bool isLast = e == pauseIntervalsLength - 1;
|
||||||
children: [
|
bool isFirst = e == 0;
|
||||||
Stack(
|
var item = pauseIntervals[e];
|
||||||
children: [
|
return Positioned(
|
||||||
Container(
|
top: 0,
|
||||||
|
left: unitScale * item.startTime,
|
||||||
|
child: Container(
|
||||||
|
width: unitScale * (item.apart ?? 0),
|
||||||
height: 8.h,
|
height: 8.h,
|
||||||
width: containerWidth,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
// color: Color.fromRGBO(146, 146, 146, 1),
|
color: Color.fromRGBO(202, 201, 201, 1),
|
||||||
color: Colors.white,
|
borderRadius: isFirst
|
||||||
borderRadius: BorderRadius.circular(50.r),
|
? BorderRadius.only(topLeft: Radius.circular(8.r), bottomLeft: Radius.circular(10.r))
|
||||||
|
: (isLast ? BorderRadius.only(topRight: Radius.circular(8.r), bottomRight: Radius.circular(10.r)) : null),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
...pauseTickMarks,
|
);
|
||||||
Container(
|
}).toList();
|
||||||
height: 8.h,
|
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 8.h,
|
||||||
|
width: containerWidth,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
// color: Color.fromRGBO(146, 146, 146, 1),
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(50.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
...pauseTickMarks,
|
||||||
|
Container(
|
||||||
|
height: 8.h,
|
||||||
|
width: containerWidth,
|
||||||
|
// color: Theme.of(context).primaryColor,
|
||||||
|
child: SliderTheme(
|
||||||
|
data: SliderTheme.of(context).copyWith(
|
||||||
|
trackHeight: 8.h, // 轨道高度
|
||||||
|
trackShape: RoundedRectSliderTrackShape(), // 轨道形状,可以自定义
|
||||||
|
activeTrackColor: Theme.of(context).primaryColor, // 激活的轨道颜色
|
||||||
|
inactiveTrackColor: Colors.transparent, // 未激活的轨道颜色
|
||||||
|
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0, disabledThumbRadius: 0),
|
||||||
|
thumbColor: Colors.white, // 滑块颜色
|
||||||
|
overlayShape: RoundSliderOverlayShape(overlayRadius: 0),
|
||||||
|
overlayColor: Colors.black54, // 滑块外圈颜色
|
||||||
|
// valueIndicatorShape: PaddleSliderValueIndicatorShape(), // 标签形状,可以自定义
|
||||||
|
),
|
||||||
|
child: Slider(
|
||||||
|
value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(),
|
||||||
|
min: 0.0,
|
||||||
|
max: usePlaybar.handwritingDuration.value.toDouble(),
|
||||||
|
inactiveColor: Colors.transparent,
|
||||||
|
onChangeEnd: (value) {
|
||||||
|
if (!usePlaybar.handWritingReady.value) return;
|
||||||
|
usePlaybar.playTimingSuspend(); // 暂停计时器得暂停
|
||||||
|
usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value));
|
||||||
|
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
||||||
|
},
|
||||||
|
onChanged: (double value) {
|
||||||
|
if (!usePlaybar.handWritingReady.value) return;
|
||||||
|
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.h),
|
||||||
|
SizedBox(
|
||||||
width: containerWidth,
|
width: containerWidth,
|
||||||
// color: Theme.of(context).primaryColor,
|
child: Row(
|
||||||
child: SliderTheme(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
data: SliderTheme.of(context).copyWith(
|
children: [
|
||||||
trackHeight: 8.h, // 轨道高度
|
quickText('累计停顿:$pauseCount次', color: Colors.white, size: 7.sp),
|
||||||
trackShape: RoundedRectSliderTrackShape(), // 轨道形状,可以自定义
|
quickText(convertSeconds(usePlaybar.useTime.value)?.toString() ?? '', color: Colors.white, size: 7.sp),
|
||||||
activeTrackColor: Theme.of(context).primaryColor, // 激活的轨道颜色
|
],
|
||||||
inactiveTrackColor: Colors.transparent, // 未激活的轨道颜色
|
|
||||||
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0, disabledThumbRadius: 0),
|
|
||||||
thumbColor: Colors.white, // 滑块颜色
|
|
||||||
overlayShape: RoundSliderOverlayShape(overlayRadius: 0),
|
|
||||||
overlayColor: Colors.black54, // 滑块外圈颜色
|
|
||||||
// valueIndicatorShape: PaddleSliderValueIndicatorShape(), // 标签形状,可以自定义
|
|
||||||
),
|
|
||||||
child: Slider(
|
|
||||||
value: (usePlaybar.handwritingDuration.value - usePlaybar.useTime.value).toDouble(),
|
|
||||||
min: 0.0,
|
|
||||||
max: usePlaybar.handwritingDuration.value.toDouble(),
|
|
||||||
inactiveColor: Colors.transparent,
|
|
||||||
onChangeEnd: (value) {
|
|
||||||
if (!usePlaybar.handWritingReady.value) return;
|
|
||||||
usePlaybar.playTimingSuspend(); // 暂停计时器得暂停
|
|
||||||
usePlaybar.eventFire(model: JobHandwritingDragProgressBarBus(value.toInt(), usePlaybar.handwritingDuration.value));
|
|
||||||
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
|
||||||
},
|
|
||||||
onChanged: (double value) {
|
|
||||||
if (!usePlaybar.handWritingReady.value) return;
|
|
||||||
usePlaybar.useTime.value = usePlaybar.handwritingDuration.value - value.toInt();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
SizedBox(height: 4.h),
|
}),
|
||||||
SizedBox(
|
|
||||||
width: containerWidth,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
quickText('累计停顿:$pauseCount次', color: Colors.white, size: 7.sp),
|
|
||||||
quickText(convertSeconds(usePlaybar.useTime.value)?.toString() ?? '', color: Colors.white, size: 7.sp),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
SizedBox(width: 16.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () => easyThrottle('job_handwriting_speed', () {
|
|
||||||
var theIndex = PlaybackSpeed.values.indexOf(usePlaybar.constantFastSpeed.value);
|
|
||||||
if (theIndex == PlaybackSpeed.values.length - 1) {
|
|
||||||
theIndex = -1;
|
|
||||||
}
|
|
||||||
usePlaybar.constantFastSpeed.value = PlaybackSpeed.values[theIndex + 1];
|
|
||||||
}, duration: Duration(milliseconds: 500)),
|
|
||||||
child: Container(
|
|
||||||
// alignment: Alignment.,
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
|
|
||||||
decoration: BoxDecoration(color: Color.fromRGBO(182, 197, 250, 1), borderRadius: BorderRadius.circular(4.r)),
|
|
||||||
child: quickText(
|
|
||||||
'${usePlaybar.constantFastSpeed.value.name}',
|
|
||||||
color: Color.fromRGBO(79, 114, 244, 1),
|
|
||||||
size: 8.sp,
|
|
||||||
align: TextAlign.center,
|
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 16.w),
|
||||||
),
|
InkWell(
|
||||||
|
onTap: () => easyThrottle('job_handwriting_speed', () {
|
||||||
|
var theIndex = PlaybackSpeed.values.indexOf(usePlaybar.constantFastSpeed.value);
|
||||||
|
if (theIndex == PlaybackSpeed.values.length - 1) {
|
||||||
|
theIndex = -1;
|
||||||
|
}
|
||||||
|
usePlaybar.constantFastSpeed.value = PlaybackSpeed.values[theIndex + 1];
|
||||||
|
}, duration: Duration(milliseconds: 500)),
|
||||||
|
child: Container(
|
||||||
|
// alignment: Alignment.,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
|
||||||
|
decoration: BoxDecoration(color: Color.fromRGBO(182, 197, 250, 1), borderRadius: BorderRadius.circular(4.r)),
|
||||||
|
child: quickText(
|
||||||
|
'${usePlaybar.constantFastSpeed.value.name}',
|
||||||
|
color: Color.fromRGBO(79, 114, 244, 1),
|
||||||
|
size: 8.sp,
|
||||||
|
align: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 学生原稿按钮视图
|
||||||
|
class StudentManuscriptBtn extends ConsumerWidget {
|
||||||
|
const StudentManuscriptBtn({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => easyThrottle('job_handwriting_udent_manuscript', () {
|
||||||
|
var showManuscript = ref.read(jobHandwritingStudentManuscriptProvider).showManuscript;
|
||||||
|
ref.read(jobHandwritingStudentManuscriptProvider.notifier).setVal(ShowStudentMmanuscript(!showManuscript));
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 2.w, vertical: 1.h),
|
||||||
|
decoration: BoxDecoration(color: Colors.grey, borderRadius: BorderRadius.circular(4.r)),
|
||||||
|
child: quickText('学生原稿', color: Colors.white, size: 8.sp),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SysjTime extends StatefulWidget {
|
class SysjTime extends StatefulWidget {
|
||||||
const SysjTime({super.key});
|
const SysjTime({super.key});
|
||||||
|
|
||||||
|
|
@ -921,7 +1004,7 @@ class _SysjTimeState extends State<SysjTime> with EventBusMixin<JobHandwritingRu
|
||||||
class UseBottomPlaybar with EventBusMixin {
|
class UseBottomPlaybar with EventBusMixin {
|
||||||
final ValueNotifier<int> handwritingDuration; // 笔迹总时长
|
final ValueNotifier<int> handwritingDuration; // 笔迹总时长
|
||||||
final ValueNotifier<bool> playPause; // 播放暂停
|
final ValueNotifier<bool> playPause; // 播放暂停
|
||||||
final ValueNotifier<PlaybackSpeed> constantFastSpeed; // 原速、快速 默认原速
|
final ValueNotifier<PlaybackSpeed> constantFastSpeed; // 播放速度
|
||||||
final ValueNotifier<bool> handWritingReady;
|
final ValueNotifier<bool> handWritingReady;
|
||||||
|
|
||||||
final ValueNotifier<int> useTime; // 耗时 单位:(秒)
|
final ValueNotifier<int> useTime; // 耗时 单位:(秒)
|
||||||
|
|
@ -942,7 +1025,7 @@ class UseBottomPlaybar with EventBusMixin {
|
||||||
if ((milliseconds % 1000) > 500) handwritingDuration += 1;
|
if ((milliseconds % 1000) > 500) handwritingDuration += 1;
|
||||||
return UseBottomPlaybar._(
|
return UseBottomPlaybar._(
|
||||||
playPause: useState(false),
|
playPause: useState(false),
|
||||||
constantFastSpeed: useState(PlaybackSpeed.ORIGINAL_SPEED),
|
constantFastSpeed: useState(PlaybackSpeed.DOUBLE_SPEED), // 默认两倍速
|
||||||
useTime: useState(handwritingDuration),
|
useTime: useState(handwritingDuration),
|
||||||
timer: useState(null),
|
timer: useState(null),
|
||||||
handwritingDuration: useState(handwritingDuration),
|
handwritingDuration: useState(handwritingDuration),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue