import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:she_healthy_desktop/presentation/bloc/classification/classification_event.dart'; import 'package:she_healthy_desktop/presentation/components/generic/loading_widget.dart'; import 'package:she_healthy_desktop/presentation/components/glcm/glcm_table.dart'; import 'package:she_healthy_desktop/presentation/components/table/table_header_custom.dart'; import 'package:she_healthy_desktop/presentation/components/table/table_row_custom.dart'; import 'package:she_healthy_desktop/presentation/components/text/generic_radius_text_container.dart'; import 'package:she_healthy_desktop/utils/string_ext.dart'; import 'package:she_healthy_desktop/utils/tooltip_message.dart'; import '../../core/constant/glcm_type.dart'; import '../../core/theme/app_primary_theme.dart'; import '../bloc/classification/classification_bloc.dart'; import '../bloc/classification/classification_state.dart'; import '../components/button/primary_button.dart'; import '../components/dialog/dialog_component.dart'; import '../components/glcm/cnn_table.dart'; import '../components/image/image_place_holder_static.dart'; const noAssumption = 'Belum ada asumsi'; //Sebagai place holder const List nullData = []; class ClassificationDetailPage extends StatefulWidget { final ClassificationBloc bloc; const ClassificationDetailPage({Key? key, required this.bloc}) : super(key: key); @override State createState() => _ClassificationDetailPageState(); } class _ClassificationDetailPageState extends State { final List _data = []; @override void initState() { super.initState(); } Widget blocBuilder() { return BlocBuilder( bloc: widget.bloc, builder: (ctx, state) { if (state is ShowSuccessClassification) { try { _data.clear(); _data.addAll(state.data.split(',')); } catch (e) { return buildBody(nullData, noAssumption, null, null, null, true, glcmType: state.glcmType); } return buildBody( _data, glcmType: state.glcmType, state.assumption, state.image, state.classificationType, state.classificationType, pattern: state.pattern, feature: state.feature, time: state.time, akurasi: state.akurasi, false); } if (state is ShowLoading) { return buildBody(nullData, noAssumption, null, null, null, true); } return buildBody(nullData, noAssumption, null, null, null, false); }, ); } Widget blocListener({required Widget child}) { return BlocListener( bloc: widget.bloc, listener: (ctx, state) { if (state is ShowFailedClassification) { if (!mounted){ return; } showFailedDialog( context: context, title: "Terjadi Kesalahan", message: 'Sepertinya ada kesalahan dari server kami, coba lagi nanti!', onTap: () { Navigator.pop(context); }); return; } }, child: child, ); } @override Widget build(BuildContext context) { return blocListener(child: blocBuilder()); } Widget buildBody(List data, String assumption, File? image, String? method, String? cancerType, bool isLoading, {String? glcmType, String? pattern, String? feature, String? time, String? akurasi}) { return Stack( children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), margin: const EdgeInsets.symmetric(horizontal: 16), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Container( margin: const EdgeInsets.symmetric( horizontal: 12, vertical: 8), child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 12.0), child: Text( 'Properties', style: AppTheme.subTitle, ), ), buildTableGLCM(data, glcmType ?? ""), ], ), ), ), // Container( // margin: // const EdgeInsets.symmetric(horizontal: 12, vertical: 8), // child: Column( // mainAxisSize: MainAxisSize.min, // children: [ // Padding( // padding: const EdgeInsets.symmetric(vertical: 12.0), // ), // Container( // decoration: BoxDecoration( // color: Colors.grey, // borderRadius: BorderRadius.circular(8), // ), // height: 350, // width: 250, // child: SizedBox( // height: double.infinity, // width: double.infinity, // child: ClipRRect( // borderRadius: BorderRadius.circular(12), // child: image == null // ? const ImagePlaceHolderStatic() // : Image.file( // image, // fit: BoxFit.cover, // color: Colors.grey, // colorBlendMode: BlendMode.color, // ), // ), // ), // ), // ], // ), // ), ], ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Text( 'Analisa', style: AppTheme.subTitle, ), ), const SizedBox( height: 8, ), buildKesimpulan(method, cancerType, pattern: pattern, feature: feature, time: time, akurasi: akurasi, assumption: assumption), const SizedBox( height: 16, ), Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: PrimaryButton( width: double.infinity, color: Colors.redAccent, context: context, isEnabled: true, onPressed: () { widget.bloc.add(ResetClassification()); }, text: 'Reset'), ), const SizedBox( height: 32, ), ], ), ), ), Visibility( visible: isLoading, child: const Positioned( top: 0, bottom: 0, left: 0, right: 0, child: LoadingWidget())) ], ); } Widget buildKesimpulan(String? method, String? cancer, {String? pattern, String? feature, String? time, String? akurasi, String? assumption}) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), margin: const EdgeInsets.symmetric(horizontal: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Kelas Kanker: ', style: AppTheme.subTitle, ), Expanded( child: Text( assumption?? '', style: AppTheme.subTitleNonBold.copyWith( color: Colors.black87, fontWeight: FontWeight.normal, ), ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Pengenalan Pola: ', style: AppTheme.subTitle, ), Expanded( child: Text( pattern ?? '', style: AppTheme.subTitleNonBold.copyWith( color: Colors.black87, fontWeight: FontWeight.normal, ), ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Ketergantungan Jmlh Fitur: ', style: AppTheme.subTitle, ), Expanded( child: Text( feature ?? '', style: AppTheme.subTitleNonBold.copyWith( color: Colors.black87, fontWeight: FontWeight.normal, ), ), ), ], ) ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Efisiensi Waktu & Akurasi : ', style: AppTheme.subTitle, ), Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( time ?? '', style: AppTheme.subTitleNonBold.copyWith( color: Colors.black87, fontWeight: FontWeight.normal, ), ), Text( akurasi ?? '', style: AppTheme.subTitleNonBold.copyWith( color: Colors.black87, fontWeight: FontWeight.normal, ), ), ], ) ), ], ) ), ], ), ); } Widget buildTableGLCM(List data, String? typeGlcm) { if (typeGlcm == all) { return buildAllGLCM(data); } if (typeGlcm == cnnBreast) { return buildCnnLayerBreast(); } if (typeGlcm == cnnCervix) { return buildCnnLayerCervix(); } if (typeGlcm == pcaBreast) { return buildPcaBreastGLCM(data); } if (typeGlcm == pcaCervix) { return buildPcaCervixGLCM(data); } if (typeGlcm == regressionBreast) { return buildRegressionBreastGLCM(data); } if (typeGlcm == regressionCervix) { return buildRegressionCervixGLCM(data); } return buildCnnLayerBreast(); } TableRow buildDataRow( String property, String? val1, String? val2, String? val3, String? val4) { return TableRow( decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.black26), ), children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Text(property, style: const TextStyle(fontWeight: FontWeight.w500), textAlign: TextAlign.center), ), Text(val1.removeChars() ?? '-', textAlign: TextAlign.center), Text(val2.removeChars() ?? '-', textAlign: TextAlign.center), Text(val3.removeChars() ?? '-', textAlign: TextAlign.center), Text(val4.removeChars() ?? '-', textAlign: TextAlign.center), ]); } Widget rowText(String text) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text(text, textAlign: TextAlign.center), ); } Widget rowTextHeading(String text) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text( text, textAlign: TextAlign.center, style: const TextStyle(fontWeight: FontWeight.w600), ), ); } }