mirror of
https://github.com/foss42/apidash.git
synced 2025-08-06 13:51:20 +08:00
Merge pull request #334 from Yousef-Rabia/elapsed-time-by-request
Elapsed time by request
This commit is contained in:
@ -31,6 +31,7 @@ class RequestModel {
|
|||||||
this.message,
|
this.message,
|
||||||
this.responseModel,
|
this.responseModel,
|
||||||
this.isWorking = false,
|
this.isWorking = false,
|
||||||
|
this.sendingTime,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
@ -50,6 +51,7 @@ class RequestModel {
|
|||||||
final String? message;
|
final String? message;
|
||||||
final ResponseModel? responseModel;
|
final ResponseModel? responseModel;
|
||||||
final bool isWorking;
|
final bool isWorking;
|
||||||
|
final DateTime? sendingTime;
|
||||||
|
|
||||||
List<NameValueModel>? get enabledRequestHeaders =>
|
List<NameValueModel>? get enabledRequestHeaders =>
|
||||||
getEnabledRows(requestHeaders, isHeaderEnabledList);
|
getEnabledRows(requestHeaders, isHeaderEnabledList);
|
||||||
@ -135,6 +137,7 @@ class RequestModel {
|
|||||||
String? message,
|
String? message,
|
||||||
ResponseModel? responseModel,
|
ResponseModel? responseModel,
|
||||||
bool? isWorking,
|
bool? isWorking,
|
||||||
|
DateTime? sendingTime,
|
||||||
}) {
|
}) {
|
||||||
var headers = requestHeaders ?? this.requestHeaders;
|
var headers = requestHeaders ?? this.requestHeaders;
|
||||||
var params = requestParams ?? this.requestParams;
|
var params = requestParams ?? this.requestParams;
|
||||||
@ -160,6 +163,7 @@ class RequestModel {
|
|||||||
message: message ?? this.message,
|
message: message ?? this.message,
|
||||||
responseModel: responseModel ?? this.responseModel,
|
responseModel: responseModel ?? this.responseModel,
|
||||||
isWorking: isWorking ?? this.isWorking,
|
isWorking: isWorking ?? this.isWorking,
|
||||||
|
sendingTime: sendingTime ?? this.sendingTime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,10 @@ class CollectionStateNotifier
|
|||||||
|
|
||||||
// set current model's isWorking to true and update state
|
// set current model's isWorking to true and update state
|
||||||
var map = {...state!};
|
var map = {...state!};
|
||||||
map[id] = requestModel.copyWith(isWorking: true);
|
map[id] = requestModel.copyWith(
|
||||||
|
isWorking: true,
|
||||||
|
sendingTime: DateTime.now(),
|
||||||
|
);
|
||||||
state = map;
|
state = map;
|
||||||
|
|
||||||
(http.Response?, Duration?, String?)? responseRec = await request(
|
(http.Response?, Duration?, String?)? responseRec = await request(
|
||||||
|
@ -12,12 +12,17 @@ class ResponsePane extends ConsumerWidget {
|
|||||||
final isWorking = ref.watch(
|
final isWorking = ref.watch(
|
||||||
selectedRequestModelProvider.select((value) => value?.isWorking)) ??
|
selectedRequestModelProvider.select((value) => value?.isWorking)) ??
|
||||||
false;
|
false;
|
||||||
|
final startSendingTime = ref.watch(
|
||||||
|
selectedRequestModelProvider.select((value) => value?.sendingTime));
|
||||||
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 (isWorking) {
|
if (isWorking) {
|
||||||
return const SendingWidget();
|
return SendingWidget(
|
||||||
|
startSendingTime: startSendingTime,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (responseStatus == null) {
|
if (responseStatus == null) {
|
||||||
return const NotSentWidget();
|
return const NotSentWidget();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
import 'package:http_parser/http_parser.dart';
|
||||||
@ -33,18 +34,80 @@ class NotSentWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SendingWidget extends StatelessWidget {
|
class SendingWidget extends StatefulWidget {
|
||||||
const SendingWidget({super.key});
|
final DateTime? startSendingTime;
|
||||||
|
const SendingWidget({
|
||||||
|
super.key,
|
||||||
|
required this.startSendingTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SendingWidget> createState() => _SendingWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SendingWidgetState extends State<SendingWidget> {
|
||||||
|
int _millisecondsElapsed = 0;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
if (widget.startSendingTime != null) {
|
||||||
|
_millisecondsElapsed =
|
||||||
|
(DateTime.now().difference(widget.startSendingTime!).inMilliseconds ~/
|
||||||
|
100) *
|
||||||
|
100;
|
||||||
|
_timer = Timer.periodic(const Duration(milliseconds: 100), _updateTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateTimer(Timer timer) {
|
||||||
|
setState(() {
|
||||||
|
_millisecondsElapsed += 100;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
if (_timer != null && _timer!.isActive) _timer?.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(
|
return Stack(
|
||||||
child: Column(
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Lottie.asset(kAssetSendingLottie),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: kPh20t40,
|
||||||
|
child: Visibility(
|
||||||
|
visible: _millisecondsElapsed >= 0,
|
||||||
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Lottie.asset(kAssetSendingLottie),
|
Icon(
|
||||||
|
Icons.alarm,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Time elapsed: ${humanizeDuration(Duration(milliseconds: _millisecondsElapsed))}',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
softWrap: false,
|
||||||
|
style: kTextStyleButton.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,15 @@ import 'package:apidash/models/models.dart';
|
|||||||
import '../test_consts.dart';
|
import '../test_consts.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Testing Sending Widget', (tester) async {
|
testWidgets('Testing Sending Widget Without Timer', (tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
title: 'Send',
|
title: 'Send',
|
||||||
theme: kThemeDataDark,
|
theme: kThemeDataDark,
|
||||||
home: const Scaffold(
|
home: const Scaffold(
|
||||||
body: SendingWidget(),
|
body: SendingWidget(
|
||||||
|
startSendingTime: null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -24,6 +26,26 @@ void main() {
|
|||||||
expect(find.byType(Lottie), findsOneWidget);
|
expect(find.byType(Lottie), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Testing Sending Widget With Timer', (tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
title: 'Send',
|
||||||
|
theme: kThemeDataDark,
|
||||||
|
home: Scaffold(
|
||||||
|
body: SendingWidget(
|
||||||
|
startSendingTime: DateTime.now(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(find.text('Time elapsed: 0 ms'), findsOneWidget);
|
||||||
|
expect(find.byType(Lottie), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.pump(const Duration(seconds: 1));
|
||||||
|
|
||||||
|
expect(find.text('Time elapsed: 1.00 s'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Testing Not Sent Widget', (tester) async {
|
testWidgets('Testing Not Sent Widget', (tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
|
Reference in New Issue
Block a user