feat: 添加起卦教程首次访问追踪和Agent时间上下文
- 后端 ProfileSettingsV1 添加 DivinationTutorialSettings 字段 - 前端三个起卦页面添加首次访问检测,自动弹出教程 - 教程展示后更新 settings 标记,避免重复弹出 - 使用本地状态管理避免并发更新覆盖问题 - Agent 系统提示添加时间上下文信息
This commit is contained in:
@@ -15,6 +15,7 @@ import '../../../../shared/widgets/divination/yao_line_row.dart';
|
||||
import '../../../../shared/widgets/date_time_picker/date_time_picker_bottom_sheet.dart';
|
||||
import '../../../../shared/widgets/toast/toast.dart';
|
||||
import '../../../../shared/widgets/toast/toast_type.dart';
|
||||
import '../../../settings/data/models/profile_settings.dart';
|
||||
import '../../data/models/divination_backend_models.dart';
|
||||
import '../../data/apis/divination_api.dart';
|
||||
import '../../data/models/divination_params.dart';
|
||||
@@ -30,12 +31,17 @@ class ManualDivinationScreen extends StatefulWidget {
|
||||
required this.runService,
|
||||
this.divinationApi,
|
||||
required this.onCompleted,
|
||||
required this.profileSettings,
|
||||
required this.onProfileSettingsChanged,
|
||||
});
|
||||
|
||||
final DivinationParams params;
|
||||
final DivinationRunService runService;
|
||||
final DivinationApi? divinationApi;
|
||||
final Future<void> Function(DivinationResultData result) onCompleted;
|
||||
final ProfileSettingsV1 profileSettings;
|
||||
final Future<void> Function(ProfileSettingsV1 settings)
|
||||
onProfileSettingsChanged;
|
||||
|
||||
@override
|
||||
State<ManualDivinationScreen> createState() => _ManualDivinationScreenState();
|
||||
@@ -47,6 +53,8 @@ class _ManualDivinationScreenState extends State<ManualDivinationScreen>
|
||||
final List<YaoType?> _selectedYaos = List<YaoType?>.filled(6, null);
|
||||
late final AnimationController _blinkController;
|
||||
bool _submitting = false;
|
||||
bool _tutorialChecked = false;
|
||||
late DivinationTutorialSettings _localTutorialSettings;
|
||||
final GlobalKey<OnboardingState> _onboardingKey =
|
||||
GlobalKey<OnboardingState>();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
@@ -66,6 +74,37 @@ class _ManualDivinationScreenState extends State<ManualDivinationScreen>
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
)..repeat(reverse: true);
|
||||
_localTutorialSettings = widget.profileSettings.divinationTutorial;
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
if (!_tutorialChecked) {
|
||||
_tutorialChecked = true;
|
||||
_checkFirstVisit();
|
||||
}
|
||||
}
|
||||
|
||||
void _checkFirstVisit() {
|
||||
if (!_localTutorialSettings.manualDivinationShown) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
_showGuide();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _markTutorialShown() async {
|
||||
setState(() {
|
||||
_localTutorialSettings = _localTutorialSettings.copyWith(
|
||||
manualDivinationShown: true,
|
||||
);
|
||||
});
|
||||
final updated = widget.profileSettings.copyWith(
|
||||
divinationTutorial: _localTutorialSettings,
|
||||
);
|
||||
await widget.onProfileSettingsChanged(updated);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -146,6 +185,7 @@ class _ManualDivinationScreenState extends State<ManualDivinationScreen>
|
||||
key: _onboardingKey,
|
||||
steps: guideSteps,
|
||||
onChanged: _onGuideStepChanged,
|
||||
onEnd: (_) => _markTutorialShown(),
|
||||
child: SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
|
||||
Reference in New Issue
Block a user