device predication implemented

main_production_copilot
WaseemAbbasi22 3 weeks ago
parent 2ae26cc363
commit 2121cd7d9d

@ -10,6 +10,7 @@ import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/asset_by_id_model.dart'; import 'package:test_sa/models/device/asset_by_id_model.dart';
import 'package:test_sa/models/device/asset_search.dart'; import 'package:test_sa/models/device/asset_search.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
@ -259,31 +260,30 @@ class AssetProvider extends ChangeNotifier {
} }
} }
Future<bool> predictDevice(File imageFile) async { Future<PredictDeviceResponse?> predictDevice(File image) async {
late Response response;
try { try {
final files = <Future<MultipartFile>>[ final files = <Future<MultipartFile>>[
MultipartFile.fromPath( MultipartFile.fromPath(
'file', 'file',
imageFile.path, image.path,
), ),
]; ];
log('Uploading file: ${files.first.runtimeType}');
response = await ApiManager.instance.multiPart( final response = await ApiManager.instance.multiPart(
URLs.predictDevice, URLs.predictDevice,
body: {}, body: {},
files: files, files: files,
); );
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
return true; final responseData = json.decode(response.body)['data'];
return PredictDeviceResponse.fromJson(responseData);
}else{
return null;
} }
return false;
} catch (error) { } catch (error) {
log('error: $error'); debugPrint('error i got in predictDevice: $error');
return false; return null;
} }
} }
} }

@ -13,10 +13,10 @@ class PredictDeviceResponse {
success = json['success']; success = json['success'];
timestamp = json['timestamp']; timestamp = json['timestamp'];
if (json['PredictedAsset'] != null) { if (json['predictedAsset'] != null) {
predictedAsset = <PredictedAsset>[]; predictedAsset = <PredictedAsset>[];
for (var item in json['PredictedAsset']) { for (var item in json['predictedAsset']) {
predictedAsset!.add( predictedAsset!.add(
PredictedAsset.fromJson(item), PredictedAsset.fromJson(item),
); );
@ -28,7 +28,7 @@ class PredictDeviceResponse {
return { return {
'success': success, 'success': success,
'timestamp': timestamp, 'timestamp': timestamp,
'PredictedAsset': 'predictedAsset':
predictedAsset?.map((e) => e.toJson()).toList(), predictedAsset?.map((e) => e.toJson()).toList(),
}; };
} }

@ -1,5 +1,5 @@
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@ -12,13 +12,16 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/modules/tm_module/device_transfer/device_filter_screen.dart'; import 'package:test_sa/modules/tm_module/device_transfer/device_filter_screen.dart';
import 'package:test_sa/modules/tm_module/device_transfer/device_search_screen.dart'; import 'package:test_sa/modules/tm_module/device_transfer/device_search_screen.dart';
import 'package:test_sa/modules/export_module/pages/export_form_view.dart'; import 'package:test_sa/modules/export_module/pages/export_form_view.dart';
import 'package:test_sa/modules/export_module/models/export_module_type.dart'; import 'package:test_sa/modules/export_module/models/export_module_type.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart'; import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart';
import 'package:test_sa/views/widgets/equipment/asset_item_gridview.dart'; import 'package:test_sa/views/widgets/equipment/asset_item_gridview.dart';
import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart'; import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart';
import 'package:test_sa/views/widgets/equipment/predict_device_list.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -685,8 +688,17 @@ class _MyAssetsPageState extends State<MyAssetsPage> with SingleTickerProviderSt
Future<void> _uploadImage(File imageFile) async { Future<void> _uploadImage(File imageFile) async {
try { try {
await _devicesProvider.predictDevice(imageFile); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
//PredictDeviceView PredictDeviceResponse? response = await _devicesProvider.predictDevice(imageFile);
Navigator.pop(context);
if (response != null && response.success == true) {
final List<PredictedAsset> predictedAssetList = response.predictedAsset ?? [];
if (predictedAssetList.isNotEmpty) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PredictDeviceView(predictedAsset: predictedAssetList)));
} else {
debugPrint('No Predicted asset found in the response.');
}
}
} catch (e) { } catch (e) {
debugPrint('Upload error: $e'); debugPrint('Upload error: $e');
} }

@ -17,8 +17,8 @@ class PredictDeviceItemGridView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
device.assetName!.cleanupWhitespace.capitalizeFirstOfEach, device.assetName!.cleanupWhitespace.capitalizeFirstOfEach,
@ -26,29 +26,12 @@ class PredictDeviceItemGridView extends StatelessWidget {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: AppTextStyles.bodyText.copyWith(color: AppColor.textStyleColor(context)), style: AppTextStyles.bodyText.copyWith(color: AppColor.textStyleColor(context)),
), ),
Column( InfoTextWidget(label: context.translation.assetNumber, value: device.metadata?.assetNumber),
crossAxisAlignment: CrossAxisAlignment.start, InfoTextWidget(label: 'Matching Percentage', value: device.confidencePercent),
mainAxisSize: MainAxisSize.min, InfoTextWidget(label: context.translation.oracleCode, value: device.metadata?.oracleCode),
children: [ InfoTextWidget(label: context.translation.site, value: device.metadata?.siteName),
InfoTextWidget(label: context.translation.assetNumber, value: device.metadata?.assetNumber), InfoTextWidget(label: context.translation.department, value: device.metadata?.departmentName,showArrow: true,),
InfoTextWidget(label: 'Matching Percentage', value: device.confidencePercent),
InfoTextWidget(label: context.translation.oracleCode, value: device.metadata?.oracleCode),
InfoTextWidget(label: context.translation.site, value: device.metadata?.siteName),
InfoTextWidget(label: context.translation.department, value: device.metadata?.departmentName),
],
).expanded,
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'View Details',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.primary10),
),
4.width,
const Icon(Icons.arrow_forward, color: AppColor.primary10, size: 14)
],
),
], ],
).expanded.onPress(() => onPressed(device)).toShadowContainer(context); ).onPress(() => onPressed(device)).toShadowContainer(context);
} }
} }

