import 'dart:io'; import 'package:drift/drift.dart' show Value; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:okane/database/sqlite.dart'; import 'package:okane/i18n/strings.g.dart'; import 'package:okane/ui/state/core.dart'; import 'package:okane/ui/utils.dart'; import 'package:okane/ui/widgets/image_wrapper.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as p; class TransactionDetailsPage extends StatelessWidget { final bool isPage; const TransactionDetailsPage({this.isPage = false, super.key}); static MaterialPageRoute get mobileRoute => MaterialPageRoute(builder: (_) => TransactionDetailsPage(isPage: true)); Future _updateBeneficiaryIcon(Beneficiary beneficiary) async { final pickedFile = await FilePicker.platform.pickFiles( type: FileType.image, ); if (pickedFile == null) { return; } final file = pickedFile.files.first; final suppPath = await getApplicationSupportDirectory(); final imageDir = p.join(suppPath.path, "beneficiaries"); final imagePath = p.join(imageDir, file.name); print("Copying ${file.path!} to $imagePath"); await Directory(imageDir).create(recursive: true); if (beneficiary.imagePath != null) { await File(beneficiary.imagePath!).delete(); } await File(file.path!).copy(imagePath); print("Updating DB"); await GetIt.I.get().beneficiariesDao.upsertBeneficiary( beneficiary.copyWith(imagePath: Value(imagePath)).toCompanion(false), ); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ if (isPage) SizedBox( height: 50, child: Row( children: [ IconButton( icon: Icon(Icons.arrow_back), onPressed: () { Navigator.of(context).pop(); }, ), ], ), ), Expanded( child: BlocBuilder( builder: (context, state) { if (state.activeTransaction == null) { return Text( t.pages.transactions.details.noTransactionSelected, ); } return Padding( padding: const EdgeInsets.all(8.0), child: ListView( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ StreamBuilder( stream: GetIt.I .get() .beneficiariesDao .watchBeneficiary( state.activeTransaction!.beneficiary.id, ), builder: (context, snapshot) { final obj = snapshot.data ?? state.activeTransaction!.beneficiary; return ImageWrapper( title: obj.name, path: obj.imagePath, onTap: () => _updateBeneficiaryIcon(obj), width: 90, height: 90, ); }, ), Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.arrow_forward_rounded), Padding( padding: EdgeInsets.only(left: 8), child: Text( state .activeTransaction! .beneficiary .name, ), ), ], ), Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.arrow_back_rounded), Padding( padding: EdgeInsets.only(left: 8), child: Text( GetIt.I .get() .activeAccount! .name!, ), ), ], ), ], ), ), Spacer(), IconButton( icon: Icon(Icons.edit), onPressed: () { // TODO: Implement }, ), ], ), // TODO /* Wrap( spacing: 8, children: state.activeTransaction!.tags .map((tag) => Chip(label: Text(tag))) .toList(), ),*/ if (state.activeTransaction!.expenseCategory != null) Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text(t.common.expenseCategory.name), Padding( padding: EdgeInsets.only(left: 16), child: Chip( label: Text( state .activeTransaction! .expenseCategory! .name, ), ), ), ], ), ), Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ state.activeTransaction!.transaction.amount > 0 ? Icon(Icons.add) : Icon(Icons.remove), Text( formatCurrency( state.activeTransaction!.transaction.amount, ), ), ], ), ), ], ), ); }, ), ), ], ), ); } }