Merge pull request #236 from opxdelwin/issue-114

[feat] Enable parallel request handling
This commit is contained in:
Ankit Mahato
2024-03-09 15:01:32 +05:30
committed by GitHub
7 changed files with 54 additions and 61 deletions

View File

@ -29,6 +29,7 @@ class RequestModel {
this.responseStatus, this.responseStatus,
this.message, this.message,
this.responseModel, this.responseModel,
this.isWorking = false,
}); });
final String id; final String id;
@ -47,6 +48,7 @@ class RequestModel {
final int? responseStatus; final int? responseStatus;
final String? message; final String? message;
final ResponseModel? responseModel; final ResponseModel? responseModel;
final bool isWorking;
List<NameValueModel>? get enabledRequestHeaders => List<NameValueModel>? get enabledRequestHeaders =>
getEnabledRows(requestHeaders, isHeaderEnabledList); getEnabledRows(requestHeaders, isHeaderEnabledList);
@ -106,6 +108,7 @@ class RequestModel {
int? responseStatus, int? responseStatus,
String? message, String? message,
ResponseModel? responseModel, ResponseModel? responseModel,
bool? isWorking,
}) { }) {
var headers = requestHeaders ?? this.requestHeaders; var headers = requestHeaders ?? this.requestHeaders;
var params = requestParams ?? this.requestParams; var params = requestParams ?? this.requestParams;
@ -129,6 +132,7 @@ class RequestModel {
responseStatus: responseStatus ?? this.responseStatus, responseStatus: responseStatus ?? this.responseStatus,
message: message ?? this.message, message: message ?? this.message,
responseModel: responseModel ?? this.responseModel, responseModel: responseModel ?? this.responseModel,
isWorking: isWorking ?? this.isWorking,
); );
} }

View File

@ -156,11 +156,20 @@ class CollectionStateNotifier
} }
Future<void> sendRequest(String id) async { Future<void> sendRequest(String id) async {
ref.read(sentRequestIdStateProvider.notifier).state = id;
ref.read(codePaneVisibleStateProvider.notifier).state = false; ref.read(codePaneVisibleStateProvider.notifier).state = false;
final defaultUriScheme = final defaultUriScheme = ref.read(
ref.read(settingsProvider.select((value) => value.defaultUriScheme)); settingsProvider.select(
(value) => value.defaultUriScheme,
),
);
RequestModel requestModel = state![id]!; RequestModel requestModel = state![id]!;
// set current model's isWorking to true and update state
var map = {...state!};
map[id] = requestModel.copyWith(isWorking: true);
state = map;
(http.Response?, Duration?, String?)? responseRec = await request( (http.Response?, Duration?, String?)? responseRec = await request(
requestModel, requestModel,
defaultUriScheme: defaultUriScheme, defaultUriScheme: defaultUriScheme,
@ -172,6 +181,7 @@ class CollectionStateNotifier
newRequestModel = requestModel.copyWith( newRequestModel = requestModel.copyWith(
responseStatus: -1, responseStatus: -1,
message: responseRec.$3, message: responseRec.$3,
isWorking: false,
); );
} else { } else {
final responseModel = baseResponseModel.fromResponse( final responseModel = baseResponseModel.fromResponse(
@ -183,10 +193,12 @@ class CollectionStateNotifier
responseStatus: statusCode, responseStatus: statusCode,
message: kResponseCodeReasons[statusCode], message: kResponseCodeReasons[statusCode],
responseModel: responseModel, responseModel: responseModel,
isWorking: false,
); );
} }
ref.read(sentRequestIdStateProvider.notifier).state = null;
var map = {...state!}; // update state with response data
map = {...state!};
map[id] = newRequestModel; map[id] = newRequestModel;
state = map; state = map;
} }

View File

@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
final navRailIndexStateProvider = StateProvider<int>((ref) => 0); final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null); final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);
final sentRequestIdStateProvider = StateProvider<String?>((ref) => null);
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false); final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
final saveDataStateProvider = StateProvider<bool>((ref) => false); final saveDataStateProvider = StateProvider<bool>((ref) => false);
final clearDataStateProvider = StateProvider<bool>((ref) => false); final clearDataStateProvider = StateProvider<bool>((ref) => false);

View File