@ -22,34 +22,14 @@ class PredictDeviceItemView extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( InfoHeaderWidget(device.assetName!.cleanupWhitespace),
crossAxisAlignment: CrossAxisAlignment.start, 4.height,
mainAxisSize: MainAxisSize.min, InfoTextWidget(label: context.translation.assetNumber, value: device.metadata?.assetNumber),
children: [ InfoTextWidget(label: 'Confidence Percentage', value: device.confidencePercent),
InfoHeaderWidget(device.assetName!.cleanupWhitespace), InfoTextWidget(label: context.translation.oracleCode, value: device.metadata?.oracleCode),
4.height, InfoTextWidget(label: context.translation.site, value: device.metadata?.siteName),
InfoTextWidget(label: context.translation.assetNumber, value: device.metadata?.assetNumber), InfoTextWidget(label: context.translation.department, value: device.metadata?.departmentName,showArrow: true,),
InfoTextWidget(label: 'Matching Percentage', value: device.confidencePercent),
InfoTextWidget(label: context.translation.oracleCode, value: device.metadata?.oracleCode),
InfoTextWidget(label: context.translation.site, value: device.metadata?.siteName),
InfoTextWidget(label: context.translation.department, value: device.metadata?.departmentName),
],
),
Align(
alignment: Alignment.bottomRight,
child: selectButton ??
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
context.translation.viewDetails,
style: AppTextStyles.bodyText2.copyWith(color: AppColor.primary10),
),
4.width,
const Icon(Icons.arrow_forward, color: AppColor.primary10, size: 14)
],
))
], ],
).expanded.toShadowContainer(context, borderColor: isSelected ? AppColor.primary10 : Colors.transparent).onPress(() => onPressed(device)); ).toShadowContainer(context, borderColor: isSelected ? AppColor.primary10 : Colors.transparent).onPress(() => onPressed(device));
} }
} }

