添加灯笼和探索内容

This commit is contained in:
tanghong668 2023-11-30 00:08:39 +08:00
parent b9c0c19f13
commit 3202fe4733
10 changed files with 440 additions and 122 deletions

View File

@ -7,12 +7,14 @@ import 'package:dreampad/app/models/models.dart';
import 'package:dreampad/app/routes/app_pages.dart'; import 'package:dreampad/app/routes/app_pages.dart';
import 'package:flustars_flutter3/flustars_flutter3.dart'; import 'package:flustars_flutter3/flustars_flutter3.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:dreampad/app/shared/shared.dart'; import 'package:dreampad/app/shared/shared.dart';
import '../models/chat_msg_model.dart'; import '../models/chat_msg_model.dart';
import '../models/explore_app_model.dart'; import '../models/explore_app_model.dart';
import '../models/knowledge_point_dialogue_model.dart';
import '../models/knowledge_point_model.dart'; import '../models/knowledge_point_model.dart';
import '../providers/home_provider.dart'; import '../providers/home_provider.dart';
import '../widgets/first_time_dialog.dart'; import '../widgets/first_time_dialog.dart';
@ -27,12 +29,14 @@ class HomeController extends GetxController {
final create = true.obs; final create = true.obs;
final prompt = false.obs; final prompt = false.obs;
final exploreCount = 0.obs; final exploreCount = 0.obs;
final exploreDay = 1.obs;
final chatMsgList = RxList<ChatMsg>([]); final chatMsgList = RxList<ChatMsg>([]);
final scrollController = ScrollController();
final selectKnowledge = Rx<KnowledgePoint?>(null); final selectKnowledge = Rx<KnowledgePoint?>(null);
final knowledgePoints = RxList<Rx<KnowledgePoint>>([]); final knowledgePoints = RxList<Rx<KnowledgePoint>>([]);
final knowledgePointDialogues = RxList<KnowledgePointDialogue?>([]);
final chatInputMsg = ''.obs;
late String account = ''; late String account = '琉璃';
late int gender = 1; late int gender = 1;
late int age = 10; late int age = 10;
@ -42,18 +46,20 @@ class HomeController extends GetxController {
late List<ExploreApp> leftExploreApps = []; late List<ExploreApp> leftExploreApps = [];
late List<ExploreApp> rightExploreApps = []; late List<ExploreApp> rightExploreApps = [];
late List<Goal> goals = []; late List<Goal> goals = [];
late int sendCount = 0;
final int second = 3; final int second = 3;
StreamSubscription<dynamic>? subscription; StreamSubscription<dynamic>? subscription;
final scrollController = ScrollController();
late TextEditingController textController = TextEditingController();
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
account = SpUtil.getString(Constant.account).nullSafe; // account = SpUtil.getString(Constant.account).nullSafe;
gender = SpUtil.getInt(Constant.gender, defValue: 1)!; gender = SpUtil.getInt(Constant.gender, defValue: 1)!;
age = SpUtil.getInt(Constant.age, defValue: 10)!; age = SpUtil.getInt(Constant.age, defValue: 10)!;
occupationName = SpUtil.getString(Constant.occupationName).nullSafe; // occupationName = SpUtil.getString(Constant.occupationName).nullSafe;
occupationId = SpUtil.getInt(Constant.occupationId, defValue: 2)!; // occupationId = SpUtil.getInt(Constant.occupationId, defValue: 2)!;
// create.value = SpUtil.getBool(Constant.create, defValue: true)!; create.value = SpUtil.getBool(Constant.create, defValue: true)!;
initLeftExploreApps(); initLeftExploreApps();
initRightExploreApps(); initRightExploreApps();
initArtistGoals(); initArtistGoals();
@ -87,28 +93,274 @@ class HomeController extends GetxController {
@override @override
void onClose() { void onClose() {
super.onClose(); super.onClose();
textController.dispose();
subscription?.cancel(); subscription?.cancel();
} }
void initKnowledgePoints() { void initKnowledgePoints() {
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 1, left: 559.0, top: 149.0, title: '钱是怎么形成的?', leared: false) id: 1, left: 559.0, top: 149.0, title: '太阳系中的行星', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 1,
id: 0,
isGpt: true,
text: '''太阳系是一个神奇的地方,它由太阳和围绕它运行的各种天体组成,包括我们的地球🌍!
🪐
🌌
1. (Mercury)
2. (Venus)
3. (Earth)
4. (Mars)
5. (Jupiter)
6. (Saturn)
7. (Uranus)
绿
8. (Neptune)
🚀'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 1, id: 1, isGpt: false, text: '太阳系的行星有什么有趣的知识?'));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 1,
id: 1,
isGpt: true,
text: '''太阳系的行星充满了许多有趣的知识和神秘的现象。让我们来探索一些关于这些行星的迷人事实吧!🌌
1. 西
2.
3.
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 1, id: 2, isGpt: false, text: '有哪些知识是我能用在生活中的?'));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 1,
id: 2,
isGpt: true,
text: '''了解太阳系和宇宙可以帮助你在日常生活中观察和理解许多现象。这里有一些知识点,不仅有趣,而且可以应用到你的日常生活中:
1.
2.
使
3.
4.
'''));
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 2, right: 751.0, top: 198.0, title: '小实验溶解糖', leared: false) id: 2, right: 751.0, top: 198.0, title: '中国历史:炎帝和皇帝', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 2, id: 0, isGpt: true, text: '''让我们来了解一下炎帝和黄帝,这两位是中国历史上非常重要的传说人物。
使
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 2, id: 1, isGpt: false, text: '为什么这两个人总是被一起提到?他们之间发生过什么故事呢?'));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 2,
id: 1,
isGpt: true,
text:
'''炎帝和黄帝之所以常常被一起提到,主要是因为他们在中国古代历史和神话中都占有非常重要的地位。他们被认为是华夏民族(古代汉族的前身)的共同祖先,象征着中国文明的起源。以下是一些关于他们的故事和为什么他们总是一起被提及的原因:
'''));
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 3, left: 632.0, top: 278.0, title: '科学家是怎么工作的?', leared: false) id: 3, left: 632.0, top: 278.0, title: '水的固态-冰', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 3,
id: 0,
isGpt: true,
text: '''冰是水在低温下的固态形式。当水的温度降到0°C32°F以下时它就会开始结冰。❄
使
🧊
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 3, id: 1, isGpt: false, text: '有什么有趣的知识?'));
knowledgePointDialogues
.add(KnowledgePointDialogue(kpId: 3, id: 1, isGpt: true, text: '''冰比水轻:
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 3, id: 2, isGpt: false, text: '有哪些知识是我能用在生活中的?'));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 3,
id: 2,
isGpt: true,
text: '''关于水的三态变化有许多实用的知识可以应用在日常生活中。让我们一起来看看:
1.
西
2.
100°C
3.
4.
5.
使
6.
'''));
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 4, left: 814.0, top: 376.0, title: '艺术家——梵高', leared: false) id: 4, left: 814.0, top: 376.0, title: '科学是什么?', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 4,
id: 0,
isGpt: true,
text: '''科学是一种了解我们周围世界的方式,它通过观察、实验和逻辑推理来探索自然界的奥秘。🔬
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 4, id: 1, isGpt: false, text: '科学跟其他学科有什么区别呢?'));
knowledgePointDialogues.add(
KnowledgePointDialogue(kpId: 4, id: 1, isGpt: true, text: '''1. 做实验:
2.
3.
4.
5.
'''));
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 5, right: 696.0, top: 438.0, title: '什么是科学?', leared: false) id: 5, right: 696.0, top: 438.0, title: '《星夜》-梵高', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 5,
id: 0,
isGpt: true,
text: '''让我们开始关于梵高的《星夜》这一主题的学习之旅吧。这幅画不仅是梵高最著名的作品之一,也是世界上最受欢迎和认可的艺术作品之一。
1889
使
使
使使
使
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 5,
id: 1,
isGpt: false,
text: '这幅画表达了一种梦幻的、充满活力的情感。画里的旋转星空让我感到一种强烈的生命力。'));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 5,
id: 1,
isGpt: true,
text: '''你对梵高的《星夜》的感受非常深刻。这幅画确实是以其独特的方式捕捉和表达了一种梦幻般、充满活力的情感。
使仿
'''));
knowledgePoints.add(KnowledgePoint( knowledgePoints.add(KnowledgePoint(
id: 6, left: 741.0, top: 499.0, title: '足球比赛规则', leared: false) id: 6, left: 741.0, top: 499.0, title: '《小王子》-第一章', leared: false)
.obs); .obs);
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 6,
id: 0,
isGpt: true,
text:
'''《小王子》是一本由法国作家安托万·德·圣-埃克苏佩里创作的著名小说它包含了许多深刻的生活哲理和寓意。让我们一起阅读《小王子》的第1章吧
1··-
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 6, id: 1, isGpt: false, text: '''1. 于是我的思维飞到从林里去探险,最后用彩色蜡笔画出了处女作。
2. :
'''));
knowledgePointDialogues.add(KnowledgePointDialogue(
kpId: 6,
id: 1,
isGpt: true,
text:
'''选择的这两句话非常有意义,它们揭示了《小王子》中一个核心主题:成人世界与儿童世界的理解和想象力的差异。这里是这两句话的英文版本以及一些关键词汇:
1. I pondered deeply, then, over the adventures of the jungle. And after some work with a colored pencil I succeeded in making my first drawing.
Pondered -
Adventures -
Jungle -
Colored pencil -
Succeeded -
Drawing -
2. I would try to find out, so, if this was a person of true understanding. But, whoever it was, he, or she, would always say, "That is a hat." Then I would never talk to that person about boa constrictors, or primeval forests, or stars. I would bring myself down to his level. L would talk to him about bridge, and golf, and politics, and neckties.
Understanding -
Person -
True -
Whoever -
Hat -
Boa constrictors -
Primeval -
Forests -
Level -
Golf -
Politics -
Neckties - '''));
} }
void initArtistGoals() { void initArtistGoals() {
@ -228,36 +480,25 @@ class HomeController extends GetxController {
} }
Future leareKnowledge(KnowledgePoint knowledge) async { Future leareKnowledge(KnowledgePoint knowledge) async {
textController = TextEditingController();
sendCount = 0;
selectKnowledge.value = knowledge; selectKnowledge.value = knowledge;
chatMsgList.clear(); chatMsgList.clear();
if (knowledge.title!.contains('科学')) {
var knowledgePointDialogue = knowledgePointDialogues.firstWhere((t) =>
t!.kpId == selectKnowledge.value!.id && t.id == sendCount && t.isGpt!);
var chatMsg = ChatMsg( var chatMsg = ChatMsg(
id: Guid.newGuid.toString(), id: Guid.newGuid.toString(),
text: '''科学是一种了解我们周围世界的方式,它通过观察、实验和逻辑推理来探索自然界的奥秘。🔬 text: knowledgePointDialogue!.text,
''',
isBot: 1, isBot: 1,
knowledgeId: selectKnowledge.value!.id, knowledgeId: selectKnowledge.value!.id,
); );
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
Future.delayed(const Duration(milliseconds: 300));
scrollController.jumpTo(scrollController.position.maxScrollExtent);
});
chatMsgList.add(chatMsg); chatMsgList.add(chatMsg);
} else {
chatMsgList.add(ChatMsg( sendCount++;
id: Guid.newGuid.toString(), knowledgePointDialogue = knowledgePointDialogues.firstWhere((t) =>
knowledgeId: knowledge.id, t!.kpId == selectKnowledge.value!.id && t.id == sendCount && !t.isGpt!);
isBot: 1, chatInputMsg.value = knowledgePointDialogue!.text!;
text: '探梦者,关于“${knowledge.title}”这个话题,你有什么想法或者疑问? 我们起交流吧!',
));
}
await Get.toNamed(Routes.HOME + Routes.EXPLORE_STUDY); await Get.toNamed(Routes.HOME + Routes.EXPLORE_STUDY);
} }
@ -270,31 +511,19 @@ class HomeController extends GetxController {
); );
chatMsgList.add(chatMsg); chatMsgList.add(chatMsg);
if (selectKnowledge.value?.title?.contains('科学') ?? false) { SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
Future.delayed(const Duration(milliseconds: 1000));
});
var knowledgePointDialogue = knowledgePointDialogues.firstWhere((t) =>
t!.kpId == selectKnowledge.value!.id && t.id == sendCount && t.isGpt!);
chatMsg = ChatMsg( chatMsg = ChatMsg(
id: Guid.newGuid.toString(), id: Guid.newGuid.toString(),
text: '''1. 做实验: text: knowledgePointDialogue!.text,
isBot: 1,
2.
3.
4.
5.
''',
isBot: 0,
knowledgeId: selectKnowledge.value!.id, knowledgeId: selectKnowledge.value!.id,
); );
chatMsgList.add(chatMsg); chatMsgList.add(chatMsg);
}
SchedulerBinding.instance.addPostFrameCallback((timeStamp) { SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
Future.delayed(const Duration(milliseconds: 300)); Future.delayed(const Duration(milliseconds: 300));
scrollController.jumpTo(scrollController.position.maxScrollExtent); scrollController.jumpTo(scrollController.position.maxScrollExtent);
@ -312,5 +541,16 @@ class HomeController extends GetxController {
if (exploreCount.value >= 2) { if (exploreCount.value >= 2) {
explored.value = true; explored.value = true;
} }
sendCount++;
knowledgePointDialogue = knowledgePointDialogues.firstWhere(
(t) =>
t!.kpId == selectKnowledge.value!.id &&
t.id == sendCount &&
!t.isGpt!,
orElse: () => null,
);
if (knowledgePointDialogue != null) {
chatInputMsg.value = knowledgePointDialogue.text!;
}
} }
} }

View File

@ -0,0 +1,13 @@
class KnowledgePointDialogue {
int? kpId;
int? id;
bool? isGpt;
String? text;
KnowledgePointDialogue({
this.kpId,
this.id,
this.isGpt,
this.text,
});
}

View File

@ -32,7 +32,8 @@ class ExploreStudyView extends GetView<HomeController> {
} }
Widget buildBody(BuildContext context) { Widget buildBody(BuildContext context) {
return Column( return Obx(
() => Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
const RSizedBox(height: 22.0), const RSizedBox(height: 22.0),
@ -56,8 +57,7 @@ class ExploreStudyView extends GetView<HomeController> {
), ),
), ),
const RSizedBox(height: 10.0), const RSizedBox(height: 10.0),
Obx( Row(
() => Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Container( Container(
@ -90,7 +90,6 @@ class ExploreStudyView extends GetView<HomeController> {
) )
], ],
), ),
),
Flexible( Flexible(
fit: FlexFit.tight, fit: FlexFit.tight,
child: Container( child: Container(
@ -102,29 +101,26 @@ class ExploreStudyView extends GetView<HomeController> {
child: buildMsgList(context), child: buildMsgList(context),
), ),
), ),
HookBuilder( HookBuilder(builder: (context) {
builder: (context) {
final textController = useTextEditingController();
useMemoized(() async { useMemoized(() async {
if (controller.selectKnowledge.value?.title?.contains('科学') ?? false) { for (int i = 0;
const guide = '科学跟其他学科有什么区别呢'; i < controller.chatInputMsg.value.length + 1;
for (int i = 0; i < guide.length + 1; i++) { i++) {
textController.text = guide.substring(0, i); controller.textController.text =
controller.chatInputMsg.value.substring(0, i);
await Future.delayed(const Duration(milliseconds: 80)); await Future.delayed(const Duration(milliseconds: 80));
} }
} SchedulerBinding.instance.addPostFrameCallback((timeStamp) {});
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
});
}); });
return ChatInputWidget( return ChatInputWidget(
controller: textController, controller: controller.textController,
onPressed: (txt) { onPressed: (txt) {
controller.addSendMsg(txt); controller.addSendMsg(txt);
}, },
); );
} }),
),
], ],
),
); );
} }

View File

@ -148,7 +148,7 @@ class ExploreView extends GetView<HomeController> {
), ),
child: Center( child: Center(
child: Text( child: Text(
'', '${Utils.getDayString(controller.exploreDay.value)}',
style: TextStyles.mediumWhite18, style: TextStyles.mediumWhite18,
), ),
), ),

View File

@ -11,6 +11,7 @@ import '../controllers/home_controller.dart';
import '../models/explore_app_model.dart'; import '../models/explore_app_model.dart';
import '../widgets/explore_widget.dart'; import '../widgets/explore_widget.dart';
import '../widgets/goal_dialog.dart'; import '../widgets/goal_dialog.dart';
import '../widgets/lantern_widget.dart';
import '../widgets/user_widget.dart'; import '../widgets/user_widget.dart';
class HomeView extends GetView<HomeController> { class HomeView extends GetView<HomeController> {
@ -507,6 +508,11 @@ class HomeView extends GetView<HomeController> {
) )
: Container(), : Container(),
controller.explored2.value >= 1 ? firstLeafWidget() : Container(), controller.explored2.value >= 1 ? firstLeafWidget() : Container(),
LanternWidget(
brightCount: controller.exploreCount.value >= 2
? controller.exploreDay.value
: controller.exploreDay.value - 1,
),
Positioned( Positioned(
left: 168.w, left: 168.w,
top: 244.h, top: 244.h,
@ -662,10 +668,7 @@ class _ShowUp extends HookWidget {
controller.forward(); controller.forward();
}); });
return FadeTransition( return FadeTransition(
opacity: CurvedAnimation( opacity: CurvedAnimation(curve: Curves.easeIn, parent: controller),
curve: Curves.easeIn,
parent: controller
),
child: child, child: child,
); );
} }

View File

@ -27,7 +27,7 @@ class _ChatInputWidgetState extends State<ChatInputWidget> {
void verify() { void verify() {
final String input = _controller.text; final String input = _controller.text;
bool clickabled = true; bool clickabled = true;
if (input.isEmpty || input.length < 5 || input.length > 120) { if (input.isEmpty || input.length < 5) {
clickabled = false; clickabled = false;
} }
setState(() { setState(() {
@ -86,6 +86,7 @@ class _ChatInputWidgetState extends State<ChatInputWidget> {
focusNode: _focus, focusNode: _focus,
style: TextStyles.mediumGray3315, style: TextStyles.mediumGray3315,
maxLength: 120, maxLength: 120,
maxLines: null,
maxLengthEnforcement: MaxLengthEnforcement.enforced, maxLengthEnforcement: MaxLengthEnforcement.enforced,
decoration: InputDecoration( decoration: InputDecoration(
hintText: '请输入你想说的内容', hintText: '请输入你想说的内容',

View File

@ -0,0 +1,49 @@
import 'package:dreampad/app/shared/shared.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class LanternWidget extends GetView {
const LanternWidget({
super.key,
this.brightCount = 0,
});
final int? brightCount;
@override
Widget build(BuildContext context) {
return Positioned(
right: 60.w,
top: 346.h,
child: Container(
height: 90.h,
width: 180.w,
decoration: const BoxDecoration(
image: DecorationImage(
image: Images.homeLantern,
fit: BoxFit.fill,
),
),
child: Stack(
clipBehavior: Clip.none,
children: [
brightCount! >= 1
? Positioned(
left: -9.w,
top: 36.h,
child: Images.homeLanternBright,
)
: Container(),
brightCount! >= 2
? Positioned(
left: 18.w,
top: 27.h,
child: Images.homeLanternBright,
)
: Container(),
],
),
),
);
}
}

View File

@ -21,10 +21,13 @@ class SendMessageWidget extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Text( Padding(
padding: REdgeInsets.only(right: 10.0),
child: Text(
userName, userName,
style: TextStyles.mediumGray9915, style: TextStyles.mediumGray9915,
), ),
),
Gaps.vGap9, Gaps.vGap9,
BubbleBox( BubbleBox(
shape: BubbleShapeBorder( shape: BubbleShapeBorder(

View File

@ -187,6 +187,12 @@ class Images {
width: 9.w, width: 9.w,
); );
static Widget homeLanternBright = LoadAssetImage(
'home/label_icon_lantern_bright',
height: 21.h,
width: 39.w,
);
static Widget studyHome = LoadAssetImage( static Widget studyHome = LoadAssetImage(
'study/btn_icon_homepage', 'study/btn_icon_homepage',
height: 66.w, height: 66.w,
@ -275,6 +281,8 @@ class Images {
AssetImage("assets/images/home/btn_bg_shine.png"); AssetImage("assets/images/home/btn_bg_shine.png");
static const AssetImage homeWindows = static const AssetImage homeWindows =
AssetImage("assets/images/home/bg_pic_windows.png"); AssetImage("assets/images/home/bg_pic_windows.png");
static const AssetImage homeLantern =
AssetImage("assets/images/home/label_icon_lantern.png");
static const AssetImage studyBg = static const AssetImage studyBg =
AssetImage("assets/images/study/bg_pic_dream_exploration_page.png"); AssetImage("assets/images/study/bg_pic_dream_exploration_page.png");

View File

@ -10,6 +10,11 @@ import '../constants/constants.dart';
import 'theme_utils.dart'; import 'theme_utils.dart';
class Utils { class Utils {
static String getDayString(int day) {
var upperString = '一二三四五六七八九';
return upperString[day - 1];
}
static String formatPrice(String price, static String formatPrice(String price,
{MoneyFormat format = MoneyFormat.END_INTEGER}) { {MoneyFormat format = MoneyFormat.END_INTEGER}) {
return MoneyUtil.changeYWithUnit( return MoneyUtil.changeYWithUnit(