完成 作业首页更改和作业笔迹还原默认两倍速 和查看原稿功能
This commit is contained in:
parent
8287518fc1
commit
1f2e5dbb56
|
|
@ -41,3 +41,11 @@ class GestureHandwritingRecording {
|
|||
required this.intervalTime,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 笔记还原页面 查看原稿
|
||||
*/
|
||||
class ShowStudentMmanuscript {
|
||||
bool showManuscript; // 查看原稿
|
||||
ShowStudentMmanuscript(this.showManuscript);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ class TrajectoryViewState extends ConsumerState<TrajectoryView> {
|
|||
|
||||
var zhixinCall = () async {
|
||||
if (mounted) {
|
||||
print('执行添加笔画${i},${j}');
|
||||
// print('执行添加笔画${i},${j}');
|
||||
trajectorys = List.from(trajectorys)..add(theRecording);
|
||||
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/services.dart';
|
||||
import 'package:flutter_easyrefresh/easy_refresh.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/common/base_page_data.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/pages/common/event_bus_mixin.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/my_text.dart';
|
||||
|
||||
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';
|
||||
|
||||
|
|
@ -24,37 +573,51 @@ class JobHome extends StatefulWidget {
|
|||
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
|
||||
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
|
||||
void initState() {
|
||||
getData();
|
||||
eventOn(callback: (JobHomeRefreshBus item) => getData());
|
||||
_refreshController = EasyRefreshController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_refreshController.dispose();
|
||||
eventCancel();
|
||||
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;
|
||||
/* 发起请求 => 作业 */
|
||||
Future<void> toGetPageData({bool isReFresh = false}) async {
|
||||
if (!isReFresh) {
|
||||
param.page++;
|
||||
}
|
||||
RestClient client = await getClient();
|
||||
BasePageData<JobTaskItem>? results = await toRefreshData(
|
||||
_refreshController,
|
||||
api: client.getJobsByPage,
|
||||
params: param,
|
||||
isReFresh: isReFresh,
|
||||
context: context,
|
||||
);
|
||||
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,
|
||||
statusBarBrightness: Brightness.light,
|
||||
),
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async => eventFire(model: JobHomeRefreshBus()),
|
||||
child: EasyRefresh(
|
||||
firstRefresh: true,
|
||||
taskIndependence: true,
|
||||
enableControlFinishLoad: true,
|
||||
enableControlFinishRefresh: true,
|
||||
emptyWidget: jobDatas.isEmpty ? const MyEmptyWidget() : null,
|
||||
controller: _refreshController,
|
||||
header: MaterialHeader(),
|
||||
footer: TaurusFooter(),
|
||||
child: ListView(
|
||||
children: [
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 200.h,
|
||||
maxWidth: double.infinity,
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// image: DecorationImage(
|
||||
// image: AssetImage('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),
|
||||
// Container(
|
||||
// constraints: BoxConstraints(
|
||||
// minHeight: 200.h,
|
||||
// maxWidth: double.infinity,
|
||||
// ),
|
||||
// // decoration: BoxDecoration(
|
||||
// // image: DecorationImage(
|
||||
// // image: AssetImage('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: MediaQuery.of(context).padding.top + 20.h),
|
||||
SlidingData([
|
||||
EntranceModel(title: '作业批阅', image: 'assets/images/job_home_marking.png', navigationUrl: RouterManager.jobMainListPagePath),
|
||||
EntranceModel(
|
||||
|
|
@ -109,8 +679,19 @@ class _JobHomeState extends State<JobHome> with CommonMixin, EventBusMixin, Auto
|
|||
], 0),
|
||||
// spaceWidth,
|
||||
// $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;
|
||||
}
|
||||
}
|
||||
|
||||
// 查看原稿
|
||||
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 ValueNotifier<List<GestureHandwritingRecording>> _vnHandWritings;
|
||||
late ValueNotifier<List<GestureHandwritingRecording>> _vnPrimaryHandWritings;
|
||||
|
||||
late RemoveListener _jobHandwritingDrawingTrajectoryListener; // 批注关闭监听
|
||||
late RemoveListener _jobHandwritingDrawingTrajectoryListener1; // 查看原稿
|
||||
List<List<GestureHandwritingRecording>> _packagedHandwritingDatas = [];
|
||||
List<GestureHandwritingRecording> _packagedHandwritingDataAll = [];
|
||||
List<GestureHandwritingRecording> _packagedHandwritingDataAll = []; // 总数据
|
||||
List<GestureHandwritingRecording> pendingData = []; // 待执行数据
|
||||
List<Timer> timers = [];
|
||||
int handwritingTime = 0;
|
||||
int handwritingDuration = 0;
|
||||
double speed = 1; // 播放速度
|
||||
double speed = 2.0; // 播放速度
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_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) {
|
||||
_vnHandWritings.value = state;
|
||||
}, fireImmediately: false);
|
||||
|
|
@ -447,7 +463,9 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
|||
if (e.isActive) e.cancel();
|
||||
});
|
||||
_jobHandwritingDrawingTrajectoryListener();
|
||||
_jobHandwritingDrawingTrajectoryListener1();
|
||||
_vnHandWritings.dispose();
|
||||
_vnPrimaryHandWritings.dispose();
|
||||
try {
|
||||
imageStream?.removeListener(theImageStreamListener);
|
||||
eventCancel();
|
||||
|
|
@ -537,7 +555,7 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
|||
pendingData.addAll(_packagedHandwritingDataAll);
|
||||
ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
|
||||
}
|
||||
|
||||
ref.read(jobHandwritingStudentManuscriptProvider.notifier).setVal(ShowStudentMmanuscript(false));
|
||||
executableData.forEach((e) {
|
||||
var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed), () => zhixinCall(e));
|
||||
timers.add(ter);
|
||||
|
|
@ -579,14 +597,12 @@ class _HandwritingDrawBoxState extends ConsumerState<HandwritingDrawBox> with Ev
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var showManuscript = ref.watch(jobHandwritingStudentManuscriptProvider).showManuscript;
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
willChange: true,
|
||||
isComplex: true,
|
||||
foregroundPainter: HandWritingDrawingPainter(ctrl: _vnHandWritings),
|
||||
// size: Size(ScreenUtil().screenWidth - 60.r, widget.boxHeight),
|
||||
foregroundPainter: HandWritingDrawingPainter(ctrl: showManuscript ? _vnPrimaryHandWritings : _vnHandWritings),
|
||||
child: RepaintBoundary(
|
||||
child: $TheCachedNetworkImage(
|
||||
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 {
|
||||
final ValueNotifier<List<GestureHandwritingRecording>> ctrl;
|
||||
HandWritingDrawingPainter({required this.ctrl}) : super(repaint: ctrl);
|
||||
|
|
@ -746,148 +803,174 @@ Widget $bottomPlaybar(BuildContext context, int timeConsuming, int pauseCount, L
|
|||
}, []);
|
||||
|
||||
return Container(
|
||||
height: 60.h,
|
||||
height: 62.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||
alignment: Alignment.center,
|
||||
color: Color.fromRGBO(0, 0, 0, 0.4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (usePlaybar.handWritingReady.value)
|
||||
InkWell(
|
||||
onTap: () => easyThrottle('job_handwriting_play_pause', () {
|
||||
if (usePlaybar.handwritingDuration.value == 0) return ToastUtils.showInfo('没有笔迹');
|
||||
Container(alignment: Alignment.centerRight, child: StudentManuscriptBtn()), // 查看原稿按钮
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
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.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
||||
}),
|
||||
child: Icon(
|
||||
!usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
||||
color: Colors.white,
|
||||
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),
|
||||
),
|
||||
usePlaybar.playPause.value = !usePlaybar.playPause.value;
|
||||
usePlaybar.eventFire(model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
|
||||
}),
|
||||
child: Icon(
|
||||
!usePlaybar.playPause.value ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
||||
color: Colors.white,
|
||||
size: 28.r,
|
||||
),
|
||||
);
|
||||
}).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(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Container(
|
||||
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,
|
||||
width: containerWidth,
|
||||
decoration: BoxDecoration(
|
||||
// color: Color.fromRGBO(146, 146, 146, 1),
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(50.r),
|
||||
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),
|
||||
),
|
||||
),
|
||||
...pauseTickMarks,
|
||||
Container(
|
||||
height: 8.h,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
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,
|
||||
// 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();
|
||||
},
|
||||
),
|
||||
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(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 {
|
||||
const SysjTime({super.key});
|
||||
|
||||
|
|
@ -921,7 +1004,7 @@ class _SysjTimeState extends State<SysjTime> with EventBusMixin<JobHandwritingRu
|
|||
class UseBottomPlaybar with EventBusMixin {
|
||||
final ValueNotifier<int> handwritingDuration; // 笔迹总时长
|
||||
final ValueNotifier<bool> playPause; // 播放暂停
|
||||
final ValueNotifier<PlaybackSpeed> constantFastSpeed; // 原速、快速 默认原速
|
||||
final ValueNotifier<PlaybackSpeed> constantFastSpeed; // 播放速度
|
||||
final ValueNotifier<bool> handWritingReady;
|
||||
|
||||
final ValueNotifier<int> useTime; // 耗时 单位:(秒)
|
||||
|
|
@ -942,7 +1025,7 @@ class UseBottomPlaybar with EventBusMixin {
|
|||
if ((milliseconds % 1000) > 500) handwritingDuration += 1;
|
||||
return UseBottomPlaybar._(
|
||||
playPause: useState(false),
|
||||
constantFastSpeed: useState(PlaybackSpeed.ORIGINAL_SPEED),
|
||||
constantFastSpeed: useState(PlaybackSpeed.DOUBLE_SPEED), // 默认两倍速
|
||||
useTime: useState(handwritingDuration),
|
||||
timer: useState(null),
|
||||
handwritingDuration: useState(handwritingDuration),
|
||||
|
|
|
|||
Loading…
Reference in New Issue