fix: resolve errors in MultiStreamBuilder and income display
This commit is contained in:
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart'; // Used indirectly by SpendingPieChart
|
||||
import 'package:intl/intl.dart'; // For date formatting
|
||||
import 'dart:async';
|
||||
import 'package:async/async.dart'; // Import StreamZip
|
||||
|
||||
// Removed import 'dart:math'; // No longer needed for random data
|
||||
|
||||
import '../database/database.dart' as db; // Import database with prefix 'db'
|
||||
@@ -226,10 +228,12 @@ class _ExpensesScreenState extends State<ExpensesScreen> with TickerProviderStat
|
||||
],
|
||||
builder: (context, snapshots) {
|
||||
// Handle loading states for all streams
|
||||
// FIX: Call .any on the list `snapshots`
|
||||
if (snapshots.any((s) => s.connectionState == ConnectionState.waiting && !s.hasData)) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
// Handle error states for all streams
|
||||
// FIX: Call .any on the list `snapshots`
|
||||
if (snapshots.any((s) => s.hasError)) {
|
||||
// Combine error messages or show a generic one
|
||||
String errors = snapshots.where((s) => s.hasError).map((s) => s.error.toString()).join('\n');
|
||||
@@ -495,9 +499,10 @@ class _ExpensesScreenState extends State<ExpensesScreen> with TickerProviderStat
|
||||
// Get the db.Transaction object from the stream
|
||||
final dbTransaction = transactions[index];
|
||||
// Get the corresponding category details (icon, color) - use defaults for income
|
||||
final categoryDetails = dbTransaction.type == 'expense'
|
||||
// FIX: Define icon/color directly for income, no CategoryDetails class
|
||||
final ({IconData iconCode, Color colorCode}) categoryDetails = dbTransaction.type == 'expense'
|
||||
? CategoryUtils.getCategoryDetails(dbTransaction.categoryName)
|
||||
: CategoryDetails( // Default/Placeholder for Income type
|
||||
: ( // Default/Placeholder for Income type
|
||||
iconCode: Icons.attach_money, // Or a more specific income icon
|
||||
colorCode: Colors.green,
|
||||
);
|
||||
@@ -580,6 +585,7 @@ class _ExpensesScreenState extends State<ExpensesScreen> with TickerProviderStat
|
||||
// Helper widget to manage multiple streams for the main body
|
||||
class MultiStreamBuilder extends StatelessWidget {
|
||||
final List<Stream<dynamic>> streams;
|
||||
// FIX: Use AsyncWidgetBuilder<List<AsyncSnapshot<dynamic>>> for clarity
|
||||
final AsyncWidgetBuilder<List<AsyncSnapshot<dynamic>>> builder;
|
||||
|
||||
const MultiStreamBuilder({
|
||||
@@ -595,19 +601,35 @@ class MultiStreamBuilder extends StatelessWidget {
|
||||
stream: StreamZip(streams), // Use StreamZip to combine latest values
|
||||
builder: (context, snapshot) {
|
||||
// Create a list of AsyncSnapshot objects from the combined snapshot data
|
||||
final List<AsyncSnapshot<dynamic>> snapshots = streams.map((stream) {
|
||||
// Find the corresponding data in the combined snapshot
|
||||
// This assumes StreamZip maintains order, which it does.
|
||||
int index = streams.indexOf(stream);
|
||||
dynamic data = snapshot.hasData ? snapshot.data![index] : null;
|
||||
// Reconstruct individual AsyncSnapshot states
|
||||
return AsyncSnapshot<dynamic>(
|
||||
connectionState: snapshot.connectionState,
|
||||
data: data,
|
||||
error: snapshot.error, // Note: StreamZip might only report the first error
|
||||
stackTrace: snapshot.stackTrace,
|
||||
);
|
||||
}).toList();
|
||||
final List<AsyncSnapshot<dynamic>> snapshots = List.generate(
|
||||
streams.length,
|
||||
(index) {
|
||||
// Reconstruct individual AsyncSnapshot states based on the combined snapshot
|
||||
if (snapshot.connectionState == ConnectionState.waiting && !snapshot.hasData) {
|
||||
// If waiting and no data yet, return waiting snapshot
|
||||
return AsyncSnapshot<dynamic>.waiting();
|
||||
}
|
||||
if (snapshot.hasError) {
|
||||
// If combined stream has error, propagate error
|
||||
// Note: StreamZip might only report the first error
|
||||
return AsyncSnapshot<dynamic>.withError(
|
||||
snapshot.connectionState,
|
||||
snapshot.error!,
|
||||
snapshot.stackTrace ?? StackTrace.empty,
|
||||
);
|
||||
}
|
||||
if (snapshot.hasData) {
|
||||
// If data exists, extract the data for this specific stream index
|
||||
return AsyncSnapshot<dynamic>.withData(
|
||||
snapshot.connectionState,
|
||||
snapshot.data![index], // Assumes StreamZip maintains order
|
||||
);
|
||||
}
|
||||
// Default/fallback case (e.g., ConnectionState.none)
|
||||
return AsyncSnapshot<dynamic>.nothing();
|
||||
},
|
||||
growable: false, // Fixed-size list
|
||||
);
|
||||
|
||||
return builder(context, snapshots);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user