@ -9,13 +9,14 @@ class ResponsePane extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider); final isWorking = ref.watch(
final sentRequestId = ref.watch(sentRequestIdStateProvider); selectedRequestModelProvider.select((value) => value?.isWorking)) ??
false;
final responseStatus = ref.watch( final responseStatus = ref.watch(
selectedRequestModelProvider.select((value) => value?.responseStatus)); selectedRequestModelProvider.select((value) => value?.responseStatus));
final message = ref final message = ref
.watch(selectedRequestModelProvider.select((value) => value?.message)); .watch(selectedRequestModelProvider.select((value) => value?.message));
if (sentRequestId != null && sentRequestId == selectedId) { if (isWorking) {
return const SendingWidget(); return const SendingWidget();
} }
if (responseStatus == null) { if (responseStatus == null) {

View File

@ -98,10 +98,11 @@ class SendButton extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final selectedId = ref.watch(selectedIdStateProvider); final selectedId = ref.watch(selectedIdStateProvider);
final sentRequestId = ref.watch(sentRequestIdStateProvider); final isWorking = ref.watch(
selectedRequestModelProvider.select((value) => value?.isWorking));
return SendRequestButton( return SendRequestButton(
selectedId: selectedId, isWorking: isWorking ?? false,
sentRequestId: sentRequestId,
onTap: () { onTap: () {
ref ref
.read(collectionStateNotifierProvider.notifier) .read(collectionStateNotifierProvider.notifier)

View File

@ -47,36 +47,37 @@ class CopyButton extends StatelessWidget {
class SendRequestButton extends StatelessWidget { class SendRequestButton extends StatelessWidget {
const SendRequestButton({ const SendRequestButton({
super.key, super.key,
required this.selectedId, required this.isWorking,
required this.sentRequestId,
required this.onTap, required this.onTap,
}); });
final String? selectedId; final bool isWorking;
final String? sentRequestId;
final void Function() onTap; final void Function() onTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool disable = sentRequestId != null;
return FilledButton( return FilledButton(
onPressed: disable ? null : onTap, onPressed: isWorking ? null : onTap,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: isWorking
Text( ? const [
disable Text(
? (selectedId == sentRequestId ? kLabelSending : kLabelBusy) kLabelSending,
: kLabelSend, style: kTextStyleButton,
style: kTextStyleButton, ),
), ]
if (!disable) kHSpacer10, : const [
if (!disable) Text(
const Icon( kLabelSend,
size: 16, style: kTextStyleButton,
Icons.send, ),
), kHSpacer10,
], Icon(
size: 16,
Icons.send,
),
],
), ),
); );
} }

View File

@ -36,8 +36,7 @@ void main() {
theme: kThemeDataLight, theme: kThemeDataLight,
home: Scaffold( home: Scaffold(
body: SendRequestButton( body: SendRequestButton(
selectedId: '1', isWorking: false,
sentRequestId: null,
onTap: () { onTap: () {
changedValue = 'Send'; changedValue = 'Send';
}, },
@ -55,7 +54,8 @@ void main() {
expect(changedValue, 'Send'); expect(changedValue, 'Send');
}); });
testWidgets('Testing for Send Request button when sentRequestId is not null', testWidgets(
'Testing for Send Request button when RequestModel is viewed and is waiting for response',
(tester) async { (tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
@ -63,32 +63,7 @@ void main() {
theme: kThemeDataLight, theme: kThemeDataLight,
home: Scaffold( home: Scaffold(
body: SendRequestButton( body: SendRequestButton(
selectedId: '1', isWorking: true,
sentRequestId: '2',
onTap: () {},
),
),
),
);
expect(find.byIcon(Icons.send), findsNothing);
expect(find.text(kLabelBusy), findsOneWidget);
final button1 = find.byType(FilledButton);
expect(button1, findsOneWidget);
expect(tester.widget<FilledButton>(button1).enabled, isFalse);
});
testWidgets('Testing for Send Request button when sentRequestId = selectedId',
(tester) async {
await tester.pumpWidget(
MaterialApp(
title: 'Send Request button',
theme: kThemeDataLight,
home: Scaffold(
body: SendRequestButton(
selectedId: '1',
sentRequestId: '1',
onTap: () {}, onTap: () {},
), ),
), ),