声音功能
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [1.3.7] - 2026-03-30
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
- 🎵 **点击音效功能**
|
||||||
|
- 新增音频管理类 `lib/utils/audio_manager.dart`,使用audioplayers库管理音效播放
|
||||||
|
- 在首页点击诗词卡片时播放音效 `assets/audios/deep.mp3`
|
||||||
|
- 在点击"下一条"按钮时播放音效
|
||||||
|
- 在点击"点赞"按钮时播放音效
|
||||||
|
- 修改 `lib/views/home/home_page.dart`,初始化音频管理器并在点赞、下一条事件中添加音效
|
||||||
|
- 修改 `lib/views/home/home_part.dart`,在诗词卡片点击事件中添加音效
|
||||||
|
- 支持静音控制,可通过AudioManager设置静音状态
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
- 📁 **音频文件声明**
|
||||||
|
- 在 `pubspec.yaml` 中添加 `assets/audios/deep.mp3` 音频文件的声明,确保应用能正确加载音频资源
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [1.3.6] - 2026-03-30
|
## [1.3.6] - 2026-03-30
|
||||||
|
|
||||||
### 新增
|
### 新增
|
||||||
|
|||||||
BIN
assets/audios/deep.mp3
Normal file
BIN
assets/audios/deep.mp3
Normal file
Binary file not shown.
97
lib/utils/audio_manager.dart
Normal file
97
lib/utils/audio_manager.dart
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
/// 时间: 2026-03-30
|
||||||
|
/// 功能: 音频管理类
|
||||||
|
/// 介绍: 管理应用中的音效播放,包括点击音效、点赞音效等
|
||||||
|
/// 最新变化: 新增音频播放功能
|
||||||
|
|
||||||
|
class AudioManager {
|
||||||
|
static AudioManager? _instance;
|
||||||
|
late AudioPlayer _audioPlayer;
|
||||||
|
bool _isInitialized = false;
|
||||||
|
bool _isMuted = false;
|
||||||
|
|
||||||
|
AudioManager._internal() {
|
||||||
|
_audioPlayer = AudioPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory AudioManager() {
|
||||||
|
_instance ??= AudioManager._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> init() async {
|
||||||
|
if (_isInitialized) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置音频播放器模式
|
||||||
|
await _audioPlayer.setPlayerMode(PlayerMode.lowLatency);
|
||||||
|
_isInitialized = true;
|
||||||
|
_debugLog('音频管理器初始化成功');
|
||||||
|
} catch (e) {
|
||||||
|
_debugLog('音频管理器初始化失败: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 播放点击音效
|
||||||
|
Future<void> playClickSound() async {
|
||||||
|
if (_isMuted) return;
|
||||||
|
await _playSound('audios/deep.mp3');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 播放点赞音效
|
||||||
|
Future<void> playLikeSound() async {
|
||||||
|
if (_isMuted) return;
|
||||||
|
await _playSound('audios/deep.mp3');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 播放下一条音效
|
||||||
|
Future<void> playNextSound() async {
|
||||||
|
if (_isMuted) return;
|
||||||
|
await _playSound('audios/deep.mp3');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 通用播放方法
|
||||||
|
Future<void> _playSound(String assetPath) async {
|
||||||
|
if (!_isInitialized) {
|
||||||
|
await init();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 停止当前播放的音频
|
||||||
|
await _audioPlayer.stop();
|
||||||
|
// 播放新音频
|
||||||
|
await _audioPlayer.play(AssetSource(assetPath));
|
||||||
|
_debugLog('播放音效: $assetPath');
|
||||||
|
} catch (e) {
|
||||||
|
_debugLog('播放音效失败: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置静音状态
|
||||||
|
void setMuted(bool muted) {
|
||||||
|
_isMuted = muted;
|
||||||
|
_debugLog('静音状态: $_isMuted');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取静音状态
|
||||||
|
bool get isMuted => _isMuted;
|
||||||
|
|
||||||
|
/// 释放资源
|
||||||
|
Future<void> dispose() async {
|
||||||
|
try {
|
||||||
|
await _audioPlayer.dispose();
|
||||||
|
_isInitialized = false;
|
||||||
|
_debugLog('音频管理器已释放');
|
||||||
|
} catch (e) {
|
||||||
|
_debugLog('释放音频管理器失败: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _debugLog(String message) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('[AudioManager] $message');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import '../../constants/app_constants.dart';
|
|||||||
import '../../../controllers/history_controller.dart';
|
import '../../../controllers/history_controller.dart';
|
||||||
import '../../../utils/http/poetry_api.dart';
|
import '../../../utils/http/poetry_api.dart';
|
||||||
import '../../../services/network_listener_service.dart';
|
import '../../../services/network_listener_service.dart';
|
||||||
|
import '../../../utils/audio_manager.dart';
|
||||||
import 'home_part.dart';
|
import 'home_part.dart';
|
||||||
import 'home_components.dart';
|
import 'home_components.dart';
|
||||||
import 'home-load.dart';
|
import 'home-load.dart';
|
||||||
@@ -57,12 +58,17 @@ class _HomePageState extends State<HomePage>
|
|||||||
_initAutoRefresh();
|
_initAutoRefresh();
|
||||||
_initDebugInfo();
|
_initDebugInfo();
|
||||||
_initOfflineDataManager();
|
_initOfflineDataManager();
|
||||||
|
_initAudioManager();
|
||||||
// 延迟加载诗词,确保页面先显示
|
// 延迟加载诗词,确保页面先显示
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_loadPoetry();
|
_loadPoetry();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _initAudioManager() async {
|
||||||
|
await AudioManager().init();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _initOfflineDataManager() async {
|
Future<void> _initOfflineDataManager() async {
|
||||||
final offlineDataManager = OfflineDataManager();
|
final offlineDataManager = OfflineDataManager();
|
||||||
await offlineDataManager.init();
|
await offlineDataManager.init();
|
||||||
@@ -287,6 +293,9 @@ class _HomePageState extends State<HomePage>
|
|||||||
Future<void> _toggleLike() async {
|
Future<void> _toggleLike() async {
|
||||||
if (_poetryData == null || _isLoadingLike) return;
|
if (_poetryData == null || _isLoadingLike) return;
|
||||||
|
|
||||||
|
// 播放点赞音效
|
||||||
|
await AudioManager().playLikeSound();
|
||||||
|
|
||||||
// 立即切换按钮状态和显示加载
|
// 立即切换按钮状态和显示加载
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoadingLike = true;
|
_isLoadingLike = true;
|
||||||
@@ -425,6 +434,9 @@ class _HomePageState extends State<HomePage>
|
|||||||
void _loadNextPoetry() async {
|
void _loadNextPoetry() async {
|
||||||
if (_isLoadingNext) return;
|
if (_isLoadingNext) return;
|
||||||
|
|
||||||
|
// 播放下一条音效
|
||||||
|
await AudioManager().playNextSound();
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoadingNext = true;
|
_isLoadingNext = true;
|
||||||
// 设置所有区域为加载状态
|
// 设置所有区域为加载状态
|
||||||
|
|||||||
@@ -5,8 +5,11 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import '../../../constants/app_constants.dart';
|
import '../../../constants/app_constants.dart';
|
||||||
import '../../../utils/http/poetry_api.dart';
|
import '../../../utils/http/poetry_api.dart';
|
||||||
|
import '../../../utils/flutter_compatibility_fix.dart';
|
||||||
|
import '../../../utils/audio_manager.dart';
|
||||||
import 'home_components.dart';
|
import 'home_components.dart';
|
||||||
|
|
||||||
/// 诗词卡片组件 - 优化版本,防止拉伸和处理文本溢出
|
/// 诗词卡片组件 - 优化版本,防止拉伸和处理文本溢出
|
||||||
@@ -31,6 +34,13 @@ class PoetryCard extends StatefulWidget {
|
|||||||
class _PoetryCardState extends State<PoetryCard> {
|
class _PoetryCardState extends State<PoetryCard> {
|
||||||
bool _showCopyTip = true;
|
bool _showCopyTip = true;
|
||||||
bool _showRecommendation = false;
|
bool _showRecommendation = false;
|
||||||
|
bool _globalTipsEnabled = true; // 添加全局Tips开关状态
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadGlobalTipsSettings(); // 加载全局Tips设置
|
||||||
|
}
|
||||||
|
|
||||||
String _getTimeOfDayGreeting() {
|
String _getTimeOfDayGreeting() {
|
||||||
final hour = DateTime.now().hour;
|
final hour = DateTime.now().hour;
|
||||||
@@ -74,10 +84,34 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载全局Tips设置
|
||||||
|
Future<void> _loadGlobalTipsSettings() async {
|
||||||
|
try {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_globalTipsEnabled = prefs.getBool('global_tips_enabled') ?? true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 如果加载失败,默认开启
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_globalTipsEnabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: widget.onTap,
|
onTap: () async {
|
||||||
|
// 播放点击音效
|
||||||
|
await AudioManager().playClickSound();
|
||||||
|
// 调用原始的onTap回调
|
||||||
|
widget.onTap?.call();
|
||||||
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@@ -87,7 +121,7 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.1),
|
color: Colors.black.withAlpha(10),
|
||||||
blurRadius: 10,
|
blurRadius: 10,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
),
|
),
|
||||||
@@ -143,7 +177,7 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
AppConstants.primaryColor.withValues(alpha: 0.8),
|
AppConstants.primaryColor.withAlpha(204),
|
||||||
AppConstants.primaryColor,
|
AppConstants.primaryColor,
|
||||||
],
|
],
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
@@ -197,7 +231,7 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: AppConstants.primaryColor.withValues(alpha: 0.3),
|
color: AppConstants.primaryColor.withAlpha(76),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
),
|
),
|
||||||
@@ -208,8 +242,8 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Icons.info_outline, color: Colors.white, size: 16),
|
const Icon(Icons.info_outline, color: Colors.white, size: 16),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
const Text(
|
Text(
|
||||||
'点击任意区域加载下一条,长按复制,下拉刷新',
|
_globalTipsEnabled ? '点击任意区域加载下一条,长按复制,下拉刷新' : '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -293,20 +327,20 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
AppConstants.primaryColor.withValues(alpha: 0.1),
|
AppConstants.primaryColor.withAlpha(26),
|
||||||
AppConstants.primaryColor.withValues(alpha: 0.05),
|
AppConstants.primaryColor.withAlpha(13),
|
||||||
],
|
],
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: AppConstants.primaryColor.withValues(alpha: 0.2),
|
color: AppConstants.primaryColor.withAlpha(51),
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: AppConstants.primaryColor.withValues(alpha: 0.1),
|
color: AppConstants.primaryColor.withAlpha(26),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
),
|
),
|
||||||
@@ -437,7 +471,7 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppConstants.secondaryColor
|
color: AppConstants.secondaryColor
|
||||||
.withValues(alpha: 0.1),
|
.withAlpha(26),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -468,8 +502,8 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
vertical: 4,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppConstants.primaryColor.withValues(
|
color: AppConstants.primaryColor.withAlpha(
|
||||||
alpha: 0.1,
|
26,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
@@ -604,11 +638,9 @@ class _PoetryCardState extends State<PoetryCard> {
|
|||||||
constraints: const BoxConstraints(maxHeight: 150),
|
constraints: const BoxConstraints(maxHeight: 150),
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppConstants.infoColor.withValues(alpha: 0.05),
|
color: AppConstants.infoColor.withAlpha(13),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(color: AppConstants.infoColor.withAlpha(51)),
|
||||||
color: AppConstants.infoColor.withValues(alpha: 0.2),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: isLoading
|
child: isLoading
|
||||||
? Center(
|
? Center(
|
||||||
@@ -671,7 +703,7 @@ class FloatingPreviousButton extends StatelessWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: AppConstants.secondaryColor.withValues(alpha: 0.3),
|
color: AppConstants.secondaryColor.withAlpha(76),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
),
|
),
|
||||||
@@ -711,7 +743,7 @@ class FloatingNextButton extends StatelessWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: AppConstants.primaryColor.withValues(alpha: 0.3),
|
color: AppConstants.primaryColor.withAlpha(76),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
),
|
),
|
||||||
@@ -759,7 +791,7 @@ class FloatingLikeButton extends StatelessWidget {
|
|||||||
BoxShadow(
|
BoxShadow(
|
||||||
color:
|
color:
|
||||||
(isLiked ? AppConstants.errorColor : AppConstants.primaryColor)
|
(isLiked ? AppConstants.errorColor : AppConstants.primaryColor)
|
||||||
.withValues(alpha: 0.3),
|
.withAlpha(76),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
),
|
),
|
||||||
@@ -813,7 +845,7 @@ class StatsCard extends StatelessWidget {
|
|||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
color: Colors.black.withAlpha(5),
|
||||||
blurRadius: 5,
|
blurRadius: 5,
|
||||||
offset: const Offset(0, 1),
|
offset: const Offset(0, 1),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
'resolveTime': '2026-04-15',
|
'resolveTime': '2026-04-15',
|
||||||
'reportTime': '2026-03-25',
|
'reportTime': '2026-03-25',
|
||||||
'affectedUsers': '部分用户',
|
'affectedUsers': '部分用户',
|
||||||
|
'expanded': false, // 添加展开状态
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 2,
|
'id': 2,
|
||||||
@@ -39,6 +40,7 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
'resolveTime': '2026-04-10',
|
'resolveTime': '2026-04-10',
|
||||||
'reportTime': '2026-03-20',
|
'reportTime': '2026-03-20',
|
||||||
'affectedUsers': '大量用户',
|
'affectedUsers': '大量用户',
|
||||||
|
'expanded': false, // 添加展开状态
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 3,
|
'id': 3,
|
||||||
@@ -50,6 +52,7 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
'resolveTime': '2026-03-28',
|
'resolveTime': '2026-03-28',
|
||||||
'reportTime': '2026-03-15',
|
'reportTime': '2026-03-15',
|
||||||
'affectedUsers': '少数用户',
|
'affectedUsers': '少数用户',
|
||||||
|
'expanded': false, // 添加展开状态
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 4,
|
'id': 4,
|
||||||
@@ -61,6 +64,7 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
'resolveTime': '2026-04-20',
|
'resolveTime': '2026-04-20',
|
||||||
'reportTime': '2026-03-22',
|
'reportTime': '2026-03-22',
|
||||||
'affectedUsers': '部分用户',
|
'affectedUsers': '部分用户',
|
||||||
|
'expanded': false, // 添加展开状态
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 5,
|
'id': 5,
|
||||||
@@ -72,12 +76,24 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
'resolveTime': '2026-03-26',
|
'resolveTime': '2026-03-26',
|
||||||
'reportTime': '2026-03-18',
|
'reportTime': '2026-03-18',
|
||||||
'affectedUsers': '少数用户',
|
'affectedUsers': '少数用户',
|
||||||
|
'expanded': false, // 添加展开状态
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
final ScrollController _scrollController = ScrollController();
|
final ScrollController _scrollController = ScrollController();
|
||||||
bool _isRefreshing = false;
|
bool _isRefreshing = false;
|
||||||
|
|
||||||
|
// 切换bug展开状态
|
||||||
|
void _toggleBugExpanded(int bugId) {
|
||||||
|
setState(() {
|
||||||
|
final bugIndex = _bugs.indexWhere((bug) => bug['id'] == bugId);
|
||||||
|
if (bugIndex != -1) {
|
||||||
|
_bugs[bugIndex]['expanded'] = !_bugs[bugIndex]['expanded'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
HapticFeedback.lightImpact();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
@@ -231,6 +247,8 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBugItem(Map<String, dynamic> bug) {
|
Widget _buildBugItem(Map<String, dynamic> bug) {
|
||||||
|
final bool isExpanded = bug['expanded'] ?? false;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(bottom: 16),
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -352,87 +370,116 @@ class _BugListPageState extends State<BugListPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(height: 12),
|
||||||
),
|
// 解决方案按钮
|
||||||
),
|
Container(
|
||||||
// 分割线
|
width: double.infinity,
|
||||||
const Divider(height: 1),
|
child: ElevatedButton.icon(
|
||||||
// 解决方案区域
|
onPressed: () => _toggleBugExpanded(bug['id']),
|
||||||
Container(
|
icon: Icon(
|
||||||
padding: const EdgeInsets.all(16),
|
isExpanded ? Icons.expand_less : Icons.expand_more,
|
||||||
decoration: BoxDecoration(
|
size: 18,
|
||||||
color: Colors.grey[50],
|
|
||||||
borderRadius: const BorderRadius.only(
|
|
||||||
bottomLeft: Radius.circular(12),
|
|
||||||
bottomRight: Radius.circular(12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.lightbulb_outline,
|
|
||||||
color: AppConstants.primaryColor,
|
|
||||||
size: 16,
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
label: Text(
|
||||||
Text(
|
isExpanded ? '收起解决方案' : '查看解决方案',
|
||||||
'解决方案',
|
style: const TextStyle(fontSize: 14),
|
||||||
style: TextStyle(
|
),
|
||||||
fontSize: 14,
|
style: ElevatedButton.styleFrom(
|
||||||
fontWeight: FontWeight.w600,
|
backgroundColor: AppConstants.primaryColor.withValues(alpha: 0.1),
|
||||||
color: AppConstants.primaryColor,
|
foregroundColor: AppConstants.primaryColor,
|
||||||
|
elevation: 0,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
side: BorderSide(
|
||||||
|
color: AppConstants.primaryColor.withValues(alpha: 0.3),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
bug['solution'] ?? '暂无解决方案',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Colors.black54,
|
|
||||||
height: 1.4,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
|
||||||
// 时间信息
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.schedule,
|
|
||||||
size: 14,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
'预计解决: ${bug['resolveTime'] ?? '待定'}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Icon(
|
|
||||||
Icons.report,
|
|
||||||
size: 14,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
'报告时间: ${bug['reportTime'] ?? '未知'}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 解决方案区域(可展开/收起)
|
||||||
|
if (isExpanded) ...[
|
||||||
|
const Divider(height: 1),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[50],
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(12),
|
||||||
|
bottomRight: Radius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.lightbulb_outline,
|
||||||
|
color: AppConstants.primaryColor,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'解决方案',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: AppConstants.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
bug['solution'] ?? '暂无解决方案',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Colors.black54,
|
||||||
|
height: 1.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
// 时间信息
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.schedule,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'预计解决: ${bug['resolveTime'] ?? '待定'}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Icon(
|
||||||
|
Icons.report,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'报告时间: ${bug['reportTime'] ?? '未知'}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import 'package:intl/intl.dart';
|
|||||||
|
|
||||||
import '../../../constants/app_constants.dart';
|
import '../../../constants/app_constants.dart';
|
||||||
import '../../../controllers/sqlite_storage_controller.dart';
|
import '../../../controllers/sqlite_storage_controller.dart';
|
||||||
|
import '../../../controllers/history_controller.dart';
|
||||||
|
import '../../../services/network_listener_service.dart';
|
||||||
|
|
||||||
/// 时间: 2026-03-28
|
/// 时间: 2026-03-28
|
||||||
/// 功能: 答题记录页面
|
/// 功能: 答题记录页面
|
||||||
@@ -177,28 +179,68 @@ class _DistinguishPageState extends State<DistinguishPage> {
|
|||||||
|
|
||||||
// 标题
|
// 标题
|
||||||
Row(
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Row(
|
||||||
padding: const EdgeInsets.all(8),
|
children: [
|
||||||
decoration: BoxDecoration(
|
Container(
|
||||||
color: AppConstants.primaryColor.withAlpha(20),
|
padding: const EdgeInsets.all(8),
|
||||||
borderRadius: BorderRadius.circular(10),
|
decoration: BoxDecoration(
|
||||||
),
|
color: AppConstants.primaryColor.withAlpha(20),
|
||||||
child: Icon(
|
borderRadius: BorderRadius.circular(10),
|
||||||
Icons.analytics_outlined,
|
),
|
||||||
color: AppConstants.primaryColor,
|
child: Icon(
|
||||||
size: 24,
|
Icons.analytics_outlined,
|
||||||
),
|
color: AppConstants.primaryColor,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
const Text(
|
||||||
|
'本次答题记录',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
// 复制内容按钮
|
||||||
const Text(
|
if (_answerRecords.isNotEmpty)
|
||||||
'答题记录',
|
Container(
|
||||||
style: TextStyle(
|
decoration: BoxDecoration(
|
||||||
fontSize: 22,
|
color: AppConstants.primaryColor.withAlpha(15),
|
||||||
fontWeight: FontWeight.bold,
|
borderRadius: BorderRadius.circular(8),
|
||||||
color: Colors.black87,
|
border: Border.all(
|
||||||
|
color: AppConstants.primaryColor.withAlpha(50),
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: _copyStatisticsContent,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.copy,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.orange[700],
|
||||||
|
),
|
||||||
|
label: Text(
|
||||||
|
'添加笔记',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.orange[700],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12,
|
||||||
|
vertical: 6,
|
||||||
|
),
|
||||||
|
minimumSize: Size.zero,
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
@@ -703,4 +745,153 @@ $_poetryLevel
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 写入统计数据到笔记
|
||||||
|
Future<void> _copyStatisticsContent() async {
|
||||||
|
try {
|
||||||
|
// 生成完整的评估报告内容
|
||||||
|
final StringBuffer content = StringBuffer();
|
||||||
|
content.writeln('🎓 诗词答题记录评估报告');
|
||||||
|
content.writeln('');
|
||||||
|
content.writeln('📊 基础数据统计');
|
||||||
|
content.writeln('━━━━━━━━━━━━━━━━');
|
||||||
|
content.writeln('• 已答题数:$_totalQuestions 题');
|
||||||
|
content.writeln('• 正确数量:$_correctAnswers 题');
|
||||||
|
content.writeln('• 错误数量:$_wrongAnswers 题');
|
||||||
|
content.writeln('• 正确率:${_correctRate.toStringAsFixed(1)}%');
|
||||||
|
content.writeln('• 错误率:${_wrongRate.toStringAsFixed(1)}%');
|
||||||
|
content.writeln('• 平均用时:${_averageTime.toStringAsFixed(1)} 秒/题');
|
||||||
|
content.writeln('');
|
||||||
|
content.writeln('📈 辅助数据');
|
||||||
|
content.writeln('━━━━━━━━━━━━━━━━');
|
||||||
|
content.writeln('• 提示次数:$_hintCount 次');
|
||||||
|
content.writeln('• 跳过次数:$_skipCount 次');
|
||||||
|
content.writeln('');
|
||||||
|
content.writeln('🏆 诗词水平评估');
|
||||||
|
content.writeln('━━━━━━━━━━━━━━━━');
|
||||||
|
content.writeln('$_poetryLevel');
|
||||||
|
content.writeln('');
|
||||||
|
content.writeln('💡 AI评估提示');
|
||||||
|
content.writeln('━━━━━━━━━━━━━━━━');
|
||||||
|
content.writeln('请根据以上答题数据,综合评估我的诗词水平,并给出:');
|
||||||
|
content.writeln('1. 当前诗词水平的详细分析');
|
||||||
|
content.writeln('2. 薄弱环节和改进建议');
|
||||||
|
content.writeln('3. 推荐学习的诗词类型或朝代');
|
||||||
|
content.writeln('4. 适合的诗词学习路径建议');
|
||||||
|
content.writeln('');
|
||||||
|
content.writeln('感谢您的评估!');
|
||||||
|
|
||||||
|
// 保存到笔记
|
||||||
|
final noteId = await HistoryController.saveNote(
|
||||||
|
title: '诗词答题评估_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}',
|
||||||
|
content: content.toString(),
|
||||||
|
category: '答题评估',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (noteId != null) {
|
||||||
|
NetworkListenerService().sendSuccessEvent(
|
||||||
|
NetworkEventType.noteUpdate,
|
||||||
|
data: noteId,
|
||||||
|
);
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('评估报告已保存到笔记'),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('保存笔记失败: $e');
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text('保存笔记失败: $e')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从答题记录创建笔记
|
||||||
|
Future<void> _createNoteFromRecords() async {
|
||||||
|
try {
|
||||||
|
// 生成答题记录的详细内容
|
||||||
|
final StringBuffer content = StringBuffer();
|
||||||
|
content.writeln('## 答题记录汇总');
|
||||||
|
content.writeln(
|
||||||
|
'生成时间: ${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}',
|
||||||
|
);
|
||||||
|
content.writeln('总记录数: ${_answerRecords.length}');
|
||||||
|
content.writeln('');
|
||||||
|
|
||||||
|
// 统计信息
|
||||||
|
int correctCount = 0;
|
||||||
|
int totalCount = _answerRecords.length;
|
||||||
|
|
||||||
|
for (final record in _answerRecords) {
|
||||||
|
if (record['isCorrect'] == true) {
|
||||||
|
correctCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content.writeln('### 统计信息');
|
||||||
|
content.writeln('- 总题数: $totalCount');
|
||||||
|
content.writeln('- 答对数: $correctCount');
|
||||||
|
content.writeln('- 答错数: ${totalCount - correctCount}');
|
||||||
|
content.writeln(
|
||||||
|
'- 正确率: ${totalCount > 0 ? (correctCount / totalCount * 100).toStringAsFixed(1) : 0}%',
|
||||||
|
);
|
||||||
|
content.writeln('');
|
||||||
|
|
||||||
|
content.writeln('### 详细记录');
|
||||||
|
content.writeln('');
|
||||||
|
|
||||||
|
for (int i = 0; i < _answerRecords.length; i++) {
|
||||||
|
final record = _answerRecords[i];
|
||||||
|
final question = record['question'] ?? '未知题目';
|
||||||
|
final userAnswer = record['userAnswer'] ?? '未知答案';
|
||||||
|
final correctAnswer = record['correctAnswer'] ?? '未知答案';
|
||||||
|
final isCorrect = record['isCorrect'] == true;
|
||||||
|
final answerTime = record['answerTime'] ?? '未知时间';
|
||||||
|
final tags = record['tags'] as List<dynamic>? ?? [];
|
||||||
|
|
||||||
|
content.writeln('#### ${i + 1}. $question');
|
||||||
|
content.writeln('- **你的答案**: $userAnswer');
|
||||||
|
content.writeln('- **正确答案**: $correctAnswer');
|
||||||
|
content.writeln('- **答题结果**: ${isCorrect ? '✅ 正确' : '❌ 错误'}');
|
||||||
|
content.writeln('- **答题时间**: ${_formatTime(answerTime)}');
|
||||||
|
|
||||||
|
if (tags.isNotEmpty) {
|
||||||
|
content.writeln('- **标签**: ${tags.join(', ')}');
|
||||||
|
}
|
||||||
|
|
||||||
|
content.writeln('');
|
||||||
|
}
|
||||||
|
|
||||||
|
final noteId = await HistoryController.saveNote(
|
||||||
|
title: '答题记录_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}',
|
||||||
|
content: content.toString(),
|
||||||
|
category: '答题记录',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (noteId != null) {
|
||||||
|
NetworkListenerService().sendSuccessEvent(
|
||||||
|
NetworkEventType.noteUpdate,
|
||||||
|
data: noteId,
|
||||||
|
);
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(const SnackBar(content: Text('答题记录已保存到笔记')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('创建笔记失败: $e');
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text('创建笔记失败: $e')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ class _AppFunSettingsPageState extends State<AppFunSettingsPage> {
|
|||||||
bool _darkModeEnabled = false;
|
bool _darkModeEnabled = false;
|
||||||
bool _preloadEnabled = true;
|
bool _preloadEnabled = true;
|
||||||
bool _notificationEnabled = true;
|
bool _notificationEnabled = true;
|
||||||
|
bool _globalTipsEnabled = true; // 添加全局Tips开关状态
|
||||||
int _cacheSize = 128;
|
int _cacheSize = 128;
|
||||||
|
|
||||||
static const String _autoRefreshKey = 'auto_refresh_enabled';
|
static const String _autoRefreshKey = 'auto_refresh_enabled';
|
||||||
static const String _debugInfoKey = 'debug_info_enabled';
|
static const String _debugInfoKey = 'debug_info_enabled';
|
||||||
|
static const String _globalTipsKey = 'global_tips_enabled'; // 添加全局Tips开关key
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -42,6 +44,8 @@ class _AppFunSettingsPageState extends State<AppFunSettingsPage> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
_autoRefreshEnabled = prefs.getBool(_autoRefreshKey) ?? false;
|
_autoRefreshEnabled = prefs.getBool(_autoRefreshKey) ?? false;
|
||||||
_debugInfoEnabled = prefs.getBool(_debugInfoKey) ?? false;
|
_debugInfoEnabled = prefs.getBool(_debugInfoKey) ?? false;
|
||||||
|
_globalTipsEnabled =
|
||||||
|
prefs.getBool(_globalTipsKey) ?? true; // 加载全局Tips开关状态
|
||||||
_preloadEnabled = prefs.getBool('preload_enabled') ?? true;
|
_preloadEnabled = prefs.getBool('preload_enabled') ?? true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -78,6 +82,17 @@ class _AppFunSettingsPageState extends State<AppFunSettingsPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置全局Tips开关
|
||||||
|
Future<void> _setGlobalTips(bool value) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool(_globalTipsKey, value);
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_globalTipsEnabled = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -143,8 +158,8 @@ class _AppFunSettingsPageState extends State<AppFunSettingsPage> {
|
|||||||
'全局Tips开关',
|
'全局Tips开关',
|
||||||
'显示一些使用技巧',
|
'显示一些使用技巧',
|
||||||
Icons.volume_up,
|
Icons.volume_up,
|
||||||
_soundEnabled,
|
_globalTipsEnabled,
|
||||||
(value) => setState(() => _soundEnabled = value),
|
(value) => _setGlobalTips(value),
|
||||||
),
|
),
|
||||||
_buildSwitchItem(
|
_buildSwitchItem(
|
||||||
'声音反馈',
|
'声音反馈',
|
||||||
@@ -420,6 +435,7 @@ class _AppFunSettingsPageState extends State<AppFunSettingsPage> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
_soundEnabled = true;
|
_soundEnabled = true;
|
||||||
_vibrationEnabled = true;
|
_vibrationEnabled = true;
|
||||||
|
_globalTipsEnabled = true; // 重置全局Tips开关为开启
|
||||||
_darkModeEnabled = false;
|
_darkModeEnabled = false;
|
||||||
_notificationEnabled = true;
|
_notificationEnabled = true;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||||
|
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
audioplayers_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
@@ -5,10 +5,14 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import audioplayers_darwin
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
162
pubspec.lock
162
pubspec.lock
@@ -5,10 +5,82 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.0"
|
version: "2.13.1"
|
||||||
|
audioplayers:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "4.1.0"
|
||||||
|
audioplayers_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_android"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "3.0.2"
|
||||||
|
audioplayers_darwin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_darwin"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "4.1.0"
|
||||||
|
audioplayers_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_linux"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "2.1.0"
|
||||||
|
audioplayers_ohos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_ohos"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "3.0.2"
|
||||||
|
audioplayers_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_platform_interface"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "5.0.1"
|
||||||
|
audioplayers_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_web"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "3.1.0"
|
||||||
|
audioplayers_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/audioplayers_windows"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: e566d678531badc1437ada9fcca87c23d6355ba4
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_audioplayers.git"
|
||||||
|
source: git
|
||||||
|
version: "2.0.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -49,6 +121,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.9"
|
version: "4.0.9"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -61,10 +141,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
|
sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da"
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.5.0"
|
version: "11.3.0"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -117,10 +197,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "6.1.4"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -144,6 +224,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.6"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -160,6 +248,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.20.2"
|
version: "0.20.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.7"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -232,6 +328,31 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
path_provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/path_provider/path_provider"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: b7d7f892e446d198c596487fda3c57d8e054f9e0
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
|
||||||
|
source: git
|
||||||
|
version: "2.1.0"
|
||||||
|
path_provider_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_android
|
||||||
|
sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.23"
|
||||||
|
path_provider_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_foundation
|
||||||
|
sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -240,6 +361,15 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
|
path_provider_ohos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "packages/path_provider/path_provider_ohos"
|
||||||
|
ref: HEAD
|
||||||
|
resolved-ref: b7d7f892e446d198c596487fda3c57d8e054f9e0
|
||||||
|
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
|
||||||
|
source: git
|
||||||
|
version: "2.2.1"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -383,6 +513,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.4.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -415,6 +553,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.1"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -467,10 +613,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32_registry
|
name: win32_registry
|
||||||
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "1.1.5"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
11
pubspec.yaml
11
pubspec.yaml
@@ -42,6 +42,12 @@ dependencies:
|
|||||||
platform_info: ^5.0.0
|
platform_info: ^5.0.0
|
||||||
vibration: ^2.0.0 #删除
|
vibration: ^2.0.0 #删除
|
||||||
intl: ^0.20.2
|
intl: ^0.20.2
|
||||||
|
audioplayers:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_audioplayers.git
|
||||||
|
path: packages/audioplayers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -67,9 +73,8 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
assets:
|
||||||
# - images/a_dot_burr.jpeg
|
- assets/audios/deep.mp3
|
||||||
# - images/a_dot_ham.jpeg
|
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
audioplayers_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
Reference in New Issue
Block a user