feat(app): responsive asset detail layout, full width chart, reactive hero header, shimmer loaders and enriched fundamentals
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../models/asset_model.dart';
|
||||
import '../../models/fundamental_data_model.dart';
|
||||
import '../../models/technical_analysis_model.dart';
|
||||
import '../../repositories/asset_repository.dart';
|
||||
import 'asset_header_event.dart';
|
||||
import 'asset_header_state.dart';
|
||||
import '../../repositories/asset_repository.dart';
|
||||
import '../../models/asset_model.dart';
|
||||
|
||||
class AssetHeaderBloc extends Bloc<AssetHeaderEvent, AssetHeaderState> {
|
||||
final AssetRepository repository;
|
||||
@@ -11,21 +13,41 @@ class AssetHeaderBloc extends Bloc<AssetHeaderEvent, AssetHeaderState> {
|
||||
final prevData = state is AssetHeaderLoaded ? (state as AssetHeaderLoaded).data : (state is AssetHeaderLoading ? (state as AssetHeaderLoading).previousData : null);
|
||||
emit(AssetHeaderLoading(previousData: prevData));
|
||||
try {
|
||||
final fundamentals = await repository.getAssetFundamentals(event.isin, event.forceRefresh, ticker: event.ticker);
|
||||
final results = await Future.wait([
|
||||
repository.getAssetFundamentals(event.isin, event.forceRefresh, ticker: event.ticker),
|
||||
repository.getAssetTechnical(event.isin, event.forceRefresh, ticker: event.ticker),
|
||||
]);
|
||||
|
||||
final fundamentals = results[0] as FundamentalDataModel?;
|
||||
final technical = results[1] as TechnicalAnalysisModel?;
|
||||
|
||||
if (fundamentals != null) {
|
||||
double initialPrice = fundamentals.currentPrice;
|
||||
String initialCurrency = fundamentals.tradingCurrency ?? 'EUR';
|
||||
|
||||
if (technical != null && technical.candles.isNotEmpty) {
|
||||
final lastClose = technical.candles.last.close;
|
||||
if (lastClose > 0) {
|
||||
initialPrice = lastClose;
|
||||
}
|
||||
if (technical.currency.isNotEmpty) {
|
||||
initialCurrency = technical.currency;
|
||||
}
|
||||
}
|
||||
|
||||
final assetModel = AssetModel(
|
||||
isin: fundamentals.isin,
|
||||
symbol: fundamentals.primaryTicker.isNotEmpty ? fundamentals.primaryTicker : fundamentals.isin,
|
||||
name: fundamentals.companyName,
|
||||
currentPrice: fundamentals.currentPrice,
|
||||
currency: fundamentals.tradingCurrency ?? 'EUR',
|
||||
currentPrice: initialPrice,
|
||||
currency: initialCurrency,
|
||||
exchange: fundamentals.exchange ?? 'XETRA',
|
||||
exchanges: [], // Can be populated if needed
|
||||
exchanges: [],
|
||||
tickers: fundamentals.availableTickers.map((t) => AssetTickerOption(
|
||||
ticker: t.ticker,
|
||||
exchange: t.exchange ?? 'Unknown',
|
||||
tradingCurrency: t.tradingCurrency ?? fundamentals.tradingCurrency ?? 'EUR',
|
||||
currentPrice: t.currentPrice,
|
||||
tradingCurrency: t.tradingCurrency ?? initialCurrency,
|
||||
currentPrice: t.currentPrice ?? initialPrice,
|
||||
)).toList(),
|
||||
image: '/api/v1/logo/${fundamentals.isin}',
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../trades/models/trade_model.dart';
|
||||
import 'asset_trades_event.dart';
|
||||
import 'asset_trades_state.dart';
|
||||
import '../../repositories/asset_repository.dart';
|
||||
@@ -17,9 +18,20 @@ class AssetTradesBloc extends Bloc<AssetTradesEvent, AssetTradesState> {
|
||||
}
|
||||
});
|
||||
on<TriggerManualAnalysis>((event, emit) async {
|
||||
emit(AssetTradesLoading());
|
||||
try {
|
||||
await repository.triggerManualAnalysis(event.isin, payload: event.payload);
|
||||
add(LoadAssetTrades(event.isin));
|
||||
final analysisRes = await repository.triggerManualAnalysis(event.isin, payload: event.payload);
|
||||
final existingTrades = await repository.getAssetTrades(event.isin, null);
|
||||
|
||||
final list = List<TradeModel>.from(existingTrades);
|
||||
final newProposal = analysisRes?.proposal;
|
||||
if (newProposal != null) {
|
||||
final isDuplicate = list.any((t) => t.id == newProposal.id || (t.analysisId.isNotEmpty && t.analysisId == newProposal.analysisId));
|
||||
if (!isDuplicate) {
|
||||
list.insert(0, newProposal);
|
||||
}
|
||||
}
|
||||
emit(AssetTradesLoaded(list));
|
||||
} catch (e) {
|
||||
emit(AssetTradesError("Failed to trigger manual analysis: $e"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user