@@ -5,12 +5,12 @@ import 'package:bloc/bloc.dart';
5
5
import 'package:bloc_concurrency/bloc_concurrency.dart' ;
6
6
import 'package:equatable/equatable.dart' ;
7
7
import 'package:komodo_defi_sdk/komodo_defi_sdk.dart' ;
8
+ import 'package:logging/logging.dart' ;
8
9
import 'package:web_dex/bloc/cex_market_data/charts.dart' ;
9
10
import 'package:web_dex/bloc/cex_market_data/profit_loss/profit_loss_repository.dart' ;
10
11
import 'package:web_dex/mm2/mm2_api/rpc/base.dart' ;
11
12
import 'package:web_dex/model/coin.dart' ;
12
13
import 'package:web_dex/model/text_error.dart' ;
13
- import 'package:web_dex/shared/utils/utils.dart' as logger;
14
14
15
15
part 'profit_loss_event.dart' ;
16
16
part 'profit_loss_state.dart' ;
@@ -32,6 +32,8 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
32
32
final ProfitLossRepository _profitLossRepository;
33
33
final KomodoDefiSdk _sdk;
34
34
35
+ final _log = Logger ('ProfitLossBloc' );
36
+
35
37
void _onClearPortfolioProfitLoss (
36
38
ProfitLossPortfolioChartClearRequested event,
37
39
Emitter <ProfitLossState > emit,
@@ -57,21 +59,22 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
57
59
58
60
await _getProfitLossChart (event, coins, useCache: true )
59
61
.then (emit.call)
60
- .catchError ((e, _) {
61
- logger.log ('Failed to load portfolio profit/loss: $e ' , isError: true );
62
+ .catchError ((Object error, StackTrace stackTrace) {
63
+ const errorMessage = 'Failed to load CACHED portfolio profit/loss' ;
64
+ // log warning here, because cached
65
+ _log.warning (errorMessage, error, stackTrace);
62
66
if (state is ! PortfolioProfitLossChartLoadSuccess ) {
63
67
emit (
64
68
ProfitLossLoadFailure (
65
- error:
66
- TextError (error: 'Failed to load portfolio profit/loss: $e ' ),
69
+ error: TextError (error: errorMessage),
67
70
selectedPeriod: event.selectedPeriod,
68
71
),
69
72
);
70
73
}
71
74
});
72
75
73
76
// Fetch the un-cached version of the chart to update the cache.
74
- coins = await _removeUnsupportedCons (event, allowInactiveCoins : false );
77
+ coins = await _removeUnsupportedCons (event);
75
78
if (coins.isNotEmpty) {
76
79
await _getProfitLossChart (event, coins, useCache: false )
77
80
.then (emit.call)
@@ -82,20 +85,18 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
82
85
// data and update the graph.
83
86
});
84
87
}
85
- } catch (e) {
86
- logger
87
- .log ('Failed to load portfolio profit/loss: $e ' , isError: true )
88
- .ignore ();
88
+ } catch (error, stackTrace) {
89
+ _log.shout ('Failed to load portfolio profit/loss' , e, stackTrace);
89
90
emit (
90
91
ProfitLossLoadFailure (
91
- error: TextError (error: 'Failed to load portfolio profit/loss: $ e ' ),
92
+ error: TextError (error: 'Failed to load portfolio profit/loss' ),
92
93
selectedPeriod: event.selectedPeriod,
93
94
),
94
95
);
95
96
}
96
97
97
98
await emit.forEach (
98
- // computation is omitted, so null-valued events are emitted on a set
99
+ // computation is omitted, so null-valued events are emitted on a set
99
100
// interval.
100
101
Stream <Object ?>.periodic (event.updateFrequency).asyncMap ((_) async {
101
102
return _getSortedProfitLossChartForCoins (
@@ -121,15 +122,9 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
121
122
);
122
123
},
123
124
onError: (e, s) {
124
- logger
125
- .log (
126
- 'Failed to load portfolio profit/loss: $e ' ,
127
- isError: true ,
128
- trace: s,
129
- )
130
- .ignore ();
125
+ _log.shout ('Failed to load portfolio profit/loss' , e, s);
131
126
return ProfitLossLoadFailure (
132
- error: TextError (error: 'Failed to load portfolio profit/loss: $ e ' ),
127
+ error: TextError (error: 'Failed to load portfolio profit/loss' ),
133
128
selectedPeriod: event.selectedPeriod,
134
129
);
135
130
},
@@ -159,21 +154,19 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
159
154
}
160
155
161
156
Future <List <Coin >> _removeUnsupportedCons (
162
- ProfitLossPortfolioChartLoadRequested event, {
163
- bool allowInactiveCoins = true ,
164
- }) async {
157
+ ProfitLossPortfolioChartLoadRequested event,
158
+ ) async {
165
159
final List <Coin > coins = List .from (event.coins);
166
160
for (final coin in event.coins) {
167
161
final isCoinSupported = await _profitLossRepository.isCoinChartSupported (
168
162
coin.id,
169
163
event.fiatCoinId,
170
- allowInactiveCoins: allowInactiveCoins,
171
164
);
172
165
if (coin.isTestCoin || ! isCoinSupported) {
173
166
coins.remove (coin);
174
167
}
175
168
}
176
- return coins;
169
+ return _removeInactiveCoins ( coins) ;
177
170
}
178
171
179
172
Future <void > _onPortfolioPeriodChanged (
@@ -182,26 +175,18 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
182
175
) async {
183
176
final eventState = state;
184
177
if (eventState is ! PortfolioProfitLossChartLoadSuccess ) {
185
- emit (
178
+ return emit (
186
179
PortfolioProfitLossChartLoadInProgress (
187
180
selectedPeriod: event.selectedPeriod,
188
181
),
189
182
);
190
183
}
191
-
192
- assert (
193
- eventState is PortfolioProfitLossChartLoadSuccess ,
194
- 'Selected period can only be changed when '
195
- 'the state is PortfolioProfitLossChartLoadSuccess' ,
196
- );
197
-
198
- final successState = eventState as PortfolioProfitLossChartLoadSuccess ;
199
184
add (
200
185
ProfitLossPortfolioChartLoadRequested (
201
- coins: successState .coins,
202
- fiatCoinId: successState .fiatCurrency,
186
+ coins: eventState .coins,
187
+ fiatCoinId: eventState .fiatCurrency,
203
188
selectedPeriod: event.selectedPeriod,
204
- walletId: successState .walletId,
189
+ walletId: eventState .walletId,
205
190
),
206
191
);
207
192
}
@@ -227,22 +212,24 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
227
212
useCache: useCache,
228
213
);
229
214
230
- final startIndex = profitLosses.indexOf (
231
- profitLosses.firstWhere ((element) => element.profitLoss != 0 ),
232
- );
233
-
234
- if (startIndex == - 1 ) {
235
- profitLosses.removeRange (0 , startIndex);
215
+ final firstNonZeroProfitLossIndex =
216
+ profitLosses.indexWhere ((element) => element.profitLoss != 0 );
217
+ if (firstNonZeroProfitLossIndex == - 1 ) {
218
+ _log.info (
219
+ 'No non-zero profit/loss data found for coin ${coin .abbr }' ,
220
+ );
221
+ return ChartData .empty ();
236
222
}
237
223
238
- return profitLosses.toChartData ();
239
- } catch (e) {
240
- logger
241
- .log (
242
- 'Failed to load cached profit/loss for coin ${coin .abbr }: $e ' ,
243
- isError: true ,
244
- )
245
- .ignore ();
224
+ final nonZeroProfitLosses =
225
+ profitLosses.sublist (firstNonZeroProfitLossIndex);
226
+ return nonZeroProfitLosses.toChartData ();
227
+ } catch (e, s) {
228
+ _log.severe (
229
+ 'Failed to load cached profit/loss for coin ${coin .abbr }' ,
230
+ e,
231
+ s,
232
+ );
246
233
return ChartData .empty ();
247
234
}
248
235
}),
@@ -251,4 +238,16 @@ class ProfitLossBloc extends Bloc<ProfitLossEvent, ProfitLossState> {
251
238
chartsList.removeWhere ((element) => element.isEmpty);
252
239
return Charts .merge (chartsList)..sort ((a, b) => a.x.compareTo (b.x));
253
240
}
241
+
242
+ Future <List <Coin >> _removeInactiveCoins (List <Coin > coins) async {
243
+ final coinsCopy = List <Coin >.of (coins);
244
+ final activeCoins = await _sdk.assets.getActivatedAssets ();
245
+ final activeCoinsMap = activeCoins.map ((e) => e.id).toSet ();
246
+ for (final coin in coins) {
247
+ if (! activeCoinsMap.contains (coin.id)) {
248
+ coinsCopy.remove (coin);
249
+ }
250
+ }
251
+ return coinsCopy;
252
+ }
254
253
}
0 commit comments