dreampad/lib/app/modules/home/views/home_view.dart

821 lines
24 KiB
Dart
Raw Normal View History

2023-11-28 10:44:58 +08:00
import 'package:dreampad/app/models/models.dart';
import 'package:dreampad/app/routes/app_pages.dart';
2023-11-30 01:56:40 +08:00
import 'package:dreampad/app/shared/constants/dimens.dart';
2023-11-28 10:44:58 +08:00
import 'package:dreampad/app/shared/shared.dart';
2023-11-30 14:58:48 +08:00
import 'package:dreampad/app/shared/widgets/touch_hint_widget.dart';
2023-11-28 10:44:58 +08:00
import 'package:flutter/material.dart';
2023-11-28 20:25:09 +08:00
import 'package:flutter_hooks/flutter_hooks.dart';
2023-11-28 10:44:58 +08:00
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
import '../models/explore_app_model.dart';
import '../widgets/explore_widget.dart';
import '../widgets/goal_dialog.dart';
2023-11-30 00:08:39 +08:00
import '../widgets/lantern_widget.dart';
2023-11-28 10:44:58 +08:00
import '../widgets/user_widget.dart';
class HomeView extends GetView<HomeController> {
const HomeView({Key? key}) : super(key: key);
2023-11-28 20:25:09 +08:00
2023-11-28 10:44:58 +08:00
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeBg,
fit: BoxFit.fill,
),
),
child: Obx(
() => Scaffold(
backgroundColor: Colors.transparent,
2023-11-30 18:06:27 +08:00
body: controller.create.value
? Center(
child: Images.homeCreate,
)
: buildBody(context),
2023-11-28 10:44:58 +08:00
),
),
),
);
}
Widget buildBody(BuildContext context) {
2023-11-30 14:58:48 +08:00
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: controller.explored2.value >= 4
? null
: () {
controller.explored2.value = controller.explored2.value + 1;
},
child: Obx(
() => Stack(
children: [
Container(
height: 458.h,
width: 996.w,
margin: REdgeInsets.only(
left: 90.0,
top: 178.0,
),
color: Colors.transparent,
child: controller.prompt.value ? null : buildApp(context),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
Container(
height: 650.h,
width: 630.w,
margin: REdgeInsets.only(
left: 262.0,
top: 0.0,
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeTree,
fit: BoxFit.fill,
),
),
child: treeWidget(),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
Container(
height: 228.h,
width: 1176.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeColud,
fit: BoxFit.fill,
),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
child: titleWidget(),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
Container(
height: 650.h,
width: 630.w,
margin: REdgeInsets.only(
left: 262.0,
top: 0.0,
),
child: goalWidget(),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
controller.prompt.value
? Container()
: Positioned(
left: 49.w,
top: 50.h,
child: UserWidget(
account: controller.account,
gender: controller.gender,
occupationName: controller.occupationName,
2023-11-30 15:21:27 +08:00
occupationId: controller.occupationId,
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
),
controller.prompt.value
? Container()
: Positioned(
right: 49.w,
top: 50.h,
child: ExploreWidget(
explored: controller.explored.value,
exploreCount: controller.exploreCount.value,
remainTimePercent: controller.remainTime.value /
HomeController.kTotalTimer,
remainTimeStr: controller.remainTimeStr.value,
onPressed: () async {
controller.explorePress();
2023-11-28 10:44:58 +08:00
},
2023-11-30 14:58:48 +08:00
),
),
Positioned(
left: 232.h,
bottom: 84.h,
child: AnimatedVisibilityWidget(
isVisible: controller.explored2.value < 4,
child: const TouchHintWidget(),
),
),
controller.prompt.value
? Container()
: Positioned(
right: 0.w,
bottom: 4.h,
child: Container(
height: 24.h,
width: 69.w,
decoration: BoxDecoration(
color: const Color(0xFF000000).withOpacity(0.4),
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(10.0).r),
),
padding: REdgeInsets.all(5.0),
child: GestureDetector(
onTap: () async {
await controller.reset();
},
child: Text.rich(
TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Images.homeReset,
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
const WidgetSpan(child: RSizedBox(width: 2.0)),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Text(
'重新体验',
style: TextStyles.mediumWhite10,
),
),
],
),
2023-11-28 10:44:58 +08:00
),
),
),
),
2023-11-30 14:58:48 +08:00
],
),
2023-11-28 10:44:58 +08:00
),
);
}
Widget goalWidget() {
return Stack(
children: [
2023-11-28 20:25:09 +08:00
controller.explored2.value >= 4
2023-11-28 17:57:36 +08:00
? Positioned(
left: 15.w,
top: 20.h,
child: Container(
height: 311.h,
width: 230.w,
color: Colors.transparent,
child: fourthGoalWidget(),
),
)
: Container(),
2023-11-28 20:25:09 +08:00
controller.explored2.value >= 3
2023-11-28 17:57:36 +08:00
? Positioned(
left: 352.w,
top: 0.0,
child: Container(
height: 221.h,
width: 281.w,
color: Colors.transparent,
child: thirdGoalWidget(),
),
)
: Container(),
2023-11-28 20:25:09 +08:00
controller.explored2.value >= 2
2023-11-28 17:57:36 +08:00
? Positioned(
left: 363.w,
top: 180.h,
child: Container(
height: 240.h,
width: 240.w,
color: Colors.transparent,
child: secondGoalWidget(),
),
)
: Container(),
2023-11-28 10:44:58 +08:00
],
);
}
Widget fourthGoalWidget() {
2023-11-30 14:58:48 +08:00
return _TextShowUp(
child: Stack(
children: [
Positioned(
left: 115.w,
top: 102.h,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: Text(
'更长期目标',
style: TextStyles.boldWhiteShadow18_111,
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
left: 20.w,
top: 56.h,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showGoalDialog(controller.getGoal(3));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'18岁目标',
style: TextStyles.boldWhiteShadow14_111,
),
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
left: 44.w,
top: 121.h,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showGoalDialog(controller.getGoal(4));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'22岁目标',
style: TextStyles.boldWhiteShadow14_111,
),
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
left: 120.w,
top: 160.h,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showGoalDialog(controller.getGoal(5));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'30岁目标',
style: TextStyles.boldWhiteShadow14_111,
),
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
],
),
2023-11-28 10:44:58 +08:00
);
}
Widget thirdGoalWidget() {
2023-11-30 14:58:48 +08:00
return _TextShowUp(
child: Stack(
children: [
Positioned(
left: 42.w,
top: 94.h,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showGoalDialog(controller.getGoal(2));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'三年内目标',
style: TextStyles.boldWhiteShadow18_111,
),
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
right: 56.w,
top: 61.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'科学竞赛参与',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-30 14:58:48 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
right: 66.w,
top: 123.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'英语能力加强',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-30 14:58:48 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
Positioned(
left: 98.w,
bottom: 18.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'拓展科学知识',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-30 14:58:48 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
],
),
2023-11-28 10:44:58 +08:00
);
}
Widget secondGoalWidget() {
2023-11-30 14:58:48 +08:00
return _TextShowUp(
2023-11-28 20:25:09 +08:00
child: Stack(
children: [
Positioned(
2023-11-30 14:58:48 +08:00
left: 35.w,
top: 58.h,
2023-11-28 20:25:09 +08:00
child: GestureDetector(
2023-11-30 14:58:48 +08:00
behavior: HitTestBehavior.translucent,
2023-11-28 20:25:09 +08:00
onTap: () {
showGoalDialog(controller.getGoal(1));
},
2023-11-30 14:58:48 +08:00
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'今年目标',
style: TextStyles.boldWhiteShadow18_111,
),
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-28 20:25:09 +08:00
Positioned(
right: 34.w,
top: 40.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'课外阅读提升',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-28 20:25:09 +08:00
Positioned(
right: 38.w,
top: 93.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'科学兴趣培养',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-28 20:25:09 +08:00
Positioned(
left: 92.w,
top: 120.h,
child: Container(
height: 36.h,
width: 56.w,
color: Colors.transparent,
child: Text(
'基础教学能力',
textAlign: TextAlign.center,
2023-11-30 18:06:27 +08:00
style: TextStyles.whiteShadow12_111,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-28 20:25:09 +08:00
],
),
2023-11-28 10:44:58 +08:00
);
}
Widget titleWidget() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const RSizedBox(height: 24),
Text(
'梦想职业',
style: TextStyles.mediumWhiteShadow20_114,
),
Text(
controller.occupationName,
style: TextStyles.boldColorShadow28_012,
),
],
);
}
Widget treeWidget() {
2023-11-30 14:58:48 +08:00
return Stack(
children: [
Positioned(
left: 218.w,
top: 244.h,
child: GestureDetector(
onTap: controller.explored2.value >= 4
? () async {
await Get.toNamed(Routes.HOME + Routes.EXPLORE);
}
: null,
child: Container(
width: 210.w,
height: 216.h,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeShine,
fit: BoxFit.fill,
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
),
child: Center(
2023-11-30 16:36:14 +08:00
child: Images.homeBtnIconDreamExploration,
2023-11-28 10:44:58 +08:00
),
),
),
2023-11-30 14:58:48 +08:00
),
controller.explored2.value >= 4
? Positioned(
left: 15.w,
top: 20.h,
child: _LeafGrowUp(
alignment: const Alignment(0.9, 0.1),
child: Container(
height: 311.h,
width: 230.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeFourthLeaf,
fit: BoxFit.fill,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
),
)
: Container(),
controller.explored2.value >= 3
? Positioned(
left: 352.w,
top: 0.0,
child: _LeafGrowUp(
alignment: const Alignment(
-0.9,
0.3,
),
child: Container(
height: 221.h,
width: 281.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeThirdLeaf,
fit: BoxFit.fill,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 14:58:48 +08:00
),
)
: Container(),
controller.explored2.value >= 2
? Positioned(
left: 363.w,
top: 180.h,
child: _LeafGrowUp(
alignment: const Alignment(-1, -0.5),
child: Container(
height: 240.h,
width: 240.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeSecondLeaf,
fit: BoxFit.fill,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
),
2023-11-30 01:56:40 +08:00
),
2023-11-30 14:58:48 +08:00
)
: Container(),
controller.explored2.value >= 1 ? firstLeafWidget() : Container(),
2023-11-30 16:36:14 +08:00
Positioned(
right: 60.w,
top: 346.h,
child: AnimatedVisibilityWidget(
2023-11-30 18:06:27 +08:00
animationWidgetBuilder:
AnimatedVisibilityWidget.fadeAnimationWidgetBuilder,
2023-11-30 16:36:14 +08:00
duration: const Duration(milliseconds: 800),
isVisible: controller.explored2.value >= 1,
2023-11-30 17:12:13 +08:00
child: Visibility(
visible: controller.explored2.value >= 1,
child: const LanternWidget(
brightCount: 0,
),
2023-11-30 16:36:14 +08:00
),
),
),
2023-11-30 14:58:48 +08:00
Positioned(
left: 168.w,
top: 244.h,
child: Images.homeIp,
),
Positioned(
left: 135.w,
bottom: 10.h,
child: GestureDetector(
onTap: () {},
child: buildMainApp(
'智慧编程',
Images.homeMainAppProgramme,
Images.homeProgramme,
Images.homeProgrammeGrey,
TextStyle(
fontSize: Dimens.font_sp10.sp,
fontFamily: 'alph-b',
color: const Color(0xFFFFBC5A),
fontWeight: FontWeight.bold,
2023-11-30 01:56:40 +08:00
),
2023-11-30 14:58:48 +08:00
controller.explored.value,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
),
Positioned(
left: 316.w,
bottom: 10.h,
child: GestureDetector(
onTap: () {},
child: buildMainApp(
'绘本创作',
Images.homeMainAppPictureBook,
Images.homePicturebook,
Images.homePicturebookGrey,
TextStyle(
fontSize: Dimens.font_sp10.sp,
fontFamily: 'alph-b',
color: const Color(0xFF68FFFA),
fontWeight: FontWeight.bold,
2023-11-30 01:56:40 +08:00
),
2023-11-30 14:58:48 +08:00
controller.explored.value,
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
),
Positioned(
right: 79.w,
bottom: 10.h,
child: GestureDetector(
onTap: () {},
child: buildMainApp(
'乐曲创作',
Images.homeMainAppMusic,
Images.homeMusic,
Images.homeMusicGrey,
TextStyle(
fontSize: Dimens.font_sp10.sp,
fontFamily: 'alph-b',
color: const Color(0xFFEA74DF),
fontWeight: FontWeight.bold,
2023-11-30 01:56:40 +08:00
),
2023-11-30 14:58:48 +08:00
controller.explored.value,
2023-11-28 20:25:09 +08:00
),
),
2023-11-30 14:58:48 +08:00
),
],
2023-11-28 10:44:58 +08:00
);
}
2023-11-30 01:56:40 +08:00
Widget buildMainApp(
String name,
AssetImage bgImage,
Widget appIco,
Widget appGreyIco,
TextStyle textStyle,
bool usable,
) {
return Container(
height: 90.w,
width: 90.w,
decoration: BoxDecoration(
image: DecorationImage(
image: usable ? bgImage : Images.homeMainAppGrey,
fit: BoxFit.fill,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
usable ? appIco : appGreyIco,
Text(
name,
style: usable ? textStyle : TextStyles.boldColor10,
)
],
),
);
}
2023-11-28 10:44:58 +08:00
void showGoalDialog(Goal goal) {
SmartDialog.show(
2023-11-28 19:22:36 +08:00
maskColor: const Color(0xFF02184B).withOpacity(0.7),
2023-11-28 10:44:58 +08:00
alignment: Alignment.center,
builder: (_) {
return GoalDialog(
goal: goal,
);
},
);
}
Widget firstLeafWidget() {
return Positioned(
right: 68.w,
top: 326.h,
2023-11-30 14:58:48 +08:00
child: _LeafGrowUp(
alignment: const Alignment(-1, 0),
2023-11-28 20:25:09 +08:00
child: Container(
height: 60.h,
width: 171.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeFirstLeaf,
fit: BoxFit.fill,
),
2023-11-28 10:44:58 +08:00
),
2023-11-28 20:25:09 +08:00
child: Stack(
children: [
Positioned(
left: 23.w,
top: 26.h,
2023-11-30 14:58:48 +08:00
child: _TextShowUp(
child: Text(
'本月已点亮${controller.exploreCount.value}个知识点',
style: TextStyles.mediumWhiteShadow12_111,
),
2023-11-28 20:25:09 +08:00
),
2023-11-28 10:44:58 +08:00
),
2023-11-28 20:25:09 +08:00
],
),
2023-11-28 10:44:58 +08:00
),
),
);
}
Widget buildApp(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RSizedBox(
width: 84,
child: Wrap(
direction: Axis.horizontal,
runSpacing: 22.h,
alignment: WrapAlignment.center,
children: controller.leftExploreApps.map((e) {
return exploreAppWidget(e);
}).toList(),
),
),
RSizedBox(
width: 120,
child: Wrap(
direction: Axis.horizontal,
runSpacing: 22.h,
alignment: WrapAlignment.center,
children: controller.rightExploreApps.map((e) {
return exploreAppWidget(e);
}).toList(),
),
),
],
);
}
Widget exploreAppWidget(ExploreApp app) {
2023-11-30 18:06:27 +08:00
final imageId = 'home/${controller.availableApp.value ? app.icon : app.grayIcon}';
2023-11-28 17:57:36 +08:00
return GestureDetector(
onTap: () {
2023-11-30 01:11:31 +08:00
if (controller.availableApp.value) {}
2023-11-28 17:57:36 +08:00
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
2023-11-30 18:06:27 +08:00
AnimatedSwitcher(
duration: kThemeAnimationDuration * 2,
child: KeyedSubtree(
key: ValueKey(imageId),
child: LoadAssetImage(
imageId,
height: 74.w,
width: 74.w,
fit: BoxFit.fill,
),
),
2023-11-28 15:44:41 +08:00
),
2023-11-28 17:57:36 +08:00
const RSizedBox(height: 2),
Text(
app.name!,
style: TextStyles.boldWhite16,
)
],
2023-11-28 10:44:58 +08:00
),
);
}
}
2023-11-28 20:25:09 +08:00
2023-11-30 14:58:48 +08:00
class _LeafGrowUp extends HookWidget {
const _LeafGrowUp({
2023-11-28 20:25:09 +08:00
required this.child,
2023-11-30 14:58:48 +08:00
required this.alignment,
2023-11-28 20:25:09 +08:00
});
final Widget child;
2023-11-30 14:58:48 +08:00
final Alignment alignment;
2023-11-28 20:25:09 +08:00
@override
Widget build(BuildContext context) {
final controller =
2023-11-30 14:58:48 +08:00
useAnimationController(duration: const Duration(milliseconds: 2000));
2023-11-28 20:25:09 +08:00
useMemoized(() {
controller.forward();
});
2023-11-30 14:58:48 +08:00
final shakeTween = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 0.0, end: 0.08), weight: 0.2),
TweenSequenceItem(tween: Tween(begin: 0.08, end: -0.03), weight: 0.2),
TweenSequenceItem(tween: Tween(begin: -0.03, end: 0.0), weight: 0.2),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 0.0), weight: 0.3),
]);
return RotationTransition(
turns: shakeTween.animate(controller),
alignment: alignment,
child: ScaleTransition(
scale: CurvedAnimation(curve: Curves.fastOutSlowIn, parent: controller),
alignment: alignment,
child: child,
),
);
}
}
class _TextShowUp extends HookWidget {
const _TextShowUp({
required this.child,
});
final Widget child;
@override
Widget build(BuildContext context) {
final controller =
useAnimationController(duration: const Duration(milliseconds: 300));
useMemoized(() async {
await Future.delayed(const Duration(milliseconds: 2000));
controller.forward();
});
2023-11-28 20:25:09 +08:00
return FadeTransition(
2023-11-30 00:08:39 +08:00
opacity: CurvedAnimation(curve: Curves.easeIn, parent: controller),
2023-11-28 20:25:09 +08:00
child: child,
);
}
}