dreampad/lib/app/modules/home/controllers/home_controller.dart

557 lines
31 KiB
Dart
Raw Normal View History

2023-11-28 10:44:58 +08:00
// ignore_for_file: unnecessary_overrides
import 'dart:async';
2023-11-28 20:25:09 +08:00
import 'package:flutter/scheduler.dart';
2023-11-28 10:44:58 +08:00
import 'package:flutter_guid/flutter_guid.dart';
import 'package:dreampad/app/models/models.dart';
import 'package:dreampad/app/routes/app_pages.dart';
import 'package:flustars_flutter3/flustars_flutter3.dart';
import 'package:flutter/widgets.dart';
2023-11-30 00:08:39 +08:00
import 'package:flutter_hooks/flutter_hooks.dart';
2023-11-28 10:44:58 +08:00
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:dreampad/app/shared/shared.dart';
import '../models/chat_msg_model.dart';
import '../models/explore_app_model.dart';
2023-11-30 00:08:39 +08:00
import '../models/knowledge_point_dialogue_model.dart';
2023-11-28 10:44:58 +08:00
import '../models/knowledge_point_model.dart';
import '../providers/home_provider.dart';
import '../widgets/first_time_dialog.dart';
class HomeController extends GetxController {
final HomeProvider homeProvider;
2023-11-28 20:25:09 +08:00
2023-11-28 10:44:58 +08:00
HomeController({required this.homeProvider});
2023-11-28 20:25:09 +08:00
2023-11-28 10:44:58 +08:00
final explored = false.obs;
2023-11-28 20:25:09 +08:00
final explored2 = 0.obs;
2023-11-28 10:44:58 +08:00
final create = true.obs;
final prompt = false.obs;
final exploreCount = 0.obs;
2023-11-30 00:08:39 +08:00
final exploreDay = 1.obs;
2023-11-28 10:44:58 +08:00
final chatMsgList = RxList<ChatMsg>([]);
2023-11-28 15:44:41 +08:00
final selectKnowledge = Rx<KnowledgePoint?>(null);
2023-11-28 19:22:36 +08:00
final knowledgePoints = RxList<Rx<KnowledgePoint>>([]);
2023-11-30 00:08:39 +08:00
final knowledgePointDialogues = RxList<KnowledgePointDialogue?>([]);
final chatInputMsg = ''.obs;
2023-11-28 10:44:58 +08:00
2023-11-30 00:08:39 +08:00
late String account = '琉璃';
2023-11-28 10:44:58 +08:00
late int gender = 1;
late int age = 10;
late int occupationId = 1;
late String occupationName = '画家';
late List<ExploreApp> leftExploreApps = [];
late List<ExploreApp> rightExploreApps = [];
late List<Goal> goals = [];
2023-11-30 00:08:39 +08:00
late int sendCount = 0;
2023-11-28 19:22:36 +08:00
final int second = 3;
2023-11-28 10:44:58 +08:00
StreamSubscription<dynamic>? subscription;
2023-11-30 00:08:39 +08:00
final scrollController = ScrollController();
late TextEditingController textController = TextEditingController();
2023-11-28 10:44:58 +08:00
@override
void onInit() {
super.onInit();
2023-11-30 00:08:39 +08:00
// account = SpUtil.getString(Constant.account).nullSafe;
2023-11-28 10:44:58 +08:00
gender = SpUtil.getInt(Constant.gender, defValue: 1)!;
age = SpUtil.getInt(Constant.age, defValue: 10)!;
2023-11-30 00:08:39 +08:00
// occupationName = SpUtil.getString(Constant.occupationName).nullSafe;
// occupationId = SpUtil.getInt(Constant.occupationId, defValue: 2)!;
create.value = SpUtil.getBool(Constant.create, defValue: true)!;
2023-11-28 10:44:58 +08:00
initLeftExploreApps();
initRightExploreApps();
initArtistGoals();
initAcademicianGoals();
initKnowledgePoints();
if (create.value) {
subscription = Stream.periodic(const Duration(seconds: 1), (int i) => i)
.take(second)
2023-11-29 20:37:45 +08:00
.listen((int i) async {
2023-11-28 10:44:58 +08:00
if (i >= second - 1) {
create.value = false;
prompt.value = true;
SpUtil.putBool(Constant.create, false);
2023-11-29 20:37:45 +08:00
await SmartDialog.show<bool>(
2023-11-28 10:44:58 +08:00
maskColor: const Color(0xFF02184B).withOpacity(0.9),
2023-11-29 20:37:45 +08:00
backDismiss: false,
clickMaskDismiss: false,
builder: (_) => const FirstTimeDialog(),
2023-11-28 10:44:58 +08:00
);
2023-11-29 20:37:45 +08:00
prompt.value = false;
2023-11-28 10:44:58 +08:00
}
});
}
}
@override
void onReady() async {
super.onReady();
}
@override
void onClose() {
super.onClose();
2023-11-30 00:08:39 +08:00
textController.dispose();
2023-11-28 10:44:58 +08:00
subscription?.cancel();
}
void initKnowledgePoints() {
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 1, left: 559.0, top: 149.0, title: '太阳系中的行星', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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.
'''));
2023-11-28 10:44:58 +08:00
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 2, right: 751.0, top: 198.0, title: '中国历史:炎帝和皇帝', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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:
'''炎帝和黄帝之所以常常被一起提到,主要是因为他们在中国古代历史和神话中都占有非常重要的地位。他们被认为是华夏民族(古代汉族的前身)的共同祖先,象征着中国文明的起源。以下是一些关于他们的故事和为什么他们总是一起被提及的原因:
'''));
2023-11-28 10:44:58 +08:00
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 3, left: 632.0, top: 278.0, title: '水的固态-冰', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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.
'''));
2023-11-28 10:44:58 +08:00
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 4, left: 814.0, top: 376.0, title: '科学是什么?', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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.
'''));
2023-11-28 10:44:58 +08:00
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 5, right: 696.0, top: 438.0, title: '《星夜》-梵高', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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: '''你对梵高的《星夜》的感受非常深刻。这幅画确实是以其独特的方式捕捉和表达了一种梦幻般、充满活力的情感。
使仿
'''));
2023-11-28 10:44:58 +08:00
knowledgePoints.add(KnowledgePoint(
2023-11-30 00:08:39 +08:00
id: 6, left: 741.0, top: 499.0, title: '《小王子》-第一章', leared: false)
2023-11-28 19:22:36 +08:00
.obs);
2023-11-30 00:08:39 +08:00
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 - '''));
2023-11-28 10:44:58 +08:00
}
void initArtistGoals() {
goals.add(
Goal(id: 1, occupationId: 1, age: age + 0, title: '今年目标', contents: [
GoalContent(title: '基础绘画技巧', content: '学习和练习基础的绘画技巧,如素描、色彩等。'),
GoalContent(title: '艺术欣赏能力', content: '参观美术馆、画展,增进对不同画派和风格的了解。'),
GoalContent(title: '创意表达培养', content: '通过日常生活的观察和想象,创作一些个人作品。'),
]));
goals.add(
Goal(id: 2, occupationId: 1, age: age + 3, title: '三年目标', contents: [
GoalContent(title: '基础绘画技巧', content: '尝试不同的绘画媒介和技巧,开始探索个人的艺术风格。'),
GoalContent(title: '艺术欣赏能力', content: '参加美术课程或夏令营,系统学习绘画知识。'),
GoalContent(title: '创意表达培养', content: '参加学校或社区的绘画比赛和展览,锻炼展示自己作品的能力。'),
]));
goals.add(Goal(id: 3, occupationId: 1, title: '18岁目标', contents: [
GoalContent(title: '艺术类院校申请', content: '申请艺术类高中或大学,接受正规的艺术教育。'),
GoalContent(title: '艺术实践加强', content: '通过参加画展、艺术竞赛等,增加实践经验。'),
GoalContent(title: '艺术理论学习', content: '学习艺术史、美学等,增强艺术理论素养。'),
]));
goals.add(Goal(id: 4, occupationId: 1, title: '22岁目标', contents: [
GoalContent(title: '专业深造', content: '在艺术类大学深入学习绘画,探索个人艺术方向。'),
GoalContent(title: '国际视野拓展', content: '参与国际艺术交流活动,了解全球艺术潮流。'),
GoalContent(title: '独立创作展示', content: '举办个人画展或参加重要艺术展览,展示个人作品。'),
]));
goals.add(Goal(id: 5, occupationId: 1, title: '30岁目标', contents: [
GoalContent(title: '个人品牌建立', content: '作为画家在艺术界建立良好的个人品牌和声誉。'),
GoalContent(title: '艺术教育贡献', content: '通过教学或工作坊等方式分享艺术知识和技巧。'),
GoalContent(title: '国际艺术影响力', content: '作品具有国际影响力,参与国际艺术交流与合作。'),
]));
}
void initAcademicianGoals() {
goals.add(
Goal(id: 1, occupationId: 2, age: age + 0, title: '今年目标', contents: [
GoalContent(title: '课外阅读提升', content: '选择与科学相关的儿童图书,每周至少阅读一本。'),
GoalContent(title: '科学兴趣培养', content: '参加科学实验兴趣小组或课外科学俱乐部,增进对科学的兴趣和理解。'),
GoalContent(title: '基础数学能力', content: '每天坚持数学练习,提高逻辑思维和解决问题的能力。'),
]));
goals.add(
Goal(id: 2, occupationId: 2, age: age + 3, title: '三年目标', contents: [
GoalContent(title: '科学竞赛参与', content: '参加学校或地区的科学竞赛,提高科学实践能力。'),
GoalContent(title: '英语能力加强', content: '科学领域英语是必备技能,提高英语水平以便阅读国际科学文献。'),
GoalContent(title: '拓展科学知识', content: '通过在线课程或夏令营等方式,学习物理、化学等更多科学知识。'),
]));
goals.add(Goal(id: 3, occupationId: 2, title: '18岁目标', contents: [
GoalContent(title: '理想大学申请', content: '申请国内外知名大学的科学相关专业,为深造打下基础。'),
GoalContent(title: '科学研究实习', content: '在大学期间尽早寻找实习机会,加入科研团队。'),
GoalContent(title: '专业网络构建', content: '建立与科学家和研究人员的联系,拓宽学术交流圈。'),
]));
goals.add(Goal(id: 4, occupationId: 2, title: '22岁目标', contents: [
GoalContent(title: '硕士/博士深造', content: '申请硕士或直接博士项目,深入专业领域研究。'),
GoalContent(title: '学术论文发表', content: '在专业期刊上发表研究成果,建立学术声誉。'),
GoalContent(title: '国际科研合作', content: '参与国际科研项目,扩大研究视野。'),
]));
goals.add(Goal(id: 5, occupationId: 2, title: '30岁目标', contents: [
GoalContent(title: '科学研究突破', content: '在某一科学领域取得显著研究成果。'),
GoalContent(title: '科学社群领导', content: '在科学界承担一定的领导角色,如项目负责人或研究小组领头。'),
GoalContent(title: '学术影响力拓展', content: '通过公开讲座、论文发表等方式,提高在科学界的影响力。'),
]));
}
void initLeftExploreApps() {
leftExploreApps.add(ExploreApp(
name: '哔哩哔哩',
icon: 'btn_app_bilibili',
grayIcon: 'btn_app_bilibili_gray',
));
leftExploreApps.add(ExploreApp(
name: '知乎',
icon: 'btn_app_zhihu',
grayIcon: 'btn_app_zhihu_gray',
));
leftExploreApps.add(ExploreApp(
name: '纪念碑谷',
icon: 'btn_app_jinianbeigu',
grayIcon: 'btn_app_jinianbeigu_gray',
));
leftExploreApps.add(ExploreApp(
name: '蛋仔派对',
icon: 'btn_app_danzaipaidui',
grayIcon: 'btn_app_danzaipaidui_gray',
));
}
void initRightExploreApps() {
rightExploreApps.add(ExploreApp(
name: '古诗文网',
icon: 'btn_app_gushiwenwang',
grayIcon: 'btn_app_gushiwenwang_gray',
));
rightExploreApps.add(ExploreApp(
name: '数理思维启蒙',
icon: 'btn_app_funexpected',
grayIcon: 'btn_app_funexpected_gray',
));
rightExploreApps.add(ExploreApp(
name: '多邻国',
icon: 'btn_app_duolingo',
grayIcon: 'btn_app_duolingo_gray',
));
rightExploreApps.add(ExploreApp(
name: '每日艺术',
icon: 'btn_app_dailyart',
grayIcon: 'btn_app_dailyart_gray',
));
}
Goal getGoal(int id) {
return goals
.firstWhere((t) => t.id == id && t.occupationId == occupationId);
}
Future reset() async {
SpUtil.remove(Constant.create);
2023-11-29 20:37:45 +08:00
await Get.offAllNamed(Routes.WELCOME);
2023-11-28 10:44:58 +08:00
}
Future leareKnowledge(KnowledgePoint knowledge) async {
2023-11-30 00:08:39 +08:00
textController = TextEditingController();
sendCount = 0;
2023-11-28 15:44:41 +08:00
selectKnowledge.value = knowledge;
2023-11-28 10:44:58 +08:00
chatMsgList.clear();
2023-11-30 00:08:39 +08:00
var knowledgePointDialogue = knowledgePointDialogues.firstWhere((t) =>
t!.kpId == selectKnowledge.value!.id && t.id == sendCount && t.isGpt!);
var chatMsg = ChatMsg(
id: Guid.newGuid.toString(),
text: knowledgePointDialogue!.text,
isBot: 1,
knowledgeId: selectKnowledge.value!.id,
);
chatMsgList.add(chatMsg);
sendCount++;
knowledgePointDialogue = knowledgePointDialogues.firstWhere((t) =>
t!.kpId == selectKnowledge.value!.id && t.id == sendCount && !t.isGpt!);
chatInputMsg.value = knowledgePointDialogue!.text!;
2023-11-28 10:44:58 +08:00
await Get.toNamed(Routes.HOME + Routes.EXPLORE_STUDY);
}
Future addSendMsg(String txt) async {
var chatMsg = ChatMsg(
id: Guid.newGuid.toString(),
text: txt,
isBot: 0,
2023-11-28 15:44:41 +08:00
knowledgeId: selectKnowledge.value!.id,
2023-11-28 10:44:58 +08:00
);
chatMsgList.add(chatMsg);
2023-11-28 15:44:41 +08:00
2023-11-30 00:08:39 +08:00
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(
id: Guid.newGuid.toString(),
text: knowledgePointDialogue!.text,
isBot: 1,
knowledgeId: selectKnowledge.value!.id,
);
chatMsgList.add(chatMsg);
2023-11-28 20:25:09 +08:00
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
Future.delayed(const Duration(milliseconds: 300));
scrollController.jumpTo(scrollController.position.maxScrollExtent);
});
2023-11-28 19:22:36 +08:00
var knowledge = knowledgePoints
.firstWhere((t) => t.value.id == selectKnowledge.value!.id);
knowledge.update((val) {
val!.leared = true;
});
2023-11-28 15:44:41 +08:00
selectKnowledge.update((val) {
val!.leared = true;
});
exploreCount.value++;
if (exploreCount.value >= 2) {
explored.value = true;
}
2023-11-30 00:08:39 +08:00
sendCount++;
knowledgePointDialogue = knowledgePointDialogues.firstWhere(
(t) =>
t!.kpId == selectKnowledge.value!.id &&
t.id == sendCount &&
!t.isGpt!,
orElse: () => null,
);
if (knowledgePointDialogue != null) {
chatInputMsg.value = knowledgePointDialogue.text!;
}
2023-11-28 10:44:58 +08:00
}
}