@ -13,7 +13,7 @@ import 'package:test_sa/views/widgets/equipment/predict_device_item_view.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
class PredictDeviceView extends StatefulWidget { class PredictDeviceView extends StatefulWidget {
static const String id = "/single-device-Picker"; static const String id = "/predict_device_view";
List<PredictedAsset> predictedAsset; List<PredictedAsset> predictedAsset;
PredictDeviceView({Key? key, required this.predictedAsset}) : super(key: key); PredictDeviceView({Key? key, required this.predictedAsset}) : super(key: key);
@ -63,118 +63,114 @@ class _PredictDeviceViewState extends State<PredictDeviceView> with SingleTicker
), ),
], ],
), ),
body: SafeArea( body: Stack(
child: Column( children: [
children: [ AnimatedSwitcher(
Expanded( duration: const Duration(milliseconds: 500),
child: widget.predictedAsset.isEmpty child: showListView
? NoDataFound(message: context.translation.noDeviceFound).center ? ListView.separated(
: Stack( key: const ValueKey('list_view'),
children: [ padding: const EdgeInsets.all(16),
AnimatedSwitcher( itemCount: widget.predictedAsset.length,
duration: const Duration(milliseconds: 500), separatorBuilder: (listContext, itemIndex) => 12.height,
child: showListView itemBuilder: (listContext, itemIndex) {
? ListView.separated( // Calculate staggered animation delay
key: const ValueKey('list_view'), final delay = itemIndex * 0.08;
padding: const EdgeInsets.all(16), final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
itemCount: widget.predictedAsset.length, CurvedAnimation(
separatorBuilder: (listContext, itemIndex) => 12.height, parent: _animationController,
itemBuilder: (listContext, itemIndex) { curve: Interval(
// Calculate staggered animation delay delay.clamp(0.0, 0.7),
final delay = itemIndex * 0.08; (delay + 0.4).clamp(0.0, 1.0),
final animation = Tween<double>(begin: 0.0, end: 1.0).animate( curve: Curves.easeOut,
CurvedAnimation( ),
parent: _animationController, ),
curve: Interval( );
delay.clamp(0.0, 0.7),
(delay + 0.4).clamp(0.0, 1.0),
curve: Curves.easeOut,
),
),
);
final slideAnimation = Tween<Offset>( final slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.15), begin: const Offset(0.0, 0.15),
end: Offset.zero, end: Offset.zero,
).animate( ).animate(
CurvedAnimation( CurvedAnimation(
parent: _animationController, parent: _animationController,
curve: Interval( curve: Interval(
delay.clamp(0.0, 0.7), delay.clamp(0.0, 0.7),
(delay + 0.4).clamp(0.0, 1.0), (delay + 0.4).clamp(0.0, 1.0),
curve: Curves.easeOutCubic, curve: Curves.easeOutCubic,
), ),
), ),
); );
return FadeTransition( return FadeTransition(
opacity: animation, opacity: animation,
child: SlideTransition( child: SlideTransition(
position: slideAnimation, position: slideAnimation,
child: PredictDeviceItemView( child: PredictDeviceItemView(
device: widget.predictedAsset[itemIndex], device: widget.predictedAsset[itemIndex],
onPressed: (device) { onPressed: (device) {
Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.assetId); //We are not getting asset id in response only have serial number
}, // Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.assetId);
), },
), ),
); ),
}, );
) },
: GridView.builder( )
key: const ValueKey('grid_view'), : GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 188 / 261, crossAxisSpacing: 12, mainAxisSpacing: 12), key: const ValueKey('grid_view'),
itemCount: widget.predictedAsset.length, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
padding: const EdgeInsets.all(16), crossAxisCount: 2,
itemBuilder: (context, index) { crossAxisSpacing: 12,
// Calculate staggered animation delay childAspectRatio: 1.5,
final delay = index * 0.08; mainAxisSpacing: 12),
final animation = Tween<double>(begin: 0.0, end: 1.0).animate( itemCount: widget.predictedAsset.length,
CurvedAnimation( padding: const EdgeInsets.all(16),
parent: _animationController, itemBuilder: (context, index) {
curve: Interval( // Calculate staggered animation delay
delay.clamp(0.0, 0.8), final delay = index * 0.08;
(delay + 0.3).clamp(0.0, 1.0), final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
curve: Curves.easeOut, CurvedAnimation(
), parent: _animationController,
), curve: Interval(
); delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOut,
),
),
);
final slideAnimation = Tween<Offset>( final slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.3), begin: const Offset(0.0, 0.3),
end: Offset.zero, end: Offset.zero,
).animate( ).animate(
CurvedAnimation( CurvedAnimation(
parent: _animationController, parent: _animationController,
curve: Interval( curve: Interval(
delay.clamp(0.0, 0.8), delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0), (delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOutCubic, curve: Curves.easeOutCubic,
), ),
), ),
); );
return FadeTransition( return FadeTransition(
opacity: animation, opacity: animation,
child: SlideTransition( child: SlideTransition(
position: slideAnimation, position: slideAnimation,
child: PredictDeviceItemGridView( child: PredictDeviceItemGridView(
device: widget.predictedAsset[index], device: widget.predictedAsset[index],
onPressed: (device) { onPressed: (device) {
Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.assetId); //We are not getting asset id in response only have serial number
}, // Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.assetId);
), },
), ),
); ),
}, );
), },
), ),
if (_devicesProvider.isLoading) Align(alignment: Alignment.bottomCenter, child: CircularProgressIndicator().paddingOnly(top: 16, bottom: 16)), ),
], ],
)), ),
],
),
),
); );
} }
} }

Loading…
Cancel
Save