feat: 优化前端 UI 与交互体验
This commit is contained in:
@@ -5,6 +5,7 @@ import '../../../../core/di/injection.dart';
|
||||
import '../../../../core/theme/design_tokens.dart';
|
||||
import '../../../../shared/widgets/app_button.dart';
|
||||
import '../../../../shared/widgets/app_loading_indicator.dart';
|
||||
import '../../../../shared/widgets/app_pull_refresh_feedback.dart';
|
||||
import '../../../../shared/widgets/app_pressable.dart';
|
||||
import '../../../../shared/widgets/app_sheet_input_field.dart';
|
||||
import '../../../../shared/widgets/toast/toast.dart';
|
||||
@@ -26,6 +27,7 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
|
||||
List<TodoResponse> _todos = [];
|
||||
bool _isLoading = true;
|
||||
bool _isPullRefreshing = false;
|
||||
bool _loadingTodosRequest = false;
|
||||
String? _error;
|
||||
|
||||
@@ -35,15 +37,19 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
_loadTodos();
|
||||
}
|
||||
|
||||
Future<void> _loadTodos() async {
|
||||
if (_loadingTodosRequest) {
|
||||
Future<void> _loadTodos({bool showPageLoader = true}) async {
|
||||
if (_loadingTodosRequest || _isPullRefreshing) {
|
||||
return;
|
||||
}
|
||||
_loadingTodosRequest = true;
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
if (showPageLoader) {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
} else {
|
||||
_isPullRefreshing = true;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -54,20 +60,32 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
setState(() {
|
||||
_todos = todos;
|
||||
_isLoading = false;
|
||||
_isPullRefreshing = false;
|
||||
_error = null;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_error = e.toString();
|
||||
_isLoading = false;
|
||||
});
|
||||
if (showPageLoader) {
|
||||
setState(() {
|
||||
_error = e.toString();
|
||||
_isLoading = false;
|
||||
_isPullRefreshing = false;
|
||||
});
|
||||
} else {
|
||||
setState(() => _isPullRefreshing = false);
|
||||
Toast.show(context, '刷新失败,请稍后重试', type: ToastType.error);
|
||||
}
|
||||
} finally {
|
||||
_loadingTodosRequest = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onPullRefresh() async {
|
||||
await _loadTodos(showPageLoader: false);
|
||||
}
|
||||
|
||||
List<TodoResponse> get _importantUrgent =>
|
||||
_todos.where((t) => t.priority == 1).toList();
|
||||
|
||||
@@ -239,44 +257,57 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: _loadTodos,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 4, bottom: 96),
|
||||
child: ListView(
|
||||
children: [
|
||||
_buildQuadrant(
|
||||
title: '重要紧急',
|
||||
textColor: AppColors.g1Text,
|
||||
dividerColor: AppColors.g1Divider,
|
||||
borderColor: AppColors.g1Border,
|
||||
items: _importantUrgent,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
return Stack(
|
||||
children: [
|
||||
RefreshIndicator.noSpinner(
|
||||
onRefresh: _onPullRefresh,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
top: 4,
|
||||
bottom: 96,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildQuadrant(
|
||||
title: '紧急不重要',
|
||||
textColor: AppColors.g2Text,
|
||||
dividerColor: AppColors.g2Divider,
|
||||
borderColor: AppColors.g2Border,
|
||||
items: _urgentNotImportant,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
child: ListView(
|
||||
children: [
|
||||
_buildQuadrant(
|
||||
title: '重要紧急',
|
||||
textColor: AppColors.g1Text,
|
||||
dividerColor: AppColors.g1Divider,
|
||||
borderColor: AppColors.g1Border,
|
||||
items: _importantUrgent,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildQuadrant(
|
||||
title: '紧急不重要',
|
||||
textColor: AppColors.g2Text,
|
||||
dividerColor: AppColors.g2Divider,
|
||||
borderColor: AppColors.g2Border,
|
||||
items: _urgentNotImportant,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildQuadrant(
|
||||
title: '重要不紧急',
|
||||
textColor: AppColors.g3Text,
|
||||
dividerColor: AppColors.g3Divider,
|
||||
borderColor: AppColors.g3Border,
|
||||
items: _importantNotUrgent,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildQuadrant(
|
||||
title: '重要不紧急',
|
||||
textColor: AppColors.g3Text,
|
||||
dividerColor: AppColors.g3Divider,
|
||||
borderColor: AppColors.g3Border,
|
||||
items: _importantNotUrgent,
|
||||
onComplete: _completeTodo,
|
||||
onTap: _navigateToDetail,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppPullRefreshFeedback(visible: _isPullRefreshing),